braintrust 3.3.0 → 3.4.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 +53 -9
- package/dev/dist/index.d.ts +53 -9
- package/dev/dist/index.js +1839 -1298
- package/dev/dist/index.mjs +1503 -962
- package/dist/auto-instrumentations/bundler/esbuild.cjs +270 -23
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/rollup.cjs +270 -23
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +270 -23
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack.cjs +270 -23
- package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
- package/dist/auto-instrumentations/{chunk-OLOPGWTJ.mjs → chunk-D5ZPIUEL.mjs} +1 -1
- package/dist/auto-instrumentations/chunk-LVWWLUMN.mjs +535 -0
- package/dist/auto-instrumentations/hook.mjs +306 -23
- package/dist/auto-instrumentations/index.cjs +270 -23
- 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/esm-hook.mjs +7 -8
- package/dist/browser.d.mts +474 -47
- package/dist/browser.d.ts +474 -47
- package/dist/browser.js +2258 -2095
- package/dist/browser.mjs +2258 -2095
- package/dist/cli.js +1817 -1232
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2188 -2027
- package/dist/edge-light.mjs +2188 -2027
- package/dist/index.d.mts +474 -47
- package/dist/index.d.ts +474 -47
- package/dist/index.js +2576 -2415
- package/dist/index.mjs +2259 -2098
- package/dist/instrumentation/index.d.mts +16 -22
- package/dist/instrumentation/index.d.ts +16 -22
- package/dist/instrumentation/index.js +1558 -1068
- package/dist/instrumentation/index.mjs +1558 -1068
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +2188 -2027
- package/dist/workerd.mjs +2188 -2027
- package/package.json +6 -3
- package/dist/auto-instrumentations/chunk-KVX7OFPD.mjs +0 -288
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,26 @@ var DefaultAsyncLocalStorage = class {
|
|
|
21
22
|
return void 0;
|
|
22
23
|
}
|
|
23
24
|
};
|
|
25
|
+
var DefaultTracingChannel = class {
|
|
26
|
+
hasSubscribers = false;
|
|
27
|
+
subscribe(_handlers) {
|
|
28
|
+
}
|
|
29
|
+
unsubscribe(_handlers) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
traceSync(fn, _message, thisArg, ...args) {
|
|
34
|
+
return fn.apply(thisArg, args);
|
|
35
|
+
}
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
+
tracePromise(fn, _message, thisArg, ...args) {
|
|
38
|
+
return Promise.resolve(fn.apply(thisArg, args));
|
|
39
|
+
}
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
|
+
traceCallback(fn, _position, _message, thisArg, ...args) {
|
|
42
|
+
return fn.apply(thisArg, args);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
24
45
|
var iso = {
|
|
25
46
|
buildType: "unknown",
|
|
26
47
|
// Will be set by configureBrowser() or configureNode()
|
|
@@ -29,6 +50,8 @@ var iso = {
|
|
|
29
50
|
getEnv: (_name) => void 0,
|
|
30
51
|
getCallerLocation: () => void 0,
|
|
31
52
|
newAsyncLocalStorage: () => new DefaultAsyncLocalStorage(),
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
|
+
newTracingChannel: (_nameOrChannels) => new DefaultTracingChannel(),
|
|
32
55
|
processOn: (_0, _1) => {
|
|
33
56
|
},
|
|
34
57
|
basename: (filepath) => filepath.split(/[\\/]/).pop() || filepath,
|
|
@@ -36,6 +59,111 @@ var iso = {
|
|
|
36
59
|
};
|
|
37
60
|
var isomorph_default = iso;
|
|
38
61
|
|
|
62
|
+
// src/debug-logger.ts
|
|
63
|
+
var PREFIX = "[braintrust]";
|
|
64
|
+
var DEBUG_LOG_LEVEL_SYMBOL = Symbol.for("braintrust-debug-log-level");
|
|
65
|
+
var LOG_LEVEL_PRIORITY = {
|
|
66
|
+
error: 0,
|
|
67
|
+
warn: 1,
|
|
68
|
+
info: 2,
|
|
69
|
+
debug: 3
|
|
70
|
+
};
|
|
71
|
+
var hasWarnedAboutInvalidEnvValue = false;
|
|
72
|
+
var debugLogStateResolver = void 0;
|
|
73
|
+
function warnInvalidEnvValue(value) {
|
|
74
|
+
if (hasWarnedAboutInvalidEnvValue) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
hasWarnedAboutInvalidEnvValue = true;
|
|
78
|
+
console.warn(
|
|
79
|
+
PREFIX,
|
|
80
|
+
`Invalid BRAINTRUST_DEBUG_LOG_LEVEL value "${value}". Expected "error", "warn", "info", or "debug".`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
function normalizeDebugLogLevelOption(option) {
|
|
84
|
+
if (option === false) {
|
|
85
|
+
return void 0;
|
|
86
|
+
}
|
|
87
|
+
if (option === "error" || option === "warn" || option === "info" || option === "debug") {
|
|
88
|
+
return option;
|
|
89
|
+
}
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Invalid debugLogLevel value "${option}". Expected false, "error", "warn", "info", or "debug".`
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
function parseDebugLogLevelEnv(value) {
|
|
95
|
+
if (!value) {
|
|
96
|
+
return void 0;
|
|
97
|
+
}
|
|
98
|
+
if (value === "error" || value === "warn" || value === "info" || value === "debug") {
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
warnInvalidEnvValue(value);
|
|
102
|
+
return void 0;
|
|
103
|
+
}
|
|
104
|
+
function getEnvDebugLogLevel() {
|
|
105
|
+
return parseDebugLogLevelEnv(isomorph_default.getEnv("BRAINTRUST_DEBUG_LOG_LEVEL"));
|
|
106
|
+
}
|
|
107
|
+
function setGlobalDebugLogLevel(level) {
|
|
108
|
+
globalThis[DEBUG_LOG_LEVEL_SYMBOL] = level;
|
|
109
|
+
}
|
|
110
|
+
function setDebugLogStateResolver(resolver) {
|
|
111
|
+
debugLogStateResolver = resolver;
|
|
112
|
+
}
|
|
113
|
+
function resolveDebugLogLevel(state) {
|
|
114
|
+
const stateLevel = state?.getDebugLogLevel?.();
|
|
115
|
+
const hasStateOverride = state?.hasDebugLogLevelOverride?.() ?? false;
|
|
116
|
+
if (hasStateOverride) {
|
|
117
|
+
return stateLevel;
|
|
118
|
+
}
|
|
119
|
+
const globalLevel = (
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
121
|
+
globalThis[DEBUG_LOG_LEVEL_SYMBOL]
|
|
122
|
+
);
|
|
123
|
+
if (globalLevel !== void 0) {
|
|
124
|
+
return globalLevel === false ? void 0 : globalLevel;
|
|
125
|
+
}
|
|
126
|
+
return getEnvDebugLogLevel();
|
|
127
|
+
}
|
|
128
|
+
function emit(method, state, args) {
|
|
129
|
+
const level = resolveDebugLogLevel(state);
|
|
130
|
+
if (!level || LOG_LEVEL_PRIORITY[method] > LOG_LEVEL_PRIORITY[level]) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (method === "info") {
|
|
134
|
+
console.log(PREFIX, ...args);
|
|
135
|
+
} else if (method === "debug") {
|
|
136
|
+
console.debug(PREFIX, ...args);
|
|
137
|
+
} else if (method === "warn") {
|
|
138
|
+
console.warn(PREFIX, ...args);
|
|
139
|
+
} else {
|
|
140
|
+
console.error(PREFIX, ...args);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function createDebugLogger(state) {
|
|
144
|
+
const resolveState = () => state ?? debugLogStateResolver?.();
|
|
145
|
+
return {
|
|
146
|
+
info(...args) {
|
|
147
|
+
emit("info", resolveState(), args);
|
|
148
|
+
},
|
|
149
|
+
debug(...args) {
|
|
150
|
+
emit("debug", resolveState(), args);
|
|
151
|
+
},
|
|
152
|
+
warn(...args) {
|
|
153
|
+
emit("warn", resolveState(), args);
|
|
154
|
+
},
|
|
155
|
+
error(...args) {
|
|
156
|
+
emit("error", resolveState(), args);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
var debugLogger = {
|
|
161
|
+
...createDebugLogger(),
|
|
162
|
+
forState(state) {
|
|
163
|
+
return createDebugLogger(state);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
39
167
|
// src/gitutil.ts
|
|
40
168
|
import { simpleGit } from "simple-git";
|
|
41
169
|
var COMMON_BASE_BRANCHES = ["main", "master", "develop"];
|
|
@@ -116,7 +244,7 @@ async function getPastNAncestors(n = 1e3, remote = void 0) {
|
|
|
116
244
|
try {
|
|
117
245
|
ancestor = await getBaseBranchAncestor(remote);
|
|
118
246
|
} catch (e) {
|
|
119
|
-
|
|
247
|
+
debugLogger.warn(
|
|
120
248
|
"Skipping git metadata. This is likely because the repository has not been published to a remote yet.",
|
|
121
249
|
`${e}`
|
|
122
250
|
);
|
|
@@ -261,7 +389,7 @@ var Queue = class {
|
|
|
261
389
|
enforceSizeLimit = false;
|
|
262
390
|
constructor(maxSize) {
|
|
263
391
|
if (maxSize < 1) {
|
|
264
|
-
|
|
392
|
+
debugLogger.warn(
|
|
265
393
|
`maxSize ${maxSize} is <1, using default ${DEFAULT_QUEUE_SIZE}`
|
|
266
394
|
);
|
|
267
395
|
maxSize = DEFAULT_QUEUE_SIZE;
|
|
@@ -4482,7 +4610,10 @@ var loginSchema = z8.strictObject({
|
|
|
4482
4610
|
proxyUrl: z8.string(),
|
|
4483
4611
|
loginToken: z8.string(),
|
|
4484
4612
|
orgId: z8.string().nullish(),
|
|
4485
|
-
gitMetadataSettings: GitMetadataSettings.nullish()
|
|
4613
|
+
gitMetadataSettings: GitMetadataSettings.nullish(),
|
|
4614
|
+
debugLogLevel: z8.enum(["error", "warn", "info", "debug"]).optional(),
|
|
4615
|
+
// Distinguishes explicit false from unset so env fallback stays disabled after deserialization.
|
|
4616
|
+
debugLogLevelDisabled: z8.boolean().optional()
|
|
4486
4617
|
});
|
|
4487
4618
|
var stateNonce = 0;
|
|
4488
4619
|
var BraintrustState = class _BraintrustState {
|
|
@@ -4503,6 +4634,16 @@ var BraintrustState = class _BraintrustState {
|
|
|
4503
4634
|
this._bgLogger = new SyncLazyValue(
|
|
4504
4635
|
() => new HTTPBackgroundLogger(new LazyValue(defaultGetLogConn), loginParams)
|
|
4505
4636
|
);
|
|
4637
|
+
if (loginParams.debugLogLevel !== void 0) {
|
|
4638
|
+
this.debugLogLevelConfigured = true;
|
|
4639
|
+
this.debugLogLevel = normalizeDebugLogLevelOption(
|
|
4640
|
+
loginParams.debugLogLevel
|
|
4641
|
+
);
|
|
4642
|
+
setGlobalDebugLogLevel(this.debugLogLevel ?? false);
|
|
4643
|
+
} else {
|
|
4644
|
+
this.debugLogLevel = getEnvDebugLogLevel();
|
|
4645
|
+
setGlobalDebugLogLevel(void 0);
|
|
4646
|
+
}
|
|
4506
4647
|
this.resetLoginInfo();
|
|
4507
4648
|
const memoryCache = new LRUCache({
|
|
4508
4649
|
max: Number(isomorph_default.getEnv("BRAINTRUST_PROMPT_CACHE_MEMORY_MAX")) ?? 1 << 10
|
|
@@ -4547,6 +4688,8 @@ var BraintrustState = class _BraintrustState {
|
|
|
4547
4688
|
proxyUrl = null;
|
|
4548
4689
|
loggedIn = false;
|
|
4549
4690
|
gitMetadataSettings;
|
|
4691
|
+
debugLogLevel;
|
|
4692
|
+
debugLogLevelConfigured = false;
|
|
4550
4693
|
fetch = globalThis.fetch;
|
|
4551
4694
|
_appConn = null;
|
|
4552
4695
|
_apiConn = null;
|
|
@@ -4612,6 +4755,11 @@ var BraintrustState = class _BraintrustState {
|
|
|
4612
4755
|
this.proxyUrl = other.proxyUrl;
|
|
4613
4756
|
this.loggedIn = other.loggedIn;
|
|
4614
4757
|
this.gitMetadataSettings = other.gitMetadataSettings;
|
|
4758
|
+
this.debugLogLevel = other.debugLogLevel;
|
|
4759
|
+
this.debugLogLevelConfigured = other.debugLogLevelConfigured;
|
|
4760
|
+
setGlobalDebugLogLevel(
|
|
4761
|
+
this.debugLogLevelConfigured ? this.debugLogLevel ?? false : void 0
|
|
4762
|
+
);
|
|
4615
4763
|
this._appConn = other._appConn;
|
|
4616
4764
|
this._apiConn = other._apiConn;
|
|
4617
4765
|
this.loginReplaceApiConn(this.apiConn());
|
|
@@ -4636,7 +4784,9 @@ var BraintrustState = class _BraintrustState {
|
|
|
4636
4784
|
orgName: this.orgName,
|
|
4637
4785
|
apiUrl: this.apiUrl,
|
|
4638
4786
|
proxyUrl: this.proxyUrl,
|
|
4639
|
-
gitMetadataSettings: this.gitMetadataSettings
|
|
4787
|
+
gitMetadataSettings: this.gitMetadataSettings,
|
|
4788
|
+
...this.debugLogLevel ? { debugLogLevel: this.debugLogLevel } : {},
|
|
4789
|
+
...this.debugLogLevelConfigured && !this.debugLogLevel ? { debugLogLevelDisabled: true } : {}
|
|
4640
4790
|
};
|
|
4641
4791
|
}
|
|
4642
4792
|
static deserialize(serialized, opts) {
|
|
@@ -4663,6 +4813,10 @@ var BraintrustState = class _BraintrustState {
|
|
|
4663
4813
|
state.proxyConn().set_token(state.loginToken);
|
|
4664
4814
|
}
|
|
4665
4815
|
state.loggedIn = true;
|
|
4816
|
+
state.debugLogLevelConfigured = "debugLogLevel" in serializedParsed.data || !!serializedParsed.data.debugLogLevelDisabled;
|
|
4817
|
+
setGlobalDebugLogLevel(
|
|
4818
|
+
state.debugLogLevelConfigured ? state.debugLogLevel ?? false : void 0
|
|
4819
|
+
);
|
|
4666
4820
|
state.loginReplaceApiConn(state.apiConn());
|
|
4667
4821
|
return state;
|
|
4668
4822
|
}
|
|
@@ -4675,7 +4829,22 @@ var BraintrustState = class _BraintrustState {
|
|
|
4675
4829
|
setMaskingFunction(maskingFunction) {
|
|
4676
4830
|
this.bgLogger().setMaskingFunction(maskingFunction);
|
|
4677
4831
|
}
|
|
4832
|
+
setDebugLogLevel(option) {
|
|
4833
|
+
if (option === void 0) {
|
|
4834
|
+
return;
|
|
4835
|
+
}
|
|
4836
|
+
this.debugLogLevelConfigured = true;
|
|
4837
|
+
this.debugLogLevel = normalizeDebugLogLevelOption(option);
|
|
4838
|
+
setGlobalDebugLogLevel(this.debugLogLevel ?? false);
|
|
4839
|
+
}
|
|
4840
|
+
getDebugLogLevel() {
|
|
4841
|
+
return this.debugLogLevel;
|
|
4842
|
+
}
|
|
4843
|
+
hasDebugLogLevelOverride() {
|
|
4844
|
+
return this.debugLogLevelConfigured;
|
|
4845
|
+
}
|
|
4678
4846
|
async login(loginParams) {
|
|
4847
|
+
this.setDebugLogLevel(loginParams.debugLogLevel);
|
|
4679
4848
|
if (this.apiUrl && !loginParams.forceLogin) {
|
|
4680
4849
|
return;
|
|
4681
4850
|
}
|
|
@@ -4786,6 +4955,7 @@ function _internalSetInitialState() {
|
|
|
4786
4955
|
_globalState = existing;
|
|
4787
4956
|
}
|
|
4788
4957
|
var _internalGetGlobalState = () => _globalState;
|
|
4958
|
+
setDebugLogStateResolver(() => _internalGetGlobalState());
|
|
4789
4959
|
var FailedHTTPResponse = class extends Error {
|
|
4790
4960
|
status;
|
|
4791
4961
|
text;
|
|
@@ -4900,7 +5070,7 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
4900
5070
|
return await resp.json();
|
|
4901
5071
|
} catch (e) {
|
|
4902
5072
|
if (i < tries - 1) {
|
|
4903
|
-
|
|
5073
|
+
debugLogger.debug(
|
|
4904
5074
|
`Retrying API request ${object_type} ${JSON.stringify(args)} ${e.status} ${e.text}`
|
|
4905
5075
|
);
|
|
4906
5076
|
continue;
|
|
@@ -5112,7 +5282,7 @@ with a Blob/ArrayBuffer, or run the program on Node.js.`
|
|
|
5112
5282
|
try {
|
|
5113
5283
|
statSync2(data);
|
|
5114
5284
|
} catch (e) {
|
|
5115
|
-
|
|
5285
|
+
debugLogger.warn(`Failed to read file: ${e}`);
|
|
5116
5286
|
}
|
|
5117
5287
|
}
|
|
5118
5288
|
};
|
|
@@ -5824,7 +5994,7 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
|
5824
5994
|
this.queueDropLoggingPeriod = queueDropLoggingPeriodEnv;
|
|
5825
5995
|
}
|
|
5826
5996
|
if (isomorph_default.getEnv("BRAINTRUST_LOG_FLUSH_CHUNK_SIZE")) {
|
|
5827
|
-
|
|
5997
|
+
debugLogger.warn(
|
|
5828
5998
|
"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
5999
|
);
|
|
5830
6000
|
}
|
|
@@ -5886,7 +6056,10 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
|
5886
6056
|
const versionInfo = await conn.get_json("version");
|
|
5887
6057
|
serverLimit = z8.object({ logs3_payload_max_bytes: z8.number().nullish() }).parse(versionInfo).logs3_payload_max_bytes ?? null;
|
|
5888
6058
|
} catch (e) {
|
|
5889
|
-
|
|
6059
|
+
debugLogger.warn(
|
|
6060
|
+
"Failed to fetch version info for payload limit:",
|
|
6061
|
+
e
|
|
6062
|
+
);
|
|
5890
6063
|
}
|
|
5891
6064
|
const validServerLimit = serverLimit !== null && serverLimit > 0 ? serverLimit : null;
|
|
5892
6065
|
const canUseOverflow = validServerLimit !== null;
|
|
@@ -6030,16 +6203,16 @@ var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
|
6030
6203
|
if (isRetrying) {
|
|
6031
6204
|
errmsg += ". Retrying";
|
|
6032
6205
|
}
|
|
6033
|
-
|
|
6206
|
+
debugLogger.warn(errmsg);
|
|
6034
6207
|
if (!isRetrying) {
|
|
6035
|
-
|
|
6208
|
+
debugLogger.warn(
|
|
6036
6209
|
`Failed to construct log records to flush after ${this.numTries} attempts. Dropping batch`
|
|
6037
6210
|
);
|
|
6038
6211
|
throw e;
|
|
6039
6212
|
} else {
|
|
6040
|
-
|
|
6213
|
+
debugLogger.warn(e);
|
|
6041
6214
|
const sleepTimeS = BACKGROUND_LOGGER_BASE_SLEEP_TIME_S * 2 ** i;
|
|
6042
|
-
|
|
6215
|
+
debugLogger.info(`Sleeping for ${sleepTimeS}s`);
|
|
6043
6216
|
await new Promise(
|
|
6044
6217
|
(resolve) => setTimeout(resolve, sleepTimeS * 1e3)
|
|
6045
6218
|
);
|
|
@@ -6140,15 +6313,15 @@ Error: ${errorText}`;
|
|
|
6140
6313
|
this.logFailedPayloadsDir();
|
|
6141
6314
|
}
|
|
6142
6315
|
if (!isRetrying) {
|
|
6143
|
-
|
|
6316
|
+
debugLogger.warn(
|
|
6144
6317
|
`log request failed after ${this.numTries} retries. Dropping batch`
|
|
6145
6318
|
);
|
|
6146
6319
|
throw new Error(errMsg);
|
|
6147
6320
|
} else {
|
|
6148
|
-
|
|
6321
|
+
debugLogger.warn(errMsg);
|
|
6149
6322
|
if (isRetrying) {
|
|
6150
6323
|
const sleepTimeS = BACKGROUND_LOGGER_BASE_SLEEP_TIME_S * 2 ** i;
|
|
6151
|
-
|
|
6324
|
+
debugLogger.info(`Sleeping for ${sleepTimeS}s`);
|
|
6152
6325
|
await new Promise(
|
|
6153
6326
|
(resolve) => setTimeout(resolve, sleepTimeS * 1e3)
|
|
6154
6327
|
);
|
|
@@ -6163,7 +6336,7 @@ Error: ${errorText}`;
|
|
|
6163
6336
|
this.queueDropLoggingState.numDropped += numItems;
|
|
6164
6337
|
const timeNow = getCurrentUnixTimestamp();
|
|
6165
6338
|
if (timeNow - this.queueDropLoggingState.lastLoggedTimestamp > this.queueDropLoggingPeriod) {
|
|
6166
|
-
|
|
6339
|
+
debugLogger.warn(
|
|
6167
6340
|
`Dropped ${this.queueDropLoggingState.numDropped} elements due to full queue`
|
|
6168
6341
|
);
|
|
6169
6342
|
if (this.failedPublishPayloadsDir) {
|
|
@@ -6195,7 +6368,7 @@ Error: ${errorText}`;
|
|
|
6195
6368
|
await _HTTPBackgroundLogger.writePayloadToDir({ payloadDir, payload });
|
|
6196
6369
|
}
|
|
6197
6370
|
} catch (e) {
|
|
6198
|
-
|
|
6371
|
+
debugLogger.error(e);
|
|
6199
6372
|
}
|
|
6200
6373
|
}
|
|
6201
6374
|
static async writePayloadToDir({
|
|
@@ -6203,7 +6376,7 @@ Error: ${errorText}`;
|
|
|
6203
6376
|
payload
|
|
6204
6377
|
}) {
|
|
6205
6378
|
if (!(isomorph_default.pathJoin && isomorph_default.mkdir && isomorph_default.writeFile)) {
|
|
6206
|
-
|
|
6379
|
+
debugLogger.warn(
|
|
6207
6380
|
"Cannot dump payloads: filesystem-operations not supported on this platform"
|
|
6208
6381
|
);
|
|
6209
6382
|
return;
|
|
@@ -6216,7 +6389,7 @@ Error: ${errorText}`;
|
|
|
6216
6389
|
await isomorph_default.mkdir(payloadDir, { recursive: true });
|
|
6217
6390
|
await isomorph_default.writeFile(payloadFile, payload);
|
|
6218
6391
|
} catch (e) {
|
|
6219
|
-
|
|
6392
|
+
debugLogger.error(
|
|
6220
6393
|
`Failed to write failed payload to output file ${payloadFile}:
|
|
6221
6394
|
`,
|
|
6222
6395
|
e
|
|
@@ -6247,7 +6420,9 @@ Error: ${errorText}`;
|
|
|
6247
6420
|
}
|
|
6248
6421
|
}
|
|
6249
6422
|
logFailedPayloadsDir() {
|
|
6250
|
-
|
|
6423
|
+
debugLogger.warn(
|
|
6424
|
+
`Logging failed payloads to ${this.failedPublishPayloadsDir}`
|
|
6425
|
+
);
|
|
6251
6426
|
}
|
|
6252
6427
|
// Should only be called by BraintrustState.
|
|
6253
6428
|
internalReplaceApiConn(apiConn) {
|
|
@@ -6412,9 +6587,7 @@ function init(projectOrOptions, optionalOptions) {
|
|
|
6412
6587
|
break;
|
|
6413
6588
|
} catch (e) {
|
|
6414
6589
|
if (args["base_experiment"] && `${"data" in e && e.data}`.includes("base experiment")) {
|
|
6415
|
-
|
|
6416
|
-
`Base experiment ${args["base_experiment"]} not found.`
|
|
6417
|
-
);
|
|
6590
|
+
debugLogger.forState(state).warn(`Base experiment ${args["base_experiment"]} not found.`);
|
|
6418
6591
|
delete args["base_experiment"];
|
|
6419
6592
|
} else {
|
|
6420
6593
|
throw e;
|
|
@@ -6556,7 +6729,11 @@ async function computeLoggerMetadata(state, {
|
|
|
6556
6729
|
}
|
|
6557
6730
|
async function login(options = {}) {
|
|
6558
6731
|
const { forceLogin = false } = options || {};
|
|
6732
|
+
if (!_internalGetGlobalState()) {
|
|
6733
|
+
_internalSetInitialState();
|
|
6734
|
+
}
|
|
6559
6735
|
const state = _internalGetGlobalState();
|
|
6736
|
+
state.setDebugLogLevel(options.debugLogLevel);
|
|
6560
6737
|
if (state.loggedIn && !forceLogin) {
|
|
6561
6738
|
let checkUpdatedParam2 = function(varname, arg, orig) {
|
|
6562
6739
|
if (!isEmpty2(arg) && !isEmpty2(orig) && arg !== orig) {
|
|
@@ -6575,9 +6752,6 @@ async function login(options = {}) {
|
|
|
6575
6752
|
checkUpdatedParam2("orgName", options.orgName, state.orgName);
|
|
6576
6753
|
return state;
|
|
6577
6754
|
}
|
|
6578
|
-
if (!state) {
|
|
6579
|
-
_internalSetInitialState();
|
|
6580
|
-
}
|
|
6581
6755
|
await state.login(options);
|
|
6582
6756
|
return state;
|
|
6583
6757
|
}
|
|
@@ -6989,7 +7163,14 @@ var ObjectFetcher = class {
|
|
|
6989
7163
|
async *fetchRecordsFromApi(batchSize) {
|
|
6990
7164
|
const state = await this.getState();
|
|
6991
7165
|
const objectId = await this.id;
|
|
6992
|
-
const
|
|
7166
|
+
const batchLimit = batchSize ?? DEFAULT_FETCH_BATCH_SIZE;
|
|
7167
|
+
const internalLimit = this._internal_btql?.limit;
|
|
7168
|
+
const limit = batchSize !== void 0 ? batchSize : internalLimit ?? batchLimit;
|
|
7169
|
+
const internalBtqlWithoutReservedQueryKeys = Object.fromEntries(
|
|
7170
|
+
Object.entries(this._internal_btql ?? {}).filter(
|
|
7171
|
+
([key]) => key !== "cursor" && key !== "limit" && key !== "select" && key !== "from"
|
|
7172
|
+
)
|
|
7173
|
+
);
|
|
6993
7174
|
let cursor = void 0;
|
|
6994
7175
|
let iterations = 0;
|
|
6995
7176
|
while (true) {
|
|
@@ -6997,7 +7178,6 @@ var ObjectFetcher = class {
|
|
|
6997
7178
|
`btql`,
|
|
6998
7179
|
{
|
|
6999
7180
|
query: {
|
|
7000
|
-
...this._internal_btql,
|
|
7001
7181
|
select: [
|
|
7002
7182
|
{
|
|
7003
7183
|
op: "star"
|
|
@@ -7017,7 +7197,8 @@ var ObjectFetcher = class {
|
|
|
7017
7197
|
]
|
|
7018
7198
|
},
|
|
7019
7199
|
cursor,
|
|
7020
|
-
limit
|
|
7200
|
+
limit,
|
|
7201
|
+
...internalBtqlWithoutReservedQueryKeys
|
|
7021
7202
|
},
|
|
7022
7203
|
use_columnstore: false,
|
|
7023
7204
|
brainstore_realtime: true,
|
|
@@ -7290,7 +7471,7 @@ var Experiment2 = class extends ObjectFetcher {
|
|
|
7290
7471
|
scores = results["scores"];
|
|
7291
7472
|
metrics = results["metrics"];
|
|
7292
7473
|
} catch (e) {
|
|
7293
|
-
|
|
7474
|
+
debugLogger.forState(state).warn(
|
|
7294
7475
|
`Failed to fetch experiment scores and metrics: ${e}
|
|
7295
7476
|
|
|
7296
7477
|
View complete results in Braintrust or run experiment.summarize() again.`
|
|
@@ -7367,7 +7548,7 @@ View complete results in Braintrust or run experiment.summarize() again.`
|
|
|
7367
7548
|
* @deprecated This function is deprecated. You can simply remove it from your code.
|
|
7368
7549
|
*/
|
|
7369
7550
|
async close() {
|
|
7370
|
-
|
|
7551
|
+
debugLogger.forState(this.state).warn(
|
|
7371
7552
|
"close is deprecated and will be removed in a future version of braintrust. It is now a no-op and can be removed"
|
|
7372
7553
|
);
|
|
7373
7554
|
return this.id;
|
|
@@ -7564,8 +7745,8 @@ var SpanImpl = class _SpanImpl {
|
|
|
7564
7745
|
...serializableInternalData,
|
|
7565
7746
|
[IS_MERGE_FIELD]: this.isMerge
|
|
7566
7747
|
});
|
|
7567
|
-
if (partialRecord.metrics?.end) {
|
|
7568
|
-
this.loggedEndTime = partialRecord.metrics
|
|
7748
|
+
if (typeof partialRecord.metrics?.end === "number") {
|
|
7749
|
+
this.loggedEndTime = partialRecord.metrics.end;
|
|
7569
7750
|
}
|
|
7570
7751
|
if (this.parentObjectType === 1 /* EXPERIMENT */) {
|
|
7571
7752
|
const cachedSpan = {
|
|
@@ -7800,7 +7981,7 @@ var Dataset2 = class extends ObjectFetcher {
|
|
|
7800
7981
|
constructor(state, lazyMetadata, pinnedVersion, legacy, _internal_btql) {
|
|
7801
7982
|
const isLegacyDataset = legacy ?? DEFAULT_IS_LEGACY_DATASET;
|
|
7802
7983
|
if (isLegacyDataset) {
|
|
7803
|
-
|
|
7984
|
+
debugLogger.forState(state).warn(
|
|
7804
7985
|
`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
7986
|
);
|
|
7806
7987
|
}
|
|
@@ -8031,7 +8212,7 @@ var Dataset2 = class extends ObjectFetcher {
|
|
|
8031
8212
|
* @deprecated This function is deprecated. You can simply remove it from your code.
|
|
8032
8213
|
*/
|
|
8033
8214
|
async close() {
|
|
8034
|
-
|
|
8215
|
+
debugLogger.forState(this.state).warn(
|
|
8035
8216
|
"close is deprecated and will be removed in a future version of braintrust. It is now a no-op and can be removed"
|
|
8036
8217
|
);
|
|
8037
8218
|
return this.id;
|
|
@@ -8447,9 +8628,6 @@ var RemoteEvalParameters = class {
|
|
|
8447
8628
|
};
|
|
8448
8629
|
var TEST_API_KEY = "___TEST_API_KEY__THIS_IS_NOT_REAL___";
|
|
8449
8630
|
|
|
8450
|
-
// src/instrumentation/core/plugin.ts
|
|
8451
|
-
import { tracingChannel } from "dc-browser";
|
|
8452
|
-
|
|
8453
8631
|
// src/instrumentation/core/stream-patcher.ts
|
|
8454
8632
|
function isAsyncIterable(value) {
|
|
8455
8633
|
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
@@ -8465,7 +8643,7 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8465
8643
|
return stream;
|
|
8466
8644
|
}
|
|
8467
8645
|
const originalIteratorFn = stream[Symbol.asyncIterator];
|
|
8468
|
-
if (originalIteratorFn
|
|
8646
|
+
if ("__braintrust_patched" in originalIteratorFn && originalIteratorFn["__braintrust_patched"]) {
|
|
8469
8647
|
return stream;
|
|
8470
8648
|
}
|
|
8471
8649
|
try {
|
|
@@ -8506,7 +8684,10 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8506
8684
|
completed = true;
|
|
8507
8685
|
if (options.onError) {
|
|
8508
8686
|
try {
|
|
8509
|
-
options.onError(
|
|
8687
|
+
options.onError(
|
|
8688
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
8689
|
+
chunks
|
|
8690
|
+
);
|
|
8510
8691
|
} catch (handlerError) {
|
|
8511
8692
|
console.error("Error in stream onError handler:", handlerError);
|
|
8512
8693
|
}
|
|
@@ -8534,7 +8715,8 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8534
8715
|
iterator.throw = async function(...args) {
|
|
8535
8716
|
if (!completed) {
|
|
8536
8717
|
completed = true;
|
|
8537
|
-
const
|
|
8718
|
+
const rawError = args[0];
|
|
8719
|
+
const error = rawError instanceof Error ? rawError : new Error(String(rawError));
|
|
8538
8720
|
if (options.onError) {
|
|
8539
8721
|
try {
|
|
8540
8722
|
options.onError(error, chunks);
|
|
@@ -8548,7 +8730,9 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8548
8730
|
}
|
|
8549
8731
|
return iterator;
|
|
8550
8732
|
};
|
|
8551
|
-
patchedIteratorFn
|
|
8733
|
+
Object.defineProperty(patchedIteratorFn, "__braintrust_patched", {
|
|
8734
|
+
value: true
|
|
8735
|
+
});
|
|
8552
8736
|
stream[Symbol.asyncIterator] = patchedIteratorFn;
|
|
8553
8737
|
return stream;
|
|
8554
8738
|
} catch (error) {
|
|
@@ -8557,6 +8741,49 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
8557
8741
|
}
|
|
8558
8742
|
}
|
|
8559
8743
|
|
|
8744
|
+
// src/instrumentation/core/channel-tracing-utils.ts
|
|
8745
|
+
function hasChannelSpanInfo(value) {
|
|
8746
|
+
return isObject(value) && isObject(value.span_info);
|
|
8747
|
+
}
|
|
8748
|
+
function getChannelSpanInfo(event) {
|
|
8749
|
+
if (isObject(event.span_info)) {
|
|
8750
|
+
return event.span_info;
|
|
8751
|
+
}
|
|
8752
|
+
const firstArg = event.arguments?.[0];
|
|
8753
|
+
if (hasChannelSpanInfo(firstArg)) {
|
|
8754
|
+
return firstArg.span_info;
|
|
8755
|
+
}
|
|
8756
|
+
return void 0;
|
|
8757
|
+
}
|
|
8758
|
+
function buildStartSpanArgs(config, event) {
|
|
8759
|
+
const spanInfo = getChannelSpanInfo(event);
|
|
8760
|
+
const spanAttributes = {
|
|
8761
|
+
type: config.type
|
|
8762
|
+
};
|
|
8763
|
+
if (isObject(spanInfo?.spanAttributes)) {
|
|
8764
|
+
mergeDicts(spanAttributes, spanInfo.spanAttributes);
|
|
8765
|
+
}
|
|
8766
|
+
return {
|
|
8767
|
+
name: typeof spanInfo?.name === "string" && spanInfo.name ? spanInfo.name : config.name,
|
|
8768
|
+
spanAttributes,
|
|
8769
|
+
spanInfoMetadata: isObject(spanInfo?.metadata) ? spanInfo.metadata : void 0
|
|
8770
|
+
};
|
|
8771
|
+
}
|
|
8772
|
+
function mergeInputMetadata(metadata, spanInfoMetadata) {
|
|
8773
|
+
if (!spanInfoMetadata) {
|
|
8774
|
+
return isObject(metadata) ? (
|
|
8775
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
8776
|
+
metadata
|
|
8777
|
+
) : void 0;
|
|
8778
|
+
}
|
|
8779
|
+
const mergedMetadata = {};
|
|
8780
|
+
mergeDicts(mergedMetadata, spanInfoMetadata);
|
|
8781
|
+
if (isObject(metadata)) {
|
|
8782
|
+
mergeDicts(mergedMetadata, metadata);
|
|
8783
|
+
}
|
|
8784
|
+
return mergedMetadata;
|
|
8785
|
+
}
|
|
8786
|
+
|
|
8560
8787
|
// src/instrumentation/core/plugin.ts
|
|
8561
8788
|
var BasePlugin = class {
|
|
8562
8789
|
enabled = false;
|
|
@@ -8588,23 +8815,25 @@ var BasePlugin = class {
|
|
|
8588
8815
|
* @param handlers - Event handlers
|
|
8589
8816
|
*/
|
|
8590
8817
|
subscribe(channelName, handlers) {
|
|
8591
|
-
const
|
|
8592
|
-
|
|
8818
|
+
const channel2 = isomorph_default.newTracingChannel(channelName);
|
|
8819
|
+
channel2.subscribe(handlers);
|
|
8593
8820
|
}
|
|
8594
8821
|
/**
|
|
8595
8822
|
* Subscribe to a channel for async methods (non-streaming).
|
|
8596
8823
|
* Creates a span and logs input/output/metrics.
|
|
8597
8824
|
*/
|
|
8598
8825
|
subscribeToChannel(channelName, config) {
|
|
8599
|
-
const
|
|
8826
|
+
const channel2 = isomorph_default.newTracingChannel(channelName);
|
|
8600
8827
|
const spans = /* @__PURE__ */ new WeakMap();
|
|
8601
8828
|
const handlers = {
|
|
8602
8829
|
start: (event) => {
|
|
8830
|
+
const { name, spanAttributes, spanInfoMetadata } = buildStartSpanArgs(
|
|
8831
|
+
config,
|
|
8832
|
+
event
|
|
8833
|
+
);
|
|
8603
8834
|
const span = startSpan({
|
|
8604
|
-
name
|
|
8605
|
-
spanAttributes
|
|
8606
|
-
type: config.type
|
|
8607
|
-
}
|
|
8835
|
+
name,
|
|
8836
|
+
spanAttributes
|
|
8608
8837
|
});
|
|
8609
8838
|
const startTime = getCurrentUnixTimestamp();
|
|
8610
8839
|
spans.set(event, { span, startTime });
|
|
@@ -8612,7 +8841,7 @@ var BasePlugin = class {
|
|
|
8612
8841
|
const { input, metadata } = config.extractInput(event.arguments);
|
|
8613
8842
|
span.log({
|
|
8614
8843
|
input,
|
|
8615
|
-
metadata
|
|
8844
|
+
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
8616
8845
|
});
|
|
8617
8846
|
} catch (error) {
|
|
8618
8847
|
console.error(`Error extracting input for ${channelName}:`, error);
|
|
@@ -8625,10 +8854,12 @@ var BasePlugin = class {
|
|
|
8625
8854
|
}
|
|
8626
8855
|
const { span, startTime } = spanData;
|
|
8627
8856
|
try {
|
|
8628
|
-
const output = config.extractOutput(event.result);
|
|
8629
|
-
const metrics = config.extractMetrics(event.result, startTime);
|
|
8857
|
+
const output = config.extractOutput(event.result, event);
|
|
8858
|
+
const metrics = config.extractMetrics(event.result, startTime, event);
|
|
8859
|
+
const metadata = config.extractMetadata?.(event.result, event);
|
|
8630
8860
|
span.log({
|
|
8631
8861
|
output,
|
|
8862
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
8632
8863
|
metrics
|
|
8633
8864
|
});
|
|
8634
8865
|
} catch (error) {
|
|
@@ -8651,9 +8882,9 @@ var BasePlugin = class {
|
|
|
8651
8882
|
spans.delete(event);
|
|
8652
8883
|
}
|
|
8653
8884
|
};
|
|
8654
|
-
|
|
8885
|
+
channel2.subscribe(handlers);
|
|
8655
8886
|
this.unsubscribers.push(() => {
|
|
8656
|
-
|
|
8887
|
+
channel2.unsubscribe(handlers);
|
|
8657
8888
|
});
|
|
8658
8889
|
}
|
|
8659
8890
|
/**
|
|
@@ -8661,15 +8892,17 @@ var BasePlugin = class {
|
|
|
8661
8892
|
* Handles both streaming and non-streaming responses.
|
|
8662
8893
|
*/
|
|
8663
8894
|
subscribeToStreamingChannel(channelName, config) {
|
|
8664
|
-
const
|
|
8895
|
+
const channel2 = isomorph_default.newTracingChannel(channelName);
|
|
8665
8896
|
const spans = /* @__PURE__ */ new WeakMap();
|
|
8666
8897
|
const handlers = {
|
|
8667
8898
|
start: (event) => {
|
|
8899
|
+
const { name, spanAttributes, spanInfoMetadata } = buildStartSpanArgs(
|
|
8900
|
+
config,
|
|
8901
|
+
event
|
|
8902
|
+
);
|
|
8668
8903
|
const span = startSpan({
|
|
8669
|
-
name
|
|
8670
|
-
spanAttributes
|
|
8671
|
-
type: config.type
|
|
8672
|
-
}
|
|
8904
|
+
name,
|
|
8905
|
+
spanAttributes
|
|
8673
8906
|
});
|
|
8674
8907
|
const startTime = getCurrentUnixTimestamp();
|
|
8675
8908
|
spans.set(event, { span, startTime });
|
|
@@ -8677,7 +8910,7 @@ var BasePlugin = class {
|
|
|
8677
8910
|
const { input, metadata } = config.extractInput(event.arguments);
|
|
8678
8911
|
span.log({
|
|
8679
8912
|
input,
|
|
8680
|
-
metadata
|
|
8913
|
+
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
8681
8914
|
});
|
|
8682
8915
|
} catch (error) {
|
|
8683
8916
|
console.error(`Error extracting input for ${channelName}:`, error);
|
|
@@ -8690,24 +8923,39 @@ var BasePlugin = class {
|
|
|
8690
8923
|
}
|
|
8691
8924
|
const { span, startTime } = spanData;
|
|
8692
8925
|
if (isAsyncIterable(event.result)) {
|
|
8926
|
+
let firstChunkTime;
|
|
8693
8927
|
patchStreamIfNeeded(event.result, {
|
|
8928
|
+
onChunk: () => {
|
|
8929
|
+
if (firstChunkTime === void 0) {
|
|
8930
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
8931
|
+
}
|
|
8932
|
+
},
|
|
8694
8933
|
onComplete: (chunks) => {
|
|
8695
8934
|
try {
|
|
8696
8935
|
let output;
|
|
8697
8936
|
let metrics;
|
|
8937
|
+
let metadata;
|
|
8698
8938
|
if (config.aggregateChunks) {
|
|
8699
|
-
const aggregated = config.aggregateChunks(
|
|
8939
|
+
const aggregated = config.aggregateChunks(
|
|
8940
|
+
chunks,
|
|
8941
|
+
event.result,
|
|
8942
|
+
event
|
|
8943
|
+
);
|
|
8700
8944
|
output = aggregated.output;
|
|
8701
8945
|
metrics = aggregated.metrics;
|
|
8946
|
+
metadata = aggregated.metadata;
|
|
8702
8947
|
} else {
|
|
8703
|
-
output = config.extractOutput(chunks);
|
|
8704
|
-
metrics = config.extractMetrics(chunks, startTime);
|
|
8948
|
+
output = config.extractOutput(chunks, event);
|
|
8949
|
+
metrics = config.extractMetrics(chunks, startTime, event);
|
|
8705
8950
|
}
|
|
8706
|
-
if (
|
|
8951
|
+
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
8952
|
+
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
8953
|
+
} else if (metrics.time_to_first_token === void 0 && chunks.length > 0) {
|
|
8707
8954
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
8708
8955
|
}
|
|
8709
8956
|
span.log({
|
|
8710
8957
|
output,
|
|
8958
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
8711
8959
|
metrics
|
|
8712
8960
|
});
|
|
8713
8961
|
} catch (error) {
|
|
@@ -8728,10 +8976,16 @@ var BasePlugin = class {
|
|
|
8728
8976
|
});
|
|
8729
8977
|
} else {
|
|
8730
8978
|
try {
|
|
8731
|
-
const output = config.extractOutput(event.result);
|
|
8732
|
-
const
|
|
8979
|
+
const output = config.extractOutput(event.result, event);
|
|
8980
|
+
const metadata = config.extractMetadata ? config.extractMetadata(event.result, event) : void 0;
|
|
8981
|
+
const metrics = config.extractMetrics(
|
|
8982
|
+
event.result,
|
|
8983
|
+
startTime,
|
|
8984
|
+
event
|
|
8985
|
+
);
|
|
8733
8986
|
span.log({
|
|
8734
8987
|
output,
|
|
8988
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
8735
8989
|
metrics
|
|
8736
8990
|
});
|
|
8737
8991
|
} catch (error) {
|
|
@@ -8755,9 +9009,9 @@ var BasePlugin = class {
|
|
|
8755
9009
|
spans.delete(event);
|
|
8756
9010
|
}
|
|
8757
9011
|
};
|
|
8758
|
-
|
|
9012
|
+
channel2.subscribe(handlers);
|
|
8759
9013
|
this.unsubscribers.push(() => {
|
|
8760
|
-
|
|
9014
|
+
channel2.unsubscribe(handlers);
|
|
8761
9015
|
});
|
|
8762
9016
|
}
|
|
8763
9017
|
/**
|
|
@@ -8765,15 +9019,17 @@ var BasePlugin = class {
|
|
|
8765
9019
|
* Used for methods like beta.chat.completions.stream() and responses.stream().
|
|
8766
9020
|
*/
|
|
8767
9021
|
subscribeToSyncStreamChannel(channelName, config) {
|
|
8768
|
-
const
|
|
9022
|
+
const channel2 = isomorph_default.newTracingChannel(channelName);
|
|
8769
9023
|
const spans = /* @__PURE__ */ new WeakMap();
|
|
8770
9024
|
const handlers = {
|
|
8771
9025
|
start: (event) => {
|
|
9026
|
+
const { name, spanAttributes, spanInfoMetadata } = buildStartSpanArgs(
|
|
9027
|
+
config,
|
|
9028
|
+
event
|
|
9029
|
+
);
|
|
8772
9030
|
const span = startSpan({
|
|
8773
|
-
name
|
|
8774
|
-
spanAttributes
|
|
8775
|
-
type: config.type
|
|
8776
|
-
}
|
|
9031
|
+
name,
|
|
9032
|
+
spanAttributes
|
|
8777
9033
|
});
|
|
8778
9034
|
const startTime = getCurrentUnixTimestamp();
|
|
8779
9035
|
spans.set(event, { span, startTime });
|
|
@@ -8781,7 +9037,7 @@ var BasePlugin = class {
|
|
|
8781
9037
|
const { input, metadata } = config.extractInput(event.arguments);
|
|
8782
9038
|
span.log({
|
|
8783
9039
|
input,
|
|
8784
|
-
metadata
|
|
9040
|
+
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
8785
9041
|
});
|
|
8786
9042
|
} catch (error) {
|
|
8787
9043
|
console.error(`Error extracting input for ${channelName}:`, error);
|
|
@@ -8865,13 +9121,335 @@ var BasePlugin = class {
|
|
|
8865
9121
|
spans.delete(event);
|
|
8866
9122
|
}
|
|
8867
9123
|
};
|
|
8868
|
-
|
|
9124
|
+
channel2.subscribe(handlers);
|
|
8869
9125
|
this.unsubscribers.push(() => {
|
|
8870
|
-
|
|
9126
|
+
channel2.unsubscribe(handlers);
|
|
8871
9127
|
});
|
|
8872
9128
|
}
|
|
8873
9129
|
};
|
|
8874
9130
|
|
|
9131
|
+
// src/instrumentation/core/channel-tracing.ts
|
|
9132
|
+
function isSyncStreamLike(value) {
|
|
9133
|
+
return !!value && typeof value === "object" && typeof value.on === "function";
|
|
9134
|
+
}
|
|
9135
|
+
function hasChoices(value) {
|
|
9136
|
+
return !!value && typeof value === "object" && "choices" in value;
|
|
9137
|
+
}
|
|
9138
|
+
function normalizeMetadata(metadata) {
|
|
9139
|
+
return isObject(metadata) ? metadata : void 0;
|
|
9140
|
+
}
|
|
9141
|
+
function startSpanForEvent(config, event, channelName) {
|
|
9142
|
+
const { name, spanAttributes, spanInfoMetadata } = buildStartSpanArgs(
|
|
9143
|
+
config,
|
|
9144
|
+
event
|
|
9145
|
+
);
|
|
9146
|
+
const span = startSpan({
|
|
9147
|
+
name,
|
|
9148
|
+
spanAttributes
|
|
9149
|
+
});
|
|
9150
|
+
const startTime = getCurrentUnixTimestamp();
|
|
9151
|
+
try {
|
|
9152
|
+
const { input, metadata } = config.extractInput(event.arguments);
|
|
9153
|
+
span.log({
|
|
9154
|
+
input,
|
|
9155
|
+
metadata: mergeInputMetadata(metadata, spanInfoMetadata)
|
|
9156
|
+
});
|
|
9157
|
+
} catch (error) {
|
|
9158
|
+
console.error(`Error extracting input for ${channelName}:`, error);
|
|
9159
|
+
}
|
|
9160
|
+
return { span, startTime };
|
|
9161
|
+
}
|
|
9162
|
+
function logErrorAndEnd(states, event) {
|
|
9163
|
+
const spanData = states.get(event);
|
|
9164
|
+
if (!spanData) {
|
|
9165
|
+
return;
|
|
9166
|
+
}
|
|
9167
|
+
spanData.span.log({
|
|
9168
|
+
error: event.error.message
|
|
9169
|
+
});
|
|
9170
|
+
spanData.span.end();
|
|
9171
|
+
states.delete(event);
|
|
9172
|
+
}
|
|
9173
|
+
function traceAsyncChannel(channel2, config) {
|
|
9174
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
9175
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
9176
|
+
const channelName = channel2.channelName;
|
|
9177
|
+
const handlers = {
|
|
9178
|
+
start: (event) => {
|
|
9179
|
+
states.set(
|
|
9180
|
+
event,
|
|
9181
|
+
startSpanForEvent(
|
|
9182
|
+
config,
|
|
9183
|
+
event,
|
|
9184
|
+
channelName
|
|
9185
|
+
)
|
|
9186
|
+
);
|
|
9187
|
+
},
|
|
9188
|
+
asyncEnd: (event) => {
|
|
9189
|
+
const spanData = states.get(event);
|
|
9190
|
+
if (!spanData) {
|
|
9191
|
+
return;
|
|
9192
|
+
}
|
|
9193
|
+
const asyncEndEvent = event;
|
|
9194
|
+
const { span, startTime } = spanData;
|
|
9195
|
+
try {
|
|
9196
|
+
const output = config.extractOutput(
|
|
9197
|
+
asyncEndEvent.result,
|
|
9198
|
+
asyncEndEvent
|
|
9199
|
+
);
|
|
9200
|
+
const metrics = config.extractMetrics(
|
|
9201
|
+
asyncEndEvent.result,
|
|
9202
|
+
startTime,
|
|
9203
|
+
asyncEndEvent
|
|
9204
|
+
);
|
|
9205
|
+
const metadata = config.extractMetadata?.(
|
|
9206
|
+
asyncEndEvent.result,
|
|
9207
|
+
asyncEndEvent
|
|
9208
|
+
);
|
|
9209
|
+
span.log({
|
|
9210
|
+
output,
|
|
9211
|
+
...normalizeMetadata(metadata) !== void 0 ? { metadata: normalizeMetadata(metadata) } : {},
|
|
9212
|
+
metrics
|
|
9213
|
+
});
|
|
9214
|
+
} catch (error) {
|
|
9215
|
+
console.error(`Error extracting output for ${channelName}:`, error);
|
|
9216
|
+
} finally {
|
|
9217
|
+
span.end();
|
|
9218
|
+
states.delete(event);
|
|
9219
|
+
}
|
|
9220
|
+
},
|
|
9221
|
+
error: (event) => {
|
|
9222
|
+
logErrorAndEnd(states, event);
|
|
9223
|
+
}
|
|
9224
|
+
};
|
|
9225
|
+
tracingChannel2.subscribe(handlers);
|
|
9226
|
+
return () => {
|
|
9227
|
+
tracingChannel2.unsubscribe(handlers);
|
|
9228
|
+
};
|
|
9229
|
+
}
|
|
9230
|
+
function traceStreamingChannel(channel2, config) {
|
|
9231
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
9232
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
9233
|
+
const channelName = channel2.channelName;
|
|
9234
|
+
const handlers = {
|
|
9235
|
+
start: (event) => {
|
|
9236
|
+
states.set(
|
|
9237
|
+
event,
|
|
9238
|
+
startSpanForEvent(
|
|
9239
|
+
config,
|
|
9240
|
+
event,
|
|
9241
|
+
channelName
|
|
9242
|
+
)
|
|
9243
|
+
);
|
|
9244
|
+
},
|
|
9245
|
+
asyncEnd: (event) => {
|
|
9246
|
+
const spanData = states.get(event);
|
|
9247
|
+
if (!spanData) {
|
|
9248
|
+
return;
|
|
9249
|
+
}
|
|
9250
|
+
const asyncEndEvent = event;
|
|
9251
|
+
const { span, startTime } = spanData;
|
|
9252
|
+
if (isAsyncIterable(asyncEndEvent.result)) {
|
|
9253
|
+
let firstChunkTime;
|
|
9254
|
+
patchStreamIfNeeded(asyncEndEvent.result, {
|
|
9255
|
+
onChunk: () => {
|
|
9256
|
+
if (firstChunkTime === void 0) {
|
|
9257
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
9258
|
+
}
|
|
9259
|
+
},
|
|
9260
|
+
onComplete: (chunks) => {
|
|
9261
|
+
try {
|
|
9262
|
+
let output;
|
|
9263
|
+
let metrics;
|
|
9264
|
+
let metadata;
|
|
9265
|
+
if (config.aggregateChunks) {
|
|
9266
|
+
const aggregated = config.aggregateChunks(
|
|
9267
|
+
chunks,
|
|
9268
|
+
asyncEndEvent.result,
|
|
9269
|
+
asyncEndEvent,
|
|
9270
|
+
startTime
|
|
9271
|
+
);
|
|
9272
|
+
output = aggregated.output;
|
|
9273
|
+
metrics = aggregated.metrics;
|
|
9274
|
+
metadata = aggregated.metadata;
|
|
9275
|
+
} else {
|
|
9276
|
+
output = config.extractOutput(
|
|
9277
|
+
chunks,
|
|
9278
|
+
asyncEndEvent
|
|
9279
|
+
);
|
|
9280
|
+
metrics = config.extractMetrics(
|
|
9281
|
+
chunks,
|
|
9282
|
+
startTime,
|
|
9283
|
+
asyncEndEvent
|
|
9284
|
+
);
|
|
9285
|
+
}
|
|
9286
|
+
if (metrics.time_to_first_token === void 0 && firstChunkTime !== void 0) {
|
|
9287
|
+
metrics.time_to_first_token = firstChunkTime - startTime;
|
|
9288
|
+
} else if (metrics.time_to_first_token === void 0 && chunks.length > 0) {
|
|
9289
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9290
|
+
}
|
|
9291
|
+
span.log({
|
|
9292
|
+
output,
|
|
9293
|
+
...metadata !== void 0 ? { metadata } : {},
|
|
9294
|
+
metrics
|
|
9295
|
+
});
|
|
9296
|
+
} catch (error) {
|
|
9297
|
+
console.error(
|
|
9298
|
+
`Error extracting output for ${channelName}:`,
|
|
9299
|
+
error
|
|
9300
|
+
);
|
|
9301
|
+
} finally {
|
|
9302
|
+
span.end();
|
|
9303
|
+
states.delete(event);
|
|
9304
|
+
}
|
|
9305
|
+
},
|
|
9306
|
+
onError: (error) => {
|
|
9307
|
+
span.log({
|
|
9308
|
+
error: error.message
|
|
9309
|
+
});
|
|
9310
|
+
span.end();
|
|
9311
|
+
states.delete(event);
|
|
9312
|
+
}
|
|
9313
|
+
});
|
|
9314
|
+
return;
|
|
9315
|
+
}
|
|
9316
|
+
try {
|
|
9317
|
+
const output = config.extractOutput(
|
|
9318
|
+
asyncEndEvent.result,
|
|
9319
|
+
asyncEndEvent
|
|
9320
|
+
);
|
|
9321
|
+
const metrics = config.extractMetrics(
|
|
9322
|
+
asyncEndEvent.result,
|
|
9323
|
+
startTime,
|
|
9324
|
+
asyncEndEvent
|
|
9325
|
+
);
|
|
9326
|
+
const metadata = config.extractMetadata?.(
|
|
9327
|
+
asyncEndEvent.result,
|
|
9328
|
+
asyncEndEvent
|
|
9329
|
+
);
|
|
9330
|
+
span.log({
|
|
9331
|
+
output,
|
|
9332
|
+
...normalizeMetadata(metadata) !== void 0 ? { metadata: normalizeMetadata(metadata) } : {},
|
|
9333
|
+
metrics
|
|
9334
|
+
});
|
|
9335
|
+
} catch (error) {
|
|
9336
|
+
console.error(`Error extracting output for ${channelName}:`, error);
|
|
9337
|
+
} finally {
|
|
9338
|
+
span.end();
|
|
9339
|
+
states.delete(event);
|
|
9340
|
+
}
|
|
9341
|
+
},
|
|
9342
|
+
error: (event) => {
|
|
9343
|
+
logErrorAndEnd(states, event);
|
|
9344
|
+
}
|
|
9345
|
+
};
|
|
9346
|
+
tracingChannel2.subscribe(handlers);
|
|
9347
|
+
return () => {
|
|
9348
|
+
tracingChannel2.unsubscribe(handlers);
|
|
9349
|
+
};
|
|
9350
|
+
}
|
|
9351
|
+
function traceSyncStreamChannel(channel2, config) {
|
|
9352
|
+
const tracingChannel2 = channel2.tracingChannel();
|
|
9353
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
9354
|
+
const channelName = channel2.channelName;
|
|
9355
|
+
const handlers = {
|
|
9356
|
+
start: (event) => {
|
|
9357
|
+
states.set(
|
|
9358
|
+
event,
|
|
9359
|
+
startSpanForEvent(
|
|
9360
|
+
config,
|
|
9361
|
+
event,
|
|
9362
|
+
channelName
|
|
9363
|
+
)
|
|
9364
|
+
);
|
|
9365
|
+
},
|
|
9366
|
+
end: (event) => {
|
|
9367
|
+
const spanData = states.get(event);
|
|
9368
|
+
if (!spanData) {
|
|
9369
|
+
return;
|
|
9370
|
+
}
|
|
9371
|
+
const { span, startTime } = spanData;
|
|
9372
|
+
const resultEvent = event;
|
|
9373
|
+
const stream = resultEvent.result;
|
|
9374
|
+
if (!isSyncStreamLike(stream)) {
|
|
9375
|
+
span.end();
|
|
9376
|
+
states.delete(event);
|
|
9377
|
+
return;
|
|
9378
|
+
}
|
|
9379
|
+
let first = true;
|
|
9380
|
+
stream.on("chunk", () => {
|
|
9381
|
+
if (first) {
|
|
9382
|
+
span.log({
|
|
9383
|
+
metrics: {
|
|
9384
|
+
time_to_first_token: getCurrentUnixTimestamp() - startTime
|
|
9385
|
+
}
|
|
9386
|
+
});
|
|
9387
|
+
first = false;
|
|
9388
|
+
}
|
|
9389
|
+
});
|
|
9390
|
+
stream.on("chatCompletion", (completion) => {
|
|
9391
|
+
try {
|
|
9392
|
+
if (hasChoices(completion)) {
|
|
9393
|
+
span.log({
|
|
9394
|
+
output: completion.choices
|
|
9395
|
+
});
|
|
9396
|
+
}
|
|
9397
|
+
} catch (error) {
|
|
9398
|
+
console.error(
|
|
9399
|
+
`Error extracting chatCompletion for ${channelName}:`,
|
|
9400
|
+
error
|
|
9401
|
+
);
|
|
9402
|
+
}
|
|
9403
|
+
});
|
|
9404
|
+
stream.on("event", (streamEvent) => {
|
|
9405
|
+
if (!config.extractFromEvent) {
|
|
9406
|
+
return;
|
|
9407
|
+
}
|
|
9408
|
+
try {
|
|
9409
|
+
if (first) {
|
|
9410
|
+
span.log({
|
|
9411
|
+
metrics: {
|
|
9412
|
+
time_to_first_token: getCurrentUnixTimestamp() - startTime
|
|
9413
|
+
}
|
|
9414
|
+
});
|
|
9415
|
+
first = false;
|
|
9416
|
+
}
|
|
9417
|
+
const extracted = config.extractFromEvent(streamEvent);
|
|
9418
|
+
if (extracted && Object.keys(extracted).length > 0) {
|
|
9419
|
+
span.log(extracted);
|
|
9420
|
+
}
|
|
9421
|
+
} catch (error) {
|
|
9422
|
+
console.error(`Error extracting event for ${channelName}:`, error);
|
|
9423
|
+
}
|
|
9424
|
+
});
|
|
9425
|
+
stream.on("end", () => {
|
|
9426
|
+
span.end();
|
|
9427
|
+
states.delete(event);
|
|
9428
|
+
});
|
|
9429
|
+
stream.on("error", (error) => {
|
|
9430
|
+
span.log({
|
|
9431
|
+
error: error.message
|
|
9432
|
+
});
|
|
9433
|
+
span.end();
|
|
9434
|
+
states.delete(event);
|
|
9435
|
+
});
|
|
9436
|
+
},
|
|
9437
|
+
error: (event) => {
|
|
9438
|
+
logErrorAndEnd(states, event);
|
|
9439
|
+
}
|
|
9440
|
+
};
|
|
9441
|
+
tracingChannel2.subscribe(handlers);
|
|
9442
|
+
return () => {
|
|
9443
|
+
tracingChannel2.unsubscribe(handlers);
|
|
9444
|
+
};
|
|
9445
|
+
}
|
|
9446
|
+
function unsubscribeAll(unsubscribers) {
|
|
9447
|
+
for (const unsubscribe of unsubscribers) {
|
|
9448
|
+
unsubscribe();
|
|
9449
|
+
}
|
|
9450
|
+
return [];
|
|
9451
|
+
}
|
|
9452
|
+
|
|
8875
9453
|
// src/wrappers/attachment-utils.ts
|
|
8876
9454
|
function getExtensionFromMediaType(mediaType) {
|
|
8877
9455
|
const extensionMap = {
|
|
@@ -8934,72 +9512,238 @@ function processInputAttachments(input) {
|
|
|
8934
9512
|
return input;
|
|
8935
9513
|
}
|
|
8936
9514
|
let attachmentIndex = 0;
|
|
8937
|
-
const
|
|
8938
|
-
|
|
8939
|
-
|
|
9515
|
+
const inferMediaTypeFromDataUrl = (value, fallback2) => {
|
|
9516
|
+
const mediaTypeMatch = value.match(/^data:([^;]+);/);
|
|
9517
|
+
return mediaTypeMatch?.[1] || fallback2;
|
|
9518
|
+
};
|
|
9519
|
+
const toAttachment = (value, mediaType, filename) => {
|
|
9520
|
+
const blob = convertDataToBlob(value, mediaType);
|
|
9521
|
+
if (!blob) {
|
|
9522
|
+
return null;
|
|
8940
9523
|
}
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
|
|
8960
|
-
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
|
|
9524
|
+
return new Attachment({
|
|
9525
|
+
data: blob,
|
|
9526
|
+
filename,
|
|
9527
|
+
contentType: mediaType
|
|
9528
|
+
});
|
|
9529
|
+
};
|
|
9530
|
+
const processNode = (node) => {
|
|
9531
|
+
if (Array.isArray(node)) {
|
|
9532
|
+
return node.map(processNode);
|
|
9533
|
+
}
|
|
9534
|
+
if (!node || typeof node !== "object") {
|
|
9535
|
+
return node;
|
|
9536
|
+
}
|
|
9537
|
+
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:")) {
|
|
9538
|
+
const mediaType = inferMediaTypeFromDataUrl(
|
|
9539
|
+
node.image_url.url,
|
|
9540
|
+
"image/png"
|
|
9541
|
+
);
|
|
9542
|
+
const filename = `image.${getExtensionFromMediaType(mediaType)}`;
|
|
9543
|
+
const attachment = toAttachment(node.image_url.url, mediaType, filename);
|
|
9544
|
+
if (attachment) {
|
|
9545
|
+
return {
|
|
9546
|
+
...node,
|
|
9547
|
+
image_url: {
|
|
9548
|
+
...node.image_url,
|
|
9549
|
+
url: attachment
|
|
9550
|
+
}
|
|
9551
|
+
};
|
|
8964
9552
|
}
|
|
8965
9553
|
}
|
|
8966
|
-
if (
|
|
8967
|
-
const mediaType =
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
9554
|
+
if (node.type === "file" && node.file && typeof node.file === "object" && typeof node.file.file_data === "string" && node.file.file_data.startsWith("data:")) {
|
|
9555
|
+
const mediaType = inferMediaTypeFromDataUrl(
|
|
9556
|
+
node.file.file_data,
|
|
9557
|
+
"application/octet-stream"
|
|
9558
|
+
);
|
|
9559
|
+
const filename = typeof node.file.filename === "string" && node.file.filename ? node.file.filename : `document.${getExtensionFromMediaType(mediaType)}`;
|
|
9560
|
+
const attachment = toAttachment(node.file.file_data, mediaType, filename);
|
|
9561
|
+
if (attachment) {
|
|
9562
|
+
return {
|
|
9563
|
+
...node,
|
|
9564
|
+
file: {
|
|
9565
|
+
...node.file,
|
|
9566
|
+
file_data: attachment
|
|
9567
|
+
}
|
|
9568
|
+
};
|
|
9569
|
+
}
|
|
9570
|
+
}
|
|
9571
|
+
if (node.type === "image" && node.image) {
|
|
9572
|
+
let mediaType = "image/png";
|
|
9573
|
+
if (typeof node.image === "string" && node.image.startsWith("data:")) {
|
|
9574
|
+
mediaType = inferMediaTypeFromDataUrl(node.image, mediaType);
|
|
9575
|
+
} else if (node.mediaType) {
|
|
9576
|
+
mediaType = node.mediaType;
|
|
9577
|
+
}
|
|
9578
|
+
const filename = `input_image_${attachmentIndex}.${getExtensionFromMediaType(mediaType)}`;
|
|
9579
|
+
const attachment = toAttachment(node.image, mediaType, filename);
|
|
9580
|
+
if (attachment) {
|
|
8971
9581
|
attachmentIndex++;
|
|
8972
|
-
const attachment = new Attachment({
|
|
8973
|
-
data: blob,
|
|
8974
|
-
filename,
|
|
8975
|
-
contentType: mediaType
|
|
8976
|
-
});
|
|
8977
9582
|
return {
|
|
8978
|
-
...
|
|
8979
|
-
|
|
9583
|
+
...node,
|
|
9584
|
+
image: attachment
|
|
8980
9585
|
};
|
|
8981
9586
|
}
|
|
8982
9587
|
}
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
|
|
9588
|
+
if (node.type === "file" && node.data) {
|
|
9589
|
+
const mediaType = node.mediaType || "application/octet-stream";
|
|
9590
|
+
const filename = node.filename || `input_file_${attachmentIndex}.${getExtensionFromMediaType(mediaType)}`;
|
|
9591
|
+
const attachment = toAttachment(node.data, mediaType, filename);
|
|
9592
|
+
if (attachment) {
|
|
9593
|
+
attachmentIndex++;
|
|
9594
|
+
return {
|
|
9595
|
+
...node,
|
|
9596
|
+
data: attachment
|
|
9597
|
+
};
|
|
9598
|
+
}
|
|
8988
9599
|
}
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
content: message.content.map(processContentPart)
|
|
8993
|
-
};
|
|
9600
|
+
const processed = {};
|
|
9601
|
+
for (const [key, value] of Object.entries(node)) {
|
|
9602
|
+
processed[key] = processNode(value);
|
|
8994
9603
|
}
|
|
8995
|
-
return
|
|
9604
|
+
return processed;
|
|
8996
9605
|
};
|
|
8997
9606
|
if (Array.isArray(input)) {
|
|
8998
|
-
return input.map(
|
|
8999
|
-
} else if (typeof input === "object" && input.content) {
|
|
9000
|
-
return processMessage(input);
|
|
9607
|
+
return input.map(processNode);
|
|
9001
9608
|
}
|
|
9002
|
-
return input;
|
|
9609
|
+
return processNode(input);
|
|
9610
|
+
}
|
|
9611
|
+
|
|
9612
|
+
// src/instrumentation/core/channel-definitions.ts
|
|
9613
|
+
function channel(spec) {
|
|
9614
|
+
return spec;
|
|
9615
|
+
}
|
|
9616
|
+
function defineChannels(pkg, channels) {
|
|
9617
|
+
return Object.fromEntries(
|
|
9618
|
+
Object.entries(channels).map(([key, spec]) => {
|
|
9619
|
+
const fullChannelName = `orchestrion:${pkg}:${spec.channelName}`;
|
|
9620
|
+
if (spec.kind === "async") {
|
|
9621
|
+
const asyncSpec = spec;
|
|
9622
|
+
const tracingChannel3 = () => isomorph_default.newTracingChannel(
|
|
9623
|
+
fullChannelName
|
|
9624
|
+
);
|
|
9625
|
+
return [
|
|
9626
|
+
key,
|
|
9627
|
+
{
|
|
9628
|
+
...asyncSpec,
|
|
9629
|
+
tracingChannel: tracingChannel3,
|
|
9630
|
+
tracePromise: (fn, context) => tracingChannel3().tracePromise(
|
|
9631
|
+
fn,
|
|
9632
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
9633
|
+
context
|
|
9634
|
+
)
|
|
9635
|
+
}
|
|
9636
|
+
];
|
|
9637
|
+
}
|
|
9638
|
+
const syncSpec = spec;
|
|
9639
|
+
const tracingChannel2 = () => isomorph_default.newTracingChannel(
|
|
9640
|
+
fullChannelName
|
|
9641
|
+
);
|
|
9642
|
+
return [
|
|
9643
|
+
key,
|
|
9644
|
+
{
|
|
9645
|
+
...syncSpec,
|
|
9646
|
+
tracingChannel: tracingChannel2,
|
|
9647
|
+
traceSync: (fn, context) => tracingChannel2().traceSync(
|
|
9648
|
+
fn,
|
|
9649
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
9650
|
+
context
|
|
9651
|
+
)
|
|
9652
|
+
}
|
|
9653
|
+
];
|
|
9654
|
+
})
|
|
9655
|
+
);
|
|
9656
|
+
}
|
|
9657
|
+
|
|
9658
|
+
// src/instrumentation/plugins/openai-channels.ts
|
|
9659
|
+
var openAIChannels = defineChannels("openai", {
|
|
9660
|
+
chatCompletionsCreate: channel({
|
|
9661
|
+
channelName: "chat.completions.create",
|
|
9662
|
+
kind: "async"
|
|
9663
|
+
}),
|
|
9664
|
+
embeddingsCreate: channel({
|
|
9665
|
+
channelName: "embeddings.create",
|
|
9666
|
+
kind: "async"
|
|
9667
|
+
}),
|
|
9668
|
+
betaChatCompletionsParse: channel({
|
|
9669
|
+
channelName: "beta.chat.completions.parse",
|
|
9670
|
+
kind: "async"
|
|
9671
|
+
}),
|
|
9672
|
+
betaChatCompletionsStream: channel({
|
|
9673
|
+
channelName: "beta.chat.completions.stream",
|
|
9674
|
+
kind: "sync-stream"
|
|
9675
|
+
}),
|
|
9676
|
+
moderationsCreate: channel({
|
|
9677
|
+
channelName: "moderations.create",
|
|
9678
|
+
kind: "async"
|
|
9679
|
+
}),
|
|
9680
|
+
responsesCreate: channel({
|
|
9681
|
+
channelName: "responses.create",
|
|
9682
|
+
kind: "async"
|
|
9683
|
+
}),
|
|
9684
|
+
responsesStream: channel({
|
|
9685
|
+
channelName: "responses.stream",
|
|
9686
|
+
kind: "sync-stream"
|
|
9687
|
+
}),
|
|
9688
|
+
responsesParse: channel({
|
|
9689
|
+
channelName: "responses.parse",
|
|
9690
|
+
kind: "async"
|
|
9691
|
+
})
|
|
9692
|
+
});
|
|
9693
|
+
|
|
9694
|
+
// src/openai-utils.ts
|
|
9695
|
+
var BRAINTRUST_CACHED_STREAM_METRIC = "__braintrust_cached_metric";
|
|
9696
|
+
var LEGACY_CACHED_HEADER = "x-cached";
|
|
9697
|
+
var X_CACHED_HEADER = "x-bt-cached";
|
|
9698
|
+
var TOKEN_NAME_MAP = {
|
|
9699
|
+
input_tokens: "prompt_tokens",
|
|
9700
|
+
output_tokens: "completion_tokens",
|
|
9701
|
+
total_tokens: "tokens"
|
|
9702
|
+
};
|
|
9703
|
+
var TOKEN_PREFIX_MAP = {
|
|
9704
|
+
input: "prompt",
|
|
9705
|
+
output: "completion"
|
|
9706
|
+
};
|
|
9707
|
+
function parseMetricsFromUsage(usage) {
|
|
9708
|
+
if (!usage) {
|
|
9709
|
+
return {};
|
|
9710
|
+
}
|
|
9711
|
+
const metrics = {};
|
|
9712
|
+
for (const [oaiName, value] of Object.entries(usage)) {
|
|
9713
|
+
if (typeof value === "number") {
|
|
9714
|
+
const metricName = TOKEN_NAME_MAP[oaiName] || oaiName;
|
|
9715
|
+
metrics[metricName] = value;
|
|
9716
|
+
continue;
|
|
9717
|
+
}
|
|
9718
|
+
if (!oaiName.endsWith("_tokens_details") || !isObject(value)) {
|
|
9719
|
+
continue;
|
|
9720
|
+
}
|
|
9721
|
+
const rawPrefix = oaiName.slice(0, -"_tokens_details".length);
|
|
9722
|
+
const prefix = TOKEN_PREFIX_MAP[rawPrefix] || rawPrefix;
|
|
9723
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
9724
|
+
if (typeof nestedValue !== "number") {
|
|
9725
|
+
continue;
|
|
9726
|
+
}
|
|
9727
|
+
metrics[`${prefix}_${key}`] = nestedValue;
|
|
9728
|
+
}
|
|
9729
|
+
}
|
|
9730
|
+
return metrics;
|
|
9731
|
+
}
|
|
9732
|
+
function parseCachedHeader(value) {
|
|
9733
|
+
if (!value) {
|
|
9734
|
+
return void 0;
|
|
9735
|
+
}
|
|
9736
|
+
return ["true", "hit"].includes(value.toLowerCase()) ? 1 : 0;
|
|
9737
|
+
}
|
|
9738
|
+
function getCachedMetricFromHeaders(headers) {
|
|
9739
|
+
if (!headers || typeof headers.get !== "function") {
|
|
9740
|
+
return void 0;
|
|
9741
|
+
}
|
|
9742
|
+
const cachedHeader = headers.get(X_CACHED_HEADER);
|
|
9743
|
+
if (cachedHeader) {
|
|
9744
|
+
return parseCachedHeader(cachedHeader);
|
|
9745
|
+
}
|
|
9746
|
+
return parseCachedHeader(headers.get(LEGACY_CACHED_HEADER));
|
|
9003
9747
|
}
|
|
9004
9748
|
|
|
9005
9749
|
// src/instrumentation/plugins/openai-plugin.ts
|
|
@@ -9008,13 +9752,11 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
9008
9752
|
super();
|
|
9009
9753
|
}
|
|
9010
9754
|
onEnable() {
|
|
9011
|
-
this.
|
|
9012
|
-
|
|
9013
|
-
{
|
|
9755
|
+
this.unsubscribers.push(
|
|
9756
|
+
traceStreamingChannel(openAIChannels.chatCompletionsCreate, {
|
|
9014
9757
|
name: "Chat Completion",
|
|
9015
9758
|
type: "llm" /* LLM */,
|
|
9016
|
-
extractInput: (
|
|
9017
|
-
const params = args[0] || {};
|
|
9759
|
+
extractInput: ([params]) => {
|
|
9018
9760
|
const { messages, ...metadata } = params;
|
|
9019
9761
|
return {
|
|
9020
9762
|
input: processInputAttachments(messages),
|
|
@@ -9024,41 +9766,49 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
9024
9766
|
extractOutput: (result) => {
|
|
9025
9767
|
return result?.choices;
|
|
9026
9768
|
},
|
|
9027
|
-
extractMetrics: (result, startTime) => {
|
|
9028
|
-
const metrics =
|
|
9769
|
+
extractMetrics: (result, startTime, endEvent) => {
|
|
9770
|
+
const metrics = withCachedMetric(
|
|
9771
|
+
parseMetricsFromUsage(result?.usage),
|
|
9772
|
+
result,
|
|
9773
|
+
endEvent
|
|
9774
|
+
);
|
|
9029
9775
|
if (startTime) {
|
|
9030
9776
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9031
9777
|
}
|
|
9032
9778
|
return metrics;
|
|
9033
9779
|
},
|
|
9034
9780
|
aggregateChunks: aggregateChatCompletionChunks
|
|
9035
|
-
}
|
|
9781
|
+
})
|
|
9036
9782
|
);
|
|
9037
|
-
this.
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9783
|
+
this.unsubscribers.push(
|
|
9784
|
+
traceAsyncChannel(openAIChannels.embeddingsCreate, {
|
|
9785
|
+
name: "Embedding",
|
|
9786
|
+
type: "llm" /* LLM */,
|
|
9787
|
+
extractInput: ([params]) => {
|
|
9788
|
+
const { input, ...metadata } = params;
|
|
9789
|
+
return {
|
|
9790
|
+
input,
|
|
9791
|
+
metadata: { ...metadata, provider: "openai" }
|
|
9792
|
+
};
|
|
9793
|
+
},
|
|
9794
|
+
extractOutput: (result) => {
|
|
9795
|
+
const embedding = result?.data?.[0]?.embedding;
|
|
9796
|
+
return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
|
|
9797
|
+
},
|
|
9798
|
+
extractMetrics: (result, _startTime, endEvent) => {
|
|
9799
|
+
return withCachedMetric(
|
|
9800
|
+
parseMetricsFromUsage(result?.usage),
|
|
9801
|
+
result,
|
|
9802
|
+
endEvent
|
|
9803
|
+
);
|
|
9804
|
+
}
|
|
9805
|
+
})
|
|
9806
|
+
);
|
|
9807
|
+
this.unsubscribers.push(
|
|
9808
|
+
traceStreamingChannel(openAIChannels.betaChatCompletionsParse, {
|
|
9058
9809
|
name: "Chat Completion",
|
|
9059
9810
|
type: "llm" /* LLM */,
|
|
9060
|
-
extractInput: (
|
|
9061
|
-
const params = args[0] || {};
|
|
9811
|
+
extractInput: ([params]) => {
|
|
9062
9812
|
const { messages, ...metadata } = params;
|
|
9063
9813
|
return {
|
|
9064
9814
|
input: processInputAttachments(messages),
|
|
@@ -9068,164 +9818,196 @@ var OpenAIPlugin = class extends BasePlugin {
|
|
|
9068
9818
|
extractOutput: (result) => {
|
|
9069
9819
|
return result?.choices;
|
|
9070
9820
|
},
|
|
9071
|
-
extractMetrics: (result, startTime) => {
|
|
9072
|
-
const metrics =
|
|
9821
|
+
extractMetrics: (result, startTime, endEvent) => {
|
|
9822
|
+
const metrics = withCachedMetric(
|
|
9823
|
+
parseMetricsFromUsage(result?.usage),
|
|
9824
|
+
result,
|
|
9825
|
+
endEvent
|
|
9826
|
+
);
|
|
9073
9827
|
if (startTime) {
|
|
9074
9828
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9075
9829
|
}
|
|
9076
9830
|
return metrics;
|
|
9077
9831
|
},
|
|
9078
9832
|
aggregateChunks: aggregateChatCompletionChunks
|
|
9079
|
-
}
|
|
9833
|
+
})
|
|
9080
9834
|
);
|
|
9081
|
-
this.
|
|
9082
|
-
|
|
9083
|
-
{
|
|
9835
|
+
this.unsubscribers.push(
|
|
9836
|
+
traceSyncStreamChannel(openAIChannels.betaChatCompletionsStream, {
|
|
9084
9837
|
name: "Chat Completion",
|
|
9085
9838
|
type: "llm" /* LLM */,
|
|
9086
|
-
extractInput: (
|
|
9087
|
-
const params = args[0] || {};
|
|
9839
|
+
extractInput: ([params]) => {
|
|
9088
9840
|
const { messages, ...metadata } = params;
|
|
9089
9841
|
return {
|
|
9090
9842
|
input: processInputAttachments(messages),
|
|
9091
9843
|
metadata: { ...metadata, provider: "openai" }
|
|
9092
9844
|
};
|
|
9093
9845
|
}
|
|
9094
|
-
}
|
|
9846
|
+
})
|
|
9095
9847
|
);
|
|
9096
|
-
this.
|
|
9097
|
-
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
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 {};
|
|
9848
|
+
this.unsubscribers.push(
|
|
9849
|
+
traceAsyncChannel(openAIChannels.moderationsCreate, {
|
|
9850
|
+
name: "Moderation",
|
|
9851
|
+
type: "llm" /* LLM */,
|
|
9852
|
+
extractInput: ([params]) => {
|
|
9853
|
+
const { input, ...metadata } = params;
|
|
9854
|
+
return {
|
|
9855
|
+
input,
|
|
9856
|
+
metadata: { ...metadata, provider: "openai" }
|
|
9857
|
+
};
|
|
9858
|
+
},
|
|
9859
|
+
extractOutput: (result) => {
|
|
9860
|
+
return result?.results;
|
|
9861
|
+
},
|
|
9862
|
+
extractMetrics: (result, _startTime, endEvent) => {
|
|
9863
|
+
return withCachedMetric(
|
|
9864
|
+
parseMetricsFromUsage(result?.usage),
|
|
9865
|
+
result,
|
|
9866
|
+
endEvent
|
|
9867
|
+
);
|
|
9150
9868
|
}
|
|
9151
|
-
|
|
9152
|
-
|
|
9869
|
+
})
|
|
9870
|
+
);
|
|
9871
|
+
this.unsubscribers.push(
|
|
9872
|
+
traceStreamingChannel(openAIChannels.responsesCreate, {
|
|
9873
|
+
name: "openai.responses.create",
|
|
9874
|
+
type: "llm" /* LLM */,
|
|
9875
|
+
extractInput: ([params]) => {
|
|
9876
|
+
const { input, ...metadata } = params;
|
|
9877
|
+
return {
|
|
9878
|
+
input: processInputAttachments(input),
|
|
9879
|
+
metadata: { ...metadata, provider: "openai" }
|
|
9880
|
+
};
|
|
9881
|
+
},
|
|
9882
|
+
extractOutput: (result) => {
|
|
9883
|
+
return processImagesInOutput(result?.output);
|
|
9884
|
+
},
|
|
9885
|
+
extractMetadata: (result) => {
|
|
9886
|
+
if (!result) {
|
|
9887
|
+
return void 0;
|
|
9888
|
+
}
|
|
9889
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
9890
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
9891
|
+
},
|
|
9892
|
+
extractMetrics: (result, startTime, endEvent) => {
|
|
9893
|
+
const metrics = withCachedMetric(
|
|
9894
|
+
parseMetricsFromUsage(result?.usage),
|
|
9895
|
+
result,
|
|
9896
|
+
endEvent
|
|
9897
|
+
);
|
|
9898
|
+
if (startTime) {
|
|
9899
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9900
|
+
}
|
|
9901
|
+
return metrics;
|
|
9902
|
+
},
|
|
9903
|
+
aggregateChunks: aggregateResponseStreamEvents
|
|
9904
|
+
})
|
|
9905
|
+
);
|
|
9906
|
+
this.unsubscribers.push(
|
|
9907
|
+
traceSyncStreamChannel(openAIChannels.responsesStream, {
|
|
9908
|
+
name: "openai.responses.create",
|
|
9909
|
+
type: "llm" /* LLM */,
|
|
9910
|
+
extractInput: ([params]) => {
|
|
9911
|
+
const { input, ...metadata } = params;
|
|
9912
|
+
return {
|
|
9913
|
+
input: processInputAttachments(input),
|
|
9914
|
+
metadata: { ...metadata, provider: "openai" }
|
|
9915
|
+
};
|
|
9916
|
+
},
|
|
9917
|
+
extractFromEvent: (event) => {
|
|
9918
|
+
if (event.type !== "response.completed" || !event.response) {
|
|
9919
|
+
return {};
|
|
9920
|
+
}
|
|
9921
|
+
const response = event.response;
|
|
9153
9922
|
const data = {};
|
|
9154
|
-
if (response
|
|
9923
|
+
if (response.output !== void 0) {
|
|
9155
9924
|
data.output = processImagesInOutput(response.output);
|
|
9156
9925
|
}
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
data.metadata = metadata;
|
|
9161
|
-
}
|
|
9926
|
+
const { usage: _usage, output: _output, ...metadata } = response;
|
|
9927
|
+
if (Object.keys(metadata).length > 0) {
|
|
9928
|
+
data.metadata = metadata;
|
|
9162
9929
|
}
|
|
9163
|
-
data.metrics = parseMetricsFromUsage(response
|
|
9930
|
+
data.metrics = parseMetricsFromUsage(response.usage);
|
|
9164
9931
|
return data;
|
|
9165
9932
|
}
|
|
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
|
-
|
|
9933
|
+
})
|
|
9934
|
+
);
|
|
9935
|
+
this.unsubscribers.push(
|
|
9936
|
+
traceStreamingChannel(openAIChannels.responsesParse, {
|
|
9937
|
+
name: "openai.responses.parse",
|
|
9938
|
+
type: "llm" /* LLM */,
|
|
9939
|
+
extractInput: ([params]) => {
|
|
9940
|
+
const { input, ...metadata } = params;
|
|
9941
|
+
return {
|
|
9942
|
+
input: processInputAttachments(input),
|
|
9943
|
+
metadata: { ...metadata, provider: "openai" }
|
|
9944
|
+
};
|
|
9945
|
+
},
|
|
9946
|
+
extractOutput: (result) => {
|
|
9947
|
+
return processImagesInOutput(result?.output);
|
|
9948
|
+
},
|
|
9949
|
+
extractMetadata: (result) => {
|
|
9950
|
+
if (!result) {
|
|
9951
|
+
return void 0;
|
|
9952
|
+
}
|
|
9953
|
+
const { output: _output, usage: _usage, ...metadata } = result;
|
|
9954
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
9955
|
+
},
|
|
9956
|
+
extractMetrics: (result, startTime, endEvent) => {
|
|
9957
|
+
const metrics = withCachedMetric(
|
|
9958
|
+
parseMetricsFromUsage(result?.usage),
|
|
9959
|
+
result,
|
|
9960
|
+
endEvent
|
|
9961
|
+
);
|
|
9962
|
+
if (startTime) {
|
|
9963
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9964
|
+
}
|
|
9965
|
+
return metrics;
|
|
9966
|
+
},
|
|
9967
|
+
aggregateChunks: aggregateResponseStreamEvents
|
|
9968
|
+
})
|
|
9969
|
+
);
|
|
9191
9970
|
}
|
|
9192
9971
|
onDisable() {
|
|
9972
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
9193
9973
|
}
|
|
9194
9974
|
};
|
|
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 {};
|
|
9975
|
+
function getCachedMetricFromEndEvent(endEvent) {
|
|
9976
|
+
if (!isObject(endEvent)) {
|
|
9977
|
+
return void 0;
|
|
9207
9978
|
}
|
|
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
|
-
}
|
|
9979
|
+
const response = endEvent.response;
|
|
9980
|
+
if (!isObject(response)) {
|
|
9981
|
+
return void 0;
|
|
9227
9982
|
}
|
|
9228
|
-
|
|
9983
|
+
const headers = response.headers;
|
|
9984
|
+
if (!headers || typeof headers.get !== "function") {
|
|
9985
|
+
return void 0;
|
|
9986
|
+
}
|
|
9987
|
+
return getCachedMetricFromHeaders(headers);
|
|
9988
|
+
}
|
|
9989
|
+
function withCachedMetric(metrics, result, endEvent) {
|
|
9990
|
+
if (metrics.cached !== void 0) {
|
|
9991
|
+
return metrics;
|
|
9992
|
+
}
|
|
9993
|
+
const cachedFromEvent = getCachedMetricFromEndEvent(endEvent);
|
|
9994
|
+
if (cachedFromEvent !== void 0) {
|
|
9995
|
+
return {
|
|
9996
|
+
...metrics,
|
|
9997
|
+
cached: cachedFromEvent
|
|
9998
|
+
};
|
|
9999
|
+
}
|
|
10000
|
+
if (!isObject(result)) {
|
|
10001
|
+
return metrics;
|
|
10002
|
+
}
|
|
10003
|
+
const cached = result[BRAINTRUST_CACHED_STREAM_METRIC];
|
|
10004
|
+
if (typeof cached !== "number") {
|
|
10005
|
+
return metrics;
|
|
10006
|
+
}
|
|
10007
|
+
return {
|
|
10008
|
+
...metrics,
|
|
10009
|
+
cached
|
|
10010
|
+
};
|
|
9229
10011
|
}
|
|
9230
10012
|
function processImagesInOutput(output) {
|
|
9231
10013
|
if (Array.isArray(output)) {
|
|
@@ -9256,7 +10038,7 @@ function processImagesInOutput(output) {
|
|
|
9256
10038
|
}
|
|
9257
10039
|
return output;
|
|
9258
10040
|
}
|
|
9259
|
-
function aggregateChatCompletionChunks(chunks) {
|
|
10041
|
+
function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
9260
10042
|
let role = void 0;
|
|
9261
10043
|
let content = void 0;
|
|
9262
10044
|
let tool_calls = void 0;
|
|
@@ -9298,6 +10080,7 @@ function aggregateChatCompletionChunks(chunks) {
|
|
|
9298
10080
|
}
|
|
9299
10081
|
}
|
|
9300
10082
|
}
|
|
10083
|
+
metrics = withCachedMetric(metrics, streamResult, endEvent);
|
|
9301
10084
|
return {
|
|
9302
10085
|
metrics,
|
|
9303
10086
|
output: [
|
|
@@ -9314,9 +10097,33 @@ function aggregateChatCompletionChunks(chunks) {
|
|
|
9314
10097
|
]
|
|
9315
10098
|
};
|
|
9316
10099
|
}
|
|
9317
|
-
|
|
9318
|
-
|
|
9319
|
-
|
|
10100
|
+
function aggregateResponseStreamEvents(chunks, _streamResult, endEvent) {
|
|
10101
|
+
let output = void 0;
|
|
10102
|
+
let metrics = {};
|
|
10103
|
+
let metadata = void 0;
|
|
10104
|
+
for (const chunk of chunks) {
|
|
10105
|
+
if (!chunk || !chunk.type || !chunk.response) {
|
|
10106
|
+
continue;
|
|
10107
|
+
}
|
|
10108
|
+
if (chunk.type !== "response.completed") {
|
|
10109
|
+
continue;
|
|
10110
|
+
}
|
|
10111
|
+
const response = chunk.response;
|
|
10112
|
+
if (response?.output !== void 0) {
|
|
10113
|
+
output = processImagesInOutput(response.output);
|
|
10114
|
+
}
|
|
10115
|
+
const { usage: _usage, output: _output, ...rest } = response || {};
|
|
10116
|
+
if (Object.keys(rest).length > 0) {
|
|
10117
|
+
metadata = rest;
|
|
10118
|
+
}
|
|
10119
|
+
metrics = parseMetricsFromUsage(response?.usage);
|
|
10120
|
+
}
|
|
10121
|
+
return {
|
|
10122
|
+
output,
|
|
10123
|
+
metrics: withCachedMetric(metrics, void 0, endEvent),
|
|
10124
|
+
...metadata !== void 0 ? { metadata } : {}
|
|
10125
|
+
};
|
|
10126
|
+
}
|
|
9320
10127
|
|
|
9321
10128
|
// src/wrappers/anthropic-tokens-util.ts
|
|
9322
10129
|
function finalizeAnthropicTokens(metrics) {
|
|
@@ -9338,20 +10145,28 @@ function extractAnthropicCacheTokens(cacheReadTokens = 0, cacheCreationTokens =
|
|
|
9338
10145
|
return cacheTokens;
|
|
9339
10146
|
}
|
|
9340
10147
|
|
|
10148
|
+
// src/instrumentation/plugins/anthropic-channels.ts
|
|
10149
|
+
var anthropicChannels = defineChannels("@anthropic-ai/sdk", {
|
|
10150
|
+
messagesCreate: channel({
|
|
10151
|
+
channelName: "messages.create",
|
|
10152
|
+
kind: "async"
|
|
10153
|
+
}),
|
|
10154
|
+
betaMessagesCreate: channel({
|
|
10155
|
+
channelName: "beta.messages.create",
|
|
10156
|
+
kind: "async"
|
|
10157
|
+
})
|
|
10158
|
+
});
|
|
10159
|
+
|
|
9341
10160
|
// src/instrumentation/plugins/anthropic-plugin.ts
|
|
9342
10161
|
var AnthropicPlugin = class extends BasePlugin {
|
|
9343
|
-
unsubscribers = [];
|
|
9344
10162
|
onEnable() {
|
|
9345
10163
|
this.subscribeToAnthropicChannels();
|
|
9346
10164
|
}
|
|
9347
10165
|
onDisable() {
|
|
9348
|
-
|
|
9349
|
-
unsubscribe();
|
|
9350
|
-
}
|
|
9351
|
-
this.unsubscribers = [];
|
|
10166
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
9352
10167
|
}
|
|
9353
10168
|
subscribeToAnthropicChannels() {
|
|
9354
|
-
|
|
10169
|
+
const anthropicConfig = {
|
|
9355
10170
|
name: "anthropic.messages.create",
|
|
9356
10171
|
type: "llm" /* LLM */,
|
|
9357
10172
|
extractInput: (args) => {
|
|
@@ -9363,190 +10178,42 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
9363
10178
|
metadata: { ...metadata, provider: "anthropic" }
|
|
9364
10179
|
};
|
|
9365
10180
|
},
|
|
9366
|
-
extractOutput: (
|
|
9367
|
-
return
|
|
10181
|
+
extractOutput: (message) => {
|
|
10182
|
+
return message ? { role: message.role, content: message.content } : null;
|
|
9368
10183
|
},
|
|
9369
|
-
extractMetrics: (
|
|
9370
|
-
const metrics = parseMetricsFromUsage2(
|
|
10184
|
+
extractMetrics: (message, startTime) => {
|
|
10185
|
+
const metrics = parseMetricsFromUsage2(message?.usage);
|
|
9371
10186
|
if (startTime) {
|
|
9372
10187
|
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9373
10188
|
}
|
|
9374
|
-
const finalized = finalizeAnthropicTokens(metrics);
|
|
9375
|
-
return Object.fromEntries(
|
|
9376
|
-
Object.entries(finalized).filter(
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
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
|
-
}
|
|
9464
|
-
},
|
|
9465
|
-
asyncEnd: (event) => {
|
|
9466
|
-
const spanData = spans.get(event);
|
|
9467
|
-
if (!spanData) {
|
|
9468
|
-
return;
|
|
9469
|
-
}
|
|
9470
|
-
const { span, startTime } = spanData;
|
|
9471
|
-
const isStreaming = config.isStreaming ? config.isStreaming(event.arguments) : isAsyncIterable(event.result);
|
|
9472
|
-
if (isStreaming && isAsyncIterable(event.result)) {
|
|
9473
|
-
patchStreamIfNeeded(event.result, {
|
|
9474
|
-
onComplete: (chunks) => {
|
|
9475
|
-
try {
|
|
9476
|
-
let output;
|
|
9477
|
-
let metrics;
|
|
9478
|
-
let metadata = {};
|
|
9479
|
-
if (config.aggregateChunks) {
|
|
9480
|
-
const aggregated = config.aggregateChunks(chunks);
|
|
9481
|
-
output = aggregated.output;
|
|
9482
|
-
metrics = aggregated.metrics;
|
|
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);
|
|
9530
|
-
}
|
|
9531
|
-
}
|
|
10189
|
+
const finalized = finalizeAnthropicTokens(metrics);
|
|
10190
|
+
return Object.fromEntries(
|
|
10191
|
+
Object.entries(finalized).filter(
|
|
10192
|
+
(entry) => entry[1] !== void 0
|
|
10193
|
+
)
|
|
10194
|
+
);
|
|
9532
10195
|
},
|
|
9533
|
-
|
|
9534
|
-
const
|
|
9535
|
-
|
|
9536
|
-
|
|
10196
|
+
extractMetadata: (message) => {
|
|
10197
|
+
const metadata = {};
|
|
10198
|
+
const metas = ["stop_reason", "stop_sequence"];
|
|
10199
|
+
for (const m of metas) {
|
|
10200
|
+
if (message?.[m] !== void 0) {
|
|
10201
|
+
metadata[m] = message[m];
|
|
10202
|
+
}
|
|
9537
10203
|
}
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
});
|
|
9542
|
-
span.end();
|
|
9543
|
-
spans.delete(event);
|
|
9544
|
-
}
|
|
10204
|
+
return metadata;
|
|
10205
|
+
},
|
|
10206
|
+
aggregateChunks: (chunks) => aggregateAnthropicStreamChunks(chunks)
|
|
9545
10207
|
};
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
10208
|
+
this.unsubscribers.push(
|
|
10209
|
+
traceStreamingChannel(anthropicChannels.messagesCreate, anthropicConfig)
|
|
10210
|
+
);
|
|
10211
|
+
this.unsubscribers.push(
|
|
10212
|
+
traceStreamingChannel(anthropicChannels.betaMessagesCreate, {
|
|
10213
|
+
...anthropicConfig,
|
|
10214
|
+
name: "anthropic.beta.messages.create"
|
|
10215
|
+
})
|
|
10216
|
+
);
|
|
9550
10217
|
}
|
|
9551
10218
|
};
|
|
9552
10219
|
function parseMetricsFromUsage2(usage) {
|
|
@@ -9570,29 +10237,29 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
9570
10237
|
const deltas = [];
|
|
9571
10238
|
let metrics = {};
|
|
9572
10239
|
let metadata = {};
|
|
9573
|
-
for (const
|
|
9574
|
-
switch (
|
|
10240
|
+
for (const event of chunks) {
|
|
10241
|
+
switch (event?.type) {
|
|
9575
10242
|
case "message_start":
|
|
9576
|
-
if (
|
|
9577
|
-
const initialMetrics = parseMetricsFromUsage2(
|
|
10243
|
+
if (event.message?.usage) {
|
|
10244
|
+
const initialMetrics = parseMetricsFromUsage2(event.message.usage);
|
|
9578
10245
|
metrics = { ...metrics, ...initialMetrics };
|
|
9579
10246
|
}
|
|
9580
10247
|
break;
|
|
9581
10248
|
case "content_block_delta":
|
|
9582
|
-
if (
|
|
9583
|
-
const text =
|
|
10249
|
+
if (event.delta?.type === "text_delta") {
|
|
10250
|
+
const text = event.delta.text;
|
|
9584
10251
|
if (text) {
|
|
9585
10252
|
deltas.push(text);
|
|
9586
10253
|
}
|
|
9587
10254
|
}
|
|
9588
10255
|
break;
|
|
9589
10256
|
case "message_delta":
|
|
9590
|
-
if (
|
|
9591
|
-
const finalMetrics = parseMetricsFromUsage2(
|
|
10257
|
+
if (event.usage) {
|
|
10258
|
+
const finalMetrics = parseMetricsFromUsage2(event.usage);
|
|
9592
10259
|
metrics = { ...metrics, ...finalMetrics };
|
|
9593
10260
|
}
|
|
9594
|
-
if (
|
|
9595
|
-
metadata = { ...metadata, ...
|
|
10261
|
+
if (event.delta) {
|
|
10262
|
+
metadata = { ...metadata, ...event.delta };
|
|
9596
10263
|
}
|
|
9597
10264
|
break;
|
|
9598
10265
|
}
|
|
@@ -9600,7 +10267,9 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
9600
10267
|
const output = deltas.join("");
|
|
9601
10268
|
const finalized = finalizeAnthropicTokens(metrics);
|
|
9602
10269
|
const filteredMetrics = Object.fromEntries(
|
|
9603
|
-
Object.entries(finalized).filter(
|
|
10270
|
+
Object.entries(finalized).filter(
|
|
10271
|
+
(entry) => entry[1] !== void 0
|
|
10272
|
+
)
|
|
9604
10273
|
);
|
|
9605
10274
|
return {
|
|
9606
10275
|
output,
|
|
@@ -9608,6 +10277,9 @@ function aggregateAnthropicStreamChunks(chunks) {
|
|
|
9608
10277
|
metadata
|
|
9609
10278
|
};
|
|
9610
10279
|
}
|
|
10280
|
+
function isAnthropicBase64ContentBlock(input) {
|
|
10281
|
+
return (input.type === "image" || input.type === "document") && isObject(input.source) && input.source.type === "base64";
|
|
10282
|
+
}
|
|
9611
10283
|
function convertBase64ToAttachment(source, contentType) {
|
|
9612
10284
|
const mediaType = typeof source.media_type === "string" ? source.media_type : "image/png";
|
|
9613
10285
|
const base64Data = source.data;
|
|
@@ -9631,14 +10303,14 @@ function convertBase64ToAttachment(source, contentType) {
|
|
|
9631
10303
|
data: attachment
|
|
9632
10304
|
};
|
|
9633
10305
|
}
|
|
9634
|
-
return source;
|
|
10306
|
+
return { ...source };
|
|
9635
10307
|
}
|
|
9636
10308
|
function processAttachmentsInInput(input) {
|
|
9637
10309
|
if (Array.isArray(input)) {
|
|
9638
10310
|
return input.map(processAttachmentsInInput);
|
|
9639
10311
|
}
|
|
9640
10312
|
if (isObject(input)) {
|
|
9641
|
-
if ((input
|
|
10313
|
+
if (isAnthropicBase64ContentBlock(input)) {
|
|
9642
10314
|
return {
|
|
9643
10315
|
...input,
|
|
9644
10316
|
source: convertBase64ToAttachment(input.source, input.type)
|
|
@@ -9669,8 +10341,35 @@ function filterFrom(obj, fieldsToRemove) {
|
|
|
9669
10341
|
return result;
|
|
9670
10342
|
}
|
|
9671
10343
|
|
|
10344
|
+
// src/instrumentation/plugins/ai-sdk-channels.ts
|
|
10345
|
+
var aiSDKChannels = defineChannels("ai", {
|
|
10346
|
+
generateText: channel({
|
|
10347
|
+
channelName: "generateText",
|
|
10348
|
+
kind: "async"
|
|
10349
|
+
}),
|
|
10350
|
+
streamText: channel({
|
|
10351
|
+
channelName: "streamText",
|
|
10352
|
+
kind: "async"
|
|
10353
|
+
}),
|
|
10354
|
+
generateObject: channel({
|
|
10355
|
+
channelName: "generateObject",
|
|
10356
|
+
kind: "async"
|
|
10357
|
+
}),
|
|
10358
|
+
streamObject: channel({
|
|
10359
|
+
channelName: "streamObject",
|
|
10360
|
+
kind: "async"
|
|
10361
|
+
}),
|
|
10362
|
+
agentGenerate: channel({
|
|
10363
|
+
channelName: "Agent.generate",
|
|
10364
|
+
kind: "async"
|
|
10365
|
+
}),
|
|
10366
|
+
agentStream: channel({
|
|
10367
|
+
channelName: "Agent.stream",
|
|
10368
|
+
kind: "async"
|
|
10369
|
+
})
|
|
10370
|
+
});
|
|
10371
|
+
|
|
9672
10372
|
// src/instrumentation/plugins/ai-sdk-plugin.ts
|
|
9673
|
-
import { tracingChannel as tracingChannel3 } from "dc-browser";
|
|
9674
10373
|
var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
9675
10374
|
// v3
|
|
9676
10375
|
"roundtrips[].request.body",
|
|
@@ -9686,7 +10385,6 @@ var DEFAULT_DENY_OUTPUT_PATHS = [
|
|
|
9686
10385
|
"steps[].response.headers"
|
|
9687
10386
|
];
|
|
9688
10387
|
var AISDKPlugin = class extends BasePlugin {
|
|
9689
|
-
unsubscribers = [];
|
|
9690
10388
|
config;
|
|
9691
10389
|
constructor(config = {}) {
|
|
9692
10390
|
super();
|
|
@@ -9696,249 +10394,148 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9696
10394
|
this.subscribeToAISDK();
|
|
9697
10395
|
}
|
|
9698
10396
|
onDisable() {
|
|
9699
|
-
|
|
9700
|
-
unsubscribe();
|
|
9701
|
-
}
|
|
9702
|
-
this.unsubscribers = [];
|
|
10397
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
9703
10398
|
}
|
|
9704
10399
|
subscribeToAISDK() {
|
|
9705
10400
|
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
|
-
return metrics;
|
|
9725
|
-
},
|
|
9726
|
-
aggregateChunks: aggregateAISDKChunks
|
|
9727
|
-
});
|
|
9728
|
-
this.subscribeToStreamingChannel("orchestrion:ai-sdk:streamText", {
|
|
9729
|
-
name: "streamText",
|
|
9730
|
-
type: "llm" /* LLM */,
|
|
9731
|
-
extractInput: (args) => {
|
|
9732
|
-
const params = args[0] || {};
|
|
9733
|
-
return {
|
|
9734
|
-
input: processAISDKInput(params),
|
|
9735
|
-
metadata: extractMetadataFromParams(params)
|
|
9736
|
-
};
|
|
9737
|
-
},
|
|
9738
|
-
extractOutput: (result) => {
|
|
9739
|
-
return processAISDKOutput(result, denyOutputPaths);
|
|
9740
|
-
},
|
|
9741
|
-
extractMetrics: (result, startTime) => {
|
|
9742
|
-
const metrics = extractTokenMetrics(result);
|
|
9743
|
-
if (startTime) {
|
|
9744
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9745
|
-
}
|
|
9746
|
-
return metrics;
|
|
9747
|
-
},
|
|
9748
|
-
aggregateChunks: aggregateAISDKChunks
|
|
9749
|
-
});
|
|
9750
|
-
this.subscribeToStreamingChannel("orchestrion:ai-sdk:generateObject", {
|
|
9751
|
-
name: "generateObject",
|
|
9752
|
-
type: "llm" /* LLM */,
|
|
9753
|
-
extractInput: (args) => {
|
|
9754
|
-
const params = args[0] || {};
|
|
9755
|
-
return {
|
|
9756
|
-
input: processAISDKInput(params),
|
|
9757
|
-
metadata: extractMetadataFromParams(params)
|
|
9758
|
-
};
|
|
9759
|
-
},
|
|
9760
|
-
extractOutput: (result) => {
|
|
9761
|
-
return processAISDKOutput(result, denyOutputPaths);
|
|
9762
|
-
},
|
|
9763
|
-
extractMetrics: (result, startTime) => {
|
|
9764
|
-
const metrics = extractTokenMetrics(result);
|
|
9765
|
-
if (startTime) {
|
|
9766
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9767
|
-
}
|
|
9768
|
-
return metrics;
|
|
9769
|
-
},
|
|
9770
|
-
aggregateChunks: aggregateAISDKChunks
|
|
9771
|
-
});
|
|
9772
|
-
this.subscribeToStreamingChannel("orchestrion:ai-sdk:streamObject", {
|
|
9773
|
-
name: "streamObject",
|
|
9774
|
-
type: "llm" /* LLM */,
|
|
9775
|
-
extractInput: (args) => {
|
|
9776
|
-
const params = args[0] || {};
|
|
9777
|
-
return {
|
|
9778
|
-
input: processAISDKInput(params),
|
|
9779
|
-
metadata: extractMetadataFromParams(params)
|
|
9780
|
-
};
|
|
9781
|
-
},
|
|
9782
|
-
extractOutput: (result) => {
|
|
9783
|
-
return processAISDKOutput(result, denyOutputPaths);
|
|
9784
|
-
},
|
|
9785
|
-
extractMetrics: (result, startTime) => {
|
|
9786
|
-
const metrics = extractTokenMetrics(result);
|
|
9787
|
-
if (startTime) {
|
|
9788
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9789
|
-
}
|
|
9790
|
-
return metrics;
|
|
9791
|
-
},
|
|
9792
|
-
aggregateChunks: aggregateAISDKChunks
|
|
9793
|
-
});
|
|
9794
|
-
this.subscribeToStreamingChannel("orchestrion:ai-sdk:Agent.generate", {
|
|
9795
|
-
name: "Agent.generate",
|
|
9796
|
-
type: "llm" /* LLM */,
|
|
9797
|
-
extractInput: (args) => {
|
|
9798
|
-
const params = args[0] || {};
|
|
9799
|
-
return {
|
|
9800
|
-
input: processAISDKInput(params),
|
|
9801
|
-
metadata: extractMetadataFromParams(params)
|
|
9802
|
-
};
|
|
9803
|
-
},
|
|
9804
|
-
extractOutput: (result) => {
|
|
9805
|
-
return processAISDKOutput(result, denyOutputPaths);
|
|
9806
|
-
},
|
|
9807
|
-
extractMetrics: (result, startTime) => {
|
|
9808
|
-
const metrics = extractTokenMetrics(result);
|
|
9809
|
-
if (startTime) {
|
|
9810
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9811
|
-
}
|
|
9812
|
-
return metrics;
|
|
9813
|
-
},
|
|
9814
|
-
aggregateChunks: aggregateAISDKChunks
|
|
9815
|
-
});
|
|
9816
|
-
this.subscribeToStreamingChannel("orchestrion:ai-sdk:Agent.stream", {
|
|
9817
|
-
name: "Agent.stream",
|
|
9818
|
-
type: "llm" /* LLM */,
|
|
9819
|
-
extractInput: (args) => {
|
|
9820
|
-
const params = args[0] || {};
|
|
9821
|
-
return {
|
|
9822
|
-
input: processAISDKInput(params),
|
|
9823
|
-
metadata: extractMetadataFromParams(params)
|
|
9824
|
-
};
|
|
9825
|
-
},
|
|
9826
|
-
extractOutput: (result) => {
|
|
9827
|
-
return processAISDKOutput(result, denyOutputPaths);
|
|
9828
|
-
},
|
|
9829
|
-
extractMetrics: (result, startTime) => {
|
|
9830
|
-
const metrics = extractTokenMetrics(result);
|
|
9831
|
-
if (startTime) {
|
|
9832
|
-
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9833
|
-
}
|
|
9834
|
-
return metrics;
|
|
9835
|
-
},
|
|
9836
|
-
aggregateChunks: aggregateAISDKChunks
|
|
9837
|
-
});
|
|
9838
|
-
}
|
|
9839
|
-
/**
|
|
9840
|
-
* Subscribe to a channel for async methods that may return streams.
|
|
9841
|
-
* Handles both streaming and non-streaming responses.
|
|
9842
|
-
*/
|
|
9843
|
-
subscribeToStreamingChannel(channelName, config) {
|
|
9844
|
-
const channel = tracingChannel3(channelName);
|
|
9845
|
-
const spans = /* @__PURE__ */ new WeakMap();
|
|
9846
|
-
const handlers = {
|
|
9847
|
-
start: (event) => {
|
|
9848
|
-
const span = startSpan({
|
|
9849
|
-
name: config.name,
|
|
9850
|
-
spanAttributes: {
|
|
9851
|
-
type: config.type
|
|
10401
|
+
this.unsubscribers.push(
|
|
10402
|
+
traceStreamingChannel(aiSDKChannels.generateText, {
|
|
10403
|
+
name: "generateText",
|
|
10404
|
+
type: "llm" /* LLM */,
|
|
10405
|
+
extractInput: ([params]) => {
|
|
10406
|
+
return {
|
|
10407
|
+
input: processAISDKInput(params),
|
|
10408
|
+
metadata: extractMetadataFromParams(params)
|
|
10409
|
+
};
|
|
10410
|
+
},
|
|
10411
|
+
extractOutput: (result) => {
|
|
10412
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
10413
|
+
},
|
|
10414
|
+
extractMetrics: (result, startTime) => {
|
|
10415
|
+
const metrics = extractTokenMetrics(result);
|
|
10416
|
+
if (startTime) {
|
|
10417
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9852
10418
|
}
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
|
|
9856
|
-
|
|
9857
|
-
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
return;
|
|
9870
|
-
}
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
9895
|
-
|
|
9896
|
-
|
|
9897
|
-
|
|
9898
|
-
|
|
9899
|
-
|
|
9900
|
-
|
|
9901
|
-
|
|
9902
|
-
|
|
9903
|
-
|
|
9904
|
-
|
|
9905
|
-
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
|
|
9909
|
-
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
|
|
9913
|
-
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
9920
|
-
|
|
9921
|
-
|
|
10419
|
+
return metrics;
|
|
10420
|
+
},
|
|
10421
|
+
aggregateChunks: aggregateAISDKChunks
|
|
10422
|
+
})
|
|
10423
|
+
);
|
|
10424
|
+
this.unsubscribers.push(
|
|
10425
|
+
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
10426
|
+
name: "streamText",
|
|
10427
|
+
type: "llm" /* LLM */,
|
|
10428
|
+
extractInput: ([params]) => {
|
|
10429
|
+
return {
|
|
10430
|
+
input: processAISDKInput(params),
|
|
10431
|
+
metadata: extractMetadataFromParams(params)
|
|
10432
|
+
};
|
|
10433
|
+
},
|
|
10434
|
+
extractOutput: (result) => {
|
|
10435
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
10436
|
+
},
|
|
10437
|
+
extractMetrics: (result, startTime) => {
|
|
10438
|
+
const metrics = extractTokenMetrics(result);
|
|
10439
|
+
if (startTime) {
|
|
10440
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
10441
|
+
}
|
|
10442
|
+
return metrics;
|
|
10443
|
+
},
|
|
10444
|
+
aggregateChunks: aggregateAISDKChunks
|
|
10445
|
+
})
|
|
10446
|
+
);
|
|
10447
|
+
this.unsubscribers.push(
|
|
10448
|
+
traceStreamingChannel(aiSDKChannels.generateObject, {
|
|
10449
|
+
name: "generateObject",
|
|
10450
|
+
type: "llm" /* LLM */,
|
|
10451
|
+
extractInput: ([params]) => {
|
|
10452
|
+
return {
|
|
10453
|
+
input: processAISDKInput(params),
|
|
10454
|
+
metadata: extractMetadataFromParams(params)
|
|
10455
|
+
};
|
|
10456
|
+
},
|
|
10457
|
+
extractOutput: (result) => {
|
|
10458
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
10459
|
+
},
|
|
10460
|
+
extractMetrics: (result, startTime) => {
|
|
10461
|
+
const metrics = extractTokenMetrics(result);
|
|
10462
|
+
if (startTime) {
|
|
10463
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
10464
|
+
}
|
|
10465
|
+
return metrics;
|
|
10466
|
+
},
|
|
10467
|
+
aggregateChunks: aggregateAISDKChunks
|
|
10468
|
+
})
|
|
10469
|
+
);
|
|
10470
|
+
this.unsubscribers.push(
|
|
10471
|
+
traceStreamingChannel(aiSDKChannels.streamObject, {
|
|
10472
|
+
name: "streamObject",
|
|
10473
|
+
type: "llm" /* LLM */,
|
|
10474
|
+
extractInput: ([params]) => {
|
|
10475
|
+
return {
|
|
10476
|
+
input: processAISDKInput(params),
|
|
10477
|
+
metadata: extractMetadataFromParams(params)
|
|
10478
|
+
};
|
|
10479
|
+
},
|
|
10480
|
+
extractOutput: (result) => {
|
|
10481
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
10482
|
+
},
|
|
10483
|
+
extractMetrics: (result, startTime) => {
|
|
10484
|
+
const metrics = extractTokenMetrics(result);
|
|
10485
|
+
if (startTime) {
|
|
10486
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
10487
|
+
}
|
|
10488
|
+
return metrics;
|
|
10489
|
+
},
|
|
10490
|
+
aggregateChunks: aggregateAISDKChunks
|
|
10491
|
+
})
|
|
10492
|
+
);
|
|
10493
|
+
this.unsubscribers.push(
|
|
10494
|
+
traceStreamingChannel(aiSDKChannels.agentGenerate, {
|
|
10495
|
+
name: "Agent.generate",
|
|
10496
|
+
type: "llm" /* LLM */,
|
|
10497
|
+
extractInput: ([params]) => {
|
|
10498
|
+
return {
|
|
10499
|
+
input: processAISDKInput(params),
|
|
10500
|
+
metadata: extractMetadataFromParams(params)
|
|
10501
|
+
};
|
|
10502
|
+
},
|
|
10503
|
+
extractOutput: (result) => {
|
|
10504
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
10505
|
+
},
|
|
10506
|
+
extractMetrics: (result, startTime) => {
|
|
10507
|
+
const metrics = extractTokenMetrics(result);
|
|
10508
|
+
if (startTime) {
|
|
10509
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
10510
|
+
}
|
|
10511
|
+
return metrics;
|
|
10512
|
+
},
|
|
10513
|
+
aggregateChunks: aggregateAISDKChunks
|
|
10514
|
+
})
|
|
10515
|
+
);
|
|
10516
|
+
this.unsubscribers.push(
|
|
10517
|
+
traceStreamingChannel(aiSDKChannels.agentStream, {
|
|
10518
|
+
name: "Agent.stream",
|
|
10519
|
+
type: "llm" /* LLM */,
|
|
10520
|
+
extractInput: ([params]) => {
|
|
10521
|
+
return {
|
|
10522
|
+
input: processAISDKInput(params),
|
|
10523
|
+
metadata: extractMetadataFromParams(params)
|
|
10524
|
+
};
|
|
10525
|
+
},
|
|
10526
|
+
extractOutput: (result) => {
|
|
10527
|
+
return processAISDKOutput(result, denyOutputPaths);
|
|
10528
|
+
},
|
|
10529
|
+
extractMetrics: (result, startTime) => {
|
|
10530
|
+
const metrics = extractTokenMetrics(result);
|
|
10531
|
+
if (startTime) {
|
|
10532
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
9922
10533
|
}
|
|
9923
|
-
|
|
9924
|
-
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
return;
|
|
9929
|
-
}
|
|
9930
|
-
const { span } = spanData;
|
|
9931
|
-
span.log({
|
|
9932
|
-
error: event.error.message
|
|
9933
|
-
});
|
|
9934
|
-
span.end();
|
|
9935
|
-
spans.delete(event);
|
|
9936
|
-
}
|
|
9937
|
-
};
|
|
9938
|
-
channel.subscribe(handlers);
|
|
9939
|
-
this.unsubscribers.push(() => {
|
|
9940
|
-
channel.unsubscribe(handlers);
|
|
9941
|
-
});
|
|
10534
|
+
return metrics;
|
|
10535
|
+
},
|
|
10536
|
+
aggregateChunks: aggregateAISDKChunks
|
|
10537
|
+
})
|
|
10538
|
+
);
|
|
9942
10539
|
}
|
|
9943
10540
|
};
|
|
9944
10541
|
function processAISDKInput(params) {
|
|
@@ -10180,7 +10777,10 @@ function omitAtPath(obj, keys) {
|
|
|
10180
10777
|
if (Array.isArray(obj)) {
|
|
10181
10778
|
obj.forEach((item) => {
|
|
10182
10779
|
if (remainingKeys.length > 0) {
|
|
10183
|
-
omitAtPath(
|
|
10780
|
+
omitAtPath(
|
|
10781
|
+
item,
|
|
10782
|
+
remainingKeys
|
|
10783
|
+
);
|
|
10184
10784
|
}
|
|
10185
10785
|
});
|
|
10186
10786
|
}
|
|
@@ -10190,7 +10790,10 @@ function omitAtPath(obj, keys) {
|
|
|
10190
10790
|
}
|
|
10191
10791
|
} else {
|
|
10192
10792
|
if (obj && typeof obj === "object" && firstKey in obj) {
|
|
10193
|
-
omitAtPath(
|
|
10793
|
+
omitAtPath(
|
|
10794
|
+
obj[firstKey],
|
|
10795
|
+
remainingKeys
|
|
10796
|
+
);
|
|
10194
10797
|
}
|
|
10195
10798
|
}
|
|
10196
10799
|
}
|
|
@@ -10203,8 +10806,18 @@ function omit(obj, paths) {
|
|
|
10203
10806
|
return result;
|
|
10204
10807
|
}
|
|
10205
10808
|
|
|
10809
|
+
// src/instrumentation/plugins/claude-agent-sdk-channels.ts
|
|
10810
|
+
var claudeAgentSDKChannels = defineChannels(
|
|
10811
|
+
"@anthropic-ai/claude-agent-sdk",
|
|
10812
|
+
{
|
|
10813
|
+
query: channel({
|
|
10814
|
+
channelName: "query",
|
|
10815
|
+
kind: "async"
|
|
10816
|
+
})
|
|
10817
|
+
}
|
|
10818
|
+
);
|
|
10819
|
+
|
|
10206
10820
|
// src/instrumentation/plugins/claude-agent-sdk-plugin.ts
|
|
10207
|
-
import { tracingChannel as tracingChannel4 } from "dc-browser";
|
|
10208
10821
|
function filterSerializableOptions(options) {
|
|
10209
10822
|
const allowedKeys = [
|
|
10210
10823
|
"model",
|
|
@@ -10288,7 +10901,9 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
10288
10901
|
const input = buildLLMInput(prompt, conversationHistory);
|
|
10289
10902
|
const outputs = messages.map(
|
|
10290
10903
|
(m) => m.message?.content && m.message?.role ? { content: m.message.content, role: m.message.role } : void 0
|
|
10291
|
-
).filter(
|
|
10904
|
+
).filter(
|
|
10905
|
+
(c) => c !== void 0
|
|
10906
|
+
);
|
|
10292
10907
|
const span = startSpan({
|
|
10293
10908
|
name: "anthropic.messages.create",
|
|
10294
10909
|
spanAttributes: {
|
|
@@ -10307,7 +10922,6 @@ async function createLLMSpanForMessages(messages, prompt, conversationHistory, o
|
|
|
10307
10922
|
return lastMessage.message?.content && lastMessage.message?.role ? { content: lastMessage.message.content, role: lastMessage.message.role } : void 0;
|
|
10308
10923
|
}
|
|
10309
10924
|
var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
10310
|
-
unsubscribers = [];
|
|
10311
10925
|
onEnable() {
|
|
10312
10926
|
this.subscribeToQuery();
|
|
10313
10927
|
}
|
|
@@ -10323,12 +10937,13 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10323
10937
|
* and individual LLM calls.
|
|
10324
10938
|
*/
|
|
10325
10939
|
subscribeToQuery() {
|
|
10326
|
-
const
|
|
10940
|
+
const channel2 = claudeAgentSDKChannels.query.tracingChannel();
|
|
10327
10941
|
const spans = /* @__PURE__ */ new WeakMap();
|
|
10328
10942
|
const handlers = {
|
|
10329
10943
|
start: (event) => {
|
|
10330
|
-
const params = event.arguments[0]
|
|
10331
|
-
const
|
|
10944
|
+
const params = event.arguments[0];
|
|
10945
|
+
const prompt = params?.prompt;
|
|
10946
|
+
const options = params?.options ?? {};
|
|
10332
10947
|
const span = startSpan({
|
|
10333
10948
|
name: "Claude Agent",
|
|
10334
10949
|
spanAttributes: {
|
|
@@ -10340,7 +10955,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10340
10955
|
span.log({
|
|
10341
10956
|
input: typeof prompt === "string" ? prompt : {
|
|
10342
10957
|
type: "streaming",
|
|
10343
|
-
description: "AsyncIterable<
|
|
10958
|
+
description: "AsyncIterable<ClaudeAgentSDKMessage>"
|
|
10344
10959
|
},
|
|
10345
10960
|
metadata: filterSerializableOptions(options)
|
|
10346
10961
|
});
|
|
@@ -10362,12 +10977,19 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10362
10977
|
if (!spanData) {
|
|
10363
10978
|
return;
|
|
10364
10979
|
}
|
|
10365
|
-
|
|
10366
|
-
|
|
10980
|
+
const eventResult = event.result;
|
|
10981
|
+
if (eventResult === void 0) {
|
|
10982
|
+
spanData.span.end();
|
|
10983
|
+
spans.delete(event);
|
|
10984
|
+
return;
|
|
10985
|
+
}
|
|
10986
|
+
if (isAsyncIterable(eventResult)) {
|
|
10987
|
+
patchStreamIfNeeded(eventResult, {
|
|
10367
10988
|
onChunk: async (message) => {
|
|
10368
10989
|
const currentTime = getCurrentUnixTimestamp();
|
|
10369
10990
|
const params = event.arguments[0];
|
|
10370
|
-
const
|
|
10991
|
+
const prompt = params?.prompt;
|
|
10992
|
+
const options = params?.options ?? {};
|
|
10371
10993
|
const messageId = message.message?.id;
|
|
10372
10994
|
if (messageId && messageId !== spanData.currentMessageId) {
|
|
10373
10995
|
if (spanData.currentMessages.length > 0) {
|
|
@@ -10426,7 +11048,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10426
11048
|
onComplete: async () => {
|
|
10427
11049
|
try {
|
|
10428
11050
|
const params = event.arguments[0];
|
|
10429
|
-
const
|
|
11051
|
+
const prompt = params?.prompt;
|
|
11052
|
+
const options = params?.options ?? {};
|
|
10430
11053
|
if (spanData.currentMessages.length > 0) {
|
|
10431
11054
|
const finalMessage = await createLLMSpanForMessages(
|
|
10432
11055
|
spanData.currentMessages,
|
|
@@ -10464,7 +11087,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10464
11087
|
} else {
|
|
10465
11088
|
try {
|
|
10466
11089
|
spanData.span.log({
|
|
10467
|
-
output:
|
|
11090
|
+
output: eventResult
|
|
10468
11091
|
});
|
|
10469
11092
|
} catch (error) {
|
|
10470
11093
|
console.error(
|
|
@@ -10479,7 +11102,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10479
11102
|
},
|
|
10480
11103
|
error: (event) => {
|
|
10481
11104
|
const spanData = spans.get(event);
|
|
10482
|
-
if (!spanData) {
|
|
11105
|
+
if (!spanData || !event.error) {
|
|
10483
11106
|
return;
|
|
10484
11107
|
}
|
|
10485
11108
|
const { span } = spanData;
|
|
@@ -10490,53 +11113,39 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
10490
11113
|
spans.delete(event);
|
|
10491
11114
|
}
|
|
10492
11115
|
};
|
|
10493
|
-
|
|
11116
|
+
channel2.subscribe(handlers);
|
|
10494
11117
|
this.unsubscribers.push(() => {
|
|
10495
|
-
|
|
11118
|
+
channel2.unsubscribe(handlers);
|
|
10496
11119
|
});
|
|
10497
11120
|
}
|
|
10498
11121
|
};
|
|
10499
11122
|
|
|
11123
|
+
// src/instrumentation/plugins/google-genai-channels.ts
|
|
11124
|
+
var googleGenAIChannels = defineChannels("@google/genai", {
|
|
11125
|
+
generateContent: channel({
|
|
11126
|
+
channelName: "models.generateContent",
|
|
11127
|
+
kind: "async"
|
|
11128
|
+
}),
|
|
11129
|
+
generateContentStream: channel({
|
|
11130
|
+
channelName: "models.generateContentStream",
|
|
11131
|
+
kind: "async"
|
|
11132
|
+
})
|
|
11133
|
+
});
|
|
11134
|
+
|
|
10500
11135
|
// src/instrumentation/plugins/google-genai-plugin.ts
|
|
10501
|
-
import { tracingChannel as tracingChannel5 } from "dc-browser";
|
|
10502
11136
|
var GoogleGenAIPlugin = class extends BasePlugin {
|
|
10503
|
-
unsubscribers = [];
|
|
10504
11137
|
onEnable() {
|
|
10505
11138
|
this.subscribeToGoogleGenAIChannels();
|
|
10506
11139
|
}
|
|
10507
11140
|
onDisable() {
|
|
10508
|
-
|
|
10509
|
-
unsubscribe();
|
|
10510
|
-
}
|
|
10511
|
-
this.unsubscribers = [];
|
|
11141
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
10512
11142
|
}
|
|
10513
11143
|
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",
|
|
11144
|
+
this.unsubscribers.push(
|
|
11145
|
+
traceAsyncChannel(googleGenAIChannels.generateContent, {
|
|
11146
|
+
name: "google-genai.generateContent",
|
|
10537
11147
|
type: "llm" /* LLM */,
|
|
10538
|
-
extractInput: (
|
|
10539
|
-
const params = args[0] || {};
|
|
11148
|
+
extractInput: ([params]) => {
|
|
10540
11149
|
const input = serializeInput(params);
|
|
10541
11150
|
const metadata = extractMetadata(params);
|
|
10542
11151
|
return {
|
|
@@ -10544,150 +11153,37 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
10544
11153
|
metadata: { ...metadata, provider: "google-genai" }
|
|
10545
11154
|
};
|
|
10546
11155
|
},
|
|
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;
|
|
11156
|
+
extractOutput: (result) => {
|
|
11157
|
+
return result;
|
|
11158
|
+
},
|
|
11159
|
+
extractMetrics: (result, startTime) => {
|
|
11160
|
+
return extractGenerateContentMetrics(result, startTime);
|
|
10598
11161
|
}
|
|
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({
|
|
11162
|
+
})
|
|
11163
|
+
);
|
|
11164
|
+
this.unsubscribers.push(
|
|
11165
|
+
traceStreamingChannel(googleGenAIChannels.generateContentStream, {
|
|
11166
|
+
name: "google-genai.generateContentStream",
|
|
11167
|
+
type: "llm" /* LLM */,
|
|
11168
|
+
extractInput: ([params]) => {
|
|
11169
|
+
const input = serializeInput(params);
|
|
11170
|
+
const metadata = extractMetadata(params);
|
|
11171
|
+
return {
|
|
10628
11172
|
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;
|
|
11173
|
+
metadata: { ...metadata, provider: "google-genai" }
|
|
11174
|
+
};
|
|
11175
|
+
},
|
|
11176
|
+
extractOutput: (result) => {
|
|
11177
|
+
return result;
|
|
11178
|
+
},
|
|
11179
|
+
extractMetrics: () => {
|
|
11180
|
+
return {};
|
|
11181
|
+
},
|
|
11182
|
+
aggregateChunks: (chunks, _result, _endEvent, startTime) => {
|
|
11183
|
+
return aggregateGenerateContentChunks(chunks, startTime);
|
|
10678
11184
|
}
|
|
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
|
-
});
|
|
11185
|
+
})
|
|
11186
|
+
);
|
|
10691
11187
|
}
|
|
10692
11188
|
};
|
|
10693
11189
|
function serializeInput(params) {
|
|
@@ -10743,8 +11239,12 @@ function serializePart(part) {
|
|
|
10743
11239
|
const buffer = typeof data === "string" ? typeof Buffer !== "undefined" ? Buffer.from(data, "base64") : new Uint8Array(
|
|
10744
11240
|
atob(data).split("").map((c) => c.charCodeAt(0))
|
|
10745
11241
|
) : typeof Buffer !== "undefined" ? Buffer.from(data) : new Uint8Array(data);
|
|
11242
|
+
const arrayBuffer = buffer instanceof Uint8Array ? buffer.buffer.slice(
|
|
11243
|
+
buffer.byteOffset,
|
|
11244
|
+
buffer.byteOffset + buffer.byteLength
|
|
11245
|
+
) : buffer;
|
|
10746
11246
|
const attachment = new Attachment({
|
|
10747
|
-
data:
|
|
11247
|
+
data: arrayBuffer,
|
|
10748
11248
|
filename,
|
|
10749
11249
|
contentType: mimeType || "application/octet-stream"
|
|
10750
11250
|
});
|
|
@@ -10793,33 +11293,36 @@ function extractGenerateContentMetrics(response, startTime) {
|
|
|
10793
11293
|
const end = getCurrentUnixTimestamp();
|
|
10794
11294
|
metrics.duration = end - startTime;
|
|
10795
11295
|
}
|
|
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
|
-
}
|
|
11296
|
+
if (response?.usageMetadata) {
|
|
11297
|
+
populateUsageMetrics(metrics, response.usageMetadata);
|
|
10813
11298
|
}
|
|
10814
11299
|
return metrics;
|
|
10815
11300
|
}
|
|
11301
|
+
function populateUsageMetrics(metrics, usage) {
|
|
11302
|
+
if (usage.promptTokenCount !== void 0) {
|
|
11303
|
+
metrics.prompt_tokens = usage.promptTokenCount;
|
|
11304
|
+
}
|
|
11305
|
+
if (usage.candidatesTokenCount !== void 0) {
|
|
11306
|
+
metrics.completion_tokens = usage.candidatesTokenCount;
|
|
11307
|
+
}
|
|
11308
|
+
if (usage.totalTokenCount !== void 0) {
|
|
11309
|
+
metrics.tokens = usage.totalTokenCount;
|
|
11310
|
+
}
|
|
11311
|
+
if (usage.cachedContentTokenCount !== void 0) {
|
|
11312
|
+
metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
|
|
11313
|
+
}
|
|
11314
|
+
if (usage.thoughtsTokenCount !== void 0) {
|
|
11315
|
+
metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
|
|
11316
|
+
}
|
|
11317
|
+
}
|
|
10816
11318
|
function aggregateGenerateContentChunks(chunks, startTime) {
|
|
10817
|
-
const
|
|
10818
|
-
|
|
10819
|
-
|
|
10820
|
-
|
|
11319
|
+
const metrics = {};
|
|
11320
|
+
if (startTime !== void 0) {
|
|
11321
|
+
const end = getCurrentUnixTimestamp();
|
|
11322
|
+
metrics.duration = end - startTime;
|
|
11323
|
+
}
|
|
10821
11324
|
let firstTokenTime = null;
|
|
10822
|
-
if (chunks.length > 0 && firstTokenTime === null) {
|
|
11325
|
+
if (chunks.length > 0 && firstTokenTime === null && startTime !== void 0) {
|
|
10823
11326
|
firstTokenTime = getCurrentUnixTimestamp();
|
|
10824
11327
|
metrics.time_to_first_token = firstTokenTime - startTime;
|
|
10825
11328
|
}
|
|
@@ -10890,21 +11393,7 @@ function aggregateGenerateContentChunks(chunks, startTime) {
|
|
|
10890
11393
|
}
|
|
10891
11394
|
if (usageMetadata) {
|
|
10892
11395
|
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
|
-
}
|
|
11396
|
+
populateUsageMetrics(metrics, usageMetadata);
|
|
10908
11397
|
}
|
|
10909
11398
|
if (text) {
|
|
10910
11399
|
output.text = text;
|
|
@@ -10916,7 +11405,8 @@ function tryToDict(obj) {
|
|
|
10916
11405
|
return null;
|
|
10917
11406
|
}
|
|
10918
11407
|
if (typeof obj === "object") {
|
|
10919
|
-
if (
|
|
11408
|
+
if ("toJSON" in obj && // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
11409
|
+
typeof obj.toJSON === "function") {
|
|
10920
11410
|
return obj.toJSON();
|
|
10921
11411
|
}
|
|
10922
11412
|
return obj;
|
|
@@ -11080,6 +11570,7 @@ function configureNode() {
|
|
|
11080
11570
|
isomorph_default.getEnv = (name) => process.env[name];
|
|
11081
11571
|
isomorph_default.getCallerLocation = getCallerLocation;
|
|
11082
11572
|
isomorph_default.newAsyncLocalStorage = () => new AsyncLocalStorage();
|
|
11573
|
+
isomorph_default.newTracingChannel = (nameOrChannels) => diagnostics_channel.tracingChannel(nameOrChannels);
|
|
11083
11574
|
isomorph_default.processOn = (event, handler) => {
|
|
11084
11575
|
process.on(event, handler);
|
|
11085
11576
|
};
|
|
@@ -12550,6 +13041,11 @@ var evalParametersSchema = z10.record(
|
|
|
12550
13041
|
default: promptDefinitionWithToolsSchema.optional(),
|
|
12551
13042
|
description: z10.string().optional()
|
|
12552
13043
|
}),
|
|
13044
|
+
z10.object({
|
|
13045
|
+
type: z10.literal("model"),
|
|
13046
|
+
default: z10.string().optional(),
|
|
13047
|
+
description: z10.string().optional()
|
|
13048
|
+
}),
|
|
12553
13049
|
z10.instanceof(z10.ZodType)
|
|
12554
13050
|
// For Zod schemas
|
|
12555
13051
|
])
|
|
@@ -12592,6 +13088,17 @@ function validateParametersWithZod(parameters, parameterSchema) {
|
|
|
12592
13088
|
throw new Error(`Parameter '${name}' is required`);
|
|
12593
13089
|
}
|
|
12594
13090
|
return [name, Prompt2.fromPromptData(name, promptData)];
|
|
13091
|
+
} else if ("type" in schema && schema.type === "model") {
|
|
13092
|
+
const model = value ?? schema.default;
|
|
13093
|
+
if (model === void 0) {
|
|
13094
|
+
throw new Error(`Parameter '${name}' is required`);
|
|
13095
|
+
}
|
|
13096
|
+
if (typeof model !== "string") {
|
|
13097
|
+
throw new Error(
|
|
13098
|
+
`Parameter '${name}' must be a string model identifier`
|
|
13099
|
+
);
|
|
13100
|
+
}
|
|
13101
|
+
return [name, model];
|
|
12595
13102
|
} else {
|
|
12596
13103
|
const schemaCasted = schema;
|
|
12597
13104
|
return [name, schemaCasted.parse(value)];
|
|
@@ -12666,10 +13173,10 @@ function callEvaluatorData(data) {
|
|
|
12666
13173
|
};
|
|
12667
13174
|
}
|
|
12668
13175
|
function isAsyncIterable3(value) {
|
|
12669
|
-
return typeof value === "object" && value !== null && typeof value[Symbol.asyncIterator] === "function";
|
|
13176
|
+
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
12670
13177
|
}
|
|
12671
13178
|
function isIterable(value) {
|
|
12672
|
-
return typeof value === "object" && value !== null && typeof value[Symbol.iterator] === "function";
|
|
13179
|
+
return typeof value === "object" && value !== null && Symbol.iterator in value && typeof value[Symbol.iterator] === "function";
|
|
12673
13180
|
}
|
|
12674
13181
|
globalThis._evals = {
|
|
12675
13182
|
functions: [],
|
|
@@ -13105,7 +13612,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
13105
13612
|
const names = Object.keys(scorerErrors).join(", ");
|
|
13106
13613
|
const errors = failingScorersAndResults.map((item) => item.error);
|
|
13107
13614
|
unhandledScores = Object.keys(scorerErrors);
|
|
13108
|
-
|
|
13615
|
+
debugLogger.forState(evaluator.state).warn(
|
|
13109
13616
|
`Found exceptions for the following scorers: ${names}`,
|
|
13110
13617
|
errors
|
|
13111
13618
|
);
|
|
@@ -13223,7 +13730,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
|
|
|
13223
13730
|
q.kill();
|
|
13224
13731
|
if (e instanceof InternalAbortError) {
|
|
13225
13732
|
if (isomorph_default.getEnv("BRAINTRUST_VERBOSE")) {
|
|
13226
|
-
|
|
13733
|
+
debugLogger.forState(evaluator.state).warn("Evaluator cancelled:", e.message);
|
|
13227
13734
|
}
|
|
13228
13735
|
}
|
|
13229
13736
|
throw e;
|
|
@@ -13318,7 +13825,11 @@ function reportFailures(evaluator, failingResults, { verbose, jsonl }) {
|
|
|
13318
13825
|
}
|
|
13319
13826
|
}
|
|
13320
13827
|
if (!verbose && !jsonl) {
|
|
13321
|
-
console.error(
|
|
13828
|
+
console.error(
|
|
13829
|
+
warning(
|
|
13830
|
+
"Use --debug-logging debug to see full stack traces and troubleshooting details."
|
|
13831
|
+
)
|
|
13832
|
+
);
|
|
13322
13833
|
}
|
|
13323
13834
|
}
|
|
13324
13835
|
}
|
|
@@ -13619,6 +14130,11 @@ var staticParametersSchema = z12.record(
|
|
|
13619
14130
|
default: PromptData.optional(),
|
|
13620
14131
|
description: z12.string().optional()
|
|
13621
14132
|
}),
|
|
14133
|
+
z12.object({
|
|
14134
|
+
type: z12.literal("model"),
|
|
14135
|
+
default: z12.string().optional(),
|
|
14136
|
+
description: z12.string().optional()
|
|
14137
|
+
}),
|
|
13622
14138
|
z12.object({
|
|
13623
14139
|
type: z12.literal("data"),
|
|
13624
14140
|
schema: z12.record(z12.unknown()),
|
|
@@ -13855,6 +14371,7 @@ var CodeFunction = class {
|
|
|
13855
14371
|
this.description = opts.description;
|
|
13856
14372
|
this.type = opts.type;
|
|
13857
14373
|
this.ifExists = opts.ifExists;
|
|
14374
|
+
this.tags = opts.tags;
|
|
13858
14375
|
this.metadata = opts.metadata;
|
|
13859
14376
|
this.parameters = opts.parameters;
|
|
13860
14377
|
this.returns = opts.returns;
|
|
@@ -13870,6 +14387,7 @@ var CodeFunction = class {
|
|
|
13870
14387
|
parameters;
|
|
13871
14388
|
returns;
|
|
13872
14389
|
ifExists;
|
|
14390
|
+
tags;
|
|
13873
14391
|
metadata;
|
|
13874
14392
|
key() {
|
|
13875
14393
|
return JSON.stringify([
|
|
@@ -13889,6 +14407,7 @@ var CodePrompt = class {
|
|
|
13889
14407
|
id;
|
|
13890
14408
|
functionType;
|
|
13891
14409
|
toolFunctions;
|
|
14410
|
+
tags;
|
|
13892
14411
|
metadata;
|
|
13893
14412
|
constructor(project, prompt, toolFunctions, opts, functionType) {
|
|
13894
14413
|
this.project = project;
|
|
@@ -13900,6 +14419,7 @@ var CodePrompt = class {
|
|
|
13900
14419
|
this.description = opts.description;
|
|
13901
14420
|
this.id = opts.id;
|
|
13902
14421
|
this.functionType = functionType;
|
|
14422
|
+
this.tags = opts.tags;
|
|
13903
14423
|
this.metadata = opts.metadata;
|
|
13904
14424
|
}
|
|
13905
14425
|
async toFunctionDefinition(projectNameToId) {
|
|
@@ -13934,6 +14454,7 @@ var CodePrompt = class {
|
|
|
13934
14454
|
function_type: this.functionType,
|
|
13935
14455
|
prompt_data,
|
|
13936
14456
|
if_exists: this.ifExists,
|
|
14457
|
+
tags: this.tags,
|
|
13937
14458
|
metadata: this.metadata
|
|
13938
14459
|
};
|
|
13939
14460
|
}
|
|
@@ -13962,6 +14483,7 @@ var PromptBuilder = class {
|
|
|
13962
14483
|
name: opts.name,
|
|
13963
14484
|
slug,
|
|
13964
14485
|
prompt_data: promptData,
|
|
14486
|
+
tags: opts.tags,
|
|
13965
14487
|
...this.project.id !== void 0 ? { project_id: this.project.id } : {}
|
|
13966
14488
|
};
|
|
13967
14489
|
const prompt = new Prompt2(
|
|
@@ -14043,6 +14565,15 @@ function serializeEvalParametersToStaticParametersSchema(parameters) {
|
|
|
14043
14565
|
description: value.description
|
|
14044
14566
|
}
|
|
14045
14567
|
];
|
|
14568
|
+
} else if ("type" in value && value.type === "model") {
|
|
14569
|
+
return [
|
|
14570
|
+
name,
|
|
14571
|
+
{
|
|
14572
|
+
type: "model",
|
|
14573
|
+
default: value.default,
|
|
14574
|
+
description: value.description
|
|
14575
|
+
}
|
|
14576
|
+
];
|
|
14046
14577
|
} else {
|
|
14047
14578
|
const schemaObj = zodToJsonSchema(value);
|
|
14048
14579
|
return [
|
|
@@ -14073,6 +14604,16 @@ function serializeEvalParameterstoParametersSchema(parameters) {
|
|
|
14073
14604
|
if (!defaultPromptData) {
|
|
14074
14605
|
required.push(name);
|
|
14075
14606
|
}
|
|
14607
|
+
} else if ("type" in value && value.type === "model") {
|
|
14608
|
+
properties[name] = {
|
|
14609
|
+
type: "string",
|
|
14610
|
+
"x-bt-type": "model",
|
|
14611
|
+
...value.description ? { description: value.description } : {},
|
|
14612
|
+
..."default" in value ? { default: value.default } : {}
|
|
14613
|
+
};
|
|
14614
|
+
if (!("default" in value)) {
|
|
14615
|
+
required.push(name);
|
|
14616
|
+
}
|
|
14076
14617
|
} else {
|
|
14077
14618
|
const schemaObj = zodToJsonSchema(value);
|
|
14078
14619
|
properties[name] = schemaObj;
|