braintrust 3.3.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/README.md +52 -67
- package/dev/dist/index.d.mts +98 -14
- package/dev/dist/index.d.ts +98 -14
- package/dev/dist/index.js +2751 -1463
- package/dev/dist/index.mjs +2383 -1095
- package/dist/auto-instrumentations/bundler/esbuild.cjs +476 -31
- 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 +476 -31
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +476 -31
- 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 +476 -31
- 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-DQTPSXJB.mjs +733 -0
- package/dist/auto-instrumentations/chunk-EVUKFMHG.mjs +41 -0
- package/dist/auto-instrumentations/{chunk-OLOPGWTJ.mjs → chunk-F3TJZ3Z2.mjs} +1 -1
- package/dist/auto-instrumentations/chunk-VLEJ5AEK.mjs +41 -0
- package/dist/auto-instrumentations/hook.mjs +540 -37
- package/dist/auto-instrumentations/index.cjs +476 -31
- package/dist/auto-instrumentations/index.d.mts +5 -5
- package/dist/auto-instrumentations/index.d.ts +5 -5
- 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 +11 -12
- 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 +806 -306
- package/dist/browser.d.ts +806 -306
- package/dist/browser.js +3235 -2317
- package/dist/browser.mjs +3235 -2317
- package/dist/cli.js +2672 -1347
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +3035 -2087
- package/dist/edge-light.mjs +3035 -2087
- package/dist/index.d.mts +806 -306
- package/dist/index.d.ts +806 -306
- package/dist/index.js +3570 -2654
- package/dist/index.mjs +3235 -2319
- package/dist/instrumentation/index.d.mts +16 -22
- package/dist/instrumentation/index.d.ts +16 -22
- package/dist/instrumentation/index.js +2241 -1077
- package/dist/instrumentation/index.mjs +2241 -1077
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +3035 -2087
- package/dist/workerd.mjs +3035 -2087
- package/package.json +26 -7
- package/dist/auto-instrumentations/chunk-KVX7OFPD.mjs +0 -288
- package/dist/auto-instrumentations/chunk-XDBPUTVE.mjs +0 -22
- package/dist/auto-instrumentations/chunk-ZEC7BCL4.mjs +0 -22
package/dev/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/node/config.ts
|
|
2
2
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
|
+
import * as diagnostics_channel from "node:diagnostics_channel";
|
|
3
4
|
import * as path from "node:path";
|
|
4
5
|
import * as fs from "node:fs/promises";
|
|
5
6
|
import * as os from "node:os";
|
|
@@ -21,6 +22,72 @@ var DefaultAsyncLocalStorage = class {
|
|
|
21
22
|
return void 0;
|
|
22
23
|
}
|
|
23
24
|
};
|
|
25
|
+
var DefaultChannel = class {
|
|
26
|
+
constructor(name) {
|
|
27
|
+
this.name = name;
|
|
28
|
+
}
|
|
29
|
+
hasSubscribers = false;
|
|
30
|
+
subscribe(_subscription) {
|
|
31
|
+
}
|
|
32
|
+
unsubscribe(_subscription) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
bindStore(_store, _transform) {
|
|
36
|
+
}
|
|
37
|
+
unbindStore(_store) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
publish(_message) {
|
|
41
|
+
}
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
+
runStores(_message, fn, thisArg, ...args) {
|
|
44
|
+
return fn.apply(thisArg, args);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var DefaultTracingChannel = class {
|
|
48
|
+
start;
|
|
49
|
+
end;
|
|
50
|
+
asyncStart;
|
|
51
|
+
asyncEnd;
|
|
52
|
+
error;
|
|
53
|
+
constructor(nameOrChannels) {
|
|
54
|
+
if (typeof nameOrChannels === "string") {
|
|
55
|
+
this.start = new DefaultChannel(`tracing:${nameOrChannels}:start`);
|
|
56
|
+
this.end = new DefaultChannel(`tracing:${nameOrChannels}:end`);
|
|
57
|
+
this.asyncStart = new DefaultChannel(
|
|
58
|
+
`tracing:${nameOrChannels}:asyncStart`
|
|
59
|
+
);
|
|
60
|
+
this.asyncEnd = new DefaultChannel(`tracing:${nameOrChannels}:asyncEnd`);
|
|
61
|
+
this.error = new DefaultChannel(`tracing:${nameOrChannels}:error`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this.start = nameOrChannels.start ?? new DefaultChannel("tracing:start");
|
|
65
|
+
this.end = nameOrChannels.end ?? new DefaultChannel("tracing:end");
|
|
66
|
+
this.asyncStart = nameOrChannels.asyncStart ?? new DefaultChannel("tracing:asyncStart");
|
|
67
|
+
this.asyncEnd = nameOrChannels.asyncEnd ?? new DefaultChannel("tracing:asyncEnd");
|
|
68
|
+
this.error = nameOrChannels.error ?? new DefaultChannel("tracing:error");
|
|
69
|
+
}
|
|
70
|
+
get hasSubscribers() {
|
|
71
|
+
return this.start.hasSubscribers || this.end.hasSubscribers || this.asyncStart.hasSubscribers || this.asyncEnd.hasSubscribers || this.error.hasSubscribers;
|
|
72
|
+
}
|
|
73
|
+
subscribe(_handlers) {
|
|
74
|
+
}
|
|
75
|
+
unsubscribe(_handlers) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
79
|
+
traceSync(fn, _message, thisArg, ...args) {
|
|
80
|
+
return fn.apply(thisArg, args);
|
|
81
|
+
}
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
|
+
tracePromise(fn, _message, thisArg, ...args) {
|
|
84
|
+
return Promise.resolve(fn.apply(thisArg, args));
|
|
85
|
+
}
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
+
traceCallback(fn, _position, _message, thisArg, ...args) {
|
|
88
|
+
return fn.apply(thisArg, args);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
24
91
|
var iso = {
|
|
25
92
|
buildType: "unknown",
|
|
26
93
|
// Will be set by configureBrowser() or configureNode()
|
|
@@ -29,6 +96,8 @@ var iso = {
|
|
|
29
96
|
getEnv: (_name) => void 0,
|
|
30
97
|
getCallerLocation: () => void 0,
|
|
31
98
|
newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
100
|
+
newTracingChannel: (nameOrChannels) => new DefaultTracingChannel(nameOrChannels),
|
|
32
101
|
processOn: (_0, _1) => {
|
|
33
102
|
},
|
|
34
103
|
basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
|
|
@@ -36,6 +105,111 @@ var iso = {
|
|
|
36
105
|
};
|
|
37
106
|
var isomorph_default = iso;
|
|
38
107
|
|
|
108
|
+
// src/debug-logger.ts
|
|
109
|
+
var PREFIX = "[braintrust]";
|
|
110
|
+
var DEBUG_LOG_LEVEL_SYMBOL = Symbol.for("braintrust-debug-log-level");
|
|
111
|
+
var LOG_LEVEL_PRIORITY = {
|
|
112
|
+
error: 0,
|
|
113
|
+
warn: 1,
|
|
114
|
+
info: 2,
|
|
115
|
+
debug: 3
|
|
116
|
+
};
|
|
117
|
+
var hasWarnedAboutInvalidEnvValue = false;
|
|
118
|
+
var debugLogStateResolver = void 0;
|
|
119
|
+
function warnInvalidEnvValue(value) {
|
|
120
|
+
if (hasWarnedAboutInvalidEnvValue) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
hasWarnedAboutInvalidEnvValue = true;
|
|
124
|
+
console.warn(
|
|
125
|
+
PREFIX,
|
|
126
|
+
`Invalid BRAINTRUST_DEBUG_LOG_LEVEL value "${value}". Expected "error", "warn", "info", or "debug".`
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
function normalizeDebugLogLevelOption(option) {
|
|
130
|
+
if (option === false) {
|
|
131
|
+
return void 0;
|
|
132
|
+
}
|
|
133
|
+
if (option === "error" || option === "warn" || option === "info" || option === "debug") {
|
|
134
|
+
return option;
|
|
135
|
+
}
|
|
136
|
+
throw new Error(
|
|
137
|
+
`Invalid debugLogLevel value "${option}". Expected false, "error", "warn", "info", or "debug".`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
function parseDebugLogLevelEnv(value) {
|
|
141
|
+
if (!value) {
|
|
142
|
+
return void 0;
|
|
143
|
+
}
|
|
144
|
+
if (value === "error" || value === "warn" || value === "info" || value === "debug") {
|
|
145
|
+
return value;
|
|
146
|
+
}
|
|
147
|
+
warnInvalidEnvValue(value);
|
|
148
|
+
return void 0;
|
|
149
|
+
}
|
|
150
|
+
function getEnvDebugLogLevel() {
|
|
151
|
+
return parseDebugLogLevelEnv(isomorph_default.getEnv("BRAINTRUST_DEBUG_LOG_LEVEL"));
|
|
152
|
+
}
|
|
153
|
+
function setGlobalDebugLogLevel(level) {
|
|
154
|
+
globalThis[DEBUG_LOG_LEVEL_SYMBOL] = level;
|
|
155
|
+
}
|
|
156
|
+
function setDebugLogStateResolver(resolver) {
|
|
157
|
+
debugLogStateResolver = resolver;
|
|
158
|
+
}
|
|
159
|
+
function resolveDebugLogLevel(state) {
|
|
160
|
+
const stateLevel = state?.getDebugLogLevel?.();
|
|
161
|
+
const hasStateOverride = state?.hasDebugLogLevelOverride?.() ?? false;
|
|
162
|
+
if (hasStateOverride) {
|
|
163
|
+
return stateLevel;
|
|
164
|
+
}
|
|
165
|
+
const globalLevel = (
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
167
|
+
globalThis[DEBUG_LOG_LEVEL_SYMBOL]
|
|
168
|
+
);
|
|
169
|
+
if (globalLevel !== void 0) {
|
|
170
|
+
return globalLevel === false ? void 0 : globalLevel;
|
|
171
|
+
}
|
|
172
|
+
return getEnvDebugLogLevel();
|
|
173
|
+
}
|
|
174
|
+
function emit(method, state, args) {
|
|
175
|
+
const level = resolveDebugLogLevel(state);
|
|
176
|
+
if (!level || LOG_LEVEL_PRIORITY[method] > LOG_LEVEL_PRIORITY[level]) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (method === "info") {
|
|
180
|
+
console.log(PREFIX, ...args);
|
|
181
|
+
} else if (method === "debug") {
|
|
182
|
+
console.debug(PREFIX, ...args);
|
|
183
|
+
} else if (method === "warn") {
|
|
184
|
+
console.warn(PREFIX, ...args);
|
|
185
|
+
} else {
|
|
186
|
+
console.error(PREFIX, ...args);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function createDebugLogger(state) {
|
|
190
|
+
const resolveState = () => state ?? debugLogStateResolver?.();
|
|
191
|
+
return {
|
|
192
|
+
info(...args) {
|
|
193
|
+
emit("info", resolveState(), args);
|
|
194
|
+
},
|
|
195
|
+
debug(...args) {
|
|
196
|
+
emit("debug", resolveState(), args);
|
|
197
|
+
},
|
|
198
|
+
warn(...args) {
|
|
199
|
+
emit("warn", resolveState(), args);
|
|
200
|
+
},
|
|
201
|
+
error(...args) {
|
|
202
|
+
emit("error", resolveState(), args);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
var debugLogger = {
|
|
207
|
+
...createDebugLogger(),
|
|
208
|
+
forState(state) {
|
|
209
|
+
return createDebugLogger(state);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
39
213
|
// src/gitutil.ts
|
|
40
214
|
import { simpleGit } from "simple-git";
|
|
41
215
|
var COMMON_BASE_BRANCHES = ["main", "master", "develop"];
|
|
@@ -116,7 +290,7 @@ async function getPastNAncestors(n = 1e3, remote = void 0) {
|
|
|
116
290
|
try {
|
|
117
291
|
ancestor = await getBaseBranchAncestor(remote);
|
|
118
292
|
} catch (e) {
|
|
119
|
-
|
|
293
|
+
debugLogger.warn(
|
|
120
294
|
"Skipping git metadata. This is likely because the repository has not been published to a remote yet.",
|
|
121
295
|
`${e}`
|
|
122
296
|
);
|
|
@@ -261,7 +435,7 @@ var Queue = class {
|
|
|
261
435
|
enforceSizeLimit = false;
|
|
262
436
|
constructor(maxSize) {
|
|
263
437
|
if (maxSize < 1) {
|
|
264
|
-
|
|
438
|
+
debugLogger.warn(
|
|
265
439
|
`maxSize ${maxSize} is <1, using default ${DEFAULT_QUEUE_SIZE}`
|
|
266
440
|
);
|
|
267
441
|
maxSize = DEFAULT_QUEUE_SIZE;
|
|
@@ -2206,6 +2380,8 @@ var Experiment = z6.object({
|
|
|
2206
2380
|
deleted_at: z6.union([z6.string(), z6.null()]).optional(),
|
|
2207
2381
|
dataset_id: z6.union([z6.string(), z6.null()]).optional(),
|
|
2208
2382
|
dataset_version: z6.union([z6.string(), z6.null()]).optional(),
|
|
2383
|
+
parameters_id: z6.union([z6.string(), z6.null()]).optional(),
|
|
2384
|
+
parameters_version: z6.union([z6.string(), z6.null()]).optional(),
|
|
2209
2385
|
public: z6.boolean(),
|
|
2210
2386
|
user_id: z6.union([z6.string(), z6.null()]).optional(),
|
|
2211
2387
|
metadata: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional(),
|
|
@@ -2228,7 +2404,11 @@ var SpanType = z6.union([
|
|
|
2228
2404
|
z6.null()
|
|
2229
2405
|
]);
|
|
2230
2406
|
var SpanAttributes = z6.union([
|
|
2231
|
-
z6.object({
|
|
2407
|
+
z6.object({
|
|
2408
|
+
name: z6.union([z6.string(), z6.null()]),
|
|
2409
|
+
type: SpanType,
|
|
2410
|
+
purpose: z6.union([z6.literal("scorer"), z6.null()])
|
|
2411
|
+
}).partial().passthrough(),
|
|
2232
2412
|
z6.null()
|
|
2233
2413
|
]);
|
|
2234
2414
|
var ExperimentEvent = z6.object({
|
|
@@ -2668,6 +2848,7 @@ var FunctionId = z6.union([
|
|
|
2668
2848
|
version: z6.string()
|
|
2669
2849
|
}),
|
|
2670
2850
|
code: z6.string(),
|
|
2851
|
+
function_type: FunctionTypeEnum.and(z6.unknown()).optional(),
|
|
2671
2852
|
name: z6.union([z6.string(), z6.null()]).optional()
|
|
2672
2853
|
}),
|
|
2673
2854
|
z6.object({
|
|
@@ -2897,7 +3078,12 @@ var TopicAutomationConfig = z6.object({
|
|
|
2897
3078
|
topic_map_functions: z6.array(TopicMapFunctionAutomation),
|
|
2898
3079
|
scope: z6.union([SpanScope, TraceScope, GroupScope, z6.null()]).optional(),
|
|
2899
3080
|
data_scope: TopicAutomationDataScope.optional(),
|
|
2900
|
-
btql_filter: z6.union([z6.string(), z6.null()]).optional()
|
|
3081
|
+
btql_filter: z6.union([z6.string(), z6.null()]).optional(),
|
|
3082
|
+
backfill_time_range: z6.union([
|
|
3083
|
+
z6.string(),
|
|
3084
|
+
z6.object({ from: z6.string(), to: z6.string() }),
|
|
3085
|
+
z6.null()
|
|
3086
|
+
]).optional()
|
|
2901
3087
|
});
|
|
2902
3088
|
var ProjectAutomation = z6.object({
|
|
2903
3089
|
id: z6.string().uuid(),
|
|
@@ -4336,6 +4522,12 @@ var parametersRowSchema = z8.object({
|
|
|
4336
4522
|
}),
|
|
4337
4523
|
metadata: z8.union([z8.object({}).partial().passthrough(), z8.null()]).optional()
|
|
4338
4524
|
});
|
|
4525
|
+
var InlineAttachmentReferenceSchema = z8.object({
|
|
4526
|
+
type: z8.literal("inline_attachment"),
|
|
4527
|
+
src: z8.string().min(1),
|
|
4528
|
+
content_type: z8.string().optional(),
|
|
4529
|
+
filename: z8.string().optional()
|
|
4530
|
+
});
|
|
4339
4531
|
var LoginInvalidOrgError = class extends Error {
|
|
4340
4532
|
constructor(message) {
|
|
4341
4533
|
super(message);
|
|
@@ -4482,7 +4674,10 @@ var loginSchema = z8.strictObject({
|
|
|
4482
4674
|
proxyUrl: z8.string(),
|
|
4483
4675
|
loginToken: z8.string(),
|
|
4484
4676
|
orgId: z8.string().nullish(),
|
|
4485
|
-
gitMetadataSettings: GitMetadataSettings.nullish()
|
|
4677
|
+
gitMetadataSettings: GitMetadataSettings.nullish(),
|
|
4678
|
+
debugLogLevel: z8.enum(["error", "warn", "info", "debug"]).optional(),
|
|
4679
|
+
// Distinguishes explicit false from unset so env fallback stays disabled after deserialization.
|
|
4680
|
+
debugLogLevelDisabled: z8.boolean().optional()
|
|
4486
4681
|
});
|
|
4487
4682
|
var stateNonce = 0;
|
|
4488
4683
|
var BraintrustState = class _BraintrustState {
|
|
@@ -4503,6 +4698,16 @@ var BraintrustState = class _BraintrustState {
|
|
|
4503
4698
|
this._bgLogger = new SyncLazyValue(
|
|
4504
4699
|
() => new HTTPBackgroundLogger(new LazyValue(defaultGetLogConn), loginParams)
|
|
4505
4700
|
);
|
|
4701
|
+
if (loginParams.debugLogLevel !== void 0) {
|
|
4702
|
+
this.debugLogLevelConfigured = true;
|
|
4703
|
+
this.debugLogLevel = normalizeDebugLogLevelOption(
|
|
4704
|
+
loginParams.debugLogLevel
|
|
4705
|
+
);
|
|
4706
|
+
setGlobalDebugLogLevel(this.debugLogLevel ?? false);
|
|
4707
|
+
} else {
|
|
4708
|
+
this.debugLogLevel = getEnvDebugLogLevel();
|
|
4709
|
+
setGlobalDebugLogLevel(void 0);
|
|
4710
|
+
}
|
|
4506
4711
|
this.resetLoginInfo();
|
|
4507
4712
|
const memoryCache = new LRUCache({
|
|
4508
4713
|
max: Number(isomorph_default.getEnv("BRAINTRUST_PROMPT_CACHE_MEMORY_MAX")) ?? 1 << 10
|
|
@@ -4547,6 +4752,8 @@ var BraintrustState = class _BraintrustState {
|
|
|
4547
4752
|
proxyUrl = null;
|
|
4548
4753
|
loggedIn = false;
|
|
4549
4754
|
gitMetadataSettings;
|
|
4755
|
+
debugLogLevel;
|
|
4756
|
+
debugLogLevelConfigured = false;
|
|
4550
4757
|
fetch = globalThis.fetch;
|
|
4551
4758
|
_appConn = null;
|
|
4552
4759
|
_apiConn = null;
|
|
@@ -4612,6 +4819,11 @@ var BraintrustState = class _BraintrustState {
|
|
|
4612
4819
|
this.proxyUrl = other.proxyUrl;
|
|
4613
4820
|
this.loggedIn = other.loggedIn;
|
|
4614
4821
|
this.gitMetadataSettings = other.gitMetadataSettings;
|
|
4822
|
+
this.debugLogLevel = other.debugLogLevel;
|
|
4823
|
+
this.debugLogLevelConfigured = other.debugLogLevelConfigured;
|
|
4824
|
+
setGlobalDebugLogLevel(
|
|
4825
|
+
this.debugLogLevelConfigured ? this.debugLogLevel ?? false : void 0
|
|
4826
|
+
);
|
|
4615
4827
|
this._appConn = other._appConn;
|
|
4616
4828
|
this._apiConn = other._apiConn;
|
|
4617
4829
|
this.loginReplaceApiConn(this.apiConn());
|
|
@@ -4636,7 +4848,9 @@ var BraintrustState = class _BraintrustState {
|
|
|
4636
4848
|
orgName: this.orgName,
|
|
4637
4849
|
apiUrl: this.apiUrl,
|
|
4638
4850
|
proxyUrl: this.proxyUrl,
|
|
4639
|
-
gitMetadataSettings: this.gitMetadataSettings
|
|
4851
|
+
gitMetadataSettings: this.gitMetadataSettings,
|
|
4852
|
+
...this.debugLogLevel ? { debugLogLevel: this.debugLogLevel } : {},
|
|
4853
|
+
...this.debugLogLevelConfigured && !this.debugLogLevel ? { debugLogLevelDisabled: true } : {}
|
|
4640
4854
|
};
|
|
4641
4855
|
}
|
|
4642
4856
|
static deserialize(serialized, opts) {
|
|
@@ -4663,6 +4877,10 @@ var BraintrustState = class _BraintrustState {
|
|
|
4663
4877
|
state.proxyConn().set_token(state.loginToken);
|
|
4664
4878
|
}
|
|
4665
4879
|
state.loggedIn = true;
|
|
4880
|
+
state.debugLogLevelConfigured = "debugLogLevel" in serializedParsed.data || !!serializedParsed.data.debugLogLevelDisabled;
|
|
4881
|
+
setGlobalDebugLogLevel(
|
|
4882
|
+
state.debugLogLevelConfigured ? state.debugLogLevel ?? false : void 0
|
|
4883
|
+
);
|
|
4666
4884
|
state.loginReplaceApiConn(state.apiConn());
|
|
4667
4885
|
return state;
|
|
4668
4886
|
}
|
|
@@ -4675,7 +4893,22 @@ var BraintrustState = class _BraintrustState {
|
|
|
4675
4893
|
setMaskingFunction(maskingFunction) {
|
|
4676
4894
|
this.bgLogger().setMaskingFunction(maskingFunction);
|
|
4677
4895
|
}
|
|
4896
|
+
setDebugLogLevel(option) {
|
|
4897
|
+
if (option === void 0) {
|
|
4898
|
+
return;
|
|
4899
|
+
}
|
|
4900
|
+
this.debugLogLevelConfigured = true;
|
|
4901
|
+
this.debugLogLevel = normalizeDebugLogLevelOption(option);
|
|
4902
|
+
setGlobalDebugLogLevel(this.debugLogLevel ?? false);
|
|
4903
|
+
}
|
|
4904
|
+
getDebugLogLevel() {
|
|
4905
|
+
return this.debugLogLevel;
|
|
4906
|
+
}
|
|
4907
|
+
hasDebugLogLevelOverride() {
|
|
4908
|
+
return this.debugLogLevelConfigured;
|
|
4909
|
+
}
|
|
4678
4910
|
async login(loginParams) {
|
|
4911
|
+
this.setDebugLogLevel(loginParams.debugLogLevel);
|
|
4679
4912
|
if (this.apiUrl && !loginParams.forceLogin) {
|
|
4680
4913
|
return;
|
|
4681
4914
|
}
|
|
@@ -4786,6 +5019,7 @@ function _internalSetInitialState() {
|
|
|
4786
5019
|
_globalState = existing;
|
|
4787
5020
|
}
|
|
4788
5021
|
var _internalGetGlobalState = () => _globalState;
|
|
5022
|
+
setDebugLogStateResolver(() => _internalGetGlobalState());
|
|
4789
5023
|
var FailedHTTPResponse = class extends Error {
|
|
4790
5024
|
status;
|
|
4791
5025
|
text;
|
|
@@ -4900,7 +5134,7 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
4900
5134
|
return await resp.json();
|
|
4901
5135
|
} catch (e) {
|
|
4902
5136
|
if (i < tries - 1) {
|
|
4903
|
-
|
|
5137
|
+
debugLogger.debug(
|
|
4904
5138
|
`Retrying API request ${object_type} ${JSON.stringify(args)} ${e.status} ${e.text}`
|
|
4905
5139
|
);
|
|
4906
5140
|
continue;
|
|
@@ -5112,7 +5346,7 @@ with a Blob/ArrayBuffer, or run the program on Node.js.`
|
|
|
5112
5346
|
try {
|
|
5113
5347
|
statSync2(data);
|
|
5114
5348
|
} catch (e) {
|
|
5115
|
-
|
|
5349
|
+
debugLogger.warn(`Failed to read file: ${e}`);
|
|
5116
5350
|
}
|
|
5117
5351
|
}
|
|
5118
5352
|
};
|
|
@@ -5824,7 +6058,7 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
|
5824
6058
|
this.queueDropLoggingPeriod = queueDropLoggingPeriodEnv;
|
|
5825
6059
|
}
|
|
5826
6060
|
if (isomorph_default.getEnv("BRAINTRUST_LOG_FLUSH_CHUNK_SIZE")) {
|
|
5827
|
-
|
|
6061
|
+
debugLogger.warn(
|
|
5828
6062
|
"BRAINTRUST_LOG_FLUSH_CHUNK_SIZE is deprecated and no longer has any effect. Log flushing now sends all items at once and batches them automatically. This environment variable will be removed in a future major release."
|
|
5829
6063
|
);
|
|
5830
6064
|
}
|
|
@@ -5886,7 +6120,10 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
|
5886
6120
|
const versionInfo = await conn.get_json("version");
|
|
5887
6121
|
serverLimit = z8.object({ logs3_payload_max_bytes: z8.number().nullish() }).parse(versionInfo).logs3_payload_max_bytes ?? null;
|
|
5888
6122
|
} catch (e) {
|
|
5889
|
-
|
|
6123
|
+
debugLogger.warn(
|
|
6124
|
+
"Failed to fetch version info for payload limit:",
|
|
6125
|
+
e
|
|
6126
|
+
);
|
|
5890
6127
|
}
|
|
5891
6128
|
const validServerLimit = serverLimit !== null && serverLimit > 0 ? serverLimit : null;
|
|
5892
6129
|
const canUseOverflow = validServerLimit !== null;
|
|
@@ -6030,16 +6267,16 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
|
6030
6267
|
if (isRetrying) {
|
|
6031
6268
|
errmsg += ". Retrying";
|
|
6032
6269
|
}
|
|
6033
|
-
|
|
6270
|
+
debugLogger.warn(errmsg);
|
|
6034
6271
|
if (!isRetrying) {
|
|
6035
|
-
|
|
6272
|
+
debugLogger.warn(
|
|
6036
6273
|
`Failed to construct log records to flush after ${this.numTries} attempts. Dropping batch`
|
|
6037
6274
|
);
|
|
6038
6275
|
throw e;
|
|
6039
6276
|
} else {
|
|
6040
|
-
|
|
6277
|
+
debugLogger.warn(e);
|
|
6041
6278
|
const sleepTimeS = BACKGROUND_LOGGER_BASE_SLEEP_TIME_S * 2 ** i;
|
|
6042
|
-
|
|
6279
|
+
debugLogger.info(`Sleeping for ${sleepTimeS}s`);
|
|
6043
6280
|
await new Promise(
|
|
6044
6281
|
(resolve) => setTimeout(resolve, sleepTimeS * 1e3)
|
|
6045
6282
|
);
|
|
@@ -6140,15 +6377,15 @@ Error: ${errorText}`;
|
|
|
6140
6377
|
this.logFailedPayloadsDir();
|
|
6141
6378
|
}
|
|
6142
6379
|
if (!isRetrying) {
|
|
6143
|
-
|
|
6380
|
+
debugLogger.warn(
|
|
6144
6381
|
`log request failed after ${this.numTries} retries. Dropping batch`
|
|
6145
6382
|
);
|
|
6146
6383
|
throw new Error(errMsg);
|
|
6147
6384
|
} else {
|
|
6148
|
-
|
|
6385
|
+
debugLogger.warn(errMsg);
|
|
6149
6386
|
if (isRetrying) {
|
|
6150
6387
|
const sleepTimeS = BACKGROUND_LOGGER_BASE_SLEEP_TIME_S * 2 ** i;
|
|
6151
|
-
|
|
6388
|
+
debugLogger.info(`Sleeping for ${sleepTimeS}s`);
|
|
6152
6389
|
await new Promise(
|
|
6153
6390
|
(resolve) => setTimeout(resolve, sleepTimeS * 1e3)
|
|
6154
6391
|
);
|
|
@@ -6163,7 +6400,7 @@ Error: ${errorText}`;
|
|
|
6163
6400
|
this.queueDropLoggingState.numDropped += numItems;
|
|
6164
6401
|
const timeNow = getCurrentUnixTimestamp();
|
|
6165
6402
|
if (timeNow - this.queueDropLoggingState.lastLoggedTimestamp > this.queueDropLoggingPeriod) {
|
|
6166
|
-
|
|
6403
|
+
debugLogger.warn(
|
|
6167
6404
|
`Dropped ${this.queueDropLoggingState.numDropped} elements due to full queue`
|
|
6168
6405
|
);
|
|
6169
6406
|
if (this.failedPublishPayloadsDir) {
|
|
@@ -6195,7 +6432,7 @@ Error: ${errorText}`;
|
|
|
6195
6432
|
await _HTTPBackgroundLogger.writePayloadToDir({ payloadDir, payload });
|
|
6196
6433
|
}
|
|
6197
6434
|
} catch (e) {
|
|
6198
|
-
|
|
6435
|
+
debugLogger.error(e);
|
|
6199
6436
|
}
|
|
6200
6437
|
}
|
|
6201
6438
|
static async writePayloadToDir({
|
|
@@ -6203,7 +6440,7 @@ Error: ${errorText}`;
|
|
|
6203
6440
|
payload
|
|
6204
6441
|
}) {
|
|
6205
6442
|
if (!(isomorph_default.pathJoin && isomorph_default.mkdir && isomorph_default.writeFile)) {
|
|
6206
|
-
|
|
6443
|
+
debugLogger.warn(
|
|
6207
6444
|
"Cannot dump payloads: filesystem-operations not supported on this platform"
|
|
6208
6445
|
);
|
|
6209
6446
|
return;
|
|
@@ -6216,7 +6453,7 @@ Error: ${errorText}`;
|
|
|
6216
6453
|
await isomorph_default.mkdir(payloadDir, { recursive: true });
|
|
6217
6454
|
await isomorph_default.writeFile(payloadFile, payload);
|
|
6218
6455
|
} catch (e) {
|
|
6219
|
-
|
|
6456
|
+
debugLogger.error(
|
|
6220
6457
|
`Failed to write failed payload to output file ${payloadFile}:
|
|
6221
6458
|
`,
|
|
6222
6459
|
e
|
|
@@ -6247,7 +6484,9 @@ Error: ${errorText}`;
|
|
|
6247
6484
|
}
|
|
6248
6485
|
}
|
|
6249
6486
|
logFailedPayloadsDir() {
|
|
6250
|
-
|
|
6487
|
+
debugLogger.warn(
|
|
6488
|
+
`Logging failed payloads to ${this.failedPublishPayloadsDir}`
|
|
6489
|
+
);
|
|
6251
6490
|
}
|
|
6252
6491
|
// Should only be called by BraintrustState.
|
|
6253
6492
|
internalReplaceApiConn(apiConn) {
|
|
@@ -6278,6 +6517,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
6278
6517
|
experiment,
|
|
6279
6518
|
description,
|
|
6280
6519
|
dataset,
|
|
6520
|
+
parameters,
|
|
6281
6521
|
baseExperiment,
|
|
6282
6522
|
isPublic,
|
|
6283
6523
|
open: open2,
|
|
@@ -6395,6 +6635,17 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
6395
6635
|
args["dataset_version"] = await dataset.version();
|
|
6396
6636
|
}
|
|
6397
6637
|
}
|
|
6638
|
+
if (parameters !== void 0) {
|
|
6639
|
+
if (RemoteEvalParameters.isParameters(parameters)) {
|
|
6640
|
+
args["parameters_id"] = parameters.id;
|
|
6641
|
+
args["parameters_version"] = parameters.version;
|
|
6642
|
+
} else {
|
|
6643
|
+
args["parameters_id"] = parameters.id;
|
|
6644
|
+
if (parameters.version !== void 0) {
|
|
6645
|
+
args["parameters_version"] = parameters.version;
|
|
6646
|
+
}
|
|
6647
|
+
}
|
|
6648
|
+
}
|
|
6398
6649
|
if (isPublic !== void 0) {
|
|
6399
6650
|
args["public"] = isPublic;
|
|
6400
6651
|
}
|
|
@@ -6412,9 +6663,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
6412
6663
|
break;
|
|
6413
6664
|
} catch (e) {
|
|
6414
6665
|
if (args["base_experiment"] && `${"data" in e && e.data}`.includes("base experiment")) {
|
|
6415
|
-
|
|
6416
|
-
`Base experiment ${args["base_experiment"]} not found.`
|
|
6417
|
-
);
|
|
6666
|
+
debugLogger.forState(state).warn(`Base experiment ${args["base_experiment"]} not found.`);
|
|
6418
6667
|
delete args["base_experiment"];
|
|
6419
6668
|
} else {
|
|
6420
6669
|
throw e;
|
|
@@ -6556,7 +6805,11 @@ async function computeLoggerMetadata(state, {
|
|
|
6556
6805
|
}
|
|
6557
6806
|
async function login(options = {}) {
|
|
6558
6807
|
const { forceLogin = false } = options || {};
|
|
6808
|
+
if (!_internalGetGlobalState()) {
|
|
6809
|
+
_internalSetInitialState();
|
|
6810
|
+
}
|
|
6559
6811
|
const state = _internalGetGlobalState();
|
|
6812
|
+
state.setDebugLogLevel(options.debugLogLevel);
|
|
6560
6813
|
if (state.loggedIn && !forceLogin) {
|
|
6561
6814
|
let checkUpdatedParam2 = function(varname, arg, orig) {
|
|
6562
6815
|
if (!isEmpty2(arg) && !isEmpty2(orig) && arg !== orig) {
|
|
@@ -6575,9 +6828,6 @@ async function login(options = {}) {
|
|
|
6575
6828
|
checkUpdatedParam2("orgName", options.orgName, state.orgName);
|
|
6576
6829
|
return state;
|
|
6577
6830
|
}
|
|
6578
|
-
if (!state) {
|
|
6579
|
-
_internalSetInitialState();
|
|
6580
|
-
}
|
|
6581
6831
|
await state.login(options);
|
|
6582
6832
|
return state;
|
|
6583
6833
|
}
|
|
@@ -6989,7 +7239,14 @@ var ObjectFetcher = class {
|
|
|
6989
7239
|
async *fetchRecordsFromApi(batchSize) {
|
|
6990
7240
|
const state = await this.getState();
|
|
6991
7241
|
const objectId = await this.id;
|
|
6992
|
-
const
|
|
7242
|
+
const batchLimit = batchSize ?? DEFAULT_FETCH_BATCH_SIZE;
|
|
7243
|
+
const internalLimit = this._internal_btql?.limit;
|
|
7244
|
+
const limit = batchSize !== void 0 ? batchSize : internalLimit ?? batchLimit;
|
|
7245
|
+
const internalBtqlWithoutReservedQueryKeys = Object.fromEntries(
|
|
7246
|
+
Object.entries(this._internal_btql ?? {}).filter(
|
|
7247
|
+
([key]) => key !== "cursor" && key !== "limit" && key !== "select" && key !== "from"
|
|
7248
|
+
)
|
|
7249
|
+
);
|
|
6993
7250
|
let cursor = void 0;
|
|
6994
7251
|
let iterations = 0;
|
|
6995
7252
|
while (true) {
|
|
@@ -6997,7 +7254,6 @@ var ObjectFetcher = class {
|
|
|
6997
7254
|
`btql`,
|
|
6998
7255
|
{
|
|
6999
7256
|
query: {
|
|
7000
|
-
...this._internal_btql,
|
|
7001
7257
|
select: [
|
|
7002
7258
|
{
|
|
7003
7259
|
op: "star"
|
|
@@ -7017,7 +7273,8 @@ var ObjectFetcher = class {
|
|
|
7017
7273
|
]
|
|
7018
7274
|
},
|
|
7019
7275
|
cursor,
|
|
7020
|
-
limit
|
|
7276
|
+
limit,
|
|
7277
|
+
...internalBtqlWithoutReservedQueryKeys
|
|
7021
7278
|
},
|
|
7022
7279
|
use_columnstore: false,
|
|
7023
7280
|
brainstore_realtime: true,
|
|
@@ -7290,7 +7547,7 @@ var Experiment2 = class extends ObjectFetcher {
|
|
|
7290
7547
|
scores = results["scores"];
|
|
7291
7548
|
metrics = results["metrics"];
|
|
7292
7549
|
} catch (e) {
|
|
7293
|
-
|
|
7550
|
+
debugLogger.forState(state).warn(
|
|
7294
7551
|
`Failed to fetch experiment scores and metrics: ${e}
|
|
7295
7552
|
|
|
7296
7553
|
View complete results in Braintrust or run experiment.summarize() again.`
|
|
@@ -7367,7 +7624,7 @@ View complete results in Braintrust or run experiment.summarize() again.`
|
|
|
7367
7624
|
* @deprecated This function is deprecated. You can simply remove it from your code.
|
|
7368
7625
|
*/
|
|
7369
7626
|
async close() {
|
|
7370
|
-
|
|
7627
|
+
debugLogger.forState(this.state).warn(
|
|
7371
7628
|
"close is deprecated and will be removed in a future version of braintrust. It is now a no-op and can be removed"
|
|
7372
7629
|
);
|
|
7373
7630
|
return this.id;
|
|
@@ -7564,8 +7821,8 @@ var SpanImpl = class _SpanImpl {
|
|
|
7564
7821
|
...serializableInternalData,
|
|
7565
7822
|
[IS_MERGE_FIELD]: this.isMerge
|
|
7566
7823
|
});
|
|
7567
|
-
if (partialRecord.metrics?.end) {
|
|
7568
|
-
this.loggedEndTime = partialRecord.metrics
|
|
7824
|
+
if (typeof partialRecord.metrics?.end === "number") {
|
|
7825
|
+
this.loggedEndTime = partialRecord.metrics.end;
|
|
7569
7826
|
}
|
|
7570
7827
|
if (this.parentObjectType === 1 /* EXPERIMENT */) {
|
|
7571
7828
|
const cachedSpan = {
|
|
@@ -7800,7 +8057,7 @@ var Dataset2 = class extends ObjectFetcher {
|
|
|
7800
8057
|
constructor(state, lazyMetadata, pinnedVersion, legacy, _internal_btql) {
|
|
7801
8058
|
const isLegacyDataset = legacy ?? DEFAULT_IS_LEGACY_DATASET;
|
|
7802
8059
|
if (isLegacyDataset) {
|
|
7803
|
-
|
|
8060
|
+
debugLogger.forState(state).warn(
|
|
7804
8061
|
`Records will be fetched from this dataset in the legacy format, with the "expected" field renamed to "output". Please update your code to use "expected", and use \`braintrust.initDataset()\` with \`{ useOutput: false }\`, which will become the default in a future version of Braintrust.`
|
|
7805
8062
|
);
|
|
7806
8063
|
}
|
|
@@ -8031,7 +8288,7 @@ var Dataset2 = class extends ObjectFetcher {
|
|
|
8031
8288
|
* @deprecated This function is deprecated. You can simply remove it from your code.
|
|
8032
8289
|
*/
|
|
8033
8290
|
async close() {
|
|
8034
|
-
|
|
8291
|
+
debugLogger.forState(this.state).warn(
|
|
8035
8292
|
"close is deprecated and will be removed in a future version of braintrust. It is now a no-op and can be removed"
|
|
8036
8293
|
);
|
|
8037
8294
|
return this.id;
|
|
@@ -8040,40 +8297,82 @@ var Dataset2 = class extends ObjectFetcher {
|
|
|
8040
8297
|
return typeof data === "object" && data !== null && "__braintrust_dataset_marker" in data;
|
|
8041
8298
|
}
|
|
8042
8299
|
};
|
|
8043
|
-
function
|
|
8300
|
+
function isAttachmentObject(value) {
|
|
8301
|
+
return BraintrustAttachmentReference.safeParse(value).success || InlineAttachmentReferenceSchema.safeParse(value).success || ExternalAttachmentReference.safeParse(value).success;
|
|
8302
|
+
}
|
|
8303
|
+
function isURL(url) {
|
|
8304
|
+
try {
|
|
8305
|
+
const parsedUrl = new URL(url.trim());
|
|
8306
|
+
return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
|
|
8307
|
+
} catch {
|
|
8308
|
+
return false;
|
|
8309
|
+
}
|
|
8310
|
+
}
|
|
8311
|
+
function expandAttachmentArrayPreTemplate(content, variables) {
|
|
8312
|
+
if (typeof content !== "string") return null;
|
|
8313
|
+
const match = content.match(/^\{\{\s*([\w.]+)\s*\}\}$/);
|
|
8314
|
+
if (!match) return null;
|
|
8315
|
+
const varPath = match[1];
|
|
8316
|
+
const value = varPath.includes(".") ? getObjValueByPath(variables, varPath.split(".")) : variables[varPath];
|
|
8317
|
+
if (!Array.isArray(value)) return null;
|
|
8318
|
+
const allValid = value.every(
|
|
8319
|
+
(v) => isAttachmentObject(v) || typeof v === "string" && isURL(v)
|
|
8320
|
+
);
|
|
8321
|
+
if (!allValid) return null;
|
|
8322
|
+
return value.map((item) => ({
|
|
8323
|
+
type: "image_url",
|
|
8324
|
+
image_url: { url: item }
|
|
8325
|
+
}));
|
|
8326
|
+
}
|
|
8327
|
+
function renderMessageImpl(render, message, variables) {
|
|
8044
8328
|
return {
|
|
8045
8329
|
...message,
|
|
8046
8330
|
..."content" in message ? {
|
|
8047
|
-
content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.
|
|
8331
|
+
content: isEmpty2(message.content) ? void 0 : typeof message.content === "string" ? render(message.content) : message.content.flatMap((c) => {
|
|
8048
8332
|
switch (c.type) {
|
|
8049
8333
|
case "text":
|
|
8050
|
-
return { ...c, text: render(c.text) };
|
|
8334
|
+
return [{ ...c, text: render(c.text) }];
|
|
8051
8335
|
case "image_url":
|
|
8052
8336
|
if (isObject(c.image_url.url)) {
|
|
8053
8337
|
throw new Error(
|
|
8054
8338
|
"Attachments must be replaced with URLs before calling `build()`"
|
|
8055
8339
|
);
|
|
8056
8340
|
}
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8341
|
+
if (variables) {
|
|
8342
|
+
const expanded = expandAttachmentArrayPreTemplate(
|
|
8343
|
+
c.image_url.url,
|
|
8344
|
+
variables
|
|
8345
|
+
);
|
|
8346
|
+
if (expanded) {
|
|
8347
|
+
return expanded;
|
|
8062
8348
|
}
|
|
8063
|
-
}
|
|
8349
|
+
}
|
|
8350
|
+
return [
|
|
8351
|
+
{
|
|
8352
|
+
...c,
|
|
8353
|
+
image_url: {
|
|
8354
|
+
...c.image_url,
|
|
8355
|
+
url: render(c.image_url.url)
|
|
8356
|
+
}
|
|
8357
|
+
}
|
|
8358
|
+
];
|
|
8064
8359
|
case "file":
|
|
8065
|
-
return
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8360
|
+
return [
|
|
8361
|
+
{
|
|
8362
|
+
...c,
|
|
8363
|
+
file: {
|
|
8364
|
+
...c.file.file_data && {
|
|
8365
|
+
file_data: render(c.file.file_data)
|
|
8366
|
+
},
|
|
8367
|
+
...c.file.file_id && {
|
|
8368
|
+
file_id: render(c.file.file_id)
|
|
8369
|
+
},
|
|
8370
|
+
...c.file.filename && {
|
|
8371
|
+
filename: render(c.file.filename)
|
|
8372
|
+
}
|
|
8074
8373
|
}
|
|
8075
8374
|
}
|
|
8076
|
-
|
|
8375
|
+
];
|
|
8077
8376
|
default:
|
|
8078
8377
|
const _exhaustiveCheck = c;
|
|
8079
8378
|
return _exhaustiveCheck;
|
|
@@ -8230,17 +8529,19 @@ var Prompt2 = class _Prompt {
|
|
|
8230
8529
|
}
|
|
8231
8530
|
runBuild(buildArgs, options) {
|
|
8232
8531
|
const { flavor } = options;
|
|
8233
|
-
const params =
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
Object.
|
|
8237
|
-
(
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8532
|
+
const params = Object.fromEntries(
|
|
8533
|
+
Object.entries({
|
|
8534
|
+
...this.defaults,
|
|
8535
|
+
...Object.fromEntries(
|
|
8536
|
+
Object.entries(this.options.params || {}).filter(
|
|
8537
|
+
([k, _v]) => !BRAINTRUST_PARAMS.includes(k)
|
|
8538
|
+
)
|
|
8539
|
+
),
|
|
8540
|
+
...!isEmpty2(this.options.model) ? {
|
|
8541
|
+
model: this.options.model
|
|
8542
|
+
} : {}
|
|
8543
|
+
}).filter(([key, value]) => key !== "response_format" || value !== null)
|
|
8544
|
+
);
|
|
8244
8545
|
if (!("model" in params) || isEmpty2(params.model)) {
|
|
8245
8546
|
throw new Error(
|
|
8246
8547
|
"No model specified. Either specify it in the prompt or as a default"
|
|
@@ -8340,7 +8641,7 @@ var Prompt2 = class _Prompt {
|
|
|
8340
8641
|
templateFormat
|
|
8341
8642
|
});
|
|
8342
8643
|
const baseMessages = (prompt.messages || []).map(
|
|
8343
|
-
(m) =>
|
|
8644
|
+
(m) => renderMessageImpl(render, m, variables)
|
|
8344
8645
|
);
|
|
8345
8646
|
const hasSystemPrompt = baseMessages.some((m) => m.role === "system");
|
|
8346
8647
|
const messages = [
|
|
@@ -8447,9 +8748,6 @@ var RemoteEvalParameters = class {
|
|
|
8447
8748
|
};
|
|
8448
8749
|
var TEST_API_KEY = "___TEST_API_KEY__THIS_IS_NOT_REAL___";
|
|
8449
8750
|
|
|
8450
|
-
// src/instrumentation/core/plugin.ts
|
|
8451
|
-
import { tracingChannel } from "dc-browser";
|
|
8452
|
-
|
|
8453
8751
|
// src/instrumentation/core/stream-patcher.ts
|
|
8454
8752
|
function isAsyncIterable(value) {
|
|
8455
8753
|
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
@@ -8465,7 +8763,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8465
8763
|
return stream;
|
|
8466
8764
|
}
|
|
8467
8765
|
const originalIteratorFn = stream[Symbol.asyncIterator];
|
|
8468
|
-
if (originalIteratorFn
|
|
8766
|
+
if ("__braintrust_patched" in originalIteratorFn && originalIteratorFn["__braintrust_patched"]) {
|
|
8469
8767
|
return stream;
|
|
8470
8768
|
}
|
|
8471
8769
|
try {
|
|
@@ -8506,7 +8804,10 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8506
8804
|
completed = true;
|
|
8507
8805
|
if (options.onError) {
|
|
8508
8806
|
try {
|
|
8509
|
-
options.onError(
|
|
8807
|
+
options.onError(
|
|
8808
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
8809
|
+
chunks
|
|
8810
|
+
);
|
|
8510
8811
|
} catch (handlerError) {
|
|
8511
8812
|
console.error("Error in stream onError handler:", handlerError);
|
|
8512
8813
|
}
|
|
@@ -8534,7 +8835,8 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8534
8835
|
iterator.throw = async function(...args) {
|
|
8535
8836
|
if (!completed) {
|
|
8536
8837
|
completed = true;
|
|
8537
|
-
const
|
|
8838
|
+
const rawError = args[0];
|
|
8839
|
+
const error = rawError instanceof Error ? rawError : new Error(String(rawError));
|
|
8538
8840
|
if (options.onError) {
|
|
8539
8841
|
try {
|
|
8540
8842
|
options.onError(error, chunks);
|
|
@@ -8548,7 +8850,9 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8548
8850
|
}
|
|
8549
8851
|
return iterator;
|
|
8550
8852
|
};
|
|
8551
|
-
patchedIteratorFn
|
|
8853
|
+
Object.defineProperty(patchedIteratorFn, "__braintrust_patched", {
|
|
8854
|
+
value: true
|
|
8855
|
+
});
|
|
8552
8856
|
stream[Symbol.asyncIterator] = patchedIteratorFn;
|
|
8553
8857
|
return stream;
|
|
8554
8858
|
} catch (error) {
|
|
@@ -8557,6 +8861,49 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8557
8861
|
}
|
|
8558
8862
|
}
|
|
8559
8863
|
|
|
8864
|
+
// src/instrumentation/core/channel-tracing-utils.ts
|
|
8865
|
+
function hasChannelSpanInfo(value) {
|
|
8866
|
+
return isObject(value) && isObject(value.span_info);
|
|
8867
|
+
}
|
|
8868
|
+
function getChannelSpanInfo(event) {
|
|
8869
|
+
if (isObject(event.span_info)) {
|
|
8870
|
+
return event.span_info;
|
|
8871
|
+
}
|
|
8872
|
+
const firstArg = event.arguments?.[0];
|
|
8873
|
+
if (hasChannelSpanInfo(firstArg)) {
|
|
8874
|
+
return firstArg.span_info;
|
|
8875
|
+
}
|
|
8876
|
+
return void 0;
|
|
8877
|
+
}
|
|
8878
|
+
function buildStartSpanArgs(config, event) {
|
|
8879
|
+
const spanInfo = getChannelSpanInfo(event);
|
|
8880
|
+
const spanAttributes = {
|
|
8881
|
+
type: config.type
|
|
8882
|
+
};
|
|
8883
|
+
if (isObject(spanInfo?.spanAttributes)) {
|
|
8884
|
+
mergeDicts(spanAttributes, spanInfo.spanAttributes);
|
|
8885
|
+
}
|
|
8886
|
+
return {
|
|
8887
|
+
name: typeof spanInfo?.name === "string" && spanInfo.name ? spanInfo.name : config.name,
|
|
8888
|
+
spanAttributes,
|
|
8889
|
+
spanInfoMetadata: isObject(spanInfo?.metadata) ? spanInfo.metadata : void 0
|
|
8890
|
+
};
|
|
8891
|
+
}
|
|
8892
|
+
function mergeInputMetadata(metadata, spanInfoMetadata) {
|
|
8893
|
+
if (!spanInfoMetadata) {
|
|
8894
|
+
return isObject(metadata) ? (
|
|
8895
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
8896
|
+
metadata
|
|
8897
|
+
) : void 0;
|
|
8898
|
+
}
|
|
8899
|
+
const mergedMetadata = {};
|
|
8900
|
+
mergeDicts(mergedMetadata, spanInfoMetadata);
|
|
8901
|
+
if (isObject(metadata)) {
|
|
8902
|
+
mergeDicts(mergedMetadata, metadata);
|
|
8903
|
+
}
|
|
8904
|
+
return mergedMetadata;
|
|
8905
|
+
}
|
|
8906
|
+
|
|
8560
8907
|
// src/instrumentation/core/plugin.ts
|
|
8561
8908
|
var BasePlugin = class {
|
|
8562
8909
|
enabled = false;
|
|
@@ -8588,23 +8935,25 @@ var BasePlugin = class {
|
|
|
8588
8935
|
* @param handlers - Event handlers
|
|
8589
8936
|
*/
|
|
8590
8937
|
subscribe(channelName, handlers) {
|
|
8591
|
-
const
|
|
8592
|
-
|
|
8938
|
+
const channel2 = isomorph_default.newTracingChannel(channelName);
|
|
8939
|
+
channel2.subscribe(handlers);
|
|
8593
8940
|
}
|
|
8594
8941
|
/**
|
|
8595
8942
|
* Subscribe to a channel for async methods (non-streaming).
|
|
8596
8943
|
* Creates a span and logs input/output/metrics.
|
|
8597
8944
|
*/
|
|
8598
8945
|
subscribeToChannel(channelName, config) {
|
|
8599
|
-
const
|
|
8946
|
+
const channel2 = isomorph_default.newTracingChannel(channelName);
|
|
8600
8947
|
const spans = /* @__PURE__ */ new WeakMap();
|
|
8601
8948
|
const handlers = {
|
|
8602
8949
|
start: (event) => {
|
|
8950
|
+
const { name, spanAttributes, spanInfoMetadata } = buildStartSpanArgs(
|
|
8951
|
+
config,
|
|
8952
|
+
event
|
|
8953
|
+
);
|
|
8603
8954
|
const span = startSpan({
|
|
8604
|
-
name
|
|
8605
|
-
spanAttributes
|
|
8606
|
-
type: config.type
|
|
8607
|
-
}
|
|
8955
|
+
name,
|
|
8956
|
+
spanAttributes
|
|
8608
8957
|
});
|
|
8609
8958
|
const startTime = getCurrentUnixTimestamp();
|
|
8610
8959
|
spans.set(event, { span, startTime });
|
|
@@ -8612,7 +8961,7 @@ var BasePlugin = class {
|
|
|
8612
8961
|
const { input, metadata } = config.extractInput(event.arguments);
|
|
8613
8962
|
span.log({
|
|
8614
8963
|
input,
|
|
8615
|
-
metadata
|
|
8964
|
+
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
8616
8965
|
});
|
|
8617
8966
|
} catch (error) {
|
|
8618
8967
|
console.error(`Error extracting input for ${channelName}:`, error);
|
|
@@ -8625,10 +8974,12 @@ var BasePlugin = class {
|
|
|
8625
8974
|
}
|
|
8626
8975
|
const { span, startTime } = spanData;
|
|
8627
8976
|
try {
|
|
8628
|
-
const output = config.extractOutput(event.result);
|
|
8629
|
-
const metrics = config.extractMetrics(event.result, startTime);
|
|
8977
|
+
const output = config.extractOutput(event.result, event);
|
|
8978
|
+
const metrics = config.extractMetrics(event.result, startTime, event);
|
|
8979
|
+
const metadata = config.extractMetadata?.(event.result, event);
|
|
8630
8980
|
span.log({
|
|
8631
8981
|
output,
|
|
8982
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
8632
8983
|
metrics
|
|
8633
8984
|
});
|
|
8634
8985
|
} catch (error) {
|
|
@@ -8651,9 +9002,9 @@ var BasePlugin = class {
|
|
|
8651
9002
|
spans.delete(event);
|
|
8652
9003
|
}
|
|
8653
9004
|
};
|
|
8654
|
-
|
|
9005
|
+
channel2.subscribe(handlers);
|
|
8655
9006
|
this.unsubscribers.push(() => {
|
|
8656
|
-
|
|
9007
|
+
channel2.unsubscribe(handlers);
|
|
8657
9008
|
});
|
|
8658
9009
|
}
|
|
8659
9010
|
/**
|
|
@@ -8661,15 +9012,17 @@ var BasePlugin = class {
|
|
|
8661
9012
|
* Handles both streaming and non-streaming responses.
|
|
8662
9013
|
*/
|
|
8663
9014
|
subscribeToStreamingChannel(channelName, config) {
|
|
8664
|
-
const
|
|
9015
|
+
const channel2 = isomorph_default.newTracingChannel(channelName);
|
|
8665
9016
|
const spans = /* @__PURE__ */ new WeakMap();
|
|
8666
9017
|
const handlers = {
|
|
8667
9018
|
start: (event) => {
|
|
9019
|
+
const { name, spanAttributes, spanInfoMetadata } = buildStartSpanArgs(
|
|
9020
|
+
config,
|
|
9021
|
+
event
|
|
9022
|
+
);
|
|
8668
9023
|
const span = startSpan({
|
|
8669
|
-
name
|
|
8670
|
-
spanAttributes
|
|
8671
|
-
type: config.type
|
|
8672
|
-
}
|
|
9024
|
+
name,
|
|
9025
|
+
spanAttributes
|
|
8673
9026
|
});
|
|
8674
9027
|
const startTime = getCurrentUnixTimestamp();
|
|
8675
9028
|
spans.set(event, { span, startTime });
|
|
@@ -8677,7 +9030,7 @@ var BasePlugin = class {
|
|
|
8677
9030
|
const { input, metadata } = config.extractInput(event.arguments);
|
|
8678
9031
|
span.log({
|
|
8679
9032
|
input,
|
|
8680
|
-
metadata
|
|
9033
|
+
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
8681
9034
|
});
|
|
8682
9035
|
} catch (error) {
|
|
8683
9036
|
console.error(`Error extracting input for ${channelName}:`, error);
|
|
@@ -8690,24 +9043,39 @@ var BasePlugin = class {
|
|
|
8690
9043
|
}
|
|
8691
9044
|
const { span, startTime } = spanData;
|
|
8692
9045
|
if (isAsyncIterable(event.result)) {
|
|
9046
|
+
let firstChunkTime;
|
|
8693
9047
|
patchStreamIfNeeded(event.result, {
|
|
9048
|
+
onChunk: () => {
|
|
9049
|
+
if (firstChunkTime === void 0) {
|
|
9050
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
9051
|
+
}
|
|
9052
|
+
},
|
|
8694
9053
|
onComplete: (chunks) => {
|
|
8695
9054
|
try {
|
|
8696
9055
|
let output;
|
|
8697
9056
|
let metrics;
|
|
9057
|
+
let metadata;
|
|
8698
9058
|
if (config.aggregateChunks) {
|
|
8699
|
-
const aggregated = config.aggregateChunks(
|
|
9059
|
+
const aggregated = config.aggregateChunks(
|
|
9060
|
+
chunks,
|
|
9061
|
+
event.result,
|
|
9062
|
+
event
|
|
9063
|
+
);
|
|
8700
9064
|
output = aggregated.output;
|
|
8701
9065
|
metrics = aggregated.metrics;
|
|
9066
|
+
metadata = aggregated.metadata;
|
|
8702
9067
|
} else {
|
|
8703
|
-
output = config.extractOutput(chunks);
|
|
8704
|
-
metrics = config.extractMetrics(chunks, startTime);
|
|
9068
|
+
output = config.extractOutput(chunks, event);
|
|
9069
|
+
metrics = config.extractMetrics(chunks, startTime, event);
|
|
8705
9070
|
}
|
|
8706
|
-
if (
|
|
9071
|
+
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
9072
|
+
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
9073
|
+
} else if (metrics.time_to_first_token === void 0 && chunks.length > 0) {
|
|
8707
9074
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
8708
9075
|
}
|
|
8709
9076
|
span.log({
|
|
8710
9077
|
output,
|
|
9078
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
8711
9079
|
metrics
|
|
8712
9080
|
});
|
|
8713
9081
|
} catch (error) {
|
|
@@ -8728,10 +9096,16 @@ var BasePlugin = class {
|
|
|
8728
9096
|
});
|
|
8729
9097
|
} else {
|
|
8730
9098
|
try {
|
|
8731
|
-
const output = config.extractOutput(event.result);
|
|
8732
|
-
const
|
|
9099
|
+
const output = config.extractOutput(event.result, event);
|
|
9100
|
+
const metadata = config.extractMetadata ? config.extractMetadata(event.result, event) : void 0;
|
|
9101
|
+
const metrics = config.extractMetrics(
|
|
9102
|
+
event.result,
|
|
9103
|
+
startTime,
|
|
9104
|
+
event
|
|
9105
|
+
);
|
|
8733
9106
|
span.log({
|
|
8734
9107
|
output,
|
|
9108
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
8735
9109
|
metrics
|
|
8736
9110
|
});
|
|
8737
9111
|
} catch (error) {
|
|
@@ -8755,9 +9129,9 @@ var BasePlugin = class {
|
|
|
8755
9129
|
spans.delete(event);
|
|
8756
9130
|
}
|
|
8757
9131
|
};
|
|
8758
|
-
|
|
9132
|
+
channel2.subscribe(handlers);
|
|
8759
9133
|
this.unsubscribers.push(() => {
|
|
8760
|
-
|
|
9134
|
+
channel2.unsubscribe(handlers);
|
|
8761
9135
|
});
|
|
8762
9136
|
}
|
|
8763
9137
|
/**
|
|
@@ -8765,15 +9139,17 @@ var BasePlugin = class {
|
|
|
8765
9139
|
* Used for methods like beta.chat.completions.stream() and responses.stream().
|
|
8766
9140
|
*/
|
|
8767
9141
|
subscribeToSyncStreamChannel(channelName, config) {
|
|
8768
|
-
const
|
|
9142
|
+
const channel2 = isomorph_default.newTracingChannel(channelName);
|
|
8769
9143
|
const spans = /* @__PURE__ */ new WeakMap();
|
|
8770
9144
|
const handlers = {
|
|
8771
9145
|
start: (event) => {
|
|
9146
|
+
const { name, spanAttributes, spanInfoMetadata } = buildStartSpanArgs(
|
|
9147
|
+
config,
|
|
9148
|
+
event
|
|
9149
|
+
);
|
|
8772
9150
|
const span = startSpan({
|
|
8773
|
-
name
|
|
8774
|
-
spanAttributes
|
|
8775
|
-
type: config.type
|
|
8776
|
-
}
|
|
9151
|
+
name,
|
|
9152
|
+
spanAttributes
|
|
8777
9153
|
});
|
|
8778
9154
|
const startTime = getCurrentUnixTimestamp();
|
|
8779
9155
|
spans.set(event, { span, startTime });
|
|
@@ -8781,7 +9157,7 @@ var BasePlugin = class {
|
|
|
8781
9157
|
const { input, metadata } = config.extractInput(event.arguments);
|
|
8782
9158
|
span.log({
|
|
8783
9159
|
input,
|
|
8784
|
-
metadata
|
|
9160
|
+
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
8785
9161
|
});
|
|
8786
9162
|
} catch (error) {
|
|
8787
9163
|
console.error(`Error extracting input for ${channelName}:`, error);
|
|
@@ -8865,141 +9241,652 @@ var BasePlugin = class {
|
|
|
8865
9241
|
spans.delete(event);
|
|
8866
9242
|
}
|
|
8867
9243
|
};
|
|
8868
|
-
|
|
9244
|
+
channel2.subscribe(handlers);
|
|
8869
9245
|
this.unsubscribers.push(() => {
|
|
8870
|
-
|
|
9246
|
+
channel2.unsubscribe(handlers);
|
|
8871
9247
|
});
|
|
8872
9248
|
}
|
|
8873
9249
|
};
|
|
8874
9250
|
|
|
8875
|
-
// src/
|
|
8876
|
-
function
|
|
8877
|
-
|
|
8878
|
-
"image/png": "png",
|
|
8879
|
-
"image/jpeg": "jpg",
|
|
8880
|
-
"image/gif": "gif",
|
|
8881
|
-
"image/webp": "webp",
|
|
8882
|
-
"image/svg+xml": "svg",
|
|
8883
|
-
"audio/mpeg": "mp3",
|
|
8884
|
-
"audio/wav": "wav",
|
|
8885
|
-
"audio/ogg": "ogg",
|
|
8886
|
-
"video/mp4": "mp4",
|
|
8887
|
-
"video/webm": "webm",
|
|
8888
|
-
"application/pdf": "pdf",
|
|
8889
|
-
"application/json": "json",
|
|
8890
|
-
"text/plain": "txt",
|
|
8891
|
-
"text/html": "html",
|
|
8892
|
-
"text/csv": "csv"
|
|
8893
|
-
};
|
|
8894
|
-
return extensionMap[mediaType] || "bin";
|
|
9251
|
+
// src/instrumentation/core/channel-tracing.ts
|
|
9252
|
+
function isSyncStreamLike(value) {
|
|
9253
|
+
return !!value && typeof value === "object" && typeof value.on === "function";
|
|
8895
9254
|
}
|
|
8896
|
-
function
|
|
9255
|
+
function hasChoices(value) {
|
|
9256
|
+
return !!value && typeof value === "object" && "choices" in value;
|
|
9257
|
+
}
|
|
9258
|
+
function normalizeMetadata(metadata) {
|
|
9259
|
+
return isObject(metadata) ? metadata : void 0;
|
|
9260
|
+
}
|
|
9261
|
+
function startSpanForEvent(config, event, channelName) {
|
|
9262
|
+
const { name, spanAttributes, spanInfoMetadata } = buildStartSpanArgs(
|
|
9263
|
+
config,
|
|
9264
|
+
event
|
|
9265
|
+
);
|
|
9266
|
+
const span = startSpan({
|
|
9267
|
+
name,
|
|
9268
|
+
spanAttributes
|
|
9269
|
+
});
|
|
9270
|
+
const startTime = getCurrentUnixTimestamp();
|
|
8897
9271
|
try {
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
8903
|
-
|
|
8904
|
-
|
|
8905
|
-
|
|
8906
|
-
|
|
8907
|
-
|
|
8908
|
-
|
|
8909
|
-
}
|
|
8910
|
-
} else if (data.startsWith("http://") || data.startsWith("https://")) {
|
|
8911
|
-
return null;
|
|
8912
|
-
} else {
|
|
8913
|
-
const binaryString = atob(data);
|
|
8914
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
8915
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
8916
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
8917
|
-
}
|
|
8918
|
-
return new Blob([bytes], { type: mediaType });
|
|
8919
|
-
}
|
|
8920
|
-
} else if (data instanceof Uint8Array) {
|
|
8921
|
-
return new Blob([data], { type: mediaType });
|
|
8922
|
-
} else if (data instanceof ArrayBuffer) {
|
|
8923
|
-
return new Blob([data], { type: mediaType });
|
|
8924
|
-
} else if (typeof Buffer !== "undefined" && data instanceof Buffer) {
|
|
8925
|
-
return new Blob([data], { type: mediaType });
|
|
8926
|
-
}
|
|
8927
|
-
} catch {
|
|
8928
|
-
return null;
|
|
9272
|
+
const { input, metadata } = config.extractInput(
|
|
9273
|
+
event.arguments,
|
|
9274
|
+
event,
|
|
9275
|
+
span
|
|
9276
|
+
);
|
|
9277
|
+
span.log({
|
|
9278
|
+
input,
|
|
9279
|
+
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
9280
|
+
});
|
|
9281
|
+
} catch (error) {
|
|
9282
|
+
console.error(`Error extracting input for ${channelName}:`, error);
|
|
8929
9283
|
}
|
|
8930
|
-
return
|
|
9284
|
+
return { span, startTime };
|
|
8931
9285
|
}
|
|
8932
|
-
function
|
|
8933
|
-
|
|
8934
|
-
|
|
9286
|
+
function logErrorAndEnd(states, event) {
|
|
9287
|
+
const spanData = states.get(event);
|
|
9288
|
+
if (!spanData) {
|
|
9289
|
+
return;
|
|
8935
9290
|
}
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
9291
|
+
spanData.span.log({
|
|
9292
|
+
error: event.error.message
|
|
9293
|
+
});
|
|
9294
|
+
spanData.span.end();
|
|
9295
|
+
states.delete(event);
|
|
9296
|
+
}
|
|
9297
|
+
function traceAsyncChannel(channel2, config) {
|
|
9298
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
9299
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
9300
|
+
const channelName = channel2.channelName;
|
|
9301
|
+
const handlers = {
|
|
9302
|
+
start: (event) => {
|
|
9303
|
+
states.set(
|
|
9304
|
+
event,
|
|
9305
|
+
startSpanForEvent(
|
|
9306
|
+
config,
|
|
9307
|
+
event,
|
|
9308
|
+
channelName
|
|
9309
|
+
)
|
|
9310
|
+
);
|
|
9311
|
+
},
|
|
9312
|
+
asyncEnd: (event) => {
|
|
9313
|
+
const spanData = states.get(event);
|
|
9314
|
+
if (!spanData) {
|
|
9315
|
+
return;
|
|
8950
9316
|
}
|
|
8951
|
-
const
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
9317
|
+
const asyncEndEvent = event;
|
|
9318
|
+
const { span, startTime } = spanData;
|
|
9319
|
+
try {
|
|
9320
|
+
const output = config.extractOutput(
|
|
9321
|
+
asyncEndEvent.result,
|
|
9322
|
+
asyncEndEvent
|
|
9323
|
+
);
|
|
9324
|
+
const metrics = config.extractMetrics(
|
|
9325
|
+
asyncEndEvent.result,
|
|
9326
|
+
startTime,
|
|
9327
|
+
asyncEndEvent
|
|
9328
|
+
);
|
|
9329
|
+
const metadata = config.extractMetadata?.(
|
|
9330
|
+
asyncEndEvent.result,
|
|
9331
|
+
asyncEndEvent
|
|
9332
|
+
);
|
|
9333
|
+
span.log({
|
|
9334
|
+
output,
|
|
9335
|
+
...normalizeMetadata(metadata) !== void 0 ? { metadata: normalizeMetadata(metadata) } : {},
|
|
9336
|
+
metrics
|
|
8959
9337
|
});
|
|
8960
|
-
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
|
|
9338
|
+
} catch (error) {
|
|
9339
|
+
console.error(`Error extracting output for ${channelName}:`, error);
|
|
9340
|
+
} finally {
|
|
9341
|
+
span.end();
|
|
9342
|
+
states.delete(event);
|
|
8964
9343
|
}
|
|
9344
|
+
},
|
|
9345
|
+
error: (event) => {
|
|
9346
|
+
logErrorAndEnd(states, event);
|
|
8965
9347
|
}
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
9348
|
+
};
|
|
9349
|
+
tracingChannel2.subscribe(handlers);
|
|
9350
|
+
return () => {
|
|
9351
|
+
tracingChannel2.unsubscribe(handlers);
|
|
9352
|
+
};
|
|
9353
|
+
}
|
|
9354
|
+
function traceStreamingChannel(channel2, config) {
|
|
9355
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
9356
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
9357
|
+
const channelName = channel2.channelName;
|
|
9358
|
+
const handlers = {
|
|
9359
|
+
start: (event) => {
|
|
9360
|
+
states.set(
|
|
9361
|
+
event,
|
|
9362
|
+
startSpanForEvent(
|
|
9363
|
+
config,
|
|
9364
|
+
event,
|
|
9365
|
+
channelName
|
|
9366
|
+
)
|
|
9367
|
+
);
|
|
9368
|
+
},
|
|
9369
|
+
asyncEnd: (event) => {
|
|
9370
|
+
const spanData = states.get(event);
|
|
9371
|
+
if (!spanData) {
|
|
9372
|
+
return;
|
|
9373
|
+
}
|
|
9374
|
+
const asyncEndEvent = event;
|
|
9375
|
+
const { span, startTime } = spanData;
|
|
9376
|
+
if (isAsyncIterable(asyncEndEvent.result)) {
|
|
9377
|
+
let firstChunkTime;
|
|
9378
|
+
patchStreamIfNeeded(asyncEndEvent.result, {
|
|
9379
|
+
onChunk: () => {
|
|
9380
|
+
if (firstChunkTime === void 0) {
|
|
9381
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
9382
|
+
}
|
|
9383
|
+
},
|
|
9384
|
+
onComplete: (chunks) => {
|
|
9385
|
+
try {
|
|
9386
|
+
let output;
|
|
9387
|
+
let metrics;
|
|
9388
|
+
let metadata;
|
|
9389
|
+
if (config.aggregateChunks) {
|
|
9390
|
+
const aggregated = config.aggregateChunks(
|
|
9391
|
+
chunks,
|
|
9392
|
+
asyncEndEvent.result,
|
|
9393
|
+
asyncEndEvent,
|
|
9394
|
+
startTime
|
|
9395
|
+
);
|
|
9396
|
+
output = aggregated.output;
|
|
9397
|
+
metrics = aggregated.metrics;
|
|
9398
|
+
metadata = aggregated.metadata;
|
|
9399
|
+
} else {
|
|
9400
|
+
output = config.extractOutput(
|
|
9401
|
+
chunks,
|
|
9402
|
+
asyncEndEvent
|
|
9403
|
+
);
|
|
9404
|
+
metrics = config.extractMetrics(
|
|
9405
|
+
chunks,
|
|
9406
|
+
startTime,
|
|
9407
|
+
asyncEndEvent
|
|
9408
|
+
);
|
|
9409
|
+
}
|
|
9410
|
+
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
9411
|
+
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
9412
|
+
} else if (metrics.time_to_first_token === void 0 && chunks.length > 0) {
|
|
9413
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9414
|
+
}
|
|
9415
|
+
span.log({
|
|
9416
|
+
output,
|
|
9417
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
9418
|
+
metrics
|
|
9419
|
+
});
|
|
9420
|
+
} catch (error) {
|
|
9421
|
+
console.error(
|
|
9422
|
+
`Error extracting output for ${channelName}:`,
|
|
9423
|
+
error
|
|
9424
|
+
);
|
|
9425
|
+
} finally {
|
|
9426
|
+
span.end();
|
|
9427
|
+
states.delete(event);
|
|
9428
|
+
}
|
|
9429
|
+
},
|
|
9430
|
+
onError: (error) => {
|
|
9431
|
+
span.log({
|
|
9432
|
+
error: error.message
|
|
9433
|
+
});
|
|
9434
|
+
span.end();
|
|
9435
|
+
states.delete(event);
|
|
9436
|
+
}
|
|
9437
|
+
});
|
|
9438
|
+
return;
|
|
9439
|
+
}
|
|
9440
|
+
if (config.patchResult?.({
|
|
9441
|
+
channelName,
|
|
9442
|
+
endEvent: asyncEndEvent,
|
|
9443
|
+
result: asyncEndEvent.result,
|
|
9444
|
+
span,
|
|
9445
|
+
startTime
|
|
9446
|
+
})) {
|
|
9447
|
+
states.delete(event);
|
|
9448
|
+
return;
|
|
9449
|
+
}
|
|
9450
|
+
try {
|
|
9451
|
+
const output = config.extractOutput(
|
|
9452
|
+
asyncEndEvent.result,
|
|
9453
|
+
asyncEndEvent
|
|
9454
|
+
);
|
|
9455
|
+
const metrics = config.extractMetrics(
|
|
9456
|
+
asyncEndEvent.result,
|
|
9457
|
+
startTime,
|
|
9458
|
+
asyncEndEvent
|
|
9459
|
+
);
|
|
9460
|
+
const metadata = config.extractMetadata?.(
|
|
9461
|
+
asyncEndEvent.result,
|
|
9462
|
+
asyncEndEvent
|
|
9463
|
+
);
|
|
9464
|
+
span.log({
|
|
9465
|
+
output,
|
|
9466
|
+
...normalizeMetadata(metadata) !== void 0 ? { metadata: normalizeMetadata(metadata) } : {},
|
|
9467
|
+
metrics
|
|
9468
|
+
});
|
|
9469
|
+
} catch (error) {
|
|
9470
|
+
console.error(`Error extracting output for ${channelName}:`, error);
|
|
9471
|
+
} finally {
|
|
9472
|
+
span.end();
|
|
9473
|
+
states.delete(event);
|
|
9474
|
+
}
|
|
9475
|
+
},
|
|
9476
|
+
error: (event) => {
|
|
9477
|
+
logErrorAndEnd(states, event);
|
|
9478
|
+
}
|
|
9479
|
+
};
|
|
9480
|
+
tracingChannel2.subscribe(handlers);
|
|
9481
|
+
return () => {
|
|
9482
|
+
tracingChannel2.unsubscribe(handlers);
|
|
9483
|
+
};
|
|
9484
|
+
}
|
|
9485
|
+
function traceSyncStreamChannel(channel2, config) {
|
|
9486
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
9487
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
9488
|
+
const channelName = channel2.channelName;
|
|
9489
|
+
const handlers = {
|
|
9490
|
+
start: (event) => {
|
|
9491
|
+
states.set(
|
|
9492
|
+
event,
|
|
9493
|
+
startSpanForEvent(
|
|
9494
|
+
config,
|
|
9495
|
+
event,
|
|
9496
|
+
channelName
|
|
9497
|
+
)
|
|
9498
|
+
);
|
|
9499
|
+
},
|
|
9500
|
+
end: (event) => {
|
|
9501
|
+
const spanData = states.get(event);
|
|
9502
|
+
if (!spanData) {
|
|
9503
|
+
return;
|
|
9504
|
+
}
|
|
9505
|
+
const { span, startTime } = spanData;
|
|
9506
|
+
const endEvent = event;
|
|
9507
|
+
if (config.patchResult?.({
|
|
9508
|
+
channelName,
|
|
9509
|
+
endEvent,
|
|
9510
|
+
result: endEvent.result,
|
|
9511
|
+
span,
|
|
9512
|
+
startTime
|
|
9513
|
+
})) {
|
|
9514
|
+
return;
|
|
9515
|
+
}
|
|
9516
|
+
const stream = endEvent.result;
|
|
9517
|
+
if (!isSyncStreamLike(stream)) {
|
|
9518
|
+
span.end();
|
|
9519
|
+
states.delete(event);
|
|
9520
|
+
return;
|
|
9521
|
+
}
|
|
9522
|
+
let first = true;
|
|
9523
|
+
stream.on("chunk", () => {
|
|
9524
|
+
if (first) {
|
|
9525
|
+
span.log({
|
|
9526
|
+
metrics: {
|
|
9527
|
+
time_to_first_token: getCurrentUnixTimestamp() - startTime
|
|
9528
|
+
}
|
|
9529
|
+
});
|
|
9530
|
+
first = false;
|
|
9531
|
+
}
|
|
9532
|
+
});
|
|
9533
|
+
stream.on("chatCompletion", (completion) => {
|
|
9534
|
+
try {
|
|
9535
|
+
if (hasChoices(completion)) {
|
|
9536
|
+
span.log({
|
|
9537
|
+
output: completion.choices
|
|
9538
|
+
});
|
|
9539
|
+
}
|
|
9540
|
+
} catch (error) {
|
|
9541
|
+
console.error(
|
|
9542
|
+
`Error extracting chatCompletion for ${channelName}:`,
|
|
9543
|
+
error
|
|
9544
|
+
);
|
|
9545
|
+
}
|
|
9546
|
+
});
|
|
9547
|
+
stream.on("event", (streamEvent) => {
|
|
9548
|
+
if (!config.extractFromEvent) {
|
|
9549
|
+
return;
|
|
9550
|
+
}
|
|
9551
|
+
try {
|
|
9552
|
+
if (first) {
|
|
9553
|
+
span.log({
|
|
9554
|
+
metrics: {
|
|
9555
|
+
time_to_first_token: getCurrentUnixTimestamp() - startTime
|
|
9556
|
+
}
|
|
9557
|
+
});
|
|
9558
|
+
first = false;
|
|
9559
|
+
}
|
|
9560
|
+
const extracted = config.extractFromEvent(streamEvent);
|
|
9561
|
+
if (extracted && Object.keys(extracted).length > 0) {
|
|
9562
|
+
span.log(extracted);
|
|
9563
|
+
}
|
|
9564
|
+
} catch (error) {
|
|
9565
|
+
console.error(`Error extracting event for ${channelName}:`, error);
|
|
9566
|
+
}
|
|
9567
|
+
});
|
|
9568
|
+
stream.on("end", () => {
|
|
9569
|
+
span.end();
|
|
9570
|
+
states.delete(event);
|
|
9571
|
+
});
|
|
9572
|
+
stream.on("error", (error) => {
|
|
9573
|
+
span.log({
|
|
9574
|
+
error: error.message
|
|
8976
9575
|
});
|
|
9576
|
+
span.end();
|
|
9577
|
+
states.delete(event);
|
|
9578
|
+
});
|
|
9579
|
+
},
|
|
9580
|
+
error: (event) => {
|
|
9581
|
+
logErrorAndEnd(states, event);
|
|
9582
|
+
}
|
|
9583
|
+
};
|
|
9584
|
+
tracingChannel2.subscribe(handlers);
|
|
9585
|
+
return () => {
|
|
9586
|
+
tracingChannel2.unsubscribe(handlers);
|
|
9587
|
+
};
|
|
9588
|
+
}
|
|
9589
|
+
function unsubscribeAll(unsubscribers) {
|
|
9590
|
+
for (const unsubscribe of unsubscribers) {
|
|
9591
|
+
unsubscribe();
|
|
9592
|
+
}
|
|
9593
|
+
return [];
|
|
9594
|
+
}
|
|
9595
|
+
|
|
9596
|
+
// src/wrappers/attachment-utils.ts
|
|
9597
|
+
function getExtensionFromMediaType(mediaType) {
|
|
9598
|
+
const extensionMap = {
|
|
9599
|
+
"image/png": "png",
|
|
9600
|
+
"image/jpeg": "jpg",
|
|
9601
|
+
"image/gif": "gif",
|
|
9602
|
+
"image/webp": "webp",
|
|
9603
|
+
"image/svg+xml": "svg",
|
|
9604
|
+
"audio/mpeg": "mp3",
|
|
9605
|
+
"audio/wav": "wav",
|
|
9606
|
+
"audio/ogg": "ogg",
|
|
9607
|
+
"video/mp4": "mp4",
|
|
9608
|
+
"video/webm": "webm",
|
|
9609
|
+
"application/pdf": "pdf",
|
|
9610
|
+
"application/json": "json",
|
|
9611
|
+
"text/plain": "txt",
|
|
9612
|
+
"text/html": "html",
|
|
9613
|
+
"text/csv": "csv"
|
|
9614
|
+
};
|
|
9615
|
+
return extensionMap[mediaType] || "bin";
|
|
9616
|
+
}
|
|
9617
|
+
function convertDataToBlob(data, mediaType) {
|
|
9618
|
+
try {
|
|
9619
|
+
if (typeof data === "string") {
|
|
9620
|
+
if (data.startsWith("data:")) {
|
|
9621
|
+
const base64Match = data.match(/^data:[^;]+;base64,(.+)$/);
|
|
9622
|
+
if (base64Match) {
|
|
9623
|
+
const base64 = base64Match[1];
|
|
9624
|
+
const binaryString = atob(base64);
|
|
9625
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
9626
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
9627
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
9628
|
+
}
|
|
9629
|
+
return new Blob([bytes], { type: mediaType });
|
|
9630
|
+
}
|
|
9631
|
+
} else if (data.startsWith("http://") || data.startsWith("https://")) {
|
|
9632
|
+
return null;
|
|
9633
|
+
} else {
|
|
9634
|
+
const binaryString = atob(data);
|
|
9635
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
9636
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
9637
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
9638
|
+
}
|
|
9639
|
+
return new Blob([bytes], { type: mediaType });
|
|
9640
|
+
}
|
|
9641
|
+
} else if (data instanceof Uint8Array) {
|
|
9642
|
+
return new Blob([data], { type: mediaType });
|
|
9643
|
+
} else if (data instanceof ArrayBuffer) {
|
|
9644
|
+
return new Blob([data], { type: mediaType });
|
|
9645
|
+
} else if (typeof Buffer !== "undefined" && data instanceof Buffer) {
|
|
9646
|
+
return new Blob([data], { type: mediaType });
|
|
9647
|
+
}
|
|
9648
|
+
} catch {
|
|
9649
|
+
return null;
|
|
9650
|
+
}
|
|
9651
|
+
return null;
|
|
9652
|
+
}
|
|
9653
|
+
function processInputAttachments(input) {
|
|
9654
|
+
if (!input) {
|
|
9655
|
+
return input;
|
|
9656
|
+
}
|
|
9657
|
+
let attachmentIndex = 0;
|
|
9658
|
+
const inferMediaTypeFromDataUrl = (value, fallback2) => {
|
|
9659
|
+
const mediaTypeMatch = value.match(/^data:([^;]+);/);
|
|
9660
|
+
return mediaTypeMatch?.[1] || fallback2;
|
|
9661
|
+
};
|
|
9662
|
+
const toAttachment = (value, mediaType, filename) => {
|
|
9663
|
+
const blob = convertDataToBlob(value, mediaType);
|
|
9664
|
+
if (!blob) {
|
|
9665
|
+
return null;
|
|
9666
|
+
}
|
|
9667
|
+
return new Attachment({
|
|
9668
|
+
data: blob,
|
|
9669
|
+
filename,
|
|
9670
|
+
contentType: mediaType
|
|
9671
|
+
});
|
|
9672
|
+
};
|
|
9673
|
+
const processNode = (node) => {
|
|
9674
|
+
if (Array.isArray(node)) {
|
|
9675
|
+
return node.map(processNode);
|
|
9676
|
+
}
|
|
9677
|
+
if (!node || typeof node !== "object") {
|
|
9678
|
+
return node;
|
|
9679
|
+
}
|
|
9680
|
+
if (node.type === "image_url" && node.image_url && typeof node.image_url === "object" && typeof node.image_url.url === "string" && node.image_url.url.startsWith("data:")) {
|
|
9681
|
+
const mediaType = inferMediaTypeFromDataUrl(
|
|
9682
|
+
node.image_url.url,
|
|
9683
|
+
"image/png"
|
|
9684
|
+
);
|
|
9685
|
+
const filename = `image.${getExtensionFromMediaType(mediaType)}`;
|
|
9686
|
+
const attachment = toAttachment(node.image_url.url, mediaType, filename);
|
|
9687
|
+
if (attachment) {
|
|
8977
9688
|
return {
|
|
8978
|
-
...
|
|
8979
|
-
|
|
9689
|
+
...node,
|
|
9690
|
+
image_url: {
|
|
9691
|
+
...node.image_url,
|
|
9692
|
+
url: attachment
|
|
9693
|
+
}
|
|
8980
9694
|
};
|
|
8981
9695
|
}
|
|
8982
9696
|
}
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
|
|
9697
|
+
if (node.type === "file" && node.file && typeof node.file === "object" && typeof node.file.file_data === "string" && node.file.file_data.startsWith("data:")) {
|
|
9698
|
+
const mediaType = inferMediaTypeFromDataUrl(
|
|
9699
|
+
node.file.file_data,
|
|
9700
|
+
"application/octet-stream"
|
|
9701
|
+
);
|
|
9702
|
+
const filename = typeof node.file.filename === "string" && node.file.filename ? node.file.filename : `document.${getExtensionFromMediaType(mediaType)}`;
|
|
9703
|
+
const attachment = toAttachment(node.file.file_data, mediaType, filename);
|
|
9704
|
+
if (attachment) {
|
|
9705
|
+
return {
|
|
9706
|
+
...node,
|
|
9707
|
+
file: {
|
|
9708
|
+
...node.file,
|
|
9709
|
+
file_data: attachment
|
|
9710
|
+
}
|
|
9711
|
+
};
|
|
9712
|
+
}
|
|
8988
9713
|
}
|
|
8989
|
-
if (
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
|
|
8993
|
-
}
|
|
9714
|
+
if (node.type === "image" && node.image) {
|
|
9715
|
+
let mediaType = "image/png";
|
|
9716
|
+
if (typeof node.image === "string" && node.image.startsWith("data:")) {
|
|
9717
|
+
mediaType = inferMediaTypeFromDataUrl(node.image, mediaType);
|
|
9718
|
+
} else if (node.mediaType) {
|
|
9719
|
+
mediaType = node.mediaType;
|
|
9720
|
+
}
|
|
9721
|
+
const filename = `input_image_${attachmentIndex}.${getExtensionFromMediaType(mediaType)}`;
|
|
9722
|
+
const attachment = toAttachment(node.image, mediaType, filename);
|
|
9723
|
+
if (attachment) {
|
|
9724
|
+
attachmentIndex++;
|
|
9725
|
+
return {
|
|
9726
|
+
...node,
|
|
9727
|
+
image: attachment
|
|
9728
|
+
};
|
|
9729
|
+
}
|
|
9730
|
+
}
|
|
9731
|
+
if (node.type === "file" && node.data) {
|
|
9732
|
+
const mediaType = node.mediaType || "application/octet-stream";
|
|
9733
|
+
const filename = node.filename || `input_file_${attachmentIndex}.${getExtensionFromMediaType(mediaType)}`;
|
|
9734
|
+
const attachment = toAttachment(node.data, mediaType, filename);
|
|
9735
|
+
if (attachment) {
|
|
9736
|
+
attachmentIndex++;
|
|
9737
|
+
return {
|
|
9738
|
+
...node,
|
|
9739
|
+
data: attachment
|
|
9740
|
+
};
|
|
9741
|
+
}
|
|
8994
9742
|
}
|
|
8995
|
-
|
|
9743
|
+
const processed = {};
|
|
9744
|
+
for (const [key, value] of Object.entries(node)) {
|
|
9745
|
+
processed[key] = processNode(value);
|
|
9746
|
+
}
|
|
9747
|
+
return processed;
|
|
8996
9748
|
};
|
|
8997
9749
|
if (Array.isArray(input)) {
|
|
8998
|
-
return input.map(
|
|
8999
|
-
} else if (typeof input === "object" && input.content) {
|
|
9000
|
-
return processMessage(input);
|
|
9750
|
+
return input.map(processNode);
|
|
9001
9751
|
}
|
|
9002
|
-
return input;
|
|
9752
|
+
return processNode(input);
|
|
9753
|
+
}
|
|
9754
|
+
|
|
9755
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
9756
|
+
function channel(spec) {
|
|
9757
|
+
return spec;
|
|
9758
|
+
}
|
|
9759
|
+
function defineChannels(pkg, channels) {
|
|
9760
|
+
return Object.fromEntries(
|
|
9761
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
9762
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
9763
|
+
if (spec.kind === "async") {
|
|
9764
|
+
const asyncSpec = spec;
|
|
9765
|
+
const tracingChannel3 = () => isomorph_default.newTracingChannel(
|
|
9766
|
+
fullChannelName
|
|
9767
|
+
);
|
|
9768
|
+
return [
|
|
9769
|
+
key,
|
|
9770
|
+
{
|
|
9771
|
+
...asyncSpec,
|
|
9772
|
+
tracingChannel: tracingChannel3,
|
|
9773
|
+
tracePromise: (fn, context) => tracingChannel3().tracePromise(
|
|
9774
|
+
fn,
|
|
9775
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
9776
|
+
context
|
|
9777
|
+
)
|
|
9778
|
+
}
|
|
9779
|
+
];
|
|
9780
|
+
}
|
|
9781
|
+
const syncSpec = spec;
|
|
9782
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
9783
|
+
fullChannelName
|
|
9784
|
+
);
|
|
9785
|
+
return [
|
|
9786
|
+
key,
|
|
9787
|
+
{
|
|
9788
|
+
...syncSpec,
|
|
9789
|
+
tracingChannel: tracingChannel2,
|
|
9790
|
+
traceSync: (fn, context) => tracingChannel2().traceSync(
|
|
9791
|
+
fn,
|
|
9792
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
9793
|
+
context
|
|
9794
|
+
)
|
|
9795
|
+
}
|
|
9796
|
+
];
|
|
9797
|
+
})
|
|
9798
|
+
);
|
|
9799
|
+
}
|
|
9800
|
+
|
|
9801
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
9802
|
+
var openAIChannels = defineChannels("openai", {
|
|
9803
|
+
chatCompletionsCreate: channel({
|
|
9804
|
+
channelName: "chat.completions.create",
|
|
9805
|
+
kind: "async"
|
|
9806
|
+
}),
|
|
9807
|
+
embeddingsCreate: channel({
|
|
9808
|
+
channelName: "embeddings.create",
|
|
9809
|
+
kind: "async"
|
|
9810
|
+
}),
|
|
9811
|
+
betaChatCompletionsParse: channel({
|
|
9812
|
+
channelName: "beta.chat.completions.parse",
|
|
9813
|
+
kind: "async"
|
|
9814
|
+
}),
|
|
9815
|
+
betaChatCompletionsStream: channel({
|
|
9816
|
+
channelName: "beta.chat.completions.stream",
|
|
9817
|
+
kind: "sync-stream"
|
|
9818
|
+
}),
|
|
9819
|
+
moderationsCreate: channel({
|
|
9820
|
+
channelName: "moderations.create",
|
|
9821
|
+
kind: "async"
|
|
9822
|
+
}),
|
|
9823
|
+
responsesCreate: channel({
|
|
9824
|
+
channelName: "responses.create",
|
|
9825
|
+
kind: "async"
|
|
9826
|
+
}),
|
|
9827
|
+
responsesStream: channel({
|
|
9828
|
+
channelName: "responses.stream",
|
|
9829
|
+
kind: "sync-stream"
|
|
9830
|
+
}),
|
|
9831
|
+
responsesParse: channel({
|
|
9832
|
+
channelName: "responses.parse",
|
|
9833
|
+
kind: "async"
|
|
9834
|
+
})
|
|
9835
|
+
});
|
|
9836
|
+
|
|
9837
|
+
// src/openai-utils.ts
|
|
9838
|
+
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
9839
|
+
var LEGACY_CACHED_HEADER = "x-cached";
|
|
9840
|
+
var X_CACHED_HEADER = "x-bt-cached";
|
|
9841
|
+
var TOKEN_NAME_MAP = {
|
|
9842
|
+
input_tokens: "prompt_tokens",
|
|
9843
|
+
output_tokens: "completion_tokens",
|
|
9844
|
+
total_tokens: "tokens"
|
|
9845
|
+
};
|
|
9846
|
+
var TOKEN_PREFIX_MAP = {
|
|
9847
|
+
input: "prompt",
|
|
9848
|
+
output: "completion"
|
|
9849
|
+
};
|
|
9850
|
+
function parseMetricsFromUsage(usage) {
|
|
9851
|
+
if (!usage) {
|
|
9852
|
+
return {};
|
|
9853
|
+
}
|
|
9854
|
+
const metrics = {};
|
|
9855
|
+
for (const [oaiName, value] of Object.entries(usage)) {
|
|
9856
|
+
if (typeof value === "number") {
|
|
9857
|
+
const metricName = TOKEN_NAME_MAP[oaiName] || oaiName;
|
|
9858
|
+
metrics[metricName] = value;
|
|
9859
|
+
continue;
|
|
9860
|
+
}
|
|
9861
|
+
if (!oaiName.endsWith("_tokens_details") || !isObject(value)) {
|
|
9862
|
+
continue;
|
|
9863
|
+
}
|
|
9864
|
+
const rawPrefix = oaiName.slice(0, -"_tokens_details".length);
|
|
9865
|
+
const prefix = TOKEN_PREFIX_MAP[rawPrefix] || rawPrefix;
|
|
9866
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
9867
|
+
if (typeof nestedValue !== "number") {
|
|
9868
|
+
continue;
|
|
9869
|
+
}
|
|
9870
|
+
metrics[`${prefix}_${key}`] = nestedValue;
|
|
9871
|
+
}
|
|
9872
|
+
}
|
|
9873
|
+
return metrics;
|
|
9874
|
+
}
|
|
9875
|
+
function parseCachedHeader(value) {
|
|
9876
|
+
if (!value) {
|
|
9877
|
+
return void 0;
|
|
9878
|
+
}
|
|
9879
|
+
return ["true", "hit"].includes(value.toLowerCase()) ? 1 : 0;
|
|
9880
|
+
}
|
|
9881
|
+
function getCachedMetricFromHeaders(headers) {
|
|
9882
|
+
if (!headers || typeof headers.get !== "function") {
|
|
9883
|
+
return void 0;
|
|
9884
|
+
}
|
|
9885
|
+
const cachedHeader = headers.get(X_CACHED_HEADER);
|
|
9886
|
+
if (cachedHeader) {
|
|
9887
|
+
return parseCachedHeader(cachedHeader);
|
|
9888
|
+
}
|
|
9889
|
+
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
9003
9890
|
}
|
|
9004
9891
|
|
|
9005
9892
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
@@ -9008,13 +9895,63 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
9008
9895
|
super();
|
|
9009
9896
|
}
|
|
9010
9897
|
onEnable() {
|
|
9011
|
-
this.
|
|
9012
|
-
|
|
9013
|
-
|
|
9898
|
+
this.unsubscribers.push(
|
|
9899
|
+
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
9900
|
+
name: "Chat Completion",
|
|
9901
|
+
type: "llm" /* LLM */,
|
|
9902
|
+
extractInput: ([params]) => {
|
|
9903
|
+
const { messages, ...metadata } = params;
|
|
9904
|
+
return {
|
|
9905
|
+
input: processInputAttachments(messages),
|
|
9906
|
+
metadata: { ...metadata, provider: "openai" }
|
|
9907
|
+
};
|
|
9908
|
+
},
|
|
9909
|
+
extractOutput: (result) => {
|
|
9910
|
+
return result?.choices;
|
|
9911
|
+
},
|
|
9912
|
+
extractMetrics: (result, startTime, endEvent) => {
|
|
9913
|
+
const metrics = withCachedMetric(
|
|
9914
|
+
parseMetricsFromUsage(result?.usage),
|
|
9915
|
+
result,
|
|
9916
|
+
endEvent
|
|
9917
|
+
);
|
|
9918
|
+
if (startTime) {
|
|
9919
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9920
|
+
}
|
|
9921
|
+
return metrics;
|
|
9922
|
+
},
|
|
9923
|
+
aggregateChunks: aggregateChatCompletionChunks
|
|
9924
|
+
})
|
|
9925
|
+
);
|
|
9926
|
+
this.unsubscribers.push(
|
|
9927
|
+
traceAsyncChannel(openAIChannels.embeddingsCreate, {
|
|
9928
|
+
name: "Embedding",
|
|
9929
|
+
type: "llm" /* LLM */,
|
|
9930
|
+
extractInput: ([params]) => {
|
|
9931
|
+
const { input, ...metadata } = params;
|
|
9932
|
+
return {
|
|
9933
|
+
input,
|
|
9934
|
+
metadata: { ...metadata, provider: "openai" }
|
|
9935
|
+
};
|
|
9936
|
+
},
|
|
9937
|
+
extractOutput: (result) => {
|
|
9938
|
+
const embedding = result?.data?.[0]?.embedding;
|
|
9939
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
9940
|
+
},
|
|
9941
|
+
extractMetrics: (result, _startTime, endEvent) => {
|
|
9942
|
+
return withCachedMetric(
|
|
9943
|
+
parseMetricsFromUsage(result?.usage),
|
|
9944
|
+
result,
|
|
9945
|
+
endEvent
|
|
9946
|
+
);
|
|
9947
|
+
}
|
|
9948
|
+
})
|
|
9949
|
+
);
|
|
9950
|
+
this.unsubscribers.push(
|
|
9951
|
+
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
9014
9952
|
name: "Chat Completion",
|
|
9015
9953
|
type: "llm" /* LLM */,
|
|
9016
|
-
extractInput: (
|
|
9017
|
-
const params = args[0] || {};
|
|
9954
|
+
extractInput: ([params]) => {
|
|
9018
9955
|
const { messages, ...metadata } = params;
|
|
9019
9956
|
return {
|
|
9020
9957
|
input: processInputAttachments(messages),
|
|
@@ -9024,208 +9961,196 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
9024
9961
|
extractOutput: (result) => {
|
|
9025
9962
|
return result?.choices;
|
|
9026
9963
|
},
|
|
9027
|
-
extractMetrics: (result, startTime) => {
|
|
9028
|
-
const metrics =
|
|
9964
|
+
extractMetrics: (result, startTime, endEvent) => {
|
|
9965
|
+
const metrics = withCachedMetric(
|
|
9966
|
+
parseMetricsFromUsage(result?.usage),
|
|
9967
|
+
result,
|
|
9968
|
+
endEvent
|
|
9969
|
+
);
|
|
9029
9970
|
if (startTime) {
|
|
9030
9971
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9031
9972
|
}
|
|
9032
9973
|
return metrics;
|
|
9033
9974
|
},
|
|
9034
9975
|
aggregateChunks: aggregateChatCompletionChunks
|
|
9035
|
-
}
|
|
9976
|
+
})
|
|
9036
9977
|
);
|
|
9037
|
-
this.
|
|
9038
|
-
|
|
9039
|
-
type: "llm" /* LLM */,
|
|
9040
|
-
extractInput: (args) => {
|
|
9041
|
-
const params = args[0] || {};
|
|
9042
|
-
const { input, ...metadata } = params;
|
|
9043
|
-
return {
|
|
9044
|
-
input,
|
|
9045
|
-
metadata: { ...metadata, provider: "openai" }
|
|
9046
|
-
};
|
|
9047
|
-
},
|
|
9048
|
-
extractOutput: (result) => {
|
|
9049
|
-
return result?.data?.map((d) => d.embedding);
|
|
9050
|
-
},
|
|
9051
|
-
extractMetrics: (result) => {
|
|
9052
|
-
return parseMetricsFromUsage(result?.usage);
|
|
9053
|
-
}
|
|
9054
|
-
});
|
|
9055
|
-
this.subscribeToStreamingChannel(
|
|
9056
|
-
"orchestrion:openai:beta.chat.completions.parse",
|
|
9057
|
-
{
|
|
9978
|
+
this.unsubscribers.push(
|
|
9979
|
+
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
9058
9980
|
name: "Chat Completion",
|
|
9059
9981
|
type: "llm" /* LLM */,
|
|
9060
|
-
extractInput: (
|
|
9061
|
-
const params = args[0] || {};
|
|
9982
|
+
extractInput: ([params]) => {
|
|
9062
9983
|
const { messages, ...metadata } = params;
|
|
9063
9984
|
return {
|
|
9064
9985
|
input: processInputAttachments(messages),
|
|
9065
9986
|
metadata: { ...metadata, provider: "openai" }
|
|
9066
9987
|
};
|
|
9988
|
+
}
|
|
9989
|
+
})
|
|
9990
|
+
);
|
|
9991
|
+
this.unsubscribers.push(
|
|
9992
|
+
traceAsyncChannel(openAIChannels.moderationsCreate, {
|
|
9993
|
+
name: "Moderation",
|
|
9994
|
+
type: "llm" /* LLM */,
|
|
9995
|
+
extractInput: ([params]) => {
|
|
9996
|
+
const { input, ...metadata } = params;
|
|
9997
|
+
return {
|
|
9998
|
+
input,
|
|
9999
|
+
metadata: { ...metadata, provider: "openai" }
|
|
10000
|
+
};
|
|
9067
10001
|
},
|
|
9068
10002
|
extractOutput: (result) => {
|
|
9069
|
-
return result?.
|
|
10003
|
+
return result?.results;
|
|
9070
10004
|
},
|
|
9071
|
-
extractMetrics: (result,
|
|
9072
|
-
|
|
10005
|
+
extractMetrics: (result, _startTime, endEvent) => {
|
|
10006
|
+
return withCachedMetric(
|
|
10007
|
+
parseMetricsFromUsage(result?.usage),
|
|
10008
|
+
result,
|
|
10009
|
+
endEvent
|
|
10010
|
+
);
|
|
10011
|
+
}
|
|
10012
|
+
})
|
|
10013
|
+
);
|
|
10014
|
+
this.unsubscribers.push(
|
|
10015
|
+
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
10016
|
+
name: "openai.responses.create",
|
|
10017
|
+
type: "llm" /* LLM */,
|
|
10018
|
+
extractInput: ([params]) => {
|
|
10019
|
+
const { input, ...metadata } = params;
|
|
10020
|
+
return {
|
|
10021
|
+
input: processInputAttachments(input),
|
|
10022
|
+
metadata: { ...metadata, provider: "openai" }
|
|
10023
|
+
};
|
|
10024
|
+
},
|
|
10025
|
+
extractOutput: (result) => {
|
|
10026
|
+
return processImagesInOutput(result?.output);
|
|
10027
|
+
},
|
|
10028
|
+
extractMetadata: (result) => {
|
|
10029
|
+
if (!result) {
|
|
10030
|
+
return void 0;
|
|
10031
|
+
}
|
|
10032
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
10033
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
10034
|
+
},
|
|
10035
|
+
extractMetrics: (result, startTime, endEvent) => {
|
|
10036
|
+
const metrics = withCachedMetric(
|
|
10037
|
+
parseMetricsFromUsage(result?.usage),
|
|
10038
|
+
result,
|
|
10039
|
+
endEvent
|
|
10040
|
+
);
|
|
9073
10041
|
if (startTime) {
|
|
9074
10042
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9075
10043
|
}
|
|
9076
10044
|
return metrics;
|
|
9077
10045
|
},
|
|
9078
|
-
aggregateChunks:
|
|
9079
|
-
}
|
|
10046
|
+
aggregateChunks: aggregateResponseStreamEvents
|
|
10047
|
+
})
|
|
9080
10048
|
);
|
|
9081
|
-
this.
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
name: "Chat Completion",
|
|
10049
|
+
this.unsubscribers.push(
|
|
10050
|
+
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
10051
|
+
name: "openai.responses.create",
|
|
9085
10052
|
type: "llm" /* LLM */,
|
|
9086
|
-
extractInput: (
|
|
9087
|
-
const
|
|
9088
|
-
const { messages, ...metadata } = params;
|
|
10053
|
+
extractInput: ([params]) => {
|
|
10054
|
+
const { input, ...metadata } = params;
|
|
9089
10055
|
return {
|
|
9090
|
-
input: processInputAttachments(
|
|
10056
|
+
input: processInputAttachments(input),
|
|
9091
10057
|
metadata: { ...metadata, provider: "openai" }
|
|
9092
10058
|
};
|
|
9093
|
-
}
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
|
|
9099
|
-
extractInput: (args) => {
|
|
9100
|
-
const params = args[0] || {};
|
|
9101
|
-
const { input, ...metadata } = params;
|
|
9102
|
-
return {
|
|
9103
|
-
input,
|
|
9104
|
-
metadata: { ...metadata, provider: "openai" }
|
|
9105
|
-
};
|
|
9106
|
-
},
|
|
9107
|
-
extractOutput: (result) => {
|
|
9108
|
-
return result?.results;
|
|
9109
|
-
},
|
|
9110
|
-
extractMetrics: () => {
|
|
9111
|
-
return {};
|
|
9112
|
-
}
|
|
9113
|
-
});
|
|
9114
|
-
this.subscribeToStreamingChannel("orchestrion:openai:responses.create", {
|
|
9115
|
-
name: "openai.responses.create",
|
|
9116
|
-
type: "llm" /* LLM */,
|
|
9117
|
-
extractInput: (args) => {
|
|
9118
|
-
const params = args[0] || {};
|
|
9119
|
-
const { input, ...metadata } = params;
|
|
9120
|
-
return {
|
|
9121
|
-
input: processInputAttachments(input),
|
|
9122
|
-
metadata: { ...metadata, provider: "openai" }
|
|
9123
|
-
};
|
|
9124
|
-
},
|
|
9125
|
-
extractOutput: (result) => {
|
|
9126
|
-
return processImagesInOutput(result?.output);
|
|
9127
|
-
},
|
|
9128
|
-
extractMetrics: (result, startTime) => {
|
|
9129
|
-
const metrics = parseMetricsFromUsage(result?.usage);
|
|
9130
|
-
if (startTime) {
|
|
9131
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9132
|
-
}
|
|
9133
|
-
return metrics;
|
|
9134
|
-
}
|
|
9135
|
-
});
|
|
9136
|
-
this.subscribeToSyncStreamChannel("orchestrion:openai:responses.stream", {
|
|
9137
|
-
name: "openai.responses.stream",
|
|
9138
|
-
type: "llm" /* LLM */,
|
|
9139
|
-
extractInput: (args) => {
|
|
9140
|
-
const params = args[0] || {};
|
|
9141
|
-
const { input, ...metadata } = params;
|
|
9142
|
-
return {
|
|
9143
|
-
input: processInputAttachments(input),
|
|
9144
|
-
metadata: { ...metadata, provider: "openai" }
|
|
9145
|
-
};
|
|
9146
|
-
},
|
|
9147
|
-
extractFromEvent: (event) => {
|
|
9148
|
-
if (!event || !event.type || !event.response) {
|
|
9149
|
-
return {};
|
|
9150
|
-
}
|
|
9151
|
-
const response = event.response;
|
|
9152
|
-
if (event.type === "response.completed") {
|
|
10059
|
+
},
|
|
10060
|
+
extractFromEvent: (event) => {
|
|
10061
|
+
if (event.type !== "response.completed" || !event.response) {
|
|
10062
|
+
return {};
|
|
10063
|
+
}
|
|
10064
|
+
const response = event.response;
|
|
9153
10065
|
const data = {};
|
|
9154
|
-
if (response
|
|
10066
|
+
if (response.output !== void 0) {
|
|
9155
10067
|
data.output = processImagesInOutput(response.output);
|
|
9156
10068
|
}
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
data.metadata = metadata;
|
|
9161
|
-
}
|
|
10069
|
+
const { usage: _usage, output: _output, ...metadata } = response;
|
|
10070
|
+
if (Object.keys(metadata).length > 0) {
|
|
10071
|
+
data.metadata = metadata;
|
|
9162
10072
|
}
|
|
9163
|
-
data.metrics = parseMetricsFromUsage(response
|
|
10073
|
+
data.metrics = parseMetricsFromUsage(response.usage);
|
|
9164
10074
|
return data;
|
|
9165
10075
|
}
|
|
9166
|
-
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
}
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
|
|
9189
|
-
|
|
9190
|
-
|
|
10076
|
+
})
|
|
10077
|
+
);
|
|
10078
|
+
this.unsubscribers.push(
|
|
10079
|
+
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
10080
|
+
name: "openai.responses.parse",
|
|
10081
|
+
type: "llm" /* LLM */,
|
|
10082
|
+
extractInput: ([params]) => {
|
|
10083
|
+
const { input, ...metadata } = params;
|
|
10084
|
+
return {
|
|
10085
|
+
input: processInputAttachments(input),
|
|
10086
|
+
metadata: { ...metadata, provider: "openai" }
|
|
10087
|
+
};
|
|
10088
|
+
},
|
|
10089
|
+
extractOutput: (result) => {
|
|
10090
|
+
return processImagesInOutput(result?.output);
|
|
10091
|
+
},
|
|
10092
|
+
extractMetadata: (result) => {
|
|
10093
|
+
if (!result) {
|
|
10094
|
+
return void 0;
|
|
10095
|
+
}
|
|
10096
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
10097
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
10098
|
+
},
|
|
10099
|
+
extractMetrics: (result, startTime, endEvent) => {
|
|
10100
|
+
const metrics = withCachedMetric(
|
|
10101
|
+
parseMetricsFromUsage(result?.usage),
|
|
10102
|
+
result,
|
|
10103
|
+
endEvent
|
|
10104
|
+
);
|
|
10105
|
+
if (startTime) {
|
|
10106
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
10107
|
+
}
|
|
10108
|
+
return metrics;
|
|
10109
|
+
},
|
|
10110
|
+
aggregateChunks: aggregateResponseStreamEvents
|
|
10111
|
+
})
|
|
10112
|
+
);
|
|
9191
10113
|
}
|
|
9192
10114
|
onDisable() {
|
|
10115
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
9193
10116
|
}
|
|
9194
10117
|
};
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
total_tokens: "tokens"
|
|
9199
|
-
};
|
|
9200
|
-
var TOKEN_PREFIX_MAP = {
|
|
9201
|
-
input: "prompt",
|
|
9202
|
-
output: "completion"
|
|
9203
|
-
};
|
|
9204
|
-
function parseMetricsFromUsage(usage) {
|
|
9205
|
-
if (!usage) {
|
|
9206
|
-
return {};
|
|
10118
|
+
function getCachedMetricFromEndEvent(endEvent) {
|
|
10119
|
+
if (!isObject(endEvent)) {
|
|
10120
|
+
return void 0;
|
|
9207
10121
|
}
|
|
9208
|
-
const
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
const metricName = TOKEN_NAME_MAP[oai_name] || oai_name;
|
|
9212
|
-
metrics[metricName] = value;
|
|
9213
|
-
} else if (oai_name.endsWith("_tokens_details")) {
|
|
9214
|
-
if (!isObject(value)) {
|
|
9215
|
-
continue;
|
|
9216
|
-
}
|
|
9217
|
-
const rawPrefix = oai_name.slice(0, -"_tokens_details".length);
|
|
9218
|
-
const prefix = TOKEN_PREFIX_MAP[rawPrefix] || rawPrefix;
|
|
9219
|
-
for (const [key, n] of Object.entries(value)) {
|
|
9220
|
-
if (typeof n !== "number") {
|
|
9221
|
-
continue;
|
|
9222
|
-
}
|
|
9223
|
-
const metricName = `${prefix}_${key}`;
|
|
9224
|
-
metrics[metricName] = n;
|
|
9225
|
-
}
|
|
9226
|
-
}
|
|
10122
|
+
const response = endEvent.response;
|
|
10123
|
+
if (!isObject(response)) {
|
|
10124
|
+
return void 0;
|
|
9227
10125
|
}
|
|
9228
|
-
|
|
10126
|
+
const headers = response.headers;
|
|
10127
|
+
if (!headers || typeof headers.get !== "function") {
|
|
10128
|
+
return void 0;
|
|
10129
|
+
}
|
|
10130
|
+
return getCachedMetricFromHeaders(headers);
|
|
10131
|
+
}
|
|
10132
|
+
function withCachedMetric(metrics, result, endEvent) {
|
|
10133
|
+
if (metrics.cached !== void 0) {
|
|
10134
|
+
return metrics;
|
|
10135
|
+
}
|
|
10136
|
+
const cachedFromEvent = getCachedMetricFromEndEvent(endEvent);
|
|
10137
|
+
if (cachedFromEvent !== void 0) {
|
|
10138
|
+
return {
|
|
10139
|
+
...metrics,
|
|
10140
|
+
cached: cachedFromEvent
|
|
10141
|
+
};
|
|
10142
|
+
}
|
|
10143
|
+
if (!isObject(result)) {
|
|
10144
|
+
return metrics;
|
|
10145
|
+
}
|
|
10146
|
+
const cached = result[BRAINTRUST_CACHED_STREAM_METRIC];
|
|
10147
|
+
if (typeof cached !== "number") {
|
|
10148
|
+
return metrics;
|
|
10149
|
+
}
|
|
10150
|
+
return {
|
|
10151
|
+
...metrics,
|
|
10152
|
+
cached
|
|
10153
|
+
};
|
|
9229
10154
|
}
|
|
9230
10155
|
function processImagesInOutput(output) {
|
|
9231
10156
|
if (Array.isArray(output)) {
|
|
@@ -9256,7 +10181,7 @@ function processImagesInOutput(output) {
|
|
|
9256
10181
|
}
|
|
9257
10182
|
return output;
|
|
9258
10183
|
}
|
|
9259
|
-
function aggregateChatCompletionChunks(chunks) {
|
|
10184
|
+
function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
9260
10185
|
let role = void 0;
|
|
9261
10186
|
let content = void 0;
|
|
9262
10187
|
let tool_calls = void 0;
|
|
@@ -9298,6 +10223,7 @@ function aggregateChatCompletionChunks(chunks) {
|
|
|
9298
10223
|
}
|
|
9299
10224
|
}
|
|
9300
10225
|
}
|
|
10226
|
+
metrics = withCachedMetric(metrics, streamResult, endEvent);
|
|
9301
10227
|
return {
|
|
9302
10228
|
metrics,
|
|
9303
10229
|
output: [
|
|
@@ -9314,9 +10240,33 @@ function aggregateChatCompletionChunks(chunks) {
|
|
|
9314
10240
|
]
|
|
9315
10241
|
};
|
|
9316
10242
|
}
|
|
9317
|
-
|
|
9318
|
-
|
|
9319
|
-
|
|
10243
|
+
function aggregateResponseStreamEvents(chunks, _streamResult, endEvent) {
|
|
10244
|
+
let output = void 0;
|
|
10245
|
+
let metrics = {};
|
|
10246
|
+
let metadata = void 0;
|
|
10247
|
+
for (const chunk of chunks) {
|
|
10248
|
+
if (!chunk || !chunk.type || !chunk.response) {
|
|
10249
|
+
continue;
|
|
10250
|
+
}
|
|
10251
|
+
if (chunk.type !== "response.completed") {
|
|
10252
|
+
continue;
|
|
10253
|
+
}
|
|
10254
|
+
const response = chunk.response;
|
|
10255
|
+
if (response?.output !== void 0) {
|
|
10256
|
+
output = processImagesInOutput(response.output);
|
|
10257
|
+
}
|
|
10258
|
+
const { usage: _usage, output: _output, ...rest } = response || {};
|
|
10259
|
+
if (Object.keys(rest).length > 0) {
|
|
10260
|
+
metadata = rest;
|
|
10261
|
+
}
|
|
10262
|
+
metrics = parseMetricsFromUsage(response?.usage);
|
|
10263
|
+
}
|
|
10264
|
+
return {
|
|
10265
|
+
output,
|
|
10266
|
+
metrics: withCachedMetric(metrics, void 0, endEvent),
|
|
10267
|
+
...metadata !== void 0 ? { metadata } : {}
|
|
10268
|
+
};
|
|
10269
|
+
}
|
|
9320
10270
|
|
|
9321
10271
|
// src/wrappers/anthropic-tokens-util.ts
|
|
9322
10272
|
function finalizeAnthropicTokens(metrics) {
|
|
@@ -9338,215 +10288,75 @@ function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens =
|
|
|
9338
10288
|
return cacheTokens;
|
|
9339
10289
|
}
|
|
9340
10290
|
|
|
10291
|
+
// src/instrumentation/plugins/anthropic-channels.ts
|
|
10292
|
+
var anthropicChannels = defineChannels("@anthropic-ai/sdk", {
|
|
10293
|
+
messagesCreate: channel({
|
|
10294
|
+
channelName: "messages.create",
|
|
10295
|
+
kind: "async"
|
|
10296
|
+
}),
|
|
10297
|
+
betaMessagesCreate: channel({
|
|
10298
|
+
channelName: "beta.messages.create",
|
|
10299
|
+
kind: "async"
|
|
10300
|
+
})
|
|
10301
|
+
});
|
|
10302
|
+
|
|
9341
10303
|
// src/instrumentation/plugins/anthropic-plugin.ts
|
|
9342
10304
|
var AnthropicPlugin = class extends BasePlugin {
|
|
9343
|
-
unsubscribers = [];
|
|
9344
10305
|
onEnable() {
|
|
9345
10306
|
this.subscribeToAnthropicChannels();
|
|
9346
10307
|
}
|
|
9347
10308
|
onDisable() {
|
|
9348
|
-
|
|
9349
|
-
unsubscribe();
|
|
9350
|
-
}
|
|
9351
|
-
this.unsubscribers = [];
|
|
10309
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
9352
10310
|
}
|
|
9353
10311
|
subscribeToAnthropicChannels() {
|
|
9354
|
-
|
|
10312
|
+
const anthropicConfig = {
|
|
9355
10313
|
name: "anthropic.messages.create",
|
|
9356
10314
|
type: "llm" /* LLM */,
|
|
9357
10315
|
extractInput: (args) => {
|
|
9358
|
-
const params = args[0] || {};
|
|
9359
|
-
const input = coalesceInput(params.messages || [], params.system);
|
|
9360
|
-
const metadata = filterFrom(params, ["messages", "system"]);
|
|
9361
|
-
return {
|
|
9362
|
-
input: processAttachmentsInInput(input),
|
|
9363
|
-
metadata: { ...metadata, provider: "anthropic" }
|
|
9364
|
-
};
|
|
9365
|
-
},
|
|
9366
|
-
extractOutput: (result) => {
|
|
9367
|
-
return result ? { role: result.role, content: result.content } : null;
|
|
9368
|
-
},
|
|
9369
|
-
extractMetrics: (result, startTime) => {
|
|
9370
|
-
const metrics = parseMetricsFromUsage2(result?.usage);
|
|
9371
|
-
if (startTime) {
|
|
9372
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9373
|
-
}
|
|
9374
|
-
const finalized = finalizeAnthropicTokens(metrics);
|
|
9375
|
-
return Object.fromEntries(
|
|
9376
|
-
Object.entries(finalized).filter(([, v]) => v !== void 0)
|
|
9377
|
-
);
|
|
9378
|
-
},
|
|
9379
|
-
extractMetadata: (result) => {
|
|
9380
|
-
const metadata = {};
|
|
9381
|
-
const metas = ["stop_reason", "stop_sequence"];
|
|
9382
|
-
for (const m of metas) {
|
|
9383
|
-
if (result?.[m] !== void 0) {
|
|
9384
|
-
metadata[m] = result[m];
|
|
9385
|
-
}
|
|
9386
|
-
}
|
|
9387
|
-
return metadata;
|
|
9388
|
-
},
|
|
9389
|
-
aggregateChunks: aggregateAnthropicStreamChunks,
|
|
9390
|
-
isStreaming: (args) => {
|
|
9391
|
-
return args[0]?.stream === true;
|
|
9392
|
-
}
|
|
9393
|
-
});
|
|
9394
|
-
this.subscribeToStreamingChannel(
|
|
9395
|
-
"orchestrion:anthropic:beta.messages.create",
|
|
9396
|
-
{
|
|
9397
|
-
name: "anthropic.beta.messages.create",
|
|
9398
|
-
type: "llm" /* LLM */,
|
|
9399
|
-
extractInput: (args) => {
|
|
9400
|
-
const params = args[0] || {};
|
|
9401
|
-
const input = coalesceInput(params.messages || [], params.system);
|
|
9402
|
-
const metadata = filterFrom(params, ["messages", "system"]);
|
|
9403
|
-
return {
|
|
9404
|
-
input: processAttachmentsInInput(input),
|
|
9405
|
-
metadata: { ...metadata, provider: "anthropic" }
|
|
9406
|
-
};
|
|
9407
|
-
},
|
|
9408
|
-
extractOutput: (result) => {
|
|
9409
|
-
return result ? { role: result.role, content: result.content } : null;
|
|
9410
|
-
},
|
|
9411
|
-
extractMetrics: (result, startTime) => {
|
|
9412
|
-
const metrics = parseMetricsFromUsage2(result?.usage);
|
|
9413
|
-
if (startTime) {
|
|
9414
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9415
|
-
}
|
|
9416
|
-
const finalized = finalizeAnthropicTokens(metrics);
|
|
9417
|
-
return Object.fromEntries(
|
|
9418
|
-
Object.entries(finalized).filter(([, v]) => v !== void 0)
|
|
9419
|
-
);
|
|
9420
|
-
},
|
|
9421
|
-
extractMetadata: (result) => {
|
|
9422
|
-
const metadata = {};
|
|
9423
|
-
const metas = ["stop_reason", "stop_sequence"];
|
|
9424
|
-
for (const m of metas) {
|
|
9425
|
-
if (result?.[m] !== void 0) {
|
|
9426
|
-
metadata[m] = result[m];
|
|
9427
|
-
}
|
|
9428
|
-
}
|
|
9429
|
-
return metadata;
|
|
9430
|
-
},
|
|
9431
|
-
aggregateChunks: aggregateAnthropicStreamChunks,
|
|
9432
|
-
isStreaming: (args) => {
|
|
9433
|
-
return args[0]?.stream === true;
|
|
9434
|
-
}
|
|
9435
|
-
}
|
|
9436
|
-
);
|
|
9437
|
-
}
|
|
9438
|
-
/**
|
|
9439
|
-
* Subscribe to a channel for async methods that may return streams.
|
|
9440
|
-
* Handles both streaming and non-streaming responses based on the stream parameter.
|
|
9441
|
-
*/
|
|
9442
|
-
subscribeToStreamingChannel(channelName, config) {
|
|
9443
|
-
const channel = tracingChannel2(channelName);
|
|
9444
|
-
const spans = /* @__PURE__ */ new WeakMap();
|
|
9445
|
-
const handlers = {
|
|
9446
|
-
start: (event) => {
|
|
9447
|
-
const span = startSpan({
|
|
9448
|
-
name: config.name,
|
|
9449
|
-
spanAttributes: {
|
|
9450
|
-
type: config.type
|
|
9451
|
-
}
|
|
9452
|
-
});
|
|
9453
|
-
const startTime = getCurrentUnixTimestamp();
|
|
9454
|
-
spans.set(event, { span, startTime });
|
|
9455
|
-
try {
|
|
9456
|
-
const { input, metadata } = config.extractInput(event.arguments);
|
|
9457
|
-
span.log({
|
|
9458
|
-
input,
|
|
9459
|
-
metadata
|
|
9460
|
-
});
|
|
9461
|
-
} catch (error) {
|
|
9462
|
-
console.error(`Error extracting input for ${channelName}:`, error);
|
|
9463
|
-
}
|
|
10316
|
+
const params = args[0] || {};
|
|
10317
|
+
const input = coalesceInput(params.messages || [], params.system);
|
|
10318
|
+
const metadata = filterFrom(params, ["messages", "system"]);
|
|
10319
|
+
return {
|
|
10320
|
+
input: processAttachmentsInInput(input),
|
|
10321
|
+
metadata: { ...metadata, provider: "anthropic" }
|
|
10322
|
+
};
|
|
9464
10323
|
},
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
10324
|
+
extractOutput: (message) => {
|
|
10325
|
+
return message ? { role: message.role, content: message.content } : null;
|
|
10326
|
+
},
|
|
10327
|
+
extractMetrics: (message, startTime) => {
|
|
10328
|
+
const metrics = parseMetricsFromUsage2(message?.usage);
|
|
10329
|
+
if (startTime) {
|
|
10330
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9469
10331
|
}
|
|
9470
|
-
const
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
|
|
9481
|
-
|
|
9482
|
-
|
|
9483
|
-
metadata = aggregated.metadata || {};
|
|
9484
|
-
} else {
|
|
9485
|
-
output = config.extractOutput(chunks);
|
|
9486
|
-
metrics = config.extractMetrics(chunks, startTime);
|
|
9487
|
-
if (config.extractMetadata) {
|
|
9488
|
-
metadata = config.extractMetadata(chunks);
|
|
9489
|
-
}
|
|
9490
|
-
}
|
|
9491
|
-
if (!metrics.time_to_first_token && chunks.length > 0) {
|
|
9492
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9493
|
-
}
|
|
9494
|
-
span.log({
|
|
9495
|
-
output,
|
|
9496
|
-
metrics,
|
|
9497
|
-
metadata
|
|
9498
|
-
});
|
|
9499
|
-
} catch (error) {
|
|
9500
|
-
console.error(
|
|
9501
|
-
`Error extracting output for ${channelName}:`,
|
|
9502
|
-
error
|
|
9503
|
-
);
|
|
9504
|
-
} finally {
|
|
9505
|
-
span.end();
|
|
9506
|
-
}
|
|
9507
|
-
},
|
|
9508
|
-
onError: (error) => {
|
|
9509
|
-
span.log({
|
|
9510
|
-
error: error.message
|
|
9511
|
-
});
|
|
9512
|
-
span.end();
|
|
9513
|
-
}
|
|
9514
|
-
});
|
|
9515
|
-
} else {
|
|
9516
|
-
try {
|
|
9517
|
-
const output = config.extractOutput(event.result);
|
|
9518
|
-
const metrics = config.extractMetrics(event.result, startTime);
|
|
9519
|
-
const metadata = config.extractMetadata ? config.extractMetadata(event.result) : {};
|
|
9520
|
-
span.log({
|
|
9521
|
-
output,
|
|
9522
|
-
metrics,
|
|
9523
|
-
metadata
|
|
9524
|
-
});
|
|
9525
|
-
} catch (error) {
|
|
9526
|
-
console.error(`Error extracting output for ${channelName}:`, error);
|
|
9527
|
-
} finally {
|
|
9528
|
-
span.end();
|
|
9529
|
-
spans.delete(event);
|
|
10332
|
+
const finalized = finalizeAnthropicTokens(metrics);
|
|
10333
|
+
return Object.fromEntries(
|
|
10334
|
+
Object.entries(finalized).filter(
|
|
10335
|
+
(entry) => entry[1] !== void 0
|
|
10336
|
+
)
|
|
10337
|
+
);
|
|
10338
|
+
},
|
|
10339
|
+
extractMetadata: (message) => {
|
|
10340
|
+
const metadata = {};
|
|
10341
|
+
const metas = ["stop_reason", "stop_sequence"];
|
|
10342
|
+
for (const m of metas) {
|
|
10343
|
+
if (message?.[m] !== void 0) {
|
|
10344
|
+
metadata[m] = message[m];
|
|
9530
10345
|
}
|
|
9531
10346
|
}
|
|
10347
|
+
return metadata;
|
|
9532
10348
|
},
|
|
9533
|
-
|
|
9534
|
-
const spanData = spans.get(event);
|
|
9535
|
-
if (!spanData) {
|
|
9536
|
-
return;
|
|
9537
|
-
}
|
|
9538
|
-
const { span } = spanData;
|
|
9539
|
-
span.log({
|
|
9540
|
-
error: event.error.message
|
|
9541
|
-
});
|
|
9542
|
-
span.end();
|
|
9543
|
-
spans.delete(event);
|
|
9544
|
-
}
|
|
10349
|
+
aggregateChunks: (chunks) => aggregateAnthropicStreamChunks(chunks)
|
|
9545
10350
|
};
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
10351
|
+
this.unsubscribers.push(
|
|
10352
|
+
traceStreamingChannel(anthropicChannels.messagesCreate, anthropicConfig)
|
|
10353
|
+
);
|
|
10354
|
+
this.unsubscribers.push(
|
|
10355
|
+
traceStreamingChannel(anthropicChannels.betaMessagesCreate, {
|
|
10356
|
+
...anthropicConfig,
|
|
10357
|
+
name: "anthropic.beta.messages.create"
|
|
10358
|
+
})
|
|
10359
|
+
);
|
|
9550
10360
|
}
|
|
9551
10361
|
};
|
|
9552
10362
|
function parseMetricsFromUsage2(usage) {
|
|
@@ -9570,29 +10380,29 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
9570
10380
|
const deltas = [];
|
|
9571
10381
|
let metrics = {};
|
|
9572
10382
|
let metadata = {};
|
|
9573
|
-
for (const
|
|
9574
|
-
switch (
|
|
10383
|
+
for (const event of chunks) {
|
|
10384
|
+
switch (event?.type) {
|
|
9575
10385
|
case "message_start":
|
|
9576
|
-
if (
|
|
9577
|
-
const initialMetrics = parseMetricsFromUsage2(
|
|
10386
|
+
if (event.message?.usage) {
|
|
10387
|
+
const initialMetrics = parseMetricsFromUsage2(event.message.usage);
|
|
9578
10388
|
metrics = { ...metrics, ...initialMetrics };
|
|
9579
10389
|
}
|
|
9580
10390
|
break;
|
|
9581
10391
|
case "content_block_delta":
|
|
9582
|
-
if (
|
|
9583
|
-
const text =
|
|
10392
|
+
if (event.delta?.type === "text_delta") {
|
|
10393
|
+
const text = event.delta.text;
|
|
9584
10394
|
if (text) {
|
|
9585
10395
|
deltas.push(text);
|
|
9586
10396
|
}
|
|
9587
10397
|
}
|
|
9588
10398
|
break;
|
|
9589
10399
|
case "message_delta":
|
|
9590
|
-
if (
|
|
9591
|
-
const finalMetrics = parseMetricsFromUsage2(
|
|
10400
|
+
if (event.usage) {
|
|
10401
|
+
const finalMetrics = parseMetricsFromUsage2(event.usage);
|
|
9592
10402
|
metrics = { ...metrics, ...finalMetrics };
|
|
9593
10403
|
}
|
|
9594
|
-
if (
|
|
9595
|
-
metadata = { ...metadata, ...
|
|
10404
|
+
if (event.delta) {
|
|
10405
|
+
metadata = { ...metadata, ...event.delta };
|
|
9596
10406
|
}
|
|
9597
10407
|
break;
|
|
9598
10408
|
}
|
|
@@ -9600,7 +10410,9 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
9600
10410
|
const output = deltas.join("");
|
|
9601
10411
|
const finalized = finalizeAnthropicTokens(metrics);
|
|
9602
10412
|
const filteredMetrics = Object.fromEntries(
|
|
9603
|
-
Object.entries(finalized).filter(
|
|
10413
|
+
Object.entries(finalized).filter(
|
|
10414
|
+
(entry) => entry[1] !== void 0
|
|
10415
|
+
)
|
|
9604
10416
|
);
|
|
9605
10417
|
return {
|
|
9606
10418
|
output,
|
|
@@ -9608,6 +10420,9 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
9608
10420
|
metadata
|
|
9609
10421
|
};
|
|
9610
10422
|
}
|
|
10423
|
+
function isAnthropicBase64ContentBlock(input) {
|
|
10424
|
+
return (input.type === "image" || input.type === "document") && isObject(input.source) && input.source.type === "base64";
|
|
10425
|
+
}
|
|
9611
10426
|
function convertBase64ToAttachment(source, contentType) {
|
|
9612
10427
|
const mediaType = typeof source.media_type === "string" ? source.media_type : "image/png";
|
|
9613
10428
|
const base64Data = source.data;
|
|
@@ -9631,14 +10446,14 @@ function convertBase64ToAttachment(source, contentType) {
|
|
|
9631
10446
|
data: attachment
|
|
9632
10447
|
};
|
|
9633
10448
|
}
|
|
9634
|
-
return source;
|
|
10449
|
+
return { ...source };
|
|
9635
10450
|
}
|
|
9636
10451
|
function processAttachmentsInInput(input) {
|
|
9637
10452
|
if (Array.isArray(input)) {
|
|
9638
10453
|
return input.map(processAttachmentsInInput);
|
|
9639
10454
|
}
|
|
9640
10455
|
if (isObject(input)) {
|
|
9641
|
-
if ((input
|
|
10456
|
+
if (isAnthropicBase64ContentBlock(input)) {
|
|
9642
10457
|
return {
|
|
9643
10458
|
...input,
|
|
9644
10459
|
source: convertBase64ToAttachment(input.source, input.type)
|
|
@@ -9669,8 +10484,153 @@ function filterFrom(obj, fieldsToRemove) {
|
|
|
9669
10484
|
return result;
|
|
9670
10485
|
}
|
|
9671
10486
|
|
|
10487
|
+
// src/wrappers/ai-sdk/normalize-logged-output.ts
|
|
10488
|
+
var REMOVE_NORMALIZED_VALUE = Symbol("braintrust.ai-sdk.remove-normalized");
|
|
10489
|
+
function normalizeAISDKLoggedOutput(value) {
|
|
10490
|
+
const normalized = normalizeAISDKLoggedValue(value);
|
|
10491
|
+
return normalized === REMOVE_NORMALIZED_VALUE ? {} : normalized;
|
|
10492
|
+
}
|
|
10493
|
+
function normalizeAISDKLoggedValue(value, context = {}) {
|
|
10494
|
+
if (Array.isArray(value)) {
|
|
10495
|
+
return value.map((entry) => normalizeAISDKLoggedValue(entry, context)).filter((entry) => entry !== REMOVE_NORMALIZED_VALUE);
|
|
10496
|
+
}
|
|
10497
|
+
if (!value || typeof value !== "object") {
|
|
10498
|
+
return value;
|
|
10499
|
+
}
|
|
10500
|
+
const nextInProviderMetadata = context.inProviderMetadata || context.parentKey === "providerMetadata" || context.parentKey === "experimental_providerMetadata";
|
|
10501
|
+
const normalizedEntries = [];
|
|
10502
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
10503
|
+
if (key === "cachedPromptTokens" && entry === 0) {
|
|
10504
|
+
continue;
|
|
10505
|
+
}
|
|
10506
|
+
if (context.parentKey === "request" && key === "body" && entry === "<omitted>") {
|
|
10507
|
+
continue;
|
|
10508
|
+
}
|
|
10509
|
+
const normalizedEntry = normalizeAISDKLoggedValue(entry, {
|
|
10510
|
+
inProviderMetadata: nextInProviderMetadata,
|
|
10511
|
+
parentKey: key
|
|
10512
|
+
});
|
|
10513
|
+
if (normalizedEntry === REMOVE_NORMALIZED_VALUE) {
|
|
10514
|
+
continue;
|
|
10515
|
+
}
|
|
10516
|
+
normalizedEntries.push([key, normalizedEntry]);
|
|
10517
|
+
}
|
|
10518
|
+
if (normalizedEntries.length === 0) {
|
|
10519
|
+
if (context.parentKey === "request" || nextInProviderMetadata) {
|
|
10520
|
+
return REMOVE_NORMALIZED_VALUE;
|
|
10521
|
+
}
|
|
10522
|
+
return {};
|
|
10523
|
+
}
|
|
10524
|
+
return Object.fromEntries(normalizedEntries);
|
|
10525
|
+
}
|
|
10526
|
+
|
|
10527
|
+
// src/zod/utils.ts
|
|
10528
|
+
import { zodToJsonSchema as zodToJsonSchemaV3 } from "zod-to-json-schema";
|
|
10529
|
+
import * as z42 from "zod/v4";
|
|
10530
|
+
function isZodV4(zodObject) {
|
|
10531
|
+
return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
|
|
10532
|
+
}
|
|
10533
|
+
function zodToJsonSchema(schema) {
|
|
10534
|
+
if (isZodV4(schema)) {
|
|
10535
|
+
return z42.toJSONSchema(schema, {
|
|
10536
|
+
target: "draft-7"
|
|
10537
|
+
});
|
|
10538
|
+
}
|
|
10539
|
+
return zodToJsonSchemaV3(schema);
|
|
10540
|
+
}
|
|
10541
|
+
|
|
10542
|
+
// src/wrappers/ai-sdk/tool-serialization.ts
|
|
10543
|
+
function isZodSchema(value) {
|
|
10544
|
+
return value != null && typeof value === "object" && "_def" in value && typeof value._def === "object";
|
|
10545
|
+
}
|
|
10546
|
+
function serializeZodSchema(schema) {
|
|
10547
|
+
try {
|
|
10548
|
+
return zodToJsonSchema(schema);
|
|
10549
|
+
} catch {
|
|
10550
|
+
return {
|
|
10551
|
+
type: "object",
|
|
10552
|
+
description: "Zod schema (conversion failed)"
|
|
10553
|
+
};
|
|
10554
|
+
}
|
|
10555
|
+
}
|
|
10556
|
+
function serializeTool(tool) {
|
|
10557
|
+
if (!tool || typeof tool !== "object") {
|
|
10558
|
+
return tool;
|
|
10559
|
+
}
|
|
10560
|
+
const serialized = { ...tool };
|
|
10561
|
+
if (isZodSchema(serialized.inputSchema)) {
|
|
10562
|
+
serialized.inputSchema = serializeZodSchema(serialized.inputSchema);
|
|
10563
|
+
}
|
|
10564
|
+
if (isZodSchema(serialized.parameters)) {
|
|
10565
|
+
serialized.parameters = serializeZodSchema(serialized.parameters);
|
|
10566
|
+
}
|
|
10567
|
+
if ("execute" in serialized) {
|
|
10568
|
+
delete serialized.execute;
|
|
10569
|
+
}
|
|
10570
|
+
if ("render" in serialized) {
|
|
10571
|
+
delete serialized.render;
|
|
10572
|
+
}
|
|
10573
|
+
return serialized;
|
|
10574
|
+
}
|
|
10575
|
+
function serializeAISDKToolsForLogging(tools) {
|
|
10576
|
+
if (!tools || typeof tools !== "object") {
|
|
10577
|
+
return tools;
|
|
10578
|
+
}
|
|
10579
|
+
if (Array.isArray(tools)) {
|
|
10580
|
+
return tools.map(serializeTool);
|
|
10581
|
+
}
|
|
10582
|
+
const serialized = {};
|
|
10583
|
+
for (const [key, tool] of Object.entries(tools)) {
|
|
10584
|
+
serialized[key] = serializeTool(tool);
|
|
10585
|
+
}
|
|
10586
|
+
return serialized;
|
|
10587
|
+
}
|
|
10588
|
+
|
|
10589
|
+
// src/instrumentation/plugins/ai-sdk-channels.ts
|
|
10590
|
+
var aiSDKChannels = defineChannels("ai", {
|
|
10591
|
+
generateText: channel({
|
|
10592
|
+
channelName: "generateText",
|
|
10593
|
+
kind: "async"
|
|
10594
|
+
}),
|
|
10595
|
+
streamText: channel({
|
|
10596
|
+
channelName: "streamText",
|
|
10597
|
+
kind: "async"
|
|
10598
|
+
}),
|
|
10599
|
+
streamTextSync: channel({
|
|
10600
|
+
channelName: "streamText.sync",
|
|
10601
|
+
kind: "sync-stream"
|
|
10602
|
+
}),
|
|
10603
|
+
generateObject: channel({
|
|
10604
|
+
channelName: "generateObject",
|
|
10605
|
+
kind: "async"
|
|
10606
|
+
}),
|
|
10607
|
+
streamObject: channel({
|
|
10608
|
+
channelName: "streamObject",
|
|
10609
|
+
kind: "async"
|
|
10610
|
+
}),
|
|
10611
|
+
streamObjectSync: channel({
|
|
10612
|
+
channelName: "streamObject.sync",
|
|
10613
|
+
kind: "sync-stream"
|
|
10614
|
+
}),
|
|
10615
|
+
agentGenerate: channel({
|
|
10616
|
+
channelName: "Agent.generate",
|
|
10617
|
+
kind: "async"
|
|
10618
|
+
}),
|
|
10619
|
+
agentStream: channel({
|
|
10620
|
+
channelName: "Agent.stream",
|
|
10621
|
+
kind: "async"
|
|
10622
|
+
}),
|
|
10623
|
+
toolLoopAgentGenerate: channel({
|
|
10624
|
+
channelName: "ToolLoopAgent.generate",
|
|
10625
|
+
kind: "async"
|
|
10626
|
+
}),
|
|
10627
|
+
toolLoopAgentStream: channel({
|
|
10628
|
+
channelName: "ToolLoopAgent.stream",
|
|
10629
|
+
kind: "async"
|
|
10630
|
+
})
|
|
10631
|
+
});
|
|
10632
|
+
|
|
9672
10633
|
// src/instrumentation/plugins/ai-sdk-plugin.ts
|
|
9673
|
-
import { tracingChannel as tracingChannel3 } from "dc-browser";
|
|
9674
10634
|
var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
9675
10635
|
// v3
|
|
9676
10636
|
"roundtrips[].request.body",
|
|
@@ -9685,8 +10645,9 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
|
9685
10645
|
"steps[].response.body",
|
|
9686
10646
|
"steps[].response.headers"
|
|
9687
10647
|
];
|
|
10648
|
+
var AUTO_PATCHED_MODEL = Symbol.for("braintrust.ai-sdk.auto-patched-model");
|
|
10649
|
+
var AUTO_PATCHED_TOOL = Symbol.for("braintrust.ai-sdk.auto-patched-tool");
|
|
9688
10650
|
var AISDKPlugin = class extends BasePlugin {
|
|
9689
|
-
unsubscribers = [];
|
|
9690
10651
|
config;
|
|
9691
10652
|
constructor(config = {}) {
|
|
9692
10653
|
super();
|
|
@@ -9696,276 +10657,579 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9696
10657
|
this.subscribeToAISDK();
|
|
9697
10658
|
}
|
|
9698
10659
|
onDisable() {
|
|
9699
|
-
|
|
9700
|
-
unsubscribe();
|
|
9701
|
-
}
|
|
9702
|
-
this.unsubscribers = [];
|
|
10660
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
9703
10661
|
}
|
|
9704
10662
|
subscribeToAISDK() {
|
|
9705
10663
|
const denyOutputPaths = this.config.denyOutputPaths || DEFAULT_DENY_OUTPUT_PATHS;
|
|
9706
|
-
this.
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
}
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9730
|
-
|
|
9731
|
-
|
|
9732
|
-
|
|
9733
|
-
|
|
9734
|
-
|
|
9735
|
-
|
|
9736
|
-
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9740
|
-
|
|
9741
|
-
|
|
9742
|
-
|
|
9743
|
-
|
|
9744
|
-
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
|
|
9748
|
-
|
|
9749
|
-
|
|
9750
|
-
this.
|
|
9751
|
-
|
|
9752
|
-
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
9758
|
-
}
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
|
|
9767
|
-
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
this.
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
9802
|
-
}
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9810
|
-
|
|
9811
|
-
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
}
|
|
9836
|
-
|
|
9837
|
-
|
|
10664
|
+
this.unsubscribers.push(
|
|
10665
|
+
traceStreamingChannel(aiSDKChannels.generateText, {
|
|
10666
|
+
name: "generateText",
|
|
10667
|
+
type: "llm" /* LLM */,
|
|
10668
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
10669
|
+
extractOutput: (result, endEvent) => {
|
|
10670
|
+
finalizeAISDKChildTracing(endEvent);
|
|
10671
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
10672
|
+
},
|
|
10673
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
10674
|
+
aggregateChunks: aggregateAISDKChunks
|
|
10675
|
+
})
|
|
10676
|
+
);
|
|
10677
|
+
this.unsubscribers.push(
|
|
10678
|
+
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
10679
|
+
name: "streamText",
|
|
10680
|
+
type: "llm" /* LLM */,
|
|
10681
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
10682
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
10683
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
10684
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
10685
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
10686
|
+
denyOutputPaths,
|
|
10687
|
+
endEvent,
|
|
10688
|
+
result,
|
|
10689
|
+
span,
|
|
10690
|
+
startTime
|
|
10691
|
+
})
|
|
10692
|
+
})
|
|
10693
|
+
);
|
|
10694
|
+
this.unsubscribers.push(
|
|
10695
|
+
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
10696
|
+
name: "streamText",
|
|
10697
|
+
type: "llm" /* LLM */,
|
|
10698
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
10699
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
10700
|
+
denyOutputPaths,
|
|
10701
|
+
endEvent,
|
|
10702
|
+
result,
|
|
10703
|
+
span,
|
|
10704
|
+
startTime
|
|
10705
|
+
})
|
|
10706
|
+
})
|
|
10707
|
+
);
|
|
10708
|
+
this.unsubscribers.push(
|
|
10709
|
+
traceStreamingChannel(aiSDKChannels.generateObject, {
|
|
10710
|
+
name: "generateObject",
|
|
10711
|
+
type: "llm" /* LLM */,
|
|
10712
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
10713
|
+
extractOutput: (result, endEvent) => {
|
|
10714
|
+
finalizeAISDKChildTracing(endEvent);
|
|
10715
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
10716
|
+
},
|
|
10717
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
10718
|
+
aggregateChunks: aggregateAISDKChunks
|
|
10719
|
+
})
|
|
10720
|
+
);
|
|
10721
|
+
this.unsubscribers.push(
|
|
10722
|
+
traceStreamingChannel(aiSDKChannels.streamObject, {
|
|
10723
|
+
name: "streamObject",
|
|
10724
|
+
type: "llm" /* LLM */,
|
|
10725
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
10726
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
10727
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
10728
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
10729
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
10730
|
+
denyOutputPaths,
|
|
10731
|
+
endEvent,
|
|
10732
|
+
result,
|
|
10733
|
+
span,
|
|
10734
|
+
startTime
|
|
10735
|
+
})
|
|
10736
|
+
})
|
|
10737
|
+
);
|
|
10738
|
+
this.unsubscribers.push(
|
|
10739
|
+
traceSyncStreamChannel(aiSDKChannels.streamObjectSync, {
|
|
10740
|
+
name: "streamObject",
|
|
10741
|
+
type: "llm" /* LLM */,
|
|
10742
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
10743
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
10744
|
+
denyOutputPaths,
|
|
10745
|
+
endEvent,
|
|
10746
|
+
result,
|
|
10747
|
+
span,
|
|
10748
|
+
startTime
|
|
10749
|
+
})
|
|
10750
|
+
})
|
|
10751
|
+
);
|
|
10752
|
+
this.unsubscribers.push(
|
|
10753
|
+
traceStreamingChannel(aiSDKChannels.agentGenerate, {
|
|
10754
|
+
name: "Agent.generate",
|
|
10755
|
+
type: "llm" /* LLM */,
|
|
10756
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
10757
|
+
extractOutput: (result, endEvent) => {
|
|
10758
|
+
finalizeAISDKChildTracing(endEvent);
|
|
10759
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
10760
|
+
},
|
|
10761
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
10762
|
+
aggregateChunks: aggregateAISDKChunks
|
|
10763
|
+
})
|
|
10764
|
+
);
|
|
10765
|
+
this.unsubscribers.push(
|
|
10766
|
+
traceStreamingChannel(aiSDKChannels.agentStream, {
|
|
10767
|
+
name: "Agent.stream",
|
|
10768
|
+
type: "llm" /* LLM */,
|
|
10769
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
10770
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
10771
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
10772
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
10773
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
10774
|
+
denyOutputPaths,
|
|
10775
|
+
endEvent,
|
|
10776
|
+
result,
|
|
10777
|
+
span,
|
|
10778
|
+
startTime
|
|
10779
|
+
})
|
|
10780
|
+
})
|
|
10781
|
+
);
|
|
10782
|
+
this.unsubscribers.push(
|
|
10783
|
+
traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
|
|
10784
|
+
name: "ToolLoopAgent.generate",
|
|
10785
|
+
type: "llm" /* LLM */,
|
|
10786
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
10787
|
+
extractOutput: (result, endEvent) => {
|
|
10788
|
+
finalizeAISDKChildTracing(endEvent);
|
|
10789
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
10790
|
+
},
|
|
10791
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent),
|
|
10792
|
+
aggregateChunks: aggregateAISDKChunks
|
|
10793
|
+
})
|
|
10794
|
+
);
|
|
10795
|
+
this.unsubscribers.push(
|
|
10796
|
+
traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
|
|
10797
|
+
name: "ToolLoopAgent.stream",
|
|
10798
|
+
type: "llm" /* LLM */,
|
|
10799
|
+
extractInput: ([params], event, span) => prepareAISDKInput(params, event, span, denyOutputPaths),
|
|
10800
|
+
extractOutput: (result) => processAISDKOutput(result, denyOutputPaths),
|
|
10801
|
+
extractMetrics: (result, startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent, startTime),
|
|
10802
|
+
aggregateChunks: aggregateAISDKChunks,
|
|
10803
|
+
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
10804
|
+
denyOutputPaths,
|
|
10805
|
+
endEvent,
|
|
10806
|
+
result,
|
|
10807
|
+
span,
|
|
10808
|
+
startTime
|
|
10809
|
+
})
|
|
10810
|
+
})
|
|
10811
|
+
);
|
|
9838
10812
|
}
|
|
9839
|
-
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
|
|
9843
|
-
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
|
|
9856
|
-
|
|
9857
|
-
|
|
10813
|
+
};
|
|
10814
|
+
function processAISDKInput(params) {
|
|
10815
|
+
if (!params) return params;
|
|
10816
|
+
const input = processInputAttachments(params);
|
|
10817
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
10818
|
+
return input;
|
|
10819
|
+
}
|
|
10820
|
+
const { tools: _tools, ...rest } = input;
|
|
10821
|
+
return rest;
|
|
10822
|
+
}
|
|
10823
|
+
function prepareAISDKInput(params, event, span, denyOutputPaths) {
|
|
10824
|
+
const input = processAISDKInput(params);
|
|
10825
|
+
const metadata = extractMetadataFromParams(params, event.self);
|
|
10826
|
+
const childTracing = prepareAISDKChildTracing(
|
|
10827
|
+
params,
|
|
10828
|
+
event.self,
|
|
10829
|
+
span,
|
|
10830
|
+
denyOutputPaths
|
|
10831
|
+
);
|
|
10832
|
+
event.__braintrust_ai_sdk_model_wrapped = childTracing.modelWrapped;
|
|
10833
|
+
if (childTracing.cleanup) {
|
|
10834
|
+
event.__braintrust_ai_sdk_cleanup = childTracing.cleanup;
|
|
10835
|
+
}
|
|
10836
|
+
return {
|
|
10837
|
+
input,
|
|
10838
|
+
metadata
|
|
10839
|
+
};
|
|
10840
|
+
}
|
|
10841
|
+
function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
10842
|
+
const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics(result);
|
|
10843
|
+
if (startTime) {
|
|
10844
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
10845
|
+
}
|
|
10846
|
+
return metrics;
|
|
10847
|
+
}
|
|
10848
|
+
function hasModelChildTracing(event) {
|
|
10849
|
+
return event?.__braintrust_ai_sdk_model_wrapped === true;
|
|
10850
|
+
}
|
|
10851
|
+
function extractMetadataFromParams(params, self) {
|
|
10852
|
+
const metadata = {
|
|
10853
|
+
braintrust: {
|
|
10854
|
+
integration_name: "ai-sdk",
|
|
10855
|
+
sdk_language: "typescript"
|
|
10856
|
+
}
|
|
10857
|
+
};
|
|
10858
|
+
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;
|
|
10859
|
+
const { model, provider } = serializeModelWithProvider(
|
|
10860
|
+
params.model ?? agentModel
|
|
10861
|
+
);
|
|
10862
|
+
if (model) {
|
|
10863
|
+
metadata.model = model;
|
|
10864
|
+
}
|
|
10865
|
+
if (provider) {
|
|
10866
|
+
metadata.provider = provider;
|
|
10867
|
+
}
|
|
10868
|
+
const tools = serializeAISDKToolsForLogging(params.tools);
|
|
10869
|
+
if (tools) {
|
|
10870
|
+
metadata.tools = tools;
|
|
10871
|
+
}
|
|
10872
|
+
return metadata;
|
|
10873
|
+
}
|
|
10874
|
+
function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths) {
|
|
10875
|
+
const cleanup = [];
|
|
10876
|
+
const patchedModels = /* @__PURE__ */ new WeakSet();
|
|
10877
|
+
const patchedTools = /* @__PURE__ */ new WeakSet();
|
|
10878
|
+
let modelWrapped = false;
|
|
10879
|
+
const patchModel = (model) => {
|
|
10880
|
+
const resolvedModel = resolveAISDKModel(model);
|
|
10881
|
+
if (!resolvedModel || typeof resolvedModel !== "object" || typeof resolvedModel.doGenerate !== "function" || patchedModels.has(resolvedModel) || resolvedModel[AUTO_PATCHED_MODEL]) {
|
|
10882
|
+
return;
|
|
10883
|
+
}
|
|
10884
|
+
patchedModels.add(resolvedModel);
|
|
10885
|
+
resolvedModel[AUTO_PATCHED_MODEL] = true;
|
|
10886
|
+
modelWrapped = true;
|
|
10887
|
+
const originalDoGenerate = resolvedModel.doGenerate;
|
|
10888
|
+
const originalDoStream = resolvedModel.doStream;
|
|
10889
|
+
const baseMetadata = buildAISDKChildMetadata(resolvedModel);
|
|
10890
|
+
resolvedModel.doGenerate = async function doGeneratePatched(options) {
|
|
10891
|
+
return parentSpan.traced(
|
|
10892
|
+
async (span) => {
|
|
10893
|
+
const result = await Reflect.apply(
|
|
10894
|
+
originalDoGenerate,
|
|
10895
|
+
resolvedModel,
|
|
10896
|
+
[options]
|
|
10897
|
+
);
|
|
9858
10898
|
span.log({
|
|
9859
|
-
|
|
9860
|
-
|
|
10899
|
+
output: processAISDKOutput(result, denyOutputPaths),
|
|
10900
|
+
metrics: extractTokenMetrics(result),
|
|
10901
|
+
...buildResolvedMetadataPayload(result)
|
|
9861
10902
|
});
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
|
|
10903
|
+
return result;
|
|
10904
|
+
},
|
|
10905
|
+
{
|
|
10906
|
+
name: "doGenerate",
|
|
10907
|
+
spanAttributes: {
|
|
10908
|
+
type: "llm" /* LLM */
|
|
10909
|
+
},
|
|
10910
|
+
event: {
|
|
10911
|
+
input: processAISDKInput(options),
|
|
10912
|
+
metadata: baseMetadata
|
|
10913
|
+
}
|
|
9870
10914
|
}
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
|
|
10915
|
+
);
|
|
10916
|
+
};
|
|
10917
|
+
if (originalDoStream) {
|
|
10918
|
+
resolvedModel.doStream = async function doStreamPatched(options) {
|
|
10919
|
+
const span = parentSpan.startSpan({
|
|
10920
|
+
name: "doStream",
|
|
10921
|
+
spanAttributes: {
|
|
10922
|
+
type: "llm" /* LLM */
|
|
10923
|
+
},
|
|
10924
|
+
event: {
|
|
10925
|
+
input: processAISDKInput(options),
|
|
10926
|
+
metadata: baseMetadata
|
|
10927
|
+
}
|
|
10928
|
+
});
|
|
10929
|
+
const result = await withCurrent(
|
|
10930
|
+
span,
|
|
10931
|
+
() => Reflect.apply(originalDoStream, resolvedModel, [options])
|
|
10932
|
+
);
|
|
10933
|
+
const output = {};
|
|
10934
|
+
let text = "";
|
|
10935
|
+
let reasoning = "";
|
|
10936
|
+
const toolCalls = [];
|
|
10937
|
+
let object = void 0;
|
|
10938
|
+
const transformStream = new TransformStream({
|
|
10939
|
+
transform(chunk, controller) {
|
|
10940
|
+
switch (chunk.type) {
|
|
10941
|
+
case "text-delta":
|
|
10942
|
+
text += extractTextDelta(chunk);
|
|
10943
|
+
break;
|
|
10944
|
+
case "reasoning-delta":
|
|
10945
|
+
if (chunk.delta) {
|
|
10946
|
+
reasoning += chunk.delta;
|
|
10947
|
+
} else if (chunk.text) {
|
|
10948
|
+
reasoning += chunk.text;
|
|
9885
10949
|
}
|
|
9886
|
-
|
|
9887
|
-
|
|
10950
|
+
break;
|
|
10951
|
+
case "tool-call":
|
|
10952
|
+
toolCalls.push(chunk);
|
|
10953
|
+
break;
|
|
10954
|
+
case "object":
|
|
10955
|
+
object = chunk.object;
|
|
10956
|
+
break;
|
|
10957
|
+
case "raw":
|
|
10958
|
+
if (chunk.rawValue) {
|
|
10959
|
+
const rawVal = chunk.rawValue;
|
|
10960
|
+
if (rawVal.delta?.content) {
|
|
10961
|
+
text += rawVal.delta.content;
|
|
10962
|
+
} else if (rawVal.choices?.[0]?.delta?.content) {
|
|
10963
|
+
text += rawVal.choices[0].delta.content;
|
|
10964
|
+
} else if (typeof rawVal.text === "string") {
|
|
10965
|
+
text += rawVal.text;
|
|
10966
|
+
} else if (typeof rawVal.content === "string") {
|
|
10967
|
+
text += rawVal.content;
|
|
10968
|
+
}
|
|
10969
|
+
}
|
|
10970
|
+
break;
|
|
10971
|
+
case "finish":
|
|
10972
|
+
output.text = text;
|
|
10973
|
+
output.reasoning = reasoning;
|
|
10974
|
+
output.toolCalls = toolCalls;
|
|
10975
|
+
output.finishReason = chunk.finishReason;
|
|
10976
|
+
output.usage = chunk.usage;
|
|
10977
|
+
if (object !== void 0) {
|
|
10978
|
+
output.object = object;
|
|
9888
10979
|
}
|
|
9889
10980
|
span.log({
|
|
9890
|
-
output
|
|
9891
|
-
|
|
10981
|
+
output: processAISDKOutput(
|
|
10982
|
+
output,
|
|
10983
|
+
denyOutputPaths
|
|
10984
|
+
),
|
|
10985
|
+
metrics: extractTokenMetrics(output),
|
|
10986
|
+
...buildResolvedMetadataPayload(output)
|
|
9892
10987
|
});
|
|
9893
|
-
} catch (error) {
|
|
9894
|
-
console.error(
|
|
9895
|
-
`Error extracting output for ${channelName}:`,
|
|
9896
|
-
error
|
|
9897
|
-
);
|
|
9898
|
-
} finally {
|
|
9899
10988
|
span.end();
|
|
9900
|
-
|
|
9901
|
-
}
|
|
9902
|
-
|
|
9903
|
-
|
|
9904
|
-
|
|
9905
|
-
|
|
9906
|
-
|
|
10989
|
+
break;
|
|
10990
|
+
}
|
|
10991
|
+
controller.enqueue(chunk);
|
|
10992
|
+
}
|
|
10993
|
+
});
|
|
10994
|
+
return {
|
|
10995
|
+
...result,
|
|
10996
|
+
stream: result.stream.pipeThrough(transformStream)
|
|
10997
|
+
};
|
|
10998
|
+
};
|
|
10999
|
+
}
|
|
11000
|
+
cleanup.push(() => {
|
|
11001
|
+
resolvedModel.doGenerate = originalDoGenerate;
|
|
11002
|
+
if (originalDoStream) {
|
|
11003
|
+
resolvedModel.doStream = originalDoStream;
|
|
11004
|
+
}
|
|
11005
|
+
delete resolvedModel[AUTO_PATCHED_MODEL];
|
|
11006
|
+
});
|
|
11007
|
+
};
|
|
11008
|
+
const patchTool = (tool, name) => {
|
|
11009
|
+
if (tool == null || typeof tool !== "object" || !("execute" in tool) || typeof tool.execute !== "function" || patchedTools.has(tool) || tool[AUTO_PATCHED_TOOL]) {
|
|
11010
|
+
return;
|
|
11011
|
+
}
|
|
11012
|
+
patchedTools.add(tool);
|
|
11013
|
+
tool[AUTO_PATCHED_TOOL] = true;
|
|
11014
|
+
const originalExecute = tool.execute;
|
|
11015
|
+
tool.execute = function executePatched(...args) {
|
|
11016
|
+
const result = Reflect.apply(originalExecute, this, args);
|
|
11017
|
+
if (isAsyncGenerator(result)) {
|
|
11018
|
+
return (async function* () {
|
|
11019
|
+
const span = parentSpan.startSpan({
|
|
11020
|
+
name,
|
|
11021
|
+
spanAttributes: {
|
|
11022
|
+
type: "tool" /* TOOL */
|
|
9907
11023
|
}
|
|
9908
11024
|
});
|
|
9909
|
-
|
|
11025
|
+
span.log({ input: args.length === 1 ? args[0] : args });
|
|
9910
11026
|
try {
|
|
9911
|
-
|
|
9912
|
-
const
|
|
11027
|
+
let lastValue;
|
|
11028
|
+
for await (const value of result) {
|
|
11029
|
+
lastValue = value;
|
|
11030
|
+
yield value;
|
|
11031
|
+
}
|
|
11032
|
+
span.log({ output: lastValue });
|
|
11033
|
+
} catch (error) {
|
|
9913
11034
|
span.log({
|
|
9914
|
-
|
|
9915
|
-
metrics
|
|
11035
|
+
error: error instanceof Error ? error.message : String(error)
|
|
9916
11036
|
});
|
|
9917
|
-
|
|
9918
|
-
console.error(`Error extracting output for ${channelName}:`, error);
|
|
11037
|
+
throw error;
|
|
9919
11038
|
} finally {
|
|
9920
11039
|
span.end();
|
|
9921
|
-
|
|
11040
|
+
}
|
|
11041
|
+
})();
|
|
11042
|
+
}
|
|
11043
|
+
return parentSpan.traced(
|
|
11044
|
+
async (span) => {
|
|
11045
|
+
span.log({ input: args.length === 1 ? args[0] : args });
|
|
11046
|
+
const awaitedResult = await result;
|
|
11047
|
+
span.log({ output: awaitedResult });
|
|
11048
|
+
return awaitedResult;
|
|
11049
|
+
},
|
|
11050
|
+
{
|
|
11051
|
+
name,
|
|
11052
|
+
spanAttributes: {
|
|
11053
|
+
type: "tool" /* TOOL */
|
|
9922
11054
|
}
|
|
9923
11055
|
}
|
|
9924
|
-
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
11056
|
+
);
|
|
11057
|
+
};
|
|
11058
|
+
cleanup.push(() => {
|
|
11059
|
+
tool.execute = originalExecute;
|
|
11060
|
+
delete tool[AUTO_PATCHED_TOOL];
|
|
11061
|
+
});
|
|
11062
|
+
};
|
|
11063
|
+
const patchTools = (tools) => {
|
|
11064
|
+
if (!tools) {
|
|
11065
|
+
return;
|
|
11066
|
+
}
|
|
11067
|
+
const inferName = (tool, fallback2) => tool && (tool.name || tool.toolName || tool.id) || fallback2;
|
|
11068
|
+
if (Array.isArray(tools)) {
|
|
11069
|
+
tools.forEach(
|
|
11070
|
+
(tool, index) => patchTool(tool, inferName(tool, `tool[${index}]`))
|
|
11071
|
+
);
|
|
11072
|
+
return;
|
|
11073
|
+
}
|
|
11074
|
+
for (const [key, tool] of Object.entries(tools)) {
|
|
11075
|
+
patchTool(tool, key);
|
|
11076
|
+
}
|
|
11077
|
+
};
|
|
11078
|
+
if (params && typeof params === "object") {
|
|
11079
|
+
patchModel(params.model);
|
|
11080
|
+
patchTools(params.tools);
|
|
11081
|
+
}
|
|
11082
|
+
if (self && typeof self === "object") {
|
|
11083
|
+
const selfRecord = self;
|
|
11084
|
+
if (selfRecord.model !== void 0) {
|
|
11085
|
+
patchModel(selfRecord.model);
|
|
11086
|
+
}
|
|
11087
|
+
if (selfRecord.settings && typeof selfRecord.settings === "object") {
|
|
11088
|
+
if (selfRecord.settings.model !== void 0) {
|
|
11089
|
+
patchModel(selfRecord.settings.model);
|
|
11090
|
+
}
|
|
11091
|
+
if (selfRecord.settings.tools !== void 0) {
|
|
11092
|
+
patchTools(selfRecord.settings.tools);
|
|
11093
|
+
}
|
|
11094
|
+
}
|
|
11095
|
+
}
|
|
11096
|
+
return {
|
|
11097
|
+
cleanup: cleanup.length > 0 ? () => {
|
|
11098
|
+
while (cleanup.length > 0) {
|
|
11099
|
+
cleanup.pop()?.();
|
|
11100
|
+
}
|
|
11101
|
+
} : void 0,
|
|
11102
|
+
modelWrapped
|
|
11103
|
+
};
|
|
11104
|
+
}
|
|
11105
|
+
function finalizeAISDKChildTracing(event) {
|
|
11106
|
+
const cleanup = event?.__braintrust_ai_sdk_cleanup;
|
|
11107
|
+
if (event && typeof cleanup === "function") {
|
|
11108
|
+
cleanup();
|
|
11109
|
+
delete event.__braintrust_ai_sdk_cleanup;
|
|
11110
|
+
}
|
|
11111
|
+
}
|
|
11112
|
+
function patchAISDKStreamingResult(args) {
|
|
11113
|
+
const { denyOutputPaths, endEvent, result, span, startTime } = args;
|
|
11114
|
+
if (!result || typeof result !== "object") {
|
|
11115
|
+
return false;
|
|
11116
|
+
}
|
|
11117
|
+
const resultRecord = result;
|
|
11118
|
+
if (!isReadableStreamLike(resultRecord.baseStream)) {
|
|
11119
|
+
return false;
|
|
11120
|
+
}
|
|
11121
|
+
let firstChunkTime;
|
|
11122
|
+
const wrappedBaseStream = resultRecord.baseStream.pipeThrough(
|
|
11123
|
+
new TransformStream({
|
|
11124
|
+
transform(chunk, controller) {
|
|
11125
|
+
if (firstChunkTime === void 0) {
|
|
11126
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
9929
11127
|
}
|
|
9930
|
-
|
|
11128
|
+
controller.enqueue(chunk);
|
|
11129
|
+
},
|
|
11130
|
+
async flush() {
|
|
11131
|
+
const metrics = extractTopLevelAISDKMetrics(result, endEvent);
|
|
11132
|
+
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
11133
|
+
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
11134
|
+
}
|
|
11135
|
+
const output = await processAISDKStreamingOutput(
|
|
11136
|
+
result,
|
|
11137
|
+
denyOutputPaths
|
|
11138
|
+
);
|
|
11139
|
+
const metadata = buildResolvedMetadataPayload(result).metadata;
|
|
9931
11140
|
span.log({
|
|
9932
|
-
|
|
11141
|
+
output,
|
|
11142
|
+
...metadata ? { metadata } : {},
|
|
11143
|
+
metrics
|
|
9933
11144
|
});
|
|
11145
|
+
finalizeAISDKChildTracing(endEvent);
|
|
9934
11146
|
span.end();
|
|
9935
|
-
spans.delete(event);
|
|
9936
11147
|
}
|
|
9937
|
-
}
|
|
9938
|
-
|
|
9939
|
-
|
|
9940
|
-
|
|
9941
|
-
|
|
11148
|
+
})
|
|
11149
|
+
);
|
|
11150
|
+
Object.defineProperty(resultRecord, "baseStream", {
|
|
11151
|
+
configurable: true,
|
|
11152
|
+
enumerable: true,
|
|
11153
|
+
value: wrappedBaseStream,
|
|
11154
|
+
writable: true
|
|
11155
|
+
});
|
|
11156
|
+
return true;
|
|
11157
|
+
}
|
|
11158
|
+
function isReadableStreamLike(value) {
|
|
11159
|
+
return value != null && typeof value === "object" && typeof value.pipeThrough === "function";
|
|
11160
|
+
}
|
|
11161
|
+
async function processAISDKStreamingOutput(result, denyOutputPaths) {
|
|
11162
|
+
const output = processAISDKOutput(result, denyOutputPaths);
|
|
11163
|
+
if (!output || typeof output !== "object") {
|
|
11164
|
+
return output;
|
|
9942
11165
|
}
|
|
9943
|
-
|
|
9944
|
-
|
|
9945
|
-
|
|
9946
|
-
|
|
11166
|
+
const outputRecord = output;
|
|
11167
|
+
try {
|
|
11168
|
+
if ("text" in result && typeof result.text === "string") {
|
|
11169
|
+
outputRecord.text = result.text;
|
|
11170
|
+
}
|
|
11171
|
+
} catch {
|
|
11172
|
+
}
|
|
11173
|
+
try {
|
|
11174
|
+
if ("object" in result) {
|
|
11175
|
+
const resolvedObject = await Promise.resolve(result.object);
|
|
11176
|
+
if (resolvedObject !== void 0) {
|
|
11177
|
+
outputRecord.object = resolvedObject;
|
|
11178
|
+
}
|
|
11179
|
+
}
|
|
11180
|
+
} catch {
|
|
11181
|
+
}
|
|
11182
|
+
return outputRecord;
|
|
9947
11183
|
}
|
|
9948
|
-
function
|
|
9949
|
-
const
|
|
11184
|
+
function buildAISDKChildMetadata(model) {
|
|
11185
|
+
const { model: modelId, provider } = serializeModelWithProvider(model);
|
|
11186
|
+
return {
|
|
11187
|
+
...modelId ? { model: modelId } : {},
|
|
11188
|
+
...provider ? { provider } : {},
|
|
9950
11189
|
braintrust: {
|
|
9951
11190
|
integration_name: "ai-sdk",
|
|
9952
11191
|
sdk_language: "typescript"
|
|
9953
11192
|
}
|
|
9954
11193
|
};
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
11194
|
+
}
|
|
11195
|
+
function buildResolvedMetadataPayload(result) {
|
|
11196
|
+
const gatewayInfo = extractGatewayRoutingInfo(result);
|
|
11197
|
+
const metadata = {};
|
|
11198
|
+
if (gatewayInfo?.provider) {
|
|
11199
|
+
metadata.provider = gatewayInfo.provider;
|
|
9958
11200
|
}
|
|
9959
|
-
if (
|
|
9960
|
-
metadata.
|
|
11201
|
+
if (gatewayInfo?.model) {
|
|
11202
|
+
metadata.model = gatewayInfo.model;
|
|
9961
11203
|
}
|
|
9962
|
-
|
|
11204
|
+
if (result.finishReason !== void 0) {
|
|
11205
|
+
metadata.finish_reason = result.finishReason;
|
|
11206
|
+
}
|
|
11207
|
+
return Object.keys(metadata).length > 0 ? { metadata } : {};
|
|
11208
|
+
}
|
|
11209
|
+
function resolveAISDKModel(model) {
|
|
11210
|
+
if (typeof model !== "string") {
|
|
11211
|
+
return model;
|
|
11212
|
+
}
|
|
11213
|
+
const provider = globalThis.AI_SDK_DEFAULT_PROVIDER ?? null;
|
|
11214
|
+
if (provider && typeof provider.languageModel === "function") {
|
|
11215
|
+
return provider.languageModel(model);
|
|
11216
|
+
}
|
|
11217
|
+
return model;
|
|
11218
|
+
}
|
|
11219
|
+
function extractTextDelta(chunk) {
|
|
11220
|
+
if (typeof chunk.textDelta === "string") return chunk.textDelta;
|
|
11221
|
+
if (typeof chunk.delta === "string") return chunk.delta;
|
|
11222
|
+
if (typeof chunk.text === "string") return chunk.text;
|
|
11223
|
+
if (typeof chunk.content === "string") return chunk.content;
|
|
11224
|
+
return "";
|
|
11225
|
+
}
|
|
11226
|
+
function isAsyncGenerator(value) {
|
|
11227
|
+
return value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function" && typeof value.next === "function" && typeof value.return === "function" && typeof value.throw === "function";
|
|
9963
11228
|
}
|
|
9964
11229
|
function processAISDKOutput(output, denyOutputPaths) {
|
|
9965
11230
|
if (!output) return output;
|
|
9966
|
-
const
|
|
9967
|
-
|
|
9968
|
-
return omit(merged, denyOutputPaths);
|
|
11231
|
+
const merged = extractSerializableOutputFields(output);
|
|
11232
|
+
return normalizeAISDKLoggedOutput(omit(merged, denyOutputPaths));
|
|
9969
11233
|
}
|
|
9970
11234
|
function extractTokenMetrics(result) {
|
|
9971
11235
|
const metrics = {};
|
|
@@ -10015,12 +11279,14 @@ function extractTokenMetrics(result) {
|
|
|
10015
11279
|
}
|
|
10016
11280
|
return metrics;
|
|
10017
11281
|
}
|
|
10018
|
-
function aggregateAISDKChunks(chunks) {
|
|
11282
|
+
function aggregateAISDKChunks(chunks, _result, endEvent) {
|
|
10019
11283
|
const lastChunk = chunks[chunks.length - 1];
|
|
10020
11284
|
const output = {};
|
|
10021
11285
|
let metrics = {};
|
|
11286
|
+
let metadata;
|
|
10022
11287
|
if (lastChunk) {
|
|
10023
|
-
metrics = extractTokenMetrics(lastChunk);
|
|
11288
|
+
metrics = hasModelChildTracing(endEvent) ? {} : extractTokenMetrics(lastChunk);
|
|
11289
|
+
metadata = buildResolvedMetadataPayload(lastChunk).metadata;
|
|
10024
11290
|
if (lastChunk.text !== void 0) {
|
|
10025
11291
|
output.text = lastChunk.text;
|
|
10026
11292
|
}
|
|
@@ -10034,7 +11300,8 @@ function aggregateAISDKChunks(chunks) {
|
|
|
10034
11300
|
output.toolCalls = lastChunk.toolCalls;
|
|
10035
11301
|
}
|
|
10036
11302
|
}
|
|
10037
|
-
|
|
11303
|
+
finalizeAISDKChildTracing(endEvent);
|
|
11304
|
+
return { output, metrics, metadata };
|
|
10038
11305
|
}
|
|
10039
11306
|
function extractGetterValues(obj) {
|
|
10040
11307
|
const getterValues = {};
|
|
@@ -10054,7 +11321,7 @@ function extractGetterValues(obj) {
|
|
|
10054
11321
|
];
|
|
10055
11322
|
for (const name of getterNames) {
|
|
10056
11323
|
try {
|
|
10057
|
-
if (obj && name in obj &&
|
|
11324
|
+
if (obj && name in obj && isSerializableOutputValue(obj[name])) {
|
|
10058
11325
|
getterValues[name] = obj[name];
|
|
10059
11326
|
}
|
|
10060
11327
|
} catch {
|
|
@@ -10062,6 +11329,47 @@ function extractGetterValues(obj) {
|
|
|
10062
11329
|
}
|
|
10063
11330
|
return getterValues;
|
|
10064
11331
|
}
|
|
11332
|
+
function extractSerializableOutputFields(output) {
|
|
11333
|
+
const serialized = {};
|
|
11334
|
+
const directFieldNames = [
|
|
11335
|
+
"steps",
|
|
11336
|
+
"request",
|
|
11337
|
+
"responseMessages",
|
|
11338
|
+
"warnings",
|
|
11339
|
+
"rawResponse",
|
|
11340
|
+
"response",
|
|
11341
|
+
"providerMetadata",
|
|
11342
|
+
"experimental_providerMetadata"
|
|
11343
|
+
];
|
|
11344
|
+
for (const name of directFieldNames) {
|
|
11345
|
+
try {
|
|
11346
|
+
const value = output?.[name];
|
|
11347
|
+
if (isSerializableOutputValue(value)) {
|
|
11348
|
+
serialized[name] = value;
|
|
11349
|
+
}
|
|
11350
|
+
} catch {
|
|
11351
|
+
}
|
|
11352
|
+
}
|
|
11353
|
+
return {
|
|
11354
|
+
...serialized,
|
|
11355
|
+
...extractGetterValues(output)
|
|
11356
|
+
};
|
|
11357
|
+
}
|
|
11358
|
+
function isSerializableOutputValue(value) {
|
|
11359
|
+
if (typeof value === "function") {
|
|
11360
|
+
return false;
|
|
11361
|
+
}
|
|
11362
|
+
if (value && typeof value === "object" && typeof value.then === "function") {
|
|
11363
|
+
return false;
|
|
11364
|
+
}
|
|
11365
|
+
if (value && typeof value === "object" && typeof value.getReader === "function") {
|
|
11366
|
+
return false;
|
|
11367
|
+
}
|
|
11368
|
+
if (value && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function") {
|
|
11369
|
+
return false;
|
|
11370
|
+
}
|
|
11371
|
+
return true;
|
|
11372
|
+
}
|
|
10065
11373
|
function serializeModelWithProvider(model) {
|
|
10066
11374
|
const modelId = typeof model === "string" ? model : model?.modelId;
|
|
10067
11375
|
const explicitProvider = typeof model === "object" ? model?.provider : void 0;
|
|
@@ -10087,6 +11395,25 @@ function parseGatewayModelString(modelString) {
|
|
|
10087
11395
|
}
|
|
10088
11396
|
return { model: modelString };
|
|
10089
11397
|
}
|
|
11398
|
+
function extractGatewayRoutingInfo(result) {
|
|
11399
|
+
if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
|
|
11400
|
+
const routing2 = result.steps[0]?.providerMetadata?.gateway?.routing;
|
|
11401
|
+
if (routing2) {
|
|
11402
|
+
return {
|
|
11403
|
+
provider: routing2.resolvedProvider || routing2.finalProvider,
|
|
11404
|
+
model: routing2.resolvedProviderApiModelId
|
|
11405
|
+
};
|
|
11406
|
+
}
|
|
11407
|
+
}
|
|
11408
|
+
const routing = result?.providerMetadata?.gateway?.routing;
|
|
11409
|
+
if (routing) {
|
|
11410
|
+
return {
|
|
11411
|
+
provider: routing.resolvedProvider || routing.finalProvider,
|
|
11412
|
+
model: routing.resolvedProviderApiModelId
|
|
11413
|
+
};
|
|
11414
|
+
}
|
|
11415
|
+
return null;
|
|
11416
|
+
}
|
|
10090
11417
|
function extractCostFromResult(result) {
|
|
10091
11418
|
if (result?.steps && Array.isArray(result.steps) && result.steps.length > 0) {
|
|
10092
11419
|
let totalCost = 0;
|
|
@@ -10180,7 +11507,10 @@ function omitAtPath(obj, keys) {
|
|
|
10180
11507
|
if (Array.isArray(obj)) {
|
|
10181
11508
|
obj.forEach((item) => {
|
|
10182
11509
|
if (remainingKeys.length > 0) {
|
|
10183
|
-
omitAtPath(
|
|
11510
|
+
omitAtPath(
|
|
11511
|
+
item,
|
|
11512
|
+
remainingKeys
|
|
11513
|
+
);
|
|
10184
11514
|
}
|
|
10185
11515
|
});
|
|
10186
11516
|
}
|
|
@@ -10190,7 +11520,10 @@ function omitAtPath(obj, keys) {
|
|
|
10190
11520
|
}
|
|
10191
11521
|
} else {
|
|
10192
11522
|
if (obj && typeof obj === "object" && firstKey in obj) {
|
|
10193
|
-
omitAtPath(
|
|
11523
|
+
omitAtPath(
|
|
11524
|
+
obj[firstKey],
|
|
11525
|
+
remainingKeys
|
|
11526
|
+
);
|
|
10194
11527
|
}
|
|
10195
11528
|
}
|
|
10196
11529
|
}
|
|
@@ -10203,8 +11536,18 @@ function omit(obj, paths) {
|
|
|
10203
11536
|
return result;
|
|
10204
11537
|
}
|
|
10205
11538
|
|
|
11539
|
+
// src/instrumentation/plugins/claude-agent-sdk-channels.ts
|
|
11540
|
+
var claudeAgentSDKChannels = defineChannels(
|
|
11541
|
+
"@anthropic-ai/claude-agent-sdk",
|
|
11542
|
+
{
|
|
11543
|
+
query: channel({
|
|
11544
|
+
channelName: "query",
|
|
11545
|
+
kind: "async"
|
|
11546
|
+
})
|
|
11547
|
+
}
|
|
11548
|
+
);
|
|
11549
|
+
|
|
10206
11550
|
// src/instrumentation/plugins/claude-agent-sdk-plugin.ts
|
|
10207
|
-
import { tracingChannel as tracingChannel4 } from "dc-browser";
|
|
10208
11551
|
function filterSerializableOptions(options) {
|
|
10209
11552
|
const allowedKeys = [
|
|
10210
11553
|
"model",
|
|
@@ -10288,7 +11631,9 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
10288
11631
|
const input = buildLLMInput(prompt, conversationHistory);
|
|
10289
11632
|
const outputs = messages.map(
|
|
10290
11633
|
(m) => m.message?.content && m.message?.role ? { content: m.message.content, role: m.message.role } : void 0
|
|
10291
|
-
).filter(
|
|
11634
|
+
).filter(
|
|
11635
|
+
(c) => c !== void 0
|
|
11636
|
+
);
|
|
10292
11637
|
const span = startSpan({
|
|
10293
11638
|
name: "anthropic.messages.create",
|
|
10294
11639
|
spanAttributes: {
|
|
@@ -10307,7 +11652,6 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
10307
11652
|
return lastMessage.message?.content && lastMessage.message?.role ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
|
|
10308
11653
|
}
|
|
10309
11654
|
var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
10310
|
-
unsubscribers = [];
|
|
10311
11655
|
onEnable() {
|
|
10312
11656
|
this.subscribeToQuery();
|
|
10313
11657
|
}
|
|
@@ -10323,12 +11667,13 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10323
11667
|
* and individual LLM calls.
|
|
10324
11668
|
*/
|
|
10325
11669
|
subscribeToQuery() {
|
|
10326
|
-
const
|
|
11670
|
+
const channel2 = claudeAgentSDKChannels.query.tracingChannel();
|
|
10327
11671
|
const spans = /* @__PURE__ */ new WeakMap();
|
|
10328
11672
|
const handlers = {
|
|
10329
11673
|
start: (event) => {
|
|
10330
|
-
const params = event.arguments[0]
|
|
10331
|
-
const
|
|
11674
|
+
const params = event.arguments[0];
|
|
11675
|
+
const prompt = params?.prompt;
|
|
11676
|
+
const options = params?.options ?? {};
|
|
10332
11677
|
const span = startSpan({
|
|
10333
11678
|
name: "Claude Agent",
|
|
10334
11679
|
spanAttributes: {
|
|
@@ -10340,7 +11685,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10340
11685
|
span.log({
|
|
10341
11686
|
input: typeof prompt === "string" ? prompt : {
|
|
10342
11687
|
type: "streaming",
|
|
10343
|
-
description: "AsyncIterable<
|
|
11688
|
+
description: "AsyncIterable<ClaudeAgentSDKMessage>"
|
|
10344
11689
|
},
|
|
10345
11690
|
metadata: filterSerializableOptions(options)
|
|
10346
11691
|
});
|
|
@@ -10362,12 +11707,19 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10362
11707
|
if (!spanData) {
|
|
10363
11708
|
return;
|
|
10364
11709
|
}
|
|
10365
|
-
|
|
10366
|
-
|
|
11710
|
+
const eventResult = event.result;
|
|
11711
|
+
if (eventResult === void 0) {
|
|
11712
|
+
spanData.span.end();
|
|
11713
|
+
spans.delete(event);
|
|
11714
|
+
return;
|
|
11715
|
+
}
|
|
11716
|
+
if (isAsyncIterable(eventResult)) {
|
|
11717
|
+
patchStreamIfNeeded(eventResult, {
|
|
10367
11718
|
onChunk: async (message) => {
|
|
10368
11719
|
const currentTime = getCurrentUnixTimestamp();
|
|
10369
11720
|
const params = event.arguments[0];
|
|
10370
|
-
const
|
|
11721
|
+
const prompt = params?.prompt;
|
|
11722
|
+
const options = params?.options ?? {};
|
|
10371
11723
|
const messageId = message.message?.id;
|
|
10372
11724
|
if (messageId && messageId !== spanData.currentMessageId) {
|
|
10373
11725
|
if (spanData.currentMessages.length > 0) {
|
|
@@ -10426,7 +11778,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10426
11778
|
onComplete: async () => {
|
|
10427
11779
|
try {
|
|
10428
11780
|
const params = event.arguments[0];
|
|
10429
|
-
const
|
|
11781
|
+
const prompt = params?.prompt;
|
|
11782
|
+
const options = params?.options ?? {};
|
|
10430
11783
|
if (spanData.currentMessages.length > 0) {
|
|
10431
11784
|
const finalMessage = await createLLMSpanForMessages(
|
|
10432
11785
|
spanData.currentMessages,
|
|
@@ -10464,7 +11817,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10464
11817
|
} else {
|
|
10465
11818
|
try {
|
|
10466
11819
|
spanData.span.log({
|
|
10467
|
-
output:
|
|
11820
|
+
output: eventResult
|
|
10468
11821
|
});
|
|
10469
11822
|
} catch (error) {
|
|
10470
11823
|
console.error(
|
|
@@ -10479,7 +11832,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10479
11832
|
},
|
|
10480
11833
|
error: (event) => {
|
|
10481
11834
|
const spanData = spans.get(event);
|
|
10482
|
-
if (!spanData) {
|
|
11835
|
+
if (!spanData || !event.error) {
|
|
10483
11836
|
return;
|
|
10484
11837
|
}
|
|
10485
11838
|
const { span } = spanData;
|
|
@@ -10490,53 +11843,39 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10490
11843
|
spans.delete(event);
|
|
10491
11844
|
}
|
|
10492
11845
|
};
|
|
10493
|
-
|
|
11846
|
+
channel2.subscribe(handlers);
|
|
10494
11847
|
this.unsubscribers.push(() => {
|
|
10495
|
-
|
|
11848
|
+
channel2.unsubscribe(handlers);
|
|
10496
11849
|
});
|
|
10497
11850
|
}
|
|
10498
11851
|
};
|
|
10499
11852
|
|
|
11853
|
+
// src/instrumentation/plugins/google-genai-channels.ts
|
|
11854
|
+
var googleGenAIChannels = defineChannels("@google/genai", {
|
|
11855
|
+
generateContent: channel({
|
|
11856
|
+
channelName: "models.generateContent",
|
|
11857
|
+
kind: "async"
|
|
11858
|
+
}),
|
|
11859
|
+
generateContentStream: channel({
|
|
11860
|
+
channelName: "models.generateContentStream",
|
|
11861
|
+
kind: "async"
|
|
11862
|
+
})
|
|
11863
|
+
});
|
|
11864
|
+
|
|
10500
11865
|
// src/instrumentation/plugins/google-genai-plugin.ts
|
|
10501
|
-
import { tracingChannel as tracingChannel5 } from "dc-browser";
|
|
10502
11866
|
var GoogleGenAIPlugin = class extends BasePlugin {
|
|
10503
|
-
unsubscribers = [];
|
|
10504
11867
|
onEnable() {
|
|
10505
11868
|
this.subscribeToGoogleGenAIChannels();
|
|
10506
11869
|
}
|
|
10507
11870
|
onDisable() {
|
|
10508
|
-
|
|
10509
|
-
unsubscribe();
|
|
10510
|
-
}
|
|
10511
|
-
this.unsubscribers = [];
|
|
11871
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
10512
11872
|
}
|
|
10513
11873
|
subscribeToGoogleGenAIChannels() {
|
|
10514
|
-
this.
|
|
10515
|
-
|
|
10516
|
-
|
|
10517
|
-
extractInput: (args) => {
|
|
10518
|
-
const params = args[0] || {};
|
|
10519
|
-
const input = serializeInput(params);
|
|
10520
|
-
const metadata = extractMetadata(params);
|
|
10521
|
-
return {
|
|
10522
|
-
input,
|
|
10523
|
-
metadata: { ...metadata, provider: "google-genai" }
|
|
10524
|
-
};
|
|
10525
|
-
},
|
|
10526
|
-
extractOutput: (result) => {
|
|
10527
|
-
return result;
|
|
10528
|
-
},
|
|
10529
|
-
extractMetrics: (result, startTime) => {
|
|
10530
|
-
return extractGenerateContentMetrics(result, startTime);
|
|
10531
|
-
}
|
|
10532
|
-
});
|
|
10533
|
-
this.subscribeToGoogleStreamingChannel(
|
|
10534
|
-
"orchestrion:google-genai:models.generateContentStream",
|
|
10535
|
-
{
|
|
10536
|
-
name: "google-genai.generateContentStream",
|
|
11874
|
+
this.unsubscribers.push(
|
|
11875
|
+
traceAsyncChannel(googleGenAIChannels.generateContent, {
|
|
11876
|
+
name: "google-genai.generateContent",
|
|
10537
11877
|
type: "llm" /* LLM */,
|
|
10538
|
-
extractInput: (
|
|
10539
|
-
const params = args[0] || {};
|
|
11878
|
+
extractInput: ([params]) => {
|
|
10540
11879
|
const input = serializeInput(params);
|
|
10541
11880
|
const metadata = extractMetadata(params);
|
|
10542
11881
|
return {
|
|
@@ -10544,150 +11883,37 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
10544
11883
|
metadata: { ...metadata, provider: "google-genai" }
|
|
10545
11884
|
};
|
|
10546
11885
|
},
|
|
10547
|
-
|
|
10548
|
-
|
|
10549
|
-
|
|
10550
|
-
|
|
10551
|
-
|
|
10552
|
-
const channel = tracingChannel5(channelName);
|
|
10553
|
-
const spans = /* @__PURE__ */ new WeakMap();
|
|
10554
|
-
const handlers = {
|
|
10555
|
-
start: (event) => {
|
|
10556
|
-
const span = startSpan({
|
|
10557
|
-
name: config.name,
|
|
10558
|
-
spanAttributes: {
|
|
10559
|
-
type: config.type
|
|
10560
|
-
}
|
|
10561
|
-
});
|
|
10562
|
-
const startTime = getCurrentUnixTimestamp();
|
|
10563
|
-
spans.set(event, { span, startTime });
|
|
10564
|
-
try {
|
|
10565
|
-
const { input, metadata } = config.extractInput(event.arguments);
|
|
10566
|
-
span.log({
|
|
10567
|
-
input,
|
|
10568
|
-
metadata
|
|
10569
|
-
});
|
|
10570
|
-
} catch (error) {
|
|
10571
|
-
console.error(`Error extracting input for ${channelName}:`, error);
|
|
10572
|
-
}
|
|
10573
|
-
},
|
|
10574
|
-
asyncEnd: (event) => {
|
|
10575
|
-
const spanData = spans.get(event);
|
|
10576
|
-
if (!spanData) {
|
|
10577
|
-
return;
|
|
10578
|
-
}
|
|
10579
|
-
const { span, startTime } = spanData;
|
|
10580
|
-
try {
|
|
10581
|
-
const output = config.extractOutput(event.result);
|
|
10582
|
-
const metrics = config.extractMetrics(event.result, startTime);
|
|
10583
|
-
span.log({
|
|
10584
|
-
output,
|
|
10585
|
-
metrics
|
|
10586
|
-
});
|
|
10587
|
-
} catch (error) {
|
|
10588
|
-
console.error(`Error extracting output for ${channelName}:`, error);
|
|
10589
|
-
} finally {
|
|
10590
|
-
span.end();
|
|
10591
|
-
spans.delete(event);
|
|
10592
|
-
}
|
|
10593
|
-
},
|
|
10594
|
-
error: (event) => {
|
|
10595
|
-
const spanData = spans.get(event);
|
|
10596
|
-
if (!spanData) {
|
|
10597
|
-
return;
|
|
11886
|
+
extractOutput: (result) => {
|
|
11887
|
+
return result;
|
|
11888
|
+
},
|
|
11889
|
+
extractMetrics: (result, startTime) => {
|
|
11890
|
+
return extractGenerateContentMetrics(result, startTime);
|
|
10598
11891
|
}
|
|
10599
|
-
|
|
10600
|
-
|
|
10601
|
-
|
|
10602
|
-
|
|
10603
|
-
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
|
|
10607
|
-
|
|
10608
|
-
|
|
10609
|
-
channel.unsubscribe(handlers);
|
|
10610
|
-
});
|
|
10611
|
-
}
|
|
10612
|
-
subscribeToGoogleStreamingChannel(channelName, config) {
|
|
10613
|
-
const channel = tracingChannel5(channelName);
|
|
10614
|
-
const spans = /* @__PURE__ */ new WeakMap();
|
|
10615
|
-
const handlers = {
|
|
10616
|
-
start: (event) => {
|
|
10617
|
-
const span = startSpan({
|
|
10618
|
-
name: config.name,
|
|
10619
|
-
spanAttributes: {
|
|
10620
|
-
type: config.type
|
|
10621
|
-
}
|
|
10622
|
-
});
|
|
10623
|
-
const startTime = getCurrentUnixTimestamp();
|
|
10624
|
-
spans.set(event, { span, startTime });
|
|
10625
|
-
try {
|
|
10626
|
-
const { input, metadata } = config.extractInput(event.arguments);
|
|
10627
|
-
span.log({
|
|
11892
|
+
})
|
|
11893
|
+
);
|
|
11894
|
+
this.unsubscribers.push(
|
|
11895
|
+
traceStreamingChannel(googleGenAIChannels.generateContentStream, {
|
|
11896
|
+
name: "google-genai.generateContentStream",
|
|
11897
|
+
type: "llm" /* LLM */,
|
|
11898
|
+
extractInput: ([params]) => {
|
|
11899
|
+
const input = serializeInput(params);
|
|
11900
|
+
const metadata = extractMetadata(params);
|
|
11901
|
+
return {
|
|
10628
11902
|
input,
|
|
10629
|
-
metadata
|
|
10630
|
-
}
|
|
10631
|
-
}
|
|
10632
|
-
|
|
10633
|
-
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
|
|
10637
|
-
|
|
10638
|
-
|
|
10639
|
-
|
|
10640
|
-
const { span, startTime } = spanData;
|
|
10641
|
-
if (isAsyncIterable(event.result)) {
|
|
10642
|
-
patchStreamIfNeeded(event.result, {
|
|
10643
|
-
onComplete: (chunks) => {
|
|
10644
|
-
try {
|
|
10645
|
-
const { output, metrics } = config.aggregateChunks(
|
|
10646
|
-
chunks,
|
|
10647
|
-
startTime
|
|
10648
|
-
);
|
|
10649
|
-
span.log({
|
|
10650
|
-
output,
|
|
10651
|
-
metrics
|
|
10652
|
-
});
|
|
10653
|
-
} catch (error) {
|
|
10654
|
-
console.error(
|
|
10655
|
-
`Error extracting output for ${channelName}:`,
|
|
10656
|
-
error
|
|
10657
|
-
);
|
|
10658
|
-
} finally {
|
|
10659
|
-
span.end();
|
|
10660
|
-
}
|
|
10661
|
-
},
|
|
10662
|
-
onError: (error) => {
|
|
10663
|
-
span.log({
|
|
10664
|
-
error: error.message
|
|
10665
|
-
});
|
|
10666
|
-
span.end();
|
|
10667
|
-
}
|
|
10668
|
-
});
|
|
10669
|
-
} else {
|
|
10670
|
-
span.end();
|
|
10671
|
-
spans.delete(event);
|
|
10672
|
-
}
|
|
10673
|
-
},
|
|
10674
|
-
error: (event) => {
|
|
10675
|
-
const spanData = spans.get(event);
|
|
10676
|
-
if (!spanData) {
|
|
10677
|
-
return;
|
|
11903
|
+
metadata: { ...metadata, provider: "google-genai" }
|
|
11904
|
+
};
|
|
11905
|
+
},
|
|
11906
|
+
extractOutput: (result) => {
|
|
11907
|
+
return result;
|
|
11908
|
+
},
|
|
11909
|
+
extractMetrics: () => {
|
|
11910
|
+
return {};
|
|
11911
|
+
},
|
|
11912
|
+
aggregateChunks: (chunks, _result, _endEvent, startTime) => {
|
|
11913
|
+
return aggregateGenerateContentChunks(chunks, startTime);
|
|
10678
11914
|
}
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
error: event.error.message
|
|
10682
|
-
});
|
|
10683
|
-
span.end();
|
|
10684
|
-
spans.delete(event);
|
|
10685
|
-
}
|
|
10686
|
-
};
|
|
10687
|
-
channel.subscribe(handlers);
|
|
10688
|
-
this.unsubscribers.push(() => {
|
|
10689
|
-
channel.unsubscribe(handlers);
|
|
10690
|
-
});
|
|
11915
|
+
})
|
|
11916
|
+
);
|
|
10691
11917
|
}
|
|
10692
11918
|
};
|
|
10693
11919
|
function serializeInput(params) {
|
|
@@ -10743,8 +11969,12 @@ function serializePart(part) {
|
|
|
10743
11969
|
const buffer = typeof data === "string" ? typeof Buffer !== "undefined" ? Buffer.from(data, "base64") : new Uint8Array(
|
|
10744
11970
|
atob(data).split("").map((c) => c.charCodeAt(0))
|
|
10745
11971
|
) : typeof Buffer !== "undefined" ? Buffer.from(data) : new Uint8Array(data);
|
|
11972
|
+
const arrayBuffer = buffer instanceof Uint8Array ? buffer.buffer.slice(
|
|
11973
|
+
buffer.byteOffset,
|
|
11974
|
+
buffer.byteOffset + buffer.byteLength
|
|
11975
|
+
) : buffer;
|
|
10746
11976
|
const attachment = new Attachment({
|
|
10747
|
-
data:
|
|
11977
|
+
data: arrayBuffer,
|
|
10748
11978
|
filename,
|
|
10749
11979
|
contentType: mimeType || "application/octet-stream"
|
|
10750
11980
|
});
|
|
@@ -10793,33 +12023,36 @@ function extractGenerateContentMetrics(response, startTime) {
|
|
|
10793
12023
|
const end = getCurrentUnixTimestamp();
|
|
10794
12024
|
metrics.duration = end - startTime;
|
|
10795
12025
|
}
|
|
10796
|
-
if (response
|
|
10797
|
-
|
|
10798
|
-
if (usage.promptTokenCount !== void 0) {
|
|
10799
|
-
metrics.prompt_tokens = usage.promptTokenCount;
|
|
10800
|
-
}
|
|
10801
|
-
if (usage.candidatesTokenCount !== void 0) {
|
|
10802
|
-
metrics.completion_tokens = usage.candidatesTokenCount;
|
|
10803
|
-
}
|
|
10804
|
-
if (usage.totalTokenCount !== void 0) {
|
|
10805
|
-
metrics.tokens = usage.totalTokenCount;
|
|
10806
|
-
}
|
|
10807
|
-
if (usage.cachedContentTokenCount !== void 0) {
|
|
10808
|
-
metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
|
|
10809
|
-
}
|
|
10810
|
-
if (usage.thoughtsTokenCount !== void 0) {
|
|
10811
|
-
metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
|
|
10812
|
-
}
|
|
12026
|
+
if (response?.usageMetadata) {
|
|
12027
|
+
populateUsageMetrics(metrics, response.usageMetadata);
|
|
10813
12028
|
}
|
|
10814
12029
|
return metrics;
|
|
10815
12030
|
}
|
|
12031
|
+
function populateUsageMetrics(metrics, usage) {
|
|
12032
|
+
if (usage.promptTokenCount !== void 0) {
|
|
12033
|
+
metrics.prompt_tokens = usage.promptTokenCount;
|
|
12034
|
+
}
|
|
12035
|
+
if (usage.candidatesTokenCount !== void 0) {
|
|
12036
|
+
metrics.completion_tokens = usage.candidatesTokenCount;
|
|
12037
|
+
}
|
|
12038
|
+
if (usage.totalTokenCount !== void 0) {
|
|
12039
|
+
metrics.tokens = usage.totalTokenCount;
|
|
12040
|
+
}
|
|
12041
|
+
if (usage.cachedContentTokenCount !== void 0) {
|
|
12042
|
+
metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
|
|
12043
|
+
}
|
|
12044
|
+
if (usage.thoughtsTokenCount !== void 0) {
|
|
12045
|
+
metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
|
|
12046
|
+
}
|
|
12047
|
+
}
|
|
10816
12048
|
function aggregateGenerateContentChunks(chunks, startTime) {
|
|
10817
|
-
const
|
|
10818
|
-
|
|
10819
|
-
|
|
10820
|
-
|
|
12049
|
+
const metrics = {};
|
|
12050
|
+
if (startTime !== void 0) {
|
|
12051
|
+
const end = getCurrentUnixTimestamp();
|
|
12052
|
+
metrics.duration = end - startTime;
|
|
12053
|
+
}
|
|
10821
12054
|
let firstTokenTime = null;
|
|
10822
|
-
if (chunks.length > 0 && firstTokenTime === null) {
|
|
12055
|
+
if (chunks.length > 0 && firstTokenTime === null && startTime !== void 0) {
|
|
10823
12056
|
firstTokenTime = getCurrentUnixTimestamp();
|
|
10824
12057
|
metrics.time_to_first_token = firstTokenTime - startTime;
|
|
10825
12058
|
}
|
|
@@ -10890,21 +12123,7 @@ function aggregateGenerateContentChunks(chunks, startTime) {
|
|
|
10890
12123
|
}
|
|
10891
12124
|
if (usageMetadata) {
|
|
10892
12125
|
output.usageMetadata = usageMetadata;
|
|
10893
|
-
|
|
10894
|
-
metrics.prompt_tokens = usageMetadata.promptTokenCount;
|
|
10895
|
-
}
|
|
10896
|
-
if (usageMetadata.candidatesTokenCount !== void 0) {
|
|
10897
|
-
metrics.completion_tokens = usageMetadata.candidatesTokenCount;
|
|
10898
|
-
}
|
|
10899
|
-
if (usageMetadata.totalTokenCount !== void 0) {
|
|
10900
|
-
metrics.tokens = usageMetadata.totalTokenCount;
|
|
10901
|
-
}
|
|
10902
|
-
if (usageMetadata.cachedContentTokenCount !== void 0) {
|
|
10903
|
-
metrics.prompt_cached_tokens = usageMetadata.cachedContentTokenCount;
|
|
10904
|
-
}
|
|
10905
|
-
if (usageMetadata.thoughtsTokenCount !== void 0) {
|
|
10906
|
-
metrics.completion_reasoning_tokens = usageMetadata.thoughtsTokenCount;
|
|
10907
|
-
}
|
|
12126
|
+
populateUsageMetrics(metrics, usageMetadata);
|
|
10908
12127
|
}
|
|
10909
12128
|
if (text) {
|
|
10910
12129
|
output.text = text;
|
|
@@ -10916,7 +12135,8 @@ function tryToDict(obj) {
|
|
|
10916
12135
|
return null;
|
|
10917
12136
|
}
|
|
10918
12137
|
if (typeof obj === "object") {
|
|
10919
|
-
if (
|
|
12138
|
+
if ("toJSON" in obj && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
12139
|
+
typeof obj.toJSON === "function") {
|
|
10920
12140
|
return obj.toJSON();
|
|
10921
12141
|
}
|
|
10922
12142
|
return obj;
|
|
@@ -11080,6 +12300,7 @@ function configureNode() {
|
|
|
11080
12300
|
isomorph_default.getEnv = (name) => process.env[name];
|
|
11081
12301
|
isomorph_default.getCallerLocation = getCallerLocation;
|
|
11082
12302
|
isomorph_default.newAsyncLocalStorage = () => new AsyncLocalStorage();
|
|
12303
|
+
isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
|
|
11083
12304
|
isomorph_default.processOn = (event, handler) => {
|
|
11084
12305
|
process.on(event, handler);
|
|
11085
12306
|
};
|
|
@@ -11113,7 +12334,7 @@ function configureNode() {
|
|
|
11113
12334
|
import express from "express";
|
|
11114
12335
|
import cors from "cors";
|
|
11115
12336
|
|
|
11116
|
-
// ../node_modules/async/dist/async.mjs
|
|
12337
|
+
// ../node_modules/.pnpm/async@3.2.5/node_modules/async/dist/async.mjs
|
|
11117
12338
|
function initialParams(fn) {
|
|
11118
12339
|
return function(...args) {
|
|
11119
12340
|
var callback = args.pop();
|
|
@@ -11181,7 +12402,7 @@ function invokeCallback(callback, error, value) {
|
|
|
11181
12402
|
function isAsync(fn) {
|
|
11182
12403
|
return fn[Symbol.toStringTag] === "AsyncFunction";
|
|
11183
12404
|
}
|
|
11184
|
-
function
|
|
12405
|
+
function isAsyncGenerator2(fn) {
|
|
11185
12406
|
return fn[Symbol.toStringTag] === "AsyncGenerator";
|
|
11186
12407
|
}
|
|
11187
12408
|
function isAsyncIterable2(obj) {
|
|
@@ -11238,6 +12459,7 @@ function isArrayLike(value) {
|
|
|
11238
12459
|
return value && typeof value.length === "number" && value.length >= 0 && value.length % 1 === 0;
|
|
11239
12460
|
}
|
|
11240
12461
|
var breakLoop = {};
|
|
12462
|
+
var breakLoop$1 = breakLoop;
|
|
11241
12463
|
function once(fn) {
|
|
11242
12464
|
function wrapper(...args) {
|
|
11243
12465
|
if (fn === null) return;
|
|
@@ -11329,7 +12551,7 @@ function asyncEachOfLimit(generator, limit, iteratee, callback) {
|
|
|
11329
12551
|
canceled = true;
|
|
11330
12552
|
return;
|
|
11331
12553
|
}
|
|
11332
|
-
if (result === breakLoop || done && running <= 0) {
|
|
12554
|
+
if (result === breakLoop$1 || done && running <= 0) {
|
|
11333
12555
|
done = true;
|
|
11334
12556
|
return callback(null);
|
|
11335
12557
|
}
|
|
@@ -11352,7 +12574,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
11352
12574
|
if (!obj) {
|
|
11353
12575
|
return callback(null);
|
|
11354
12576
|
}
|
|
11355
|
-
if (
|
|
12577
|
+
if (isAsyncGenerator2(obj)) {
|
|
11356
12578
|
return asyncEachOfLimit(obj, limit, iteratee, callback);
|
|
11357
12579
|
}
|
|
11358
12580
|
if (isAsyncIterable2(obj)) {
|
|
@@ -11372,7 +12594,7 @@ var eachOfLimit$2 = (limit) => {
|
|
|
11372
12594
|
} else if (err === false) {
|
|
11373
12595
|
done = true;
|
|
11374
12596
|
canceled = true;
|
|
11375
|
-
} else if (value === breakLoop || done && running <= 0) {
|
|
12597
|
+
} else if (value === breakLoop$1 || done && running <= 0) {
|
|
11376
12598
|
done = true;
|
|
11377
12599
|
return callback(null);
|
|
11378
12600
|
} else if (!looping) {
|
|
@@ -11415,7 +12637,7 @@ function eachOfArrayLike(coll, iteratee, callback) {
|
|
|
11415
12637
|
if (canceled === true) return;
|
|
11416
12638
|
if (err) {
|
|
11417
12639
|
callback(err);
|
|
11418
|
-
} else if (++completed === length || value === breakLoop) {
|
|
12640
|
+
} else if (++completed === length || value === breakLoop$1) {
|
|
11419
12641
|
callback(null);
|
|
11420
12642
|
}
|
|
11421
12643
|
}
|
|
@@ -11811,7 +13033,7 @@ function _createTester(check, getResult) {
|
|
|
11811
13033
|
if (check(result) && !testResult) {
|
|
11812
13034
|
testPassed = true;
|
|
11813
13035
|
testResult = getResult(true, value);
|
|
11814
|
-
return callback(null, breakLoop);
|
|
13036
|
+
return callback(null, breakLoop$1);
|
|
11815
13037
|
}
|
|
11816
13038
|
callback();
|
|
11817
13039
|
});
|
|
@@ -12514,7 +13736,8 @@ var promptDefinitionSchema = promptContentsSchema.and(
|
|
|
12514
13736
|
z9.object({
|
|
12515
13737
|
model: z9.string(),
|
|
12516
13738
|
params: ModelParams.optional(),
|
|
12517
|
-
templateFormat: z9.enum(["mustache", "nunjucks", "none"]).optional()
|
|
13739
|
+
templateFormat: z9.enum(["mustache", "nunjucks", "none"]).optional(),
|
|
13740
|
+
environments: z9.array(z9.string()).optional()
|
|
12518
13741
|
})
|
|
12519
13742
|
);
|
|
12520
13743
|
var promptDefinitionWithToolsSchema = promptDefinitionSchema.and(
|
|
@@ -12550,6 +13773,11 @@ var evalParametersSchema = z10.record(
|
|
|
12550
13773
|
default: promptDefinitionWithToolsSchema.optional(),
|
|
12551
13774
|
description: z10.string().optional()
|
|
12552
13775
|
}),
|
|
13776
|
+
z10.object({
|
|
13777
|
+
type: z10.literal("model"),
|
|
13778
|
+
default: z10.string().optional(),
|
|
13779
|
+
description: z10.string().optional()
|
|
13780
|
+
}),
|
|
12553
13781
|
z10.instanceof(z10.ZodType)
|
|
12554
13782
|
// For Zod schemas
|
|
12555
13783
|
])
|
|
@@ -12592,6 +13820,17 @@ function validateParametersWithZod(parameters, parameterSchema) {
|
|
|
12592
13820
|
throw new Error(`Parameter '${name}' is required`);
|
|
12593
13821
|
}
|
|
12594
13822
|
return [name, Prompt2.fromPromptData(name, promptData)];
|
|
13823
|
+
} else if ("type" in schema && schema.type === "model") {
|
|
13824
|
+
const model = value ?? schema.default;
|
|
13825
|
+
if (model === void 0) {
|
|
13826
|
+
throw new Error(`Parameter '${name}' is required`);
|
|
13827
|
+
}
|
|
13828
|
+
if (typeof model !== "string") {
|
|
13829
|
+
throw new Error(
|
|
13830
|
+
`Parameter '${name}' must be a string model identifier`
|
|
13831
|
+
);
|
|
13832
|
+
}
|
|
13833
|
+
return [name, model];
|
|
12595
13834
|
} else {
|
|
12596
13835
|
const schemaCasted = schema;
|
|
12597
13836
|
return [name, schemaCasted.parse(value)];
|
|
@@ -12654,6 +13893,22 @@ function initExperiment(state, options = {}) {
|
|
|
12654
13893
|
setCurrent: false
|
|
12655
13894
|
});
|
|
12656
13895
|
}
|
|
13896
|
+
async function getExperimentParametersRef(parameters) {
|
|
13897
|
+
if (!parameters) {
|
|
13898
|
+
return void 0;
|
|
13899
|
+
}
|
|
13900
|
+
const resolvedParameters = parameters instanceof Promise ? await parameters : parameters;
|
|
13901
|
+
if (!RemoteEvalParameters.isParameters(resolvedParameters)) {
|
|
13902
|
+
return void 0;
|
|
13903
|
+
}
|
|
13904
|
+
if (resolvedParameters.id === void 0) {
|
|
13905
|
+
return void 0;
|
|
13906
|
+
}
|
|
13907
|
+
return {
|
|
13908
|
+
id: resolvedParameters.id,
|
|
13909
|
+
version: resolvedParameters.version
|
|
13910
|
+
};
|
|
13911
|
+
}
|
|
12657
13912
|
function callEvaluatorData(data) {
|
|
12658
13913
|
const dataResult = typeof data === "function" ? data() : data;
|
|
12659
13914
|
let baseExperiment = void 0;
|
|
@@ -12666,10 +13921,10 @@ function callEvaluatorData(data) {
|
|
|
12666
13921
|
};
|
|
12667
13922
|
}
|
|
12668
13923
|
function isAsyncIterable3(value) {
|
|
12669
|
-
return typeof value === "object" && value !== null && typeof value[Symbol.asyncIterator] === "function";
|
|
13924
|
+
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
12670
13925
|
}
|
|
12671
13926
|
function isIterable(value) {
|
|
12672
|
-
return typeof value === "object" && value !== null && typeof value[Symbol.iterator] === "function";
|
|
13927
|
+
return typeof value === "object" && value !== null && Symbol.iterator in value && typeof value[Symbol.iterator] === "function";
|
|
12673
13928
|
}
|
|
12674
13929
|
globalThis._evals = {
|
|
12675
13930
|
functions: [],
|
|
@@ -12720,6 +13975,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
12720
13975
|
const { data, baseExperiment: defaultBaseExperiment } = callEvaluatorData(
|
|
12721
13976
|
evaluator.data
|
|
12722
13977
|
);
|
|
13978
|
+
const parameters = await getExperimentParametersRef(evaluator.parameters);
|
|
12723
13979
|
const experiment = options.parent || options.noSendLogs ? null : initExperiment(evaluator.state, {
|
|
12724
13980
|
...evaluator.projectId ? { projectId: evaluator.projectId } : { project: name },
|
|
12725
13981
|
experiment: evaluator.experimentName,
|
|
@@ -12732,7 +13988,8 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
12732
13988
|
baseExperimentId: evaluator.baseExperimentId,
|
|
12733
13989
|
gitMetadataSettings: evaluator.gitMetadataSettings,
|
|
12734
13990
|
repoInfo: evaluator.repoInfo,
|
|
12735
|
-
dataset: Dataset2.isDataset(data) ? data : void 0
|
|
13991
|
+
dataset: Dataset2.isDataset(data) ? data : void 0,
|
|
13992
|
+
parameters
|
|
12736
13993
|
});
|
|
12737
13994
|
if (experiment && typeof process !== "undefined" && globalThis.BRAINTRUST_CONTEXT_MANAGER !== void 0) {
|
|
12738
13995
|
await experiment._waitForId();
|
|
@@ -12787,7 +14044,7 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
12787
14044
|
if (experiment) {
|
|
12788
14045
|
await experiment.flush().catch(console.error);
|
|
12789
14046
|
} else if (options.parent) {
|
|
12790
|
-
await flush().catch(console.error);
|
|
14047
|
+
await flush({ state: evaluator.state }).catch(console.error);
|
|
12791
14048
|
}
|
|
12792
14049
|
}
|
|
12793
14050
|
} finally {
|
|
@@ -13105,7 +14362,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
13105
14362
|
const names = Object.keys(scorerErrors).join(", ");
|
|
13106
14363
|
const errors = failingScorersAndResults.map((item) => item.error);
|
|
13107
14364
|
unhandledScores = Object.keys(scorerErrors);
|
|
13108
|
-
|
|
14365
|
+
debugLogger.forState(evaluator.state).warn(
|
|
13109
14366
|
`Found exceptions for the following scorers: ${names}`,
|
|
13110
14367
|
errors
|
|
13111
14368
|
);
|
|
@@ -13156,6 +14413,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
13156
14413
|
},
|
|
13157
14414
|
Math.max(evaluator.maxConcurrency ?? Number.MAX_SAFE_INTEGER, 1)
|
|
13158
14415
|
);
|
|
14416
|
+
const queueErrors = [];
|
|
13159
14417
|
const enqueuePromise = (async () => {
|
|
13160
14418
|
for await (const datum of dataIterable) {
|
|
13161
14419
|
if (cancelled) {
|
|
@@ -13171,7 +14429,11 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
13171
14429
|
}
|
|
13172
14430
|
scheduledTrials++;
|
|
13173
14431
|
progressReporter.setTotal?.(evaluator.evalName, scheduledTrials);
|
|
13174
|
-
q.
|
|
14432
|
+
q.pushAsync({ datum, trialIndex }).catch((e) => {
|
|
14433
|
+
if (queueErrors.length < 5) {
|
|
14434
|
+
queueErrors.push(e);
|
|
14435
|
+
}
|
|
14436
|
+
});
|
|
13175
14437
|
}
|
|
13176
14438
|
}
|
|
13177
14439
|
})();
|
|
@@ -13219,11 +14481,17 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
13219
14481
|
})();
|
|
13220
14482
|
try {
|
|
13221
14483
|
await Promise.race([waitForQueue, cancel()]);
|
|
14484
|
+
if (queueErrors.length > 0) {
|
|
14485
|
+
throw new AggregateError(
|
|
14486
|
+
queueErrors,
|
|
14487
|
+
`Encountered ${queueErrors.length} unhandled task errors`
|
|
14488
|
+
);
|
|
14489
|
+
}
|
|
13222
14490
|
} catch (e) {
|
|
13223
14491
|
q.kill();
|
|
13224
14492
|
if (e instanceof InternalAbortError) {
|
|
13225
14493
|
if (isomorph_default.getEnv("BRAINTRUST_VERBOSE")) {
|
|
13226
|
-
|
|
14494
|
+
debugLogger.forState(evaluator.state).warn("Evaluator cancelled:", e.message);
|
|
13227
14495
|
}
|
|
13228
14496
|
}
|
|
13229
14497
|
throw e;
|
|
@@ -13318,7 +14586,11 @@ function reportFailures(evaluator, failingResults, { verbose, jsonl }) {
|
|
|
13318
14586
|
}
|
|
13319
14587
|
}
|
|
13320
14588
|
if (!verbose && !jsonl) {
|
|
13321
|
-
console.error(
|
|
14589
|
+
console.error(
|
|
14590
|
+
warning(
|
|
14591
|
+
"Use --debug-logging debug to see full stack traces and troubleshooting details."
|
|
14592
|
+
)
|
|
14593
|
+
);
|
|
13322
14594
|
}
|
|
13323
14595
|
}
|
|
13324
14596
|
}
|
|
@@ -13619,6 +14891,11 @@ var staticParametersSchema = z12.record(
|
|
|
13619
14891
|
default: PromptData.optional(),
|
|
13620
14892
|
description: z12.string().optional()
|
|
13621
14893
|
}),
|
|
14894
|
+
z12.object({
|
|
14895
|
+
type: z12.literal("model"),
|
|
14896
|
+
default: z12.string().optional(),
|
|
14897
|
+
description: z12.string().optional()
|
|
14898
|
+
}),
|
|
13622
14899
|
z12.object({
|
|
13623
14900
|
type: z12.literal("data"),
|
|
13624
14901
|
schema: z12.record(z12.unknown()),
|
|
@@ -13671,23 +14948,6 @@ import { ValidationError } from "ajv";
|
|
|
13671
14948
|
|
|
13672
14949
|
// src/framework2.ts
|
|
13673
14950
|
import { z as z13 } from "zod/v3";
|
|
13674
|
-
|
|
13675
|
-
// src/zod/utils.ts
|
|
13676
|
-
import { zodToJsonSchema as zodToJsonSchemaV3 } from "zod-to-json-schema";
|
|
13677
|
-
import * as z42 from "zod/v4";
|
|
13678
|
-
function isZodV4(zodObject) {
|
|
13679
|
-
return typeof zodObject === "object" && zodObject !== null && "_zod" in zodObject && zodObject._zod !== void 0;
|
|
13680
|
-
}
|
|
13681
|
-
function zodToJsonSchema(schema) {
|
|
13682
|
-
if (isZodV4(schema)) {
|
|
13683
|
-
return z42.toJSONSchema(schema, {
|
|
13684
|
-
target: "draft-7"
|
|
13685
|
-
});
|
|
13686
|
-
}
|
|
13687
|
-
return zodToJsonSchemaV3(schema);
|
|
13688
|
-
}
|
|
13689
|
-
|
|
13690
|
-
// src/framework2.ts
|
|
13691
14951
|
var currentFilename = typeof __filename !== "undefined" ? __filename : "unknown";
|
|
13692
14952
|
var ProjectBuilder = class {
|
|
13693
14953
|
create(opts) {
|
|
@@ -13855,6 +15115,7 @@ var CodeFunction = class {
|
|
|
13855
15115
|
this.description = opts.description;
|
|
13856
15116
|
this.type = opts.type;
|
|
13857
15117
|
this.ifExists = opts.ifExists;
|
|
15118
|
+
this.tags = opts.tags;
|
|
13858
15119
|
this.metadata = opts.metadata;
|
|
13859
15120
|
this.parameters = opts.parameters;
|
|
13860
15121
|
this.returns = opts.returns;
|
|
@@ -13870,6 +15131,7 @@ var CodeFunction = class {
|
|
|
13870
15131
|
parameters;
|
|
13871
15132
|
returns;
|
|
13872
15133
|
ifExists;
|
|
15134
|
+
tags;
|
|
13873
15135
|
metadata;
|
|
13874
15136
|
key() {
|
|
13875
15137
|
return JSON.stringify([
|
|
@@ -13889,7 +15151,9 @@ var CodePrompt = class {
|
|
|
13889
15151
|
id;
|
|
13890
15152
|
functionType;
|
|
13891
15153
|
toolFunctions;
|
|
15154
|
+
tags;
|
|
13892
15155
|
metadata;
|
|
15156
|
+
environmentSlugs;
|
|
13893
15157
|
constructor(project, prompt, toolFunctions, opts, functionType) {
|
|
13894
15158
|
this.project = project;
|
|
13895
15159
|
this.name = opts.name;
|
|
@@ -13900,7 +15164,9 @@ var CodePrompt = class {
|
|
|
13900
15164
|
this.description = opts.description;
|
|
13901
15165
|
this.id = opts.id;
|
|
13902
15166
|
this.functionType = functionType;
|
|
15167
|
+
this.tags = opts.tags;
|
|
13903
15168
|
this.metadata = opts.metadata;
|
|
15169
|
+
this.environmentSlugs = opts.environments;
|
|
13904
15170
|
}
|
|
13905
15171
|
async toFunctionDefinition(projectNameToId) {
|
|
13906
15172
|
const prompt_data = {
|
|
@@ -13934,7 +15200,9 @@ var CodePrompt = class {
|
|
|
13934
15200
|
function_type: this.functionType,
|
|
13935
15201
|
prompt_data,
|
|
13936
15202
|
if_exists: this.ifExists,
|
|
13937
|
-
|
|
15203
|
+
tags: this.tags,
|
|
15204
|
+
metadata: this.metadata,
|
|
15205
|
+
environments: this.environmentSlugs && this.environmentSlugs.length > 0 ? this.environmentSlugs.map((slug) => ({ slug })) : void 0
|
|
13938
15206
|
};
|
|
13939
15207
|
}
|
|
13940
15208
|
};
|
|
@@ -13962,6 +15230,7 @@ var PromptBuilder = class {
|
|
|
13962
15230
|
name: opts.name,
|
|
13963
15231
|
slug,
|
|
13964
15232
|
prompt_data: promptData,
|
|
15233
|
+
tags: opts.tags,
|
|
13965
15234
|
...this.project.id !== void 0 ? { project_id: this.project.id } : {}
|
|
13966
15235
|
};
|
|
13967
15236
|
const prompt = new Prompt2(
|
|
@@ -14043,6 +15312,15 @@ function serializeEvalParametersToStaticParametersSchema(parameters) {
|
|
|
14043
15312
|
description: value.description
|
|
14044
15313
|
}
|
|
14045
15314
|
];
|
|
15315
|
+
} else if ("type" in value && value.type === "model") {
|
|
15316
|
+
return [
|
|
15317
|
+
name,
|
|
15318
|
+
{
|
|
15319
|
+
type: "model",
|
|
15320
|
+
default: value.default,
|
|
15321
|
+
description: value.description
|
|
15322
|
+
}
|
|
15323
|
+
];
|
|
14046
15324
|
} else {
|
|
14047
15325
|
const schemaObj = zodToJsonSchema(value);
|
|
14048
15326
|
return [
|
|
@@ -14073,6 +15351,16 @@ function serializeEvalParameterstoParametersSchema(parameters) {
|
|
|
14073
15351
|
if (!defaultPromptData) {
|
|
14074
15352
|
required.push(name);
|
|
14075
15353
|
}
|
|
15354
|
+
} else if ("type" in value && value.type === "model") {
|
|
15355
|
+
properties[name] = {
|
|
15356
|
+
type: "string",
|
|
15357
|
+
"x-bt-type": "model",
|
|
15358
|
+
...value.description ? { description: value.description } : {},
|
|
15359
|
+
..."default" in value ? { default: value.default } : {}
|
|
15360
|
+
};
|
|
15361
|
+
if (!("default" in value)) {
|
|
15362
|
+
required.push(name);
|
|
15363
|
+
}
|
|
14076
15364
|
} else {
|
|
14077
15365
|
const schemaObj = zodToJsonSchema(value);
|
|
14078
15366
|
properties[name] = schemaObj;
|