braintrust 3.8.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dev/dist/index.d.mts +84 -3
- package/dev/dist/index.d.ts +84 -3
- package/dev/dist/index.js +3687 -691
- package/dev/dist/index.mjs +3399 -403
- package/dist/auto-instrumentations/bundler/esbuild.cjs +575 -2
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/rollup.cjs +575 -2
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +575 -2
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +575 -2
- package/dist/auto-instrumentations/bundler/webpack.cjs +575 -2
- package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
- package/dist/auto-instrumentations/{chunk-MD7W27YH.mjs → chunk-G7F6HZGE.mjs} +5 -1
- package/dist/auto-instrumentations/{chunk-OLBMPZXE.mjs → chunk-KIMMUFAK.mjs} +578 -3
- package/dist/auto-instrumentations/hook.mjs +757 -10
- package/dist/auto-instrumentations/index.cjs +739 -2
- package/dist/auto-instrumentations/index.d.mts +18 -1
- package/dist/auto-instrumentations/index.d.ts +18 -1
- package/dist/auto-instrumentations/index.mjs +168 -1
- package/dist/auto-instrumentations/loader/esm-hook.mjs +2 -1
- package/dist/browser.d.mts +312 -6
- package/dist/browser.d.ts +312 -6
- package/dist/browser.js +5335 -1892
- package/dist/browser.mjs +5335 -1892
- package/dist/cli.js +3514 -489
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +5335 -1892
- package/dist/edge-light.mjs +5335 -1892
- package/dist/index.d.mts +312 -6
- package/dist/index.d.ts +312 -6
- package/dist/index.js +4244 -801
- package/dist/index.mjs +5335 -1892
- package/dist/instrumentation/index.d.mts +10 -0
- package/dist/instrumentation/index.d.ts +10 -0
- package/dist/instrumentation/index.js +3160 -286
- package/dist/instrumentation/index.mjs +3160 -286
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +5335 -1892
- package/dist/workerd.mjs +5335 -1892
- package/package.json +52 -47
- package/util/dist/index.d.mts +42 -1
- package/util/dist/index.d.ts +42 -1
- package/util/dist/index.js +5 -1
- package/util/dist/index.mjs +4 -0
- package/LICENSE +0 -201
|
@@ -99,6 +99,16 @@ var isomorph_default = iso;
|
|
|
99
99
|
function isAsyncIterable(value) {
|
|
100
100
|
return value !== null && typeof value === "object" && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
101
101
|
}
|
|
102
|
+
function hasAsyncIteratorMethods(value) {
|
|
103
|
+
return value !== null && typeof value === "object" && "next" in value && typeof value.next === "function";
|
|
104
|
+
}
|
|
105
|
+
function isSelfAsyncIterator(value) {
|
|
106
|
+
try {
|
|
107
|
+
return value[Symbol.asyncIterator]() === value;
|
|
108
|
+
} catch {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
102
112
|
function patchStreamIfNeeded(stream, options) {
|
|
103
113
|
if (!isAsyncIterable(stream)) {
|
|
104
114
|
return stream;
|
|
@@ -109,6 +119,98 @@ function patchStreamIfNeeded(stream, options) {
|
|
|
109
119
|
);
|
|
110
120
|
return stream;
|
|
111
121
|
}
|
|
122
|
+
if (hasAsyncIteratorMethods(stream) && isSelfAsyncIterator(stream)) {
|
|
123
|
+
if ("__braintrust_patched_iterator_methods" in stream) {
|
|
124
|
+
return stream;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const originalNext = stream.next.bind(stream);
|
|
128
|
+
const originalReturn = typeof stream.return === "function" ? stream.return.bind(stream) : null;
|
|
129
|
+
const originalThrow = typeof stream.throw === "function" ? stream.throw.bind(stream) : null;
|
|
130
|
+
const chunks = [];
|
|
131
|
+
let completed = false;
|
|
132
|
+
stream.next = async (...args) => {
|
|
133
|
+
try {
|
|
134
|
+
const result = await originalNext(...args);
|
|
135
|
+
if (result.done) {
|
|
136
|
+
if (!completed) {
|
|
137
|
+
completed = true;
|
|
138
|
+
try {
|
|
139
|
+
await options.onComplete(chunks);
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.error("Error in stream onComplete handler:", error);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
const chunk = result.value;
|
|
146
|
+
const shouldCollect = options.shouldCollect ? options.shouldCollect(chunk) : true;
|
|
147
|
+
if (shouldCollect) {
|
|
148
|
+
chunks.push(chunk);
|
|
149
|
+
if (options.onChunk) {
|
|
150
|
+
try {
|
|
151
|
+
await options.onChunk(chunk);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.error("Error in stream onChunk handler:", error);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
} catch (error) {
|
|
160
|
+
if (!completed) {
|
|
161
|
+
completed = true;
|
|
162
|
+
if (options.onError) {
|
|
163
|
+
try {
|
|
164
|
+
await options.onError(
|
|
165
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
166
|
+
chunks
|
|
167
|
+
);
|
|
168
|
+
} catch (handlerError) {
|
|
169
|
+
console.error("Error in stream onError handler:", handlerError);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
if (originalReturn) {
|
|
177
|
+
stream.return = async (...args) => {
|
|
178
|
+
if (!completed) {
|
|
179
|
+
completed = true;
|
|
180
|
+
try {
|
|
181
|
+
await options.onComplete(chunks);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error("Error in stream onComplete handler:", error);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return originalReturn(...args);
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (originalThrow) {
|
|
190
|
+
stream.throw = async (...args) => {
|
|
191
|
+
if (!completed) {
|
|
192
|
+
completed = true;
|
|
193
|
+
const rawError = args[0];
|
|
194
|
+
const error = rawError instanceof Error ? rawError : new Error(String(rawError));
|
|
195
|
+
if (options.onError) {
|
|
196
|
+
try {
|
|
197
|
+
await options.onError(error, chunks);
|
|
198
|
+
} catch (handlerError) {
|
|
199
|
+
console.error("Error in stream onError handler:", handlerError);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return originalThrow(...args);
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
Object.defineProperty(stream, "__braintrust_patched_iterator_methods", {
|
|
207
|
+
value: true
|
|
208
|
+
});
|
|
209
|
+
return stream;
|
|
210
|
+
} catch (error) {
|
|
211
|
+
console.warn("Failed to patch stream iterator methods:", error);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
112
214
|
const originalIteratorFn = stream[Symbol.asyncIterator];
|
|
113
215
|
if ("__braintrust_patched" in originalIteratorFn && originalIteratorFn["__braintrust_patched"]) {
|
|
114
216
|
return stream;
|
|
@@ -1018,6 +1120,9 @@ function isArray(value) {
|
|
|
1018
1120
|
function isObjectOrArray(value) {
|
|
1019
1121
|
return value instanceof Object;
|
|
1020
1122
|
}
|
|
1123
|
+
function isPromiseLike(value) {
|
|
1124
|
+
return value != null && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
1125
|
+
}
|
|
1021
1126
|
|
|
1022
1127
|
// util/object_util.ts
|
|
1023
1128
|
var SET_UNION_FIELDS = /* @__PURE__ */ new Set(["tags"]);
|
|
@@ -1973,7 +2078,11 @@ var CodeBundle = z6.object({
|
|
|
1973
2078
|
eval_name: z6.string(),
|
|
1974
2079
|
position: z6.union([
|
|
1975
2080
|
z6.object({ type: z6.literal("task") }),
|
|
1976
|
-
z6.object({ type: z6.literal("scorer"), index: z6.number().int().gte(0) })
|
|
2081
|
+
z6.object({ type: z6.literal("scorer"), index: z6.number().int().gte(0) }),
|
|
2082
|
+
z6.object({
|
|
2083
|
+
type: z6.literal("classifier"),
|
|
2084
|
+
index: z6.number().int().gte(0)
|
|
2085
|
+
})
|
|
1977
2086
|
])
|
|
1978
2087
|
}),
|
|
1979
2088
|
z6.object({ type: z6.literal("function"), index: z6.number().int().gte(0) }),
|
|
@@ -3095,11 +3204,15 @@ var RunEval = z6.object({
|
|
|
3095
3204
|
data: z6.union([
|
|
3096
3205
|
z6.object({
|
|
3097
3206
|
dataset_id: z6.string(),
|
|
3207
|
+
dataset_version: z6.union([z6.string(), z6.null()]).optional(),
|
|
3208
|
+
dataset_environment: z6.union([z6.string(), z6.null()]).optional(),
|
|
3098
3209
|
_internal_btql: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
|
|
3099
3210
|
}),
|
|
3100
3211
|
z6.object({
|
|
3101
3212
|
project_name: z6.string(),
|
|
3102
3213
|
dataset_name: z6.string(),
|
|
3214
|
+
dataset_version: z6.union([z6.string(), z6.null()]).optional(),
|
|
3215
|
+
dataset_environment: z6.union([z6.string(), z6.null()]).optional(),
|
|
3103
3216
|
_internal_btql: z6.union([z6.object({}).partial().passthrough(), z6.null()]).optional()
|
|
3104
3217
|
}),
|
|
3105
3218
|
z6.object({ data: z6.array(z6.unknown()) })
|
|
@@ -3227,6 +3340,7 @@ var ViewOptions = z6.union([
|
|
|
3227
3340
|
rowHeight: z6.union([z6.string(), z6.null()]),
|
|
3228
3341
|
tallGroupRows: z6.union([z6.boolean(), z6.null()]),
|
|
3229
3342
|
layout: z6.union([z6.string(), z6.null()]),
|
|
3343
|
+
topicMapReportKey: z6.union([z6.string(), z6.null()]),
|
|
3230
3344
|
chartHeight: z6.union([z6.number(), z6.null()]),
|
|
3231
3345
|
excludedMeasures: z6.union([
|
|
3232
3346
|
z6.array(
|
|
@@ -3269,6 +3383,7 @@ var ViewOptions = z6.union([
|
|
|
3269
3383
|
z6.null()
|
|
3270
3384
|
]),
|
|
3271
3385
|
queryShape: z6.union([z6.enum(["traces", "spans"]), z6.null()]),
|
|
3386
|
+
cluster: z6.union([z6.string(), z6.null()]),
|
|
3272
3387
|
freezeColumns: z6.union([z6.boolean(), z6.null()])
|
|
3273
3388
|
}).partial(),
|
|
3274
3389
|
z6.null()
|
|
@@ -6538,8 +6653,9 @@ function validateAndSanitizeExperimentLogPartialArgs(event) {
|
|
|
6538
6653
|
}
|
|
6539
6654
|
function deepCopyEvent(event) {
|
|
6540
6655
|
const attachments = [];
|
|
6541
|
-
const
|
|
6542
|
-
const
|
|
6656
|
+
const ATTACHMENT_INDEX_KEY = "_bt_internal_saved_attachment_idx";
|
|
6657
|
+
const ATTACHMENT_MARKER_KEY = "_bt_internal_saved_attachment_marker";
|
|
6658
|
+
const attachmentMarker = ++deepCopyEventMarkerCounter;
|
|
6543
6659
|
const serialized = JSON.stringify(event, (_k, v) => {
|
|
6544
6660
|
if (v instanceof SpanImpl || v instanceof NoopSpan) {
|
|
6545
6661
|
return `<span>`;
|
|
@@ -6551,21 +6667,39 @@ function deepCopyEvent(event) {
|
|
|
6551
6667
|
return `<logger>`;
|
|
6552
6668
|
} else if (v instanceof BaseAttachment) {
|
|
6553
6669
|
const idx = attachments.push(v);
|
|
6554
|
-
return {
|
|
6670
|
+
return {
|
|
6671
|
+
[ATTACHMENT_INDEX_KEY]: idx - 1,
|
|
6672
|
+
[ATTACHMENT_MARKER_KEY]: attachmentMarker
|
|
6673
|
+
};
|
|
6555
6674
|
} else if (v instanceof ReadonlyAttachment) {
|
|
6556
6675
|
return v.reference;
|
|
6557
6676
|
}
|
|
6558
6677
|
return v;
|
|
6559
6678
|
});
|
|
6560
6679
|
const x = JSON.parse(serialized, (_k, v) => {
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
return attachments[parsedAttachment.data[IDENTIFIER]];
|
|
6680
|
+
if (isDeepCopyAttachmentPlaceholder(v, attachmentMarker)) {
|
|
6681
|
+
return attachments[v[ATTACHMENT_INDEX_KEY]];
|
|
6564
6682
|
}
|
|
6565
6683
|
return v;
|
|
6566
6684
|
});
|
|
6567
6685
|
return x;
|
|
6568
6686
|
}
|
|
6687
|
+
var deepCopyEventMarkerCounter = 0;
|
|
6688
|
+
function isDeepCopyAttachmentPlaceholder(value, attachmentMarker) {
|
|
6689
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
6690
|
+
return false;
|
|
6691
|
+
}
|
|
6692
|
+
const record = value;
|
|
6693
|
+
if (!Object.hasOwn(record, "_bt_internal_saved_attachment_idx") || !Object.hasOwn(record, "_bt_internal_saved_attachment_marker")) {
|
|
6694
|
+
return false;
|
|
6695
|
+
}
|
|
6696
|
+
if (Object.keys(record).length !== 2) {
|
|
6697
|
+
return false;
|
|
6698
|
+
}
|
|
6699
|
+
const attachmentIndex = record._bt_internal_saved_attachment_idx;
|
|
6700
|
+
const marker = record._bt_internal_saved_attachment_marker;
|
|
6701
|
+
return Number.isInteger(attachmentIndex) && attachmentIndex >= 0 && marker === attachmentMarker;
|
|
6702
|
+
}
|
|
6569
6703
|
function extractAttachments(event, attachments) {
|
|
6570
6704
|
for (const [key, value] of Object.entries(event)) {
|
|
6571
6705
|
if (!value) {
|
|
@@ -9144,10 +9278,42 @@ function processImagesInOutput(output) {
|
|
|
9144
9278
|
}
|
|
9145
9279
|
return output;
|
|
9146
9280
|
}
|
|
9281
|
+
function mergeLogprobTokens(existing, incoming) {
|
|
9282
|
+
if (incoming === void 0) {
|
|
9283
|
+
return existing;
|
|
9284
|
+
}
|
|
9285
|
+
if (incoming === null) {
|
|
9286
|
+
return existing ?? null;
|
|
9287
|
+
}
|
|
9288
|
+
if (Array.isArray(existing)) {
|
|
9289
|
+
return [...existing, ...incoming];
|
|
9290
|
+
}
|
|
9291
|
+
return [...incoming];
|
|
9292
|
+
}
|
|
9293
|
+
function aggregateChatLogprobs(existing, incoming) {
|
|
9294
|
+
if (incoming === void 0) {
|
|
9295
|
+
return existing;
|
|
9296
|
+
}
|
|
9297
|
+
if (incoming === null) {
|
|
9298
|
+
return existing ?? null;
|
|
9299
|
+
}
|
|
9300
|
+
const aggregated = existing && existing !== null ? { ...existing, ...incoming } : { ...incoming };
|
|
9301
|
+
const content = mergeLogprobTokens(existing?.content, incoming.content);
|
|
9302
|
+
if (content !== void 0) {
|
|
9303
|
+
aggregated.content = content;
|
|
9304
|
+
}
|
|
9305
|
+
const refusal = mergeLogprobTokens(existing?.refusal, incoming.refusal);
|
|
9306
|
+
if (refusal !== void 0) {
|
|
9307
|
+
aggregated.refusal = refusal;
|
|
9308
|
+
}
|
|
9309
|
+
return aggregated;
|
|
9310
|
+
}
|
|
9147
9311
|
function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
9148
9312
|
let role = void 0;
|
|
9149
9313
|
let content = void 0;
|
|
9314
|
+
let refusal = void 0;
|
|
9150
9315
|
let tool_calls = void 0;
|
|
9316
|
+
let logprobs = void 0;
|
|
9151
9317
|
let finish_reason = void 0;
|
|
9152
9318
|
let metrics = {};
|
|
9153
9319
|
for (const chunk of chunks) {
|
|
@@ -9157,19 +9323,30 @@ function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
|
9157
9323
|
...parseMetricsFromUsage(chunk.usage)
|
|
9158
9324
|
};
|
|
9159
9325
|
}
|
|
9160
|
-
const
|
|
9161
|
-
if (!
|
|
9326
|
+
const choice = chunk.choices?.[0];
|
|
9327
|
+
if (!choice) {
|
|
9162
9328
|
continue;
|
|
9163
9329
|
}
|
|
9164
|
-
if (
|
|
9165
|
-
|
|
9330
|
+
if (choice.finish_reason) {
|
|
9331
|
+
finish_reason = choice.finish_reason;
|
|
9332
|
+
}
|
|
9333
|
+
logprobs = aggregateChatLogprobs(logprobs, choice.logprobs);
|
|
9334
|
+
const delta = choice.delta;
|
|
9335
|
+
if (!delta) {
|
|
9336
|
+
continue;
|
|
9166
9337
|
}
|
|
9167
9338
|
if (delta.finish_reason) {
|
|
9168
9339
|
finish_reason = delta.finish_reason;
|
|
9169
9340
|
}
|
|
9341
|
+
if (!role && delta.role) {
|
|
9342
|
+
role = delta.role;
|
|
9343
|
+
}
|
|
9170
9344
|
if (delta.content) {
|
|
9171
9345
|
content = (content || "") + delta.content;
|
|
9172
9346
|
}
|
|
9347
|
+
if (delta.refusal) {
|
|
9348
|
+
refusal = (refusal || "") + delta.refusal;
|
|
9349
|
+
}
|
|
9173
9350
|
if (delta.tool_calls) {
|
|
9174
9351
|
const toolDelta = delta.tool_calls[0];
|
|
9175
9352
|
if (!tool_calls || toolDelta.id && tool_calls[tool_calls.length - 1].id !== toolDelta.id) {
|
|
@@ -9195,9 +9372,10 @@ function aggregateChatCompletionChunks(chunks, streamResult, endEvent) {
|
|
|
9195
9372
|
message: {
|
|
9196
9373
|
role,
|
|
9197
9374
|
content,
|
|
9375
|
+
...refusal !== void 0 ? { refusal } : {},
|
|
9198
9376
|
tool_calls
|
|
9199
9377
|
},
|
|
9200
|
-
logprobs: null,
|
|
9378
|
+
logprobs: logprobs ?? null,
|
|
9201
9379
|
finish_reason
|
|
9202
9380
|
}
|
|
9203
9381
|
]
|
|
@@ -9260,13 +9438,21 @@ var anthropicChannels = defineChannels("@anthropic-ai/sdk", {
|
|
|
9260
9438
|
betaMessagesCreate: channel({
|
|
9261
9439
|
channelName: "beta.messages.create",
|
|
9262
9440
|
kind: "async"
|
|
9441
|
+
}),
|
|
9442
|
+
betaMessagesToolRunner: channel({
|
|
9443
|
+
channelName: "beta.messages.toolRunner",
|
|
9444
|
+
kind: "sync-stream"
|
|
9263
9445
|
})
|
|
9264
9446
|
});
|
|
9265
9447
|
|
|
9266
9448
|
// src/instrumentation/plugins/anthropic-plugin.ts
|
|
9449
|
+
var ANTHROPIC_TOOL_RUNNER_TOOL_WRAPPED = Symbol.for(
|
|
9450
|
+
"braintrust.anthropic_tool_runner_tool_wrapped"
|
|
9451
|
+
);
|
|
9267
9452
|
var AnthropicPlugin = class extends BasePlugin {
|
|
9268
9453
|
onEnable() {
|
|
9269
9454
|
this.subscribeToAnthropicChannels();
|
|
9455
|
+
this.subscribeToAnthropicToolRunner();
|
|
9270
9456
|
}
|
|
9271
9457
|
onDisable() {
|
|
9272
9458
|
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
@@ -9321,6 +9507,61 @@ var AnthropicPlugin = class extends BasePlugin {
|
|
|
9321
9507
|
})
|
|
9322
9508
|
);
|
|
9323
9509
|
}
|
|
9510
|
+
subscribeToAnthropicToolRunner() {
|
|
9511
|
+
const tracingChannel = anthropicChannels.betaMessagesToolRunner.tracingChannel();
|
|
9512
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
9513
|
+
const handlers = {
|
|
9514
|
+
start: (event) => {
|
|
9515
|
+
const params = event.arguments[0] ?? {};
|
|
9516
|
+
const span = startSpan({
|
|
9517
|
+
name: "anthropic.beta.messages.toolRunner",
|
|
9518
|
+
spanAttributes: {
|
|
9519
|
+
type: "task" /* TASK */
|
|
9520
|
+
}
|
|
9521
|
+
});
|
|
9522
|
+
span.log({
|
|
9523
|
+
input: processAttachmentsInInput(
|
|
9524
|
+
coalesceInput(params.messages ?? [], params.system)
|
|
9525
|
+
),
|
|
9526
|
+
metadata: {
|
|
9527
|
+
...extractAnthropicToolRunnerMetadata(params),
|
|
9528
|
+
provider: "anthropic"
|
|
9529
|
+
}
|
|
9530
|
+
});
|
|
9531
|
+
const state = {
|
|
9532
|
+
aggregatedMetrics: {},
|
|
9533
|
+
finalized: false,
|
|
9534
|
+
iterationCount: 0,
|
|
9535
|
+
seenMessages: /* @__PURE__ */ new WeakSet(),
|
|
9536
|
+
span,
|
|
9537
|
+
startTime: getCurrentUnixTimestamp()
|
|
9538
|
+
};
|
|
9539
|
+
states.set(event, state);
|
|
9540
|
+
},
|
|
9541
|
+
end: (event) => {
|
|
9542
|
+
const state = states.get(event);
|
|
9543
|
+
if (!state) {
|
|
9544
|
+
return;
|
|
9545
|
+
}
|
|
9546
|
+
patchAnthropicToolRunner({
|
|
9547
|
+
runner: event.result,
|
|
9548
|
+
state
|
|
9549
|
+
});
|
|
9550
|
+
},
|
|
9551
|
+
error: (event) => {
|
|
9552
|
+
const state = states.get(event);
|
|
9553
|
+
if (!state || !event.error) {
|
|
9554
|
+
return;
|
|
9555
|
+
}
|
|
9556
|
+
finalizeAnthropicToolRunnerError(state, event.error);
|
|
9557
|
+
states.delete(event);
|
|
9558
|
+
}
|
|
9559
|
+
};
|
|
9560
|
+
tracingChannel.subscribe(handlers);
|
|
9561
|
+
this.unsubscribers.push(() => {
|
|
9562
|
+
tracingChannel.unsubscribe(handlers);
|
|
9563
|
+
});
|
|
9564
|
+
}
|
|
9324
9565
|
};
|
|
9325
9566
|
function parseMetricsFromUsage2(usage) {
|
|
9326
9567
|
if (!usage) {
|
|
@@ -9337,72 +9578,411 @@ function parseMetricsFromUsage2(usage) {
|
|
|
9337
9578
|
saveIfExistsTo("output_tokens", "completion_tokens");
|
|
9338
9579
|
saveIfExistsTo("cache_read_input_tokens", "prompt_cached_tokens");
|
|
9339
9580
|
saveIfExistsTo("cache_creation_input_tokens", "prompt_cache_creation_tokens");
|
|
9581
|
+
if (isObject(usage.server_tool_use)) {
|
|
9582
|
+
for (const [name, value] of Object.entries(usage.server_tool_use)) {
|
|
9583
|
+
if (typeof value === "number") {
|
|
9584
|
+
metrics[`server_tool_use_${name}`] = value;
|
|
9585
|
+
}
|
|
9586
|
+
}
|
|
9587
|
+
}
|
|
9340
9588
|
return metrics;
|
|
9341
9589
|
}
|
|
9342
|
-
function
|
|
9343
|
-
const
|
|
9344
|
-
const
|
|
9345
|
-
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9355
|
-
|
|
9356
|
-
|
|
9357
|
-
|
|
9358
|
-
|
|
9359
|
-
|
|
9360
|
-
|
|
9361
|
-
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
|
|
9367
|
-
|
|
9368
|
-
|
|
9369
|
-
|
|
9370
|
-
|
|
9371
|
-
|
|
9372
|
-
|
|
9373
|
-
|
|
9374
|
-
|
|
9375
|
-
|
|
9376
|
-
|
|
9590
|
+
function extractAnthropicToolRunnerMetadata(params) {
|
|
9591
|
+
const metadata = filterFrom(params, ["messages", "system", "tools"]);
|
|
9592
|
+
const toolNames = extractAnthropicToolNames(params.tools);
|
|
9593
|
+
return {
|
|
9594
|
+
...metadata,
|
|
9595
|
+
operation: "toolRunner",
|
|
9596
|
+
...toolNames.length > 0 ? { tool_names: toolNames } : {}
|
|
9597
|
+
};
|
|
9598
|
+
}
|
|
9599
|
+
function extractAnthropicToolNames(tools) {
|
|
9600
|
+
const toolNames = [];
|
|
9601
|
+
for (const tool of tools) {
|
|
9602
|
+
if (!tool || typeof tool !== "object") {
|
|
9603
|
+
continue;
|
|
9604
|
+
}
|
|
9605
|
+
const toolRecord = tool;
|
|
9606
|
+
if (typeof toolRecord.name === "string") {
|
|
9607
|
+
toolNames.push(toolRecord.name);
|
|
9608
|
+
continue;
|
|
9609
|
+
}
|
|
9610
|
+
if (typeof toolRecord.mcp_server_name === "string") {
|
|
9611
|
+
toolNames.push(toolRecord.mcp_server_name);
|
|
9612
|
+
}
|
|
9613
|
+
}
|
|
9614
|
+
return toolNames;
|
|
9615
|
+
}
|
|
9616
|
+
function toErrorMessage(error) {
|
|
9617
|
+
return error instanceof Error ? error.message : String(error);
|
|
9618
|
+
}
|
|
9619
|
+
function getAnthropicToolRunnerInput(args) {
|
|
9620
|
+
return args.length > 0 ? args[0] : void 0;
|
|
9621
|
+
}
|
|
9622
|
+
function wrapAnthropicToolRunnerTools(params, state) {
|
|
9623
|
+
if (!Array.isArray(params.tools)) {
|
|
9624
|
+
return;
|
|
9625
|
+
}
|
|
9626
|
+
params.tools = params.tools.map(
|
|
9627
|
+
(tool, index) => wrapAnthropicToolRunnerTool(tool, index, state)
|
|
9628
|
+
);
|
|
9629
|
+
}
|
|
9630
|
+
function wrapAnthropicToolRunnerTool(tool, index, state) {
|
|
9631
|
+
if (!tool || typeof tool !== "object" || typeof tool.run !== "function" || tool[ANTHROPIC_TOOL_RUNNER_TOOL_WRAPPED]) {
|
|
9632
|
+
return tool;
|
|
9633
|
+
}
|
|
9634
|
+
const toolName = typeof tool.name === "string" ? tool.name : `tool[${index}]`;
|
|
9635
|
+
const originalRun = tool.run;
|
|
9636
|
+
const runDescriptor = Object.getOwnPropertyDescriptor(tool, "run");
|
|
9637
|
+
const wrappedTool = Object.create(
|
|
9638
|
+
Object.getPrototypeOf(tool),
|
|
9639
|
+
Object.getOwnPropertyDescriptors(tool)
|
|
9640
|
+
);
|
|
9641
|
+
Object.defineProperty(wrappedTool, "run", {
|
|
9642
|
+
configurable: runDescriptor?.configurable ?? true,
|
|
9643
|
+
enumerable: runDescriptor?.enumerable ?? true,
|
|
9644
|
+
value: function braintrustAnthropicToolRunnerRun(...args) {
|
|
9645
|
+
return state.span.traced(
|
|
9646
|
+
(span) => {
|
|
9647
|
+
const finalizeSuccess = (result) => {
|
|
9648
|
+
span.log({ output: result });
|
|
9649
|
+
return result;
|
|
9650
|
+
};
|
|
9651
|
+
const finalizeError = (error) => {
|
|
9652
|
+
span.log({ error: toErrorMessage(error) });
|
|
9653
|
+
throw error;
|
|
9654
|
+
};
|
|
9655
|
+
try {
|
|
9656
|
+
const result = Reflect.apply(originalRun, this, args);
|
|
9657
|
+
if (isPromiseLike(result)) {
|
|
9658
|
+
return result.then(finalizeSuccess, finalizeError);
|
|
9377
9659
|
}
|
|
9660
|
+
return finalizeSuccess(result);
|
|
9661
|
+
} catch (error) {
|
|
9662
|
+
return finalizeError(error);
|
|
9378
9663
|
}
|
|
9379
|
-
}
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
}
|
|
9389
|
-
|
|
9390
|
-
|
|
9391
|
-
if (citation && acc !== void 0) {
|
|
9392
|
-
acc.citations.push(citation);
|
|
9664
|
+
},
|
|
9665
|
+
{
|
|
9666
|
+
event: {
|
|
9667
|
+
input: getAnthropicToolRunnerInput(args),
|
|
9668
|
+
metadata: {
|
|
9669
|
+
"gen_ai.tool.name": toolName,
|
|
9670
|
+
provider: "anthropic"
|
|
9671
|
+
}
|
|
9672
|
+
},
|
|
9673
|
+
name: `tool: ${toolName}`,
|
|
9674
|
+
spanAttributes: {
|
|
9675
|
+
type: "tool" /* TOOL */
|
|
9393
9676
|
}
|
|
9394
9677
|
}
|
|
9395
|
-
|
|
9396
|
-
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
|
|
9678
|
+
);
|
|
9679
|
+
},
|
|
9680
|
+
writable: runDescriptor?.writable ?? true
|
|
9681
|
+
});
|
|
9682
|
+
Object.defineProperty(wrappedTool, ANTHROPIC_TOOL_RUNNER_TOOL_WRAPPED, {
|
|
9683
|
+
configurable: false,
|
|
9684
|
+
enumerable: false,
|
|
9685
|
+
value: true,
|
|
9686
|
+
writable: false
|
|
9687
|
+
});
|
|
9688
|
+
return wrappedTool;
|
|
9689
|
+
}
|
|
9690
|
+
function getAnthropicToolRunnerParams(runnerRecord) {
|
|
9691
|
+
const params = Reflect.get(runnerRecord, "params");
|
|
9692
|
+
return params && typeof params === "object" ? params : void 0;
|
|
9693
|
+
}
|
|
9694
|
+
function ensureAnthropicToolRunnerToolsWrapped(runnerRecord, state) {
|
|
9695
|
+
const params = getAnthropicToolRunnerParams(runnerRecord);
|
|
9696
|
+
if (params) {
|
|
9697
|
+
wrapAnthropicToolRunnerTools(params, state);
|
|
9698
|
+
}
|
|
9699
|
+
}
|
|
9700
|
+
function wrapAnthropicToolRunnerSetMessagesParams(runnerRecord, state) {
|
|
9701
|
+
const setMessagesParams = Reflect.get(runnerRecord, "setMessagesParams");
|
|
9702
|
+
if (typeof setMessagesParams !== "function") {
|
|
9703
|
+
return;
|
|
9704
|
+
}
|
|
9705
|
+
Reflect.set(
|
|
9706
|
+
runnerRecord,
|
|
9707
|
+
"setMessagesParams",
|
|
9708
|
+
function patchedSetMessagesParams(...args) {
|
|
9709
|
+
const result = Reflect.apply(setMessagesParams, this, args);
|
|
9710
|
+
const nextParams = getAnthropicToolRunnerParams(runnerRecord);
|
|
9711
|
+
if (nextParams) {
|
|
9712
|
+
wrapAnthropicToolRunnerTools(nextParams, state);
|
|
9713
|
+
}
|
|
9714
|
+
return result;
|
|
9715
|
+
}
|
|
9716
|
+
);
|
|
9717
|
+
}
|
|
9718
|
+
function isAnthropicMessage(value) {
|
|
9719
|
+
return !!value && typeof value === "object" && typeof value.role === "string" && Array.isArray(value.content);
|
|
9720
|
+
}
|
|
9721
|
+
function isAnthropicMessageStream(value) {
|
|
9722
|
+
return !!value && typeof value === "object" && isAsyncIterable(value) && "finalMessage" in value && typeof value.finalMessage === "function";
|
|
9723
|
+
}
|
|
9724
|
+
function recordAnthropicToolRunnerMessage(state, message) {
|
|
9725
|
+
if (typeof message !== "object" || message === null) {
|
|
9726
|
+
return;
|
|
9727
|
+
}
|
|
9728
|
+
if (state.seenMessages.has(message)) {
|
|
9729
|
+
state.lastMessage = message;
|
|
9730
|
+
return;
|
|
9731
|
+
}
|
|
9732
|
+
state.seenMessages.add(message);
|
|
9733
|
+
state.lastMessage = message;
|
|
9734
|
+
const parsedMetrics = parseMetricsFromUsage2(message.usage);
|
|
9735
|
+
for (const [key, value] of Object.entries(parsedMetrics)) {
|
|
9736
|
+
if (typeof value === "number") {
|
|
9737
|
+
state.aggregatedMetrics[key] = (state.aggregatedMetrics[key] ?? 0) + value;
|
|
9738
|
+
}
|
|
9739
|
+
}
|
|
9740
|
+
}
|
|
9741
|
+
function instrumentAnthropicMessageStream(stream, state) {
|
|
9742
|
+
if ("__braintrust_tool_runner_stream_patched" in stream) {
|
|
9743
|
+
return;
|
|
9744
|
+
}
|
|
9745
|
+
if (!Object.isFrozen(stream) && !Object.isSealed(stream)) {
|
|
9746
|
+
patchStreamIfNeeded(stream, {
|
|
9747
|
+
onChunk: () => {
|
|
9748
|
+
if (state.firstTokenTime === void 0) {
|
|
9749
|
+
state.firstTokenTime = getCurrentUnixTimestamp();
|
|
9750
|
+
}
|
|
9751
|
+
},
|
|
9752
|
+
onComplete: () => void 0
|
|
9753
|
+
});
|
|
9754
|
+
}
|
|
9755
|
+
if (typeof stream.finalMessage === "function") {
|
|
9756
|
+
const originalFinalMessage = stream.finalMessage.bind(stream);
|
|
9757
|
+
stream.finalMessage = async () => {
|
|
9758
|
+
const message = await originalFinalMessage();
|
|
9759
|
+
recordAnthropicToolRunnerMessage(state, message);
|
|
9760
|
+
return message;
|
|
9761
|
+
};
|
|
9762
|
+
}
|
|
9763
|
+
Object.defineProperty(stream, "__braintrust_tool_runner_stream_patched", {
|
|
9764
|
+
value: true
|
|
9765
|
+
});
|
|
9766
|
+
}
|
|
9767
|
+
async function finalizeAnthropicToolRunner(state, finalMessage) {
|
|
9768
|
+
if (state.finalized) {
|
|
9769
|
+
return;
|
|
9770
|
+
}
|
|
9771
|
+
state.finalized = true;
|
|
9772
|
+
const message = finalMessage ?? state.lastMessage;
|
|
9773
|
+
if (message) {
|
|
9774
|
+
recordAnthropicToolRunnerMessage(state, message);
|
|
9775
|
+
}
|
|
9776
|
+
const metrics = finalizeAnthropicTokens({
|
|
9777
|
+
...state.aggregatedMetrics
|
|
9778
|
+
});
|
|
9779
|
+
if (state.firstTokenTime !== void 0) {
|
|
9780
|
+
metrics.time_to_first_token = state.firstTokenTime - state.startTime;
|
|
9781
|
+
}
|
|
9782
|
+
const metadata = {
|
|
9783
|
+
anthropic_tool_runner_iterations: state.iterationCount
|
|
9784
|
+
};
|
|
9785
|
+
if (message?.stop_reason !== void 0) {
|
|
9786
|
+
metadata.stop_reason = message.stop_reason;
|
|
9787
|
+
}
|
|
9788
|
+
if (message?.stop_sequence !== void 0) {
|
|
9789
|
+
metadata.stop_sequence = message.stop_sequence;
|
|
9790
|
+
}
|
|
9791
|
+
state.span.log({
|
|
9792
|
+
...message ? { output: { role: message.role, content: message.content } } : {},
|
|
9793
|
+
metadata,
|
|
9794
|
+
metrics: Object.fromEntries(
|
|
9795
|
+
Object.entries(metrics).filter(
|
|
9796
|
+
(entry) => entry[1] !== void 0
|
|
9797
|
+
)
|
|
9798
|
+
)
|
|
9799
|
+
});
|
|
9800
|
+
state.span.end();
|
|
9801
|
+
}
|
|
9802
|
+
function finalizeAnthropicToolRunnerError(state, error) {
|
|
9803
|
+
if (state.finalized) {
|
|
9804
|
+
return;
|
|
9805
|
+
}
|
|
9806
|
+
state.finalized = true;
|
|
9807
|
+
state.span.log({
|
|
9808
|
+
error: error instanceof Error ? error.message : String(error)
|
|
9809
|
+
});
|
|
9810
|
+
state.span.end();
|
|
9811
|
+
}
|
|
9812
|
+
async function resolveAnthropicToolRunnerFinalMessage(runner) {
|
|
9813
|
+
if (typeof runner.done === "function") {
|
|
9814
|
+
return await runner.done();
|
|
9815
|
+
}
|
|
9816
|
+
if (typeof runner.runUntilDone === "function") {
|
|
9817
|
+
return await runner.runUntilDone();
|
|
9818
|
+
}
|
|
9819
|
+
return void 0;
|
|
9820
|
+
}
|
|
9821
|
+
function wrapAnthropicToolRunnerPromiseMethod(runnerRecord, methodName, state) {
|
|
9822
|
+
const method = runnerRecord[methodName];
|
|
9823
|
+
if (typeof method !== "function") {
|
|
9824
|
+
return;
|
|
9825
|
+
}
|
|
9826
|
+
runnerRecord[methodName] = async (...args) => {
|
|
9827
|
+
ensureAnthropicToolRunnerToolsWrapped(runnerRecord, state);
|
|
9828
|
+
return await withCurrent(state.span, async () => {
|
|
9829
|
+
try {
|
|
9830
|
+
const message = await method.apply(runnerRecord, args);
|
|
9831
|
+
recordAnthropicToolRunnerMessage(state, message);
|
|
9832
|
+
await finalizeAnthropicToolRunner(state, message);
|
|
9833
|
+
return message;
|
|
9834
|
+
} catch (error) {
|
|
9835
|
+
finalizeAnthropicToolRunnerError(state, error);
|
|
9836
|
+
throw error;
|
|
9837
|
+
}
|
|
9838
|
+
});
|
|
9839
|
+
};
|
|
9840
|
+
}
|
|
9841
|
+
function patchAnthropicToolRunner(args) {
|
|
9842
|
+
const { runner, state } = args;
|
|
9843
|
+
if (!runner || typeof runner !== "object") {
|
|
9844
|
+
void finalizeAnthropicToolRunner(state);
|
|
9845
|
+
return;
|
|
9846
|
+
}
|
|
9847
|
+
const runnerRecord = runner;
|
|
9848
|
+
if ("__braintrust_tool_runner_patched" in runnerRecord) {
|
|
9849
|
+
return;
|
|
9850
|
+
}
|
|
9851
|
+
ensureAnthropicToolRunnerToolsWrapped(runnerRecord, state);
|
|
9852
|
+
wrapAnthropicToolRunnerSetMessagesParams(runnerRecord, state);
|
|
9853
|
+
wrapAnthropicToolRunnerPromiseMethod(runnerRecord, "done", state);
|
|
9854
|
+
wrapAnthropicToolRunnerPromiseMethod(runnerRecord, "runUntilDone", state);
|
|
9855
|
+
if (!isAsyncIterable(runnerRecord)) {
|
|
9856
|
+
Object.defineProperty(runnerRecord, "__braintrust_tool_runner_patched", {
|
|
9857
|
+
value: true
|
|
9858
|
+
});
|
|
9859
|
+
return;
|
|
9860
|
+
}
|
|
9861
|
+
const originalIterator = runnerRecord[Symbol.asyncIterator].bind(runnerRecord);
|
|
9862
|
+
runnerRecord[Symbol.asyncIterator] = function() {
|
|
9863
|
+
const iterator = originalIterator();
|
|
9864
|
+
return {
|
|
9865
|
+
async next(value) {
|
|
9866
|
+
try {
|
|
9867
|
+
ensureAnthropicToolRunnerToolsWrapped(runnerRecord, state);
|
|
9868
|
+
const result = await withCurrent(
|
|
9869
|
+
state.span,
|
|
9870
|
+
() => value === void 0 ? iterator.next() : iterator.next(value)
|
|
9871
|
+
);
|
|
9872
|
+
if (result.done) {
|
|
9873
|
+
const finalMessage = await resolveAnthropicToolRunnerFinalMessage(runner);
|
|
9874
|
+
await finalizeAnthropicToolRunner(state, finalMessage);
|
|
9875
|
+
return result;
|
|
9876
|
+
}
|
|
9877
|
+
state.iterationCount += 1;
|
|
9878
|
+
if (isAnthropicMessage(result.value)) {
|
|
9879
|
+
if (state.firstTokenTime === void 0) {
|
|
9880
|
+
state.firstTokenTime = getCurrentUnixTimestamp();
|
|
9881
|
+
}
|
|
9882
|
+
recordAnthropicToolRunnerMessage(state, result.value);
|
|
9883
|
+
} else if (isAnthropicMessageStream(result.value)) {
|
|
9884
|
+
instrumentAnthropicMessageStream(result.value, state);
|
|
9885
|
+
}
|
|
9886
|
+
return result;
|
|
9887
|
+
} catch (error) {
|
|
9888
|
+
finalizeAnthropicToolRunnerError(state, error);
|
|
9889
|
+
throw error;
|
|
9890
|
+
}
|
|
9891
|
+
},
|
|
9892
|
+
async return(value) {
|
|
9893
|
+
try {
|
|
9894
|
+
ensureAnthropicToolRunnerToolsWrapped(runnerRecord, state);
|
|
9895
|
+
const result = typeof iterator.return === "function" ? await withCurrent(state.span, () => iterator.return(value)) : { done: true, value };
|
|
9896
|
+
const finalMessage = await resolveAnthropicToolRunnerFinalMessage(
|
|
9897
|
+
runner
|
|
9898
|
+
).catch(() => void 0);
|
|
9899
|
+
await finalizeAnthropicToolRunner(state, finalMessage);
|
|
9900
|
+
return result;
|
|
9901
|
+
} catch (error) {
|
|
9902
|
+
finalizeAnthropicToolRunnerError(state, error);
|
|
9903
|
+
throw error;
|
|
9904
|
+
}
|
|
9905
|
+
},
|
|
9906
|
+
async throw(error) {
|
|
9907
|
+
finalizeAnthropicToolRunnerError(state, error);
|
|
9908
|
+
if (typeof iterator.throw === "function") {
|
|
9909
|
+
return await withCurrent(state.span, () => iterator.throw(error));
|
|
9910
|
+
}
|
|
9911
|
+
throw error;
|
|
9912
|
+
},
|
|
9913
|
+
[Symbol.asyncIterator]() {
|
|
9914
|
+
return this;
|
|
9915
|
+
}
|
|
9916
|
+
};
|
|
9917
|
+
};
|
|
9918
|
+
Object.defineProperty(runnerRecord, "__braintrust_tool_runner_patched", {
|
|
9919
|
+
value: true
|
|
9920
|
+
});
|
|
9921
|
+
}
|
|
9922
|
+
function aggregateAnthropicStreamChunks(chunks) {
|
|
9923
|
+
const fallbackTextDeltas = [];
|
|
9924
|
+
const contentBlocks = {};
|
|
9925
|
+
const contentBlockDeltas = {};
|
|
9926
|
+
let metrics = {};
|
|
9927
|
+
let metadata = {};
|
|
9928
|
+
let role;
|
|
9929
|
+
for (const event of chunks) {
|
|
9930
|
+
switch (event?.type) {
|
|
9931
|
+
case "message_start":
|
|
9932
|
+
if (event.message?.usage) {
|
|
9933
|
+
const initialMetrics = parseMetricsFromUsage2(event.message.usage);
|
|
9934
|
+
metrics = { ...metrics, ...initialMetrics };
|
|
9935
|
+
}
|
|
9936
|
+
if (typeof event.message?.role === "string") {
|
|
9937
|
+
role = event.message.role;
|
|
9938
|
+
}
|
|
9939
|
+
break;
|
|
9940
|
+
case "content_block_start":
|
|
9941
|
+
if (event.content_block) {
|
|
9942
|
+
contentBlocks[event.index] = event.content_block;
|
|
9943
|
+
contentBlockDeltas[event.index] = { textDeltas: [], citations: [] };
|
|
9944
|
+
}
|
|
9945
|
+
break;
|
|
9946
|
+
case "content_block_delta": {
|
|
9947
|
+
const acc = contentBlockDeltas[event.index];
|
|
9948
|
+
const delta = event.delta;
|
|
9949
|
+
if (!delta) break;
|
|
9950
|
+
if (delta.type === "text_delta" && "text" in delta) {
|
|
9951
|
+
const text = delta.text;
|
|
9952
|
+
if (text) {
|
|
9953
|
+
if (acc !== void 0) {
|
|
9954
|
+
acc.textDeltas.push(text);
|
|
9955
|
+
} else {
|
|
9956
|
+
fallbackTextDeltas.push(text);
|
|
9957
|
+
}
|
|
9958
|
+
}
|
|
9959
|
+
} else if (delta.type === "input_json_delta" && "partial_json" in delta) {
|
|
9960
|
+
const partialJson = delta.partial_json;
|
|
9961
|
+
if (partialJson && acc !== void 0) {
|
|
9962
|
+
acc.textDeltas.push(partialJson);
|
|
9963
|
+
}
|
|
9964
|
+
} else if (delta.type === "thinking_delta" && "thinking" in delta) {
|
|
9965
|
+
const thinking = delta.thinking;
|
|
9966
|
+
if (thinking && acc !== void 0) {
|
|
9967
|
+
acc.textDeltas.push(thinking);
|
|
9968
|
+
}
|
|
9969
|
+
} else if (delta.type === "citations_delta" && "citation" in delta) {
|
|
9970
|
+
const citation = delta.citation;
|
|
9971
|
+
if (citation && acc !== void 0) {
|
|
9972
|
+
acc.citations.push(citation);
|
|
9973
|
+
}
|
|
9974
|
+
}
|
|
9975
|
+
break;
|
|
9976
|
+
}
|
|
9977
|
+
case "content_block_stop":
|
|
9978
|
+
finalizeContentBlock(
|
|
9979
|
+
event.index,
|
|
9980
|
+
contentBlocks,
|
|
9981
|
+
contentBlockDeltas,
|
|
9982
|
+
fallbackTextDeltas
|
|
9983
|
+
);
|
|
9984
|
+
break;
|
|
9985
|
+
case "message_delta":
|
|
9406
9986
|
if (event.usage) {
|
|
9407
9987
|
const finalMetrics = parseMetricsFromUsage2(event.usage);
|
|
9408
9988
|
metrics = { ...metrics, ...finalMetrics };
|
|
@@ -9447,15 +10027,24 @@ function finalizeContentBlock(index, contentBlocks, contentBlockDeltas, fallback
|
|
|
9447
10027
|
}
|
|
9448
10028
|
const acc = contentBlockDeltas[index];
|
|
9449
10029
|
const text = acc?.textDeltas.join("") ?? "";
|
|
9450
|
-
if (
|
|
10030
|
+
if (isToolUseLikeContentBlock(contentBlock)) {
|
|
9451
10031
|
if (!text) {
|
|
9452
10032
|
return;
|
|
9453
10033
|
}
|
|
9454
10034
|
try {
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
10035
|
+
const parsedInput = JSON.parse(text);
|
|
10036
|
+
if (!isObject(parsedInput)) {
|
|
10037
|
+
fallbackTextDeltas.push(text);
|
|
10038
|
+
delete contentBlocks[index];
|
|
10039
|
+
return;
|
|
10040
|
+
}
|
|
10041
|
+
const parsedToolUseBlock = {
|
|
10042
|
+
type: contentBlock.type,
|
|
10043
|
+
id: contentBlock.id,
|
|
10044
|
+
name: contentBlock.name,
|
|
10045
|
+
input: parsedInput
|
|
9458
10046
|
};
|
|
10047
|
+
contentBlocks[index] = parsedToolUseBlock;
|
|
9459
10048
|
} catch {
|
|
9460
10049
|
fallbackTextDeltas.push(text);
|
|
9461
10050
|
delete contentBlocks[index];
|
|
@@ -9489,8 +10078,8 @@ function finalizeContentBlock(index, contentBlocks, contentBlockDeltas, fallback
|
|
|
9489
10078
|
function isTextContentBlock(contentBlock) {
|
|
9490
10079
|
return contentBlock.type === "text";
|
|
9491
10080
|
}
|
|
9492
|
-
function
|
|
9493
|
-
return contentBlock.type === "tool_use";
|
|
10081
|
+
function isToolUseLikeContentBlock(contentBlock) {
|
|
10082
|
+
return (contentBlock.type === "tool_use" || contentBlock.type === "server_tool_use") && typeof contentBlock.id === "string" && typeof contentBlock.name === "string" && isObject(contentBlock.input);
|
|
9494
10083
|
}
|
|
9495
10084
|
function isThinkingContentBlock(contentBlock) {
|
|
9496
10085
|
return contentBlock.type === "thinking";
|
|
@@ -9688,6 +10277,10 @@ var aiSDKChannels = defineChannels("ai", {
|
|
|
9688
10277
|
channelName: "embedMany",
|
|
9689
10278
|
kind: "async"
|
|
9690
10279
|
}),
|
|
10280
|
+
rerank: channel({
|
|
10281
|
+
channelName: "rerank",
|
|
10282
|
+
kind: "async"
|
|
10283
|
+
}),
|
|
9691
10284
|
agentGenerate: channel({
|
|
9692
10285
|
channelName: "Agent.generate",
|
|
9693
10286
|
kind: "async"
|
|
@@ -9747,7 +10340,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9747
10340
|
this.unsubscribers.push(
|
|
9748
10341
|
traceStreamingChannel(aiSDKChannels.generateText, {
|
|
9749
10342
|
name: "generateText",
|
|
9750
|
-
type: "
|
|
10343
|
+
type: "function" /* FUNCTION */,
|
|
9751
10344
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9752
10345
|
extractOutput: (result, endEvent) => {
|
|
9753
10346
|
finalizeAISDKChildTracing(endEvent);
|
|
@@ -9763,7 +10356,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9763
10356
|
this.unsubscribers.push(
|
|
9764
10357
|
traceStreamingChannel(aiSDKChannels.streamText, {
|
|
9765
10358
|
name: "streamText",
|
|
9766
|
-
type: "
|
|
10359
|
+
type: "function" /* FUNCTION */,
|
|
9767
10360
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9768
10361
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
9769
10362
|
result,
|
|
@@ -9783,7 +10376,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9783
10376
|
this.unsubscribers.push(
|
|
9784
10377
|
traceSyncStreamChannel(aiSDKChannels.streamTextSync, {
|
|
9785
10378
|
name: "streamText",
|
|
9786
|
-
type: "
|
|
10379
|
+
type: "function" /* FUNCTION */,
|
|
9787
10380
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9788
10381
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
9789
10382
|
defaultDenyOutputPaths: denyOutputPaths,
|
|
@@ -9797,7 +10390,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9797
10390
|
this.unsubscribers.push(
|
|
9798
10391
|
traceStreamingChannel(aiSDKChannels.generateObject, {
|
|
9799
10392
|
name: "generateObject",
|
|
9800
|
-
type: "
|
|
10393
|
+
type: "function" /* FUNCTION */,
|
|
9801
10394
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9802
10395
|
extractOutput: (result, endEvent) => {
|
|
9803
10396
|
finalizeAISDKChildTracing(endEvent);
|
|
@@ -9813,7 +10406,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9813
10406
|
this.unsubscribers.push(
|
|
9814
10407
|
traceStreamingChannel(aiSDKChannels.streamObject, {
|
|
9815
10408
|
name: "streamObject",
|
|
9816
|
-
type: "
|
|
10409
|
+
type: "function" /* FUNCTION */,
|
|
9817
10410
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9818
10411
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
9819
10412
|
result,
|
|
@@ -9833,7 +10426,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9833
10426
|
this.unsubscribers.push(
|
|
9834
10427
|
traceSyncStreamChannel(aiSDKChannels.streamObjectSync, {
|
|
9835
10428
|
name: "streamObject",
|
|
9836
|
-
type: "
|
|
10429
|
+
type: "function" /* FUNCTION */,
|
|
9837
10430
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9838
10431
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
9839
10432
|
defaultDenyOutputPaths: denyOutputPaths,
|
|
@@ -9847,7 +10440,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9847
10440
|
this.unsubscribers.push(
|
|
9848
10441
|
traceAsyncChannel(aiSDKChannels.embed, {
|
|
9849
10442
|
name: "embed",
|
|
9850
|
-
type: "
|
|
10443
|
+
type: "function" /* FUNCTION */,
|
|
9851
10444
|
extractInput: ([params], event) => prepareAISDKEmbedInput(params, event.self),
|
|
9852
10445
|
extractOutput: (result, endEvent) => processAISDKEmbeddingOutput(
|
|
9853
10446
|
result,
|
|
@@ -9859,7 +10452,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9859
10452
|
this.unsubscribers.push(
|
|
9860
10453
|
traceAsyncChannel(aiSDKChannels.embedMany, {
|
|
9861
10454
|
name: "embedMany",
|
|
9862
|
-
type: "
|
|
10455
|
+
type: "function" /* FUNCTION */,
|
|
9863
10456
|
extractInput: ([params], event) => prepareAISDKEmbedInput(params, event.self),
|
|
9864
10457
|
extractOutput: (result, endEvent) => processAISDKEmbeddingOutput(
|
|
9865
10458
|
result,
|
|
@@ -9868,10 +10461,22 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9868
10461
|
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent)
|
|
9869
10462
|
})
|
|
9870
10463
|
);
|
|
10464
|
+
this.unsubscribers.push(
|
|
10465
|
+
traceAsyncChannel(aiSDKChannels.rerank, {
|
|
10466
|
+
name: "rerank",
|
|
10467
|
+
type: "function" /* FUNCTION */,
|
|
10468
|
+
extractInput: ([params], event) => prepareAISDKRerankInput(params, event.self),
|
|
10469
|
+
extractOutput: (result, endEvent) => processAISDKRerankOutput(
|
|
10470
|
+
result,
|
|
10471
|
+
resolveDenyOutputPaths(endEvent, denyOutputPaths)
|
|
10472
|
+
),
|
|
10473
|
+
extractMetrics: (result, _startTime, endEvent) => extractTopLevelAISDKMetrics(result, endEvent)
|
|
10474
|
+
})
|
|
10475
|
+
);
|
|
9871
10476
|
this.unsubscribers.push(
|
|
9872
10477
|
traceStreamingChannel(aiSDKChannels.agentGenerate, {
|
|
9873
10478
|
name: "Agent.generate",
|
|
9874
|
-
type: "
|
|
10479
|
+
type: "function" /* FUNCTION */,
|
|
9875
10480
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9876
10481
|
extractOutput: (result, endEvent) => {
|
|
9877
10482
|
finalizeAISDKChildTracing(endEvent);
|
|
@@ -9887,7 +10492,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9887
10492
|
this.unsubscribers.push(
|
|
9888
10493
|
traceStreamingChannel(aiSDKChannels.agentStream, {
|
|
9889
10494
|
name: "Agent.stream",
|
|
9890
|
-
type: "
|
|
10495
|
+
type: "function" /* FUNCTION */,
|
|
9891
10496
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9892
10497
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
9893
10498
|
result,
|
|
@@ -9907,7 +10512,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9907
10512
|
this.unsubscribers.push(
|
|
9908
10513
|
traceSyncStreamChannel(aiSDKChannels.agentStreamSync, {
|
|
9909
10514
|
name: "Agent.stream",
|
|
9910
|
-
type: "
|
|
10515
|
+
type: "function" /* FUNCTION */,
|
|
9911
10516
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9912
10517
|
patchResult: ({ endEvent, result, span, startTime }) => patchAISDKStreamingResult({
|
|
9913
10518
|
defaultDenyOutputPaths: denyOutputPaths,
|
|
@@ -9921,7 +10526,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9921
10526
|
this.unsubscribers.push(
|
|
9922
10527
|
traceStreamingChannel(aiSDKChannels.toolLoopAgentGenerate, {
|
|
9923
10528
|
name: "ToolLoopAgent.generate",
|
|
9924
|
-
type: "
|
|
10529
|
+
type: "function" /* FUNCTION */,
|
|
9925
10530
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9926
10531
|
extractOutput: (result, endEvent) => {
|
|
9927
10532
|
finalizeAISDKChildTracing(endEvent);
|
|
@@ -9937,7 +10542,7 @@ var AISDKPlugin = class extends BasePlugin {
|
|
|
9937
10542
|
this.unsubscribers.push(
|
|
9938
10543
|
traceStreamingChannel(aiSDKChannels.toolLoopAgentStream, {
|
|
9939
10544
|
name: "ToolLoopAgent.stream",
|
|
9940
|
-
type: "
|
|
10545
|
+
type: "function" /* FUNCTION */,
|
|
9941
10546
|
extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths),
|
|
9942
10547
|
extractOutput: (result, endEvent) => processAISDKOutput(
|
|
9943
10548
|
result,
|
|
@@ -10287,6 +10892,16 @@ function prepareAISDKEmbedInput(params, self) {
|
|
|
10287
10892
|
metadata: extractMetadataFromEmbedParams(params, self)
|
|
10288
10893
|
};
|
|
10289
10894
|
}
|
|
10895
|
+
function prepareAISDKRerankInput(params, self) {
|
|
10896
|
+
const { documents, query } = params;
|
|
10897
|
+
return {
|
|
10898
|
+
input: {
|
|
10899
|
+
documents,
|
|
10900
|
+
query
|
|
10901
|
+
},
|
|
10902
|
+
metadata: extractMetadataFromRerankParams(params, self)
|
|
10903
|
+
};
|
|
10904
|
+
}
|
|
10290
10905
|
function extractTopLevelAISDKMetrics(result, event, startTime) {
|
|
10291
10906
|
const metrics = hasModelChildTracing(event) ? {} : extractTokenMetrics(result);
|
|
10292
10907
|
if (startTime) {
|
|
@@ -10332,6 +10947,16 @@ function extractMetadataFromCallParams(params, self) {
|
|
|
10332
10947
|
function extractMetadataFromEmbedParams(params, self) {
|
|
10333
10948
|
return extractBaseMetadata(params.model, self);
|
|
10334
10949
|
}
|
|
10950
|
+
function extractMetadataFromRerankParams(params, self) {
|
|
10951
|
+
const metadata = extractBaseMetadata(params.model, self);
|
|
10952
|
+
if (typeof params.topN === "number") {
|
|
10953
|
+
metadata.topN = params.topN;
|
|
10954
|
+
}
|
|
10955
|
+
if (Array.isArray(params.documents)) {
|
|
10956
|
+
metadata.document_count = params.documents.length;
|
|
10957
|
+
}
|
|
10958
|
+
return metadata;
|
|
10959
|
+
}
|
|
10335
10960
|
function prepareAISDKChildTracing(params, self, parentSpan, denyOutputPaths, aiSDK) {
|
|
10336
10961
|
const cleanup = [];
|
|
10337
10962
|
const patchedModels = /* @__PURE__ */ new WeakSet();
|
|
@@ -10879,6 +11504,22 @@ function processAISDKEmbeddingOutput(output, denyOutputPaths) {
|
|
|
10879
11504
|
}
|
|
10880
11505
|
return normalizeAISDKLoggedOutput(omit(summarized, denyOutputPaths));
|
|
10881
11506
|
}
|
|
11507
|
+
function processAISDKRerankOutput(output, _denyOutputPaths) {
|
|
11508
|
+
if (!output || typeof output !== "object") {
|
|
11509
|
+
return output;
|
|
11510
|
+
}
|
|
11511
|
+
const ranking = safeSerializableFieldRead(output, "ranking");
|
|
11512
|
+
if (Array.isArray(ranking)) {
|
|
11513
|
+
return ranking.slice(0, 100).map((item) => {
|
|
11514
|
+
const entry = item && typeof item === "object" ? item : void 0;
|
|
11515
|
+
return {
|
|
11516
|
+
index: typeof entry?.originalIndex === "number" ? entry.originalIndex : void 0,
|
|
11517
|
+
relevance_score: typeof entry?.score === "number" ? entry.score : void 0
|
|
11518
|
+
};
|
|
11519
|
+
});
|
|
11520
|
+
}
|
|
11521
|
+
return void 0;
|
|
11522
|
+
}
|
|
10882
11523
|
function extractTokenMetrics(result) {
|
|
10883
11524
|
const metrics = {};
|
|
10884
11525
|
let usage;
|
|
@@ -10921,12 +11562,80 @@ function extractTokenMetrics(result) {
|
|
|
10921
11562
|
if (totalTokens !== void 0) {
|
|
10922
11563
|
metrics.tokens = totalTokens;
|
|
10923
11564
|
}
|
|
11565
|
+
const promptCachedTokens = firstNumber(
|
|
11566
|
+
usage.inputTokens?.cacheRead,
|
|
11567
|
+
usage.inputTokenDetails?.cacheReadTokens,
|
|
11568
|
+
usage.cachedInputTokens,
|
|
11569
|
+
usage.promptCachedTokens,
|
|
11570
|
+
usage.prompt_cached_tokens
|
|
11571
|
+
);
|
|
11572
|
+
if (promptCachedTokens !== void 0) {
|
|
11573
|
+
metrics.prompt_cached_tokens = promptCachedTokens;
|
|
11574
|
+
}
|
|
11575
|
+
const promptCacheCreationTokens = firstNumber(
|
|
11576
|
+
usage.inputTokens?.cacheWrite,
|
|
11577
|
+
usage.inputTokenDetails?.cacheWriteTokens,
|
|
11578
|
+
usage.promptCacheCreationTokens,
|
|
11579
|
+
usage.prompt_cache_creation_tokens,
|
|
11580
|
+
extractAnthropicCacheCreationTokens(result)
|
|
11581
|
+
);
|
|
11582
|
+
if (promptCacheCreationTokens !== void 0) {
|
|
11583
|
+
metrics.prompt_cache_creation_tokens = promptCacheCreationTokens;
|
|
11584
|
+
}
|
|
11585
|
+
const promptReasoningTokens = firstNumber(
|
|
11586
|
+
usage.promptReasoningTokens,
|
|
11587
|
+
usage.prompt_reasoning_tokens
|
|
11588
|
+
);
|
|
11589
|
+
if (promptReasoningTokens !== void 0) {
|
|
11590
|
+
metrics.prompt_reasoning_tokens = promptReasoningTokens;
|
|
11591
|
+
}
|
|
11592
|
+
const completionCachedTokens = firstNumber(
|
|
11593
|
+
usage.completionCachedTokens,
|
|
11594
|
+
usage.completion_cached_tokens
|
|
11595
|
+
);
|
|
11596
|
+
if (completionCachedTokens !== void 0) {
|
|
11597
|
+
metrics.completion_cached_tokens = completionCachedTokens;
|
|
11598
|
+
}
|
|
11599
|
+
const reasoningTokenCount = firstNumber(
|
|
11600
|
+
usage.outputTokens?.reasoning,
|
|
11601
|
+
usage.reasoningTokens,
|
|
11602
|
+
usage.completionReasoningTokens,
|
|
11603
|
+
usage.completion_reasoning_tokens,
|
|
11604
|
+
usage.reasoning_tokens,
|
|
11605
|
+
usage.thinkingTokens,
|
|
11606
|
+
usage.thinking_tokens
|
|
11607
|
+
);
|
|
11608
|
+
if (reasoningTokenCount !== void 0) {
|
|
11609
|
+
metrics.completion_reasoning_tokens = reasoningTokenCount;
|
|
11610
|
+
metrics.reasoning_tokens = reasoningTokenCount;
|
|
11611
|
+
}
|
|
11612
|
+
const completionAudioTokens = firstNumber(
|
|
11613
|
+
usage.completionAudioTokens,
|
|
11614
|
+
usage.completion_audio_tokens
|
|
11615
|
+
);
|
|
11616
|
+
if (completionAudioTokens !== void 0) {
|
|
11617
|
+
metrics.completion_audio_tokens = completionAudioTokens;
|
|
11618
|
+
}
|
|
10924
11619
|
const cost = extractCostFromResult(result);
|
|
10925
11620
|
if (cost !== void 0) {
|
|
10926
11621
|
metrics.estimated_cost = cost;
|
|
10927
11622
|
}
|
|
10928
11623
|
return metrics;
|
|
10929
11624
|
}
|
|
11625
|
+
function extractAnthropicCacheCreationTokens(result) {
|
|
11626
|
+
const providerMetadata = safeSerializableFieldRead(
|
|
11627
|
+
result,
|
|
11628
|
+
"providerMetadata"
|
|
11629
|
+
);
|
|
11630
|
+
const anthropicMetadata = providerMetadata?.anthropic;
|
|
11631
|
+
if (!anthropicMetadata) {
|
|
11632
|
+
return void 0;
|
|
11633
|
+
}
|
|
11634
|
+
return firstNumber(
|
|
11635
|
+
anthropicMetadata.cacheCreationInputTokens,
|
|
11636
|
+
anthropicMetadata.usage?.cache_creation_input_tokens
|
|
11637
|
+
);
|
|
11638
|
+
}
|
|
10930
11639
|
function safeResultFieldRead(result, field) {
|
|
10931
11640
|
return safeSerializableFieldRead(result, field);
|
|
10932
11641
|
}
|
|
@@ -11043,14 +11752,11 @@ function extractSerializableOutputFields(output) {
|
|
|
11043
11752
|
...extractGetterValues(output)
|
|
11044
11753
|
};
|
|
11045
11754
|
}
|
|
11046
|
-
function isPromiseLike(value) {
|
|
11047
|
-
return value != null && typeof value === "object" && typeof value.then === "function";
|
|
11048
|
-
}
|
|
11049
11755
|
function isSerializableOutputValue(value) {
|
|
11050
11756
|
if (typeof value === "function") {
|
|
11051
11757
|
return false;
|
|
11052
11758
|
}
|
|
11053
|
-
if (value
|
|
11759
|
+
if (isPromiseLike(value)) {
|
|
11054
11760
|
return false;
|
|
11055
11761
|
}
|
|
11056
11762
|
if (value && typeof value === "object" && typeof value.getReader === "function") {
|
|
@@ -11370,12 +12076,9 @@ function bindClaudeLocalToolContextToAsyncIterable(result, localToolContext) {
|
|
|
11370
12076
|
var LOCAL_TOOL_HANDLER_WRAPPED = Symbol.for(
|
|
11371
12077
|
"braintrust.claude_agent_sdk.local_tool_handler_wrapped"
|
|
11372
12078
|
);
|
|
11373
|
-
function
|
|
12079
|
+
function toErrorMessage2(error) {
|
|
11374
12080
|
return error instanceof Error ? error.message : String(error);
|
|
11375
12081
|
}
|
|
11376
|
-
function isPromiseLike2(value) {
|
|
11377
|
-
return value !== null && typeof value === "object" && "then" in value && typeof value.then === "function";
|
|
11378
|
-
}
|
|
11379
12082
|
function getToolUseIdFromExtra(extra) {
|
|
11380
12083
|
if (!extra || typeof extra !== "object" || !("_meta" in extra)) {
|
|
11381
12084
|
return void 0;
|
|
@@ -11422,14 +12125,14 @@ function wrapLocalClaudeToolHandler(handler, getMetadata) {
|
|
|
11422
12125
|
return result;
|
|
11423
12126
|
};
|
|
11424
12127
|
const finalizeError = (error) => {
|
|
11425
|
-
span.log({ error:
|
|
12128
|
+
span.log({ error: toErrorMessage2(error) });
|
|
11426
12129
|
span.end();
|
|
11427
12130
|
throw error;
|
|
11428
12131
|
};
|
|
11429
12132
|
return withCurrent(span, () => {
|
|
11430
12133
|
try {
|
|
11431
12134
|
const result = runHandler();
|
|
11432
|
-
if (
|
|
12135
|
+
if (isPromiseLike(result)) {
|
|
11433
12136
|
return result.then(finalizeSuccess, finalizeError);
|
|
11434
12137
|
}
|
|
11435
12138
|
return finalizeSuccess(result);
|
|
@@ -11549,7 +12252,7 @@ var ROOT_LLM_PARENT_KEY = "__root__";
|
|
|
11549
12252
|
function llmParentKey(parentToolUseId) {
|
|
11550
12253
|
return parentToolUseId ?? ROOT_LLM_PARENT_KEY;
|
|
11551
12254
|
}
|
|
11552
|
-
function
|
|
12255
|
+
function isSubAgentDelegationToolName(toolName) {
|
|
11553
12256
|
return toolName === "Agent" || toolName === "Task";
|
|
11554
12257
|
}
|
|
11555
12258
|
function filterSerializableOptions(options) {
|
|
@@ -11583,24 +12286,92 @@ function getNumberProperty(obj, key) {
|
|
|
11583
12286
|
const value = Reflect.get(obj, key);
|
|
11584
12287
|
return typeof value === "number" ? value : void 0;
|
|
11585
12288
|
}
|
|
11586
|
-
function
|
|
11587
|
-
|
|
11588
|
-
|
|
11589
|
-
if (message.type === "assistant") {
|
|
11590
|
-
usage = message.message?.usage;
|
|
11591
|
-
} else if (message.type === "result") {
|
|
11592
|
-
usage = message.usage;
|
|
12289
|
+
function getStringProperty(obj, key) {
|
|
12290
|
+
if (!obj || typeof obj !== "object" || !(key in obj)) {
|
|
12291
|
+
return void 0;
|
|
11593
12292
|
}
|
|
11594
|
-
|
|
11595
|
-
|
|
12293
|
+
const value = Reflect.get(obj, key);
|
|
12294
|
+
return typeof value === "string" ? value : void 0;
|
|
12295
|
+
}
|
|
12296
|
+
function upsertSubAgentDetails(detailsByToolUseId, toolUseId, update) {
|
|
12297
|
+
const existing = detailsByToolUseId.get(toolUseId) ?? {};
|
|
12298
|
+
const merged = {
|
|
12299
|
+
...existing,
|
|
12300
|
+
...Object.fromEntries(
|
|
12301
|
+
Object.entries(update).filter(([, value]) => value !== void 0)
|
|
12302
|
+
)
|
|
12303
|
+
};
|
|
12304
|
+
detailsByToolUseId.set(toolUseId, merged);
|
|
12305
|
+
return merged;
|
|
12306
|
+
}
|
|
12307
|
+
function formatSubAgentSpanName(details) {
|
|
12308
|
+
if (details?.description) {
|
|
12309
|
+
return `Agent: ${details.description}`;
|
|
11596
12310
|
}
|
|
11597
|
-
|
|
11598
|
-
|
|
11599
|
-
metrics.prompt_tokens = inputTokens;
|
|
12311
|
+
if (details?.agentType) {
|
|
12312
|
+
return `Agent: ${details.agentType}`;
|
|
11600
12313
|
}
|
|
11601
|
-
|
|
11602
|
-
|
|
11603
|
-
|
|
12314
|
+
return "Agent: sub-agent";
|
|
12315
|
+
}
|
|
12316
|
+
function subAgentDetailsToMetadata(details) {
|
|
12317
|
+
if (!details) {
|
|
12318
|
+
return {};
|
|
12319
|
+
}
|
|
12320
|
+
const metadata = {};
|
|
12321
|
+
if (details.agentId) {
|
|
12322
|
+
metadata["claude_agent_sdk.agent_id"] = details.agentId;
|
|
12323
|
+
}
|
|
12324
|
+
if (details.agentType) {
|
|
12325
|
+
metadata["claude_agent_sdk.agent_type"] = details.agentType;
|
|
12326
|
+
}
|
|
12327
|
+
if (details.description) {
|
|
12328
|
+
metadata["claude_agent_sdk.description"] = details.description;
|
|
12329
|
+
}
|
|
12330
|
+
if (details.taskId) {
|
|
12331
|
+
metadata["claude_agent_sdk.task_id"] = details.taskId;
|
|
12332
|
+
}
|
|
12333
|
+
if (details.taskType) {
|
|
12334
|
+
metadata["claude_agent_sdk.task_type"] = details.taskType;
|
|
12335
|
+
}
|
|
12336
|
+
if (details.toolUseId) {
|
|
12337
|
+
metadata["claude_agent_sdk.tool_use_id"] = details.toolUseId;
|
|
12338
|
+
}
|
|
12339
|
+
if (details.workflowName) {
|
|
12340
|
+
metadata["claude_agent_sdk.workflow_name"] = details.workflowName;
|
|
12341
|
+
}
|
|
12342
|
+
return metadata;
|
|
12343
|
+
}
|
|
12344
|
+
function resolveTaskToolUseId(taskIdToToolUseId, message) {
|
|
12345
|
+
const messageToolUseId = typeof message.tool_use_id === "string" ? message.tool_use_id : void 0;
|
|
12346
|
+
if (messageToolUseId && typeof message.task_id === "string") {
|
|
12347
|
+
taskIdToToolUseId.set(message.task_id, messageToolUseId);
|
|
12348
|
+
}
|
|
12349
|
+
if (messageToolUseId) {
|
|
12350
|
+
return messageToolUseId;
|
|
12351
|
+
}
|
|
12352
|
+
if (typeof message.task_id === "string") {
|
|
12353
|
+
return taskIdToToolUseId.get(message.task_id);
|
|
12354
|
+
}
|
|
12355
|
+
return void 0;
|
|
12356
|
+
}
|
|
12357
|
+
function extractUsageFromMessage(message) {
|
|
12358
|
+
const metrics = {};
|
|
12359
|
+
let usage;
|
|
12360
|
+
if (message.type === "assistant") {
|
|
12361
|
+
usage = message.message?.usage;
|
|
12362
|
+
} else if (message.type === "result") {
|
|
12363
|
+
usage = message.usage;
|
|
12364
|
+
}
|
|
12365
|
+
if (!usage || typeof usage !== "object") {
|
|
12366
|
+
return metrics;
|
|
12367
|
+
}
|
|
12368
|
+
const inputTokens = getNumberProperty(usage, "input_tokens");
|
|
12369
|
+
if (inputTokens !== void 0) {
|
|
12370
|
+
metrics.prompt_tokens = inputTokens;
|
|
12371
|
+
}
|
|
12372
|
+
const outputTokens = getNumberProperty(usage, "output_tokens");
|
|
12373
|
+
if (outputTokens !== void 0) {
|
|
12374
|
+
metrics.completion_tokens = outputTokens;
|
|
11604
12375
|
}
|
|
11605
12376
|
const cacheReadTokens = getNumberProperty(usage, "cache_read_input_tokens") || 0;
|
|
11606
12377
|
const cacheCreationTokens = getNumberProperty(usage, "cache_creation_input_tokens") || 0;
|
|
@@ -11755,7 +12526,7 @@ function prepareLocalToolHandlersInMcpServers(mcpServers) {
|
|
|
11755
12526
|
}
|
|
11756
12527
|
return { hasLocalToolHandlers, localToolHookNames };
|
|
11757
12528
|
}
|
|
11758
|
-
function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentSpans, endedSubAgentSpans) {
|
|
12529
|
+
function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
11759
12530
|
const preToolUse = async (input, toolUseID) => {
|
|
11760
12531
|
if (input.hook_event_name !== "PreToolUse" || !toolUseID) {
|
|
11761
12532
|
return {};
|
|
@@ -11763,9 +12534,6 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
11763
12534
|
if (skipLocalToolHooks && (isLocalToolUse(input.tool_name, mcpServers) || localToolHookNames.has(input.tool_name))) {
|
|
11764
12535
|
return {};
|
|
11765
12536
|
}
|
|
11766
|
-
if (isSubAgentToolName(input.tool_name)) {
|
|
11767
|
-
return {};
|
|
11768
|
-
}
|
|
11769
12537
|
const parsed = parseToolName(input.tool_name);
|
|
11770
12538
|
const toolSpan = startSpan({
|
|
11771
12539
|
event: {
|
|
@@ -11795,10 +12563,18 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
11795
12563
|
return {};
|
|
11796
12564
|
}
|
|
11797
12565
|
const subAgentSpan = subAgentSpans.get(toolUseID);
|
|
12566
|
+
const toolSpan = activeToolSpans.get(toolUseID);
|
|
11798
12567
|
if (subAgentSpan) {
|
|
12568
|
+
if (endedSubAgentSpans.has(toolUseID)) {
|
|
12569
|
+
return {};
|
|
12570
|
+
}
|
|
11799
12571
|
try {
|
|
11800
12572
|
const response = input.tool_response;
|
|
11801
|
-
const metadata = {
|
|
12573
|
+
const metadata = {
|
|
12574
|
+
...subAgentDetailsToMetadata(
|
|
12575
|
+
subAgentDetailsByToolUseId.get(toolUseID)
|
|
12576
|
+
)
|
|
12577
|
+
};
|
|
11802
12578
|
if (response?.status) {
|
|
11803
12579
|
metadata["claude_agent_sdk.status"] = response.status;
|
|
11804
12580
|
}
|
|
@@ -11816,9 +12592,16 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
11816
12592
|
subAgentSpan.end();
|
|
11817
12593
|
endedSubAgentSpans.add(toolUseID);
|
|
11818
12594
|
}
|
|
12595
|
+
if (toolSpan) {
|
|
12596
|
+
try {
|
|
12597
|
+
toolSpan.log({ output: input.tool_response });
|
|
12598
|
+
} finally {
|
|
12599
|
+
toolSpan.end();
|
|
12600
|
+
activeToolSpans.delete(toolUseID);
|
|
12601
|
+
}
|
|
12602
|
+
}
|
|
11819
12603
|
return {};
|
|
11820
12604
|
}
|
|
11821
|
-
const toolSpan = activeToolSpans.get(toolUseID);
|
|
11822
12605
|
if (!toolSpan) {
|
|
11823
12606
|
return {};
|
|
11824
12607
|
}
|
|
@@ -11838,16 +12621,43 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
11838
12621
|
return {};
|
|
11839
12622
|
}
|
|
11840
12623
|
const subAgentSpan = subAgentSpans.get(toolUseID);
|
|
12624
|
+
const toolSpan = activeToolSpans.get(toolUseID);
|
|
11841
12625
|
if (subAgentSpan) {
|
|
12626
|
+
if (endedSubAgentSpans.has(toolUseID)) {
|
|
12627
|
+
return {};
|
|
12628
|
+
}
|
|
11842
12629
|
try {
|
|
11843
|
-
subAgentSpan.log({
|
|
12630
|
+
subAgentSpan.log({
|
|
12631
|
+
error: input.error,
|
|
12632
|
+
metadata: subAgentDetailsToMetadata(
|
|
12633
|
+
subAgentDetailsByToolUseId.get(toolUseID)
|
|
12634
|
+
)
|
|
12635
|
+
});
|
|
11844
12636
|
} finally {
|
|
11845
12637
|
subAgentSpan.end();
|
|
11846
12638
|
endedSubAgentSpans.add(toolUseID);
|
|
11847
12639
|
}
|
|
12640
|
+
if (toolSpan) {
|
|
12641
|
+
const parsed2 = parseToolName(input.tool_name);
|
|
12642
|
+
try {
|
|
12643
|
+
toolSpan.log({
|
|
12644
|
+
error: input.error,
|
|
12645
|
+
metadata: {
|
|
12646
|
+
"claude_agent_sdk.is_interrupt": input.is_interrupt,
|
|
12647
|
+
"claude_agent_sdk.session_id": input.session_id,
|
|
12648
|
+
"claude_agent_sdk.raw_tool_name": parsed2.rawToolName,
|
|
12649
|
+
"gen_ai.tool.call.id": toolUseID,
|
|
12650
|
+
"gen_ai.tool.name": parsed2.toolName,
|
|
12651
|
+
...parsed2.mcpServer && { "mcp.server": parsed2.mcpServer }
|
|
12652
|
+
}
|
|
12653
|
+
});
|
|
12654
|
+
} finally {
|
|
12655
|
+
toolSpan.end();
|
|
12656
|
+
activeToolSpans.delete(toolUseID);
|
|
12657
|
+
}
|
|
12658
|
+
}
|
|
11848
12659
|
return {};
|
|
11849
12660
|
}
|
|
11850
|
-
const toolSpan = activeToolSpans.get(toolUseID);
|
|
11851
12661
|
if (!toolSpan) {
|
|
11852
12662
|
return {};
|
|
11853
12663
|
}
|
|
@@ -11869,15 +12679,84 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
|
|
|
11869
12679
|
}
|
|
11870
12680
|
return {};
|
|
11871
12681
|
};
|
|
11872
|
-
|
|
12682
|
+
const subagentStart = async (input, toolUseID) => {
|
|
12683
|
+
if (input.hook_event_name !== "SubagentStart" || !toolUseID) {
|
|
12684
|
+
return {};
|
|
12685
|
+
}
|
|
12686
|
+
const details = upsertSubAgentDetails(
|
|
12687
|
+
subAgentDetailsByToolUseId,
|
|
12688
|
+
toolUseID,
|
|
12689
|
+
{
|
|
12690
|
+
agentId: input.agent_id,
|
|
12691
|
+
agentType: input.agent_type,
|
|
12692
|
+
toolUseId: toolUseID
|
|
12693
|
+
}
|
|
12694
|
+
);
|
|
12695
|
+
const subAgentSpan = subAgentSpans.get(toolUseID);
|
|
12696
|
+
if (subAgentSpan && !endedSubAgentSpans.has(toolUseID)) {
|
|
12697
|
+
subAgentSpan.log({
|
|
12698
|
+
metadata: subAgentDetailsToMetadata(details)
|
|
12699
|
+
});
|
|
12700
|
+
}
|
|
12701
|
+
return {};
|
|
12702
|
+
};
|
|
12703
|
+
const subagentStop = async (input, toolUseID) => {
|
|
12704
|
+
if (input.hook_event_name !== "SubagentStop" || !toolUseID) {
|
|
12705
|
+
return {};
|
|
12706
|
+
}
|
|
12707
|
+
const details = upsertSubAgentDetails(
|
|
12708
|
+
subAgentDetailsByToolUseId,
|
|
12709
|
+
toolUseID,
|
|
12710
|
+
{
|
|
12711
|
+
agentId: input.agent_id,
|
|
12712
|
+
agentType: input.agent_type,
|
|
12713
|
+
toolUseId: toolUseID
|
|
12714
|
+
}
|
|
12715
|
+
);
|
|
12716
|
+
const subAgentSpan = subAgentSpans.get(toolUseID);
|
|
12717
|
+
if (!subAgentSpan || endedSubAgentSpans.has(toolUseID)) {
|
|
12718
|
+
return {};
|
|
12719
|
+
}
|
|
12720
|
+
const metadata = {
|
|
12721
|
+
...subAgentDetailsToMetadata(details),
|
|
12722
|
+
...input.agent_transcript_path && {
|
|
12723
|
+
"claude_agent_sdk.agent_transcript_path": input.agent_transcript_path
|
|
12724
|
+
},
|
|
12725
|
+
"claude_agent_sdk.stop_hook_active": input.stop_hook_active
|
|
12726
|
+
};
|
|
12727
|
+
try {
|
|
12728
|
+
subAgentSpan.log({
|
|
12729
|
+
metadata,
|
|
12730
|
+
output: input.last_assistant_message
|
|
12731
|
+
});
|
|
12732
|
+
} finally {
|
|
12733
|
+
subAgentSpan.end();
|
|
12734
|
+
endedSubAgentSpans.add(toolUseID);
|
|
12735
|
+
}
|
|
12736
|
+
return {};
|
|
12737
|
+
};
|
|
12738
|
+
return {
|
|
12739
|
+
postToolUse,
|
|
12740
|
+
postToolUseFailure,
|
|
12741
|
+
preToolUse,
|
|
12742
|
+
subagentStart,
|
|
12743
|
+
subagentStop
|
|
12744
|
+
};
|
|
11873
12745
|
}
|
|
11874
|
-
function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentSpans, endedSubAgentSpans) {
|
|
11875
|
-
const {
|
|
12746
|
+
function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localToolHookNames, skipLocalToolHooks, subAgentDetailsByToolUseId, subAgentSpans, endedSubAgentSpans) {
|
|
12747
|
+
const {
|
|
12748
|
+
preToolUse,
|
|
12749
|
+
postToolUse,
|
|
12750
|
+
postToolUseFailure,
|
|
12751
|
+
subagentStart,
|
|
12752
|
+
subagentStop
|
|
12753
|
+
} = createToolTracingHooks(
|
|
11876
12754
|
resolveParentSpan,
|
|
11877
12755
|
activeToolSpans,
|
|
11878
12756
|
options.mcpServers,
|
|
11879
12757
|
localToolHookNames,
|
|
11880
12758
|
skipLocalToolHooks,
|
|
12759
|
+
subAgentDetailsByToolUseId,
|
|
11881
12760
|
subAgentSpans,
|
|
11882
12761
|
endedSubAgentSpans
|
|
11883
12762
|
);
|
|
@@ -11899,6 +12778,18 @@ function injectTracingHooks(options, resolveParentSpan, activeToolSpans, localTo
|
|
|
11899
12778
|
PreToolUse: [
|
|
11900
12779
|
...existingHooks.PreToolUse ?? [],
|
|
11901
12780
|
{ hooks: [preToolUse] }
|
|
12781
|
+
],
|
|
12782
|
+
SubagentStart: [
|
|
12783
|
+
...existingHooks.SubagentStart ?? [],
|
|
12784
|
+
{
|
|
12785
|
+
hooks: [subagentStart]
|
|
12786
|
+
}
|
|
12787
|
+
],
|
|
12788
|
+
SubagentStop: [
|
|
12789
|
+
...existingHooks.SubagentStop ?? [],
|
|
12790
|
+
{
|
|
12791
|
+
hooks: [subagentStop]
|
|
12792
|
+
}
|
|
11902
12793
|
]
|
|
11903
12794
|
}
|
|
11904
12795
|
};
|
|
@@ -11927,7 +12818,6 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
11927
12818
|
parentSpan,
|
|
11928
12819
|
existingLlmSpan
|
|
11929
12820
|
);
|
|
11930
|
-
state.activeLlmSpansByParentToolUse.delete(parentKey);
|
|
11931
12821
|
if (llmSpanResult) {
|
|
11932
12822
|
if (parentToolUseId) {
|
|
11933
12823
|
state.latestLlmParentBySubAgentToolUse.set(
|
|
@@ -11941,6 +12831,7 @@ async function finalizeCurrentMessageGroup(state) {
|
|
|
11941
12831
|
state.finalResults.push(llmSpanResult.finalMessage);
|
|
11942
12832
|
}
|
|
11943
12833
|
}
|
|
12834
|
+
state.activeLlmSpansByParentToolUse.delete(parentKey);
|
|
11944
12835
|
const lastMessage = state.currentMessages[state.currentMessages.length - 1];
|
|
11945
12836
|
if (lastMessage?.message?.usage) {
|
|
11946
12837
|
state.accumulatedOutputTokens += getNumberProperty(lastMessage.message.usage, "output_tokens") || 0;
|
|
@@ -11957,8 +12848,12 @@ function maybeTrackToolUseContext(state, message) {
|
|
|
11957
12848
|
continue;
|
|
11958
12849
|
}
|
|
11959
12850
|
state.toolUseToParent.set(block.id, parentToolUseId);
|
|
11960
|
-
if (block.name === "
|
|
11961
|
-
state.
|
|
12851
|
+
if (typeof block.name === "string" && isSubAgentDelegationToolName(block.name) && typeof block.input === "object" && block.input !== null) {
|
|
12852
|
+
upsertSubAgentDetails(state.subAgentDetailsByToolUseId, block.id, {
|
|
12853
|
+
agentType: getStringProperty(block.input, "subagent_type"),
|
|
12854
|
+
description: getStringProperty(block.input, "description"),
|
|
12855
|
+
toolUseId: block.id
|
|
12856
|
+
});
|
|
11962
12857
|
}
|
|
11963
12858
|
}
|
|
11964
12859
|
}
|
|
@@ -11971,34 +12866,133 @@ async function maybeStartSubAgentSpan(state, message) {
|
|
|
11971
12866
|
return;
|
|
11972
12867
|
}
|
|
11973
12868
|
await ensureSubAgentSpan(
|
|
11974
|
-
state.
|
|
12869
|
+
state.subAgentDetailsByToolUseId,
|
|
11975
12870
|
state.span,
|
|
12871
|
+
state.activeToolSpans,
|
|
11976
12872
|
state.subAgentSpans,
|
|
11977
12873
|
parentToolUseId
|
|
11978
12874
|
);
|
|
11979
12875
|
}
|
|
11980
|
-
async function ensureSubAgentSpan(
|
|
12876
|
+
async function ensureSubAgentSpan(subAgentDetailsByToolUseId, rootSpan, activeToolSpans, subAgentSpans, parentToolUseId) {
|
|
11981
12877
|
const existingSpan = subAgentSpans.get(parentToolUseId);
|
|
11982
12878
|
if (existingSpan) {
|
|
11983
12879
|
return existingSpan;
|
|
11984
12880
|
}
|
|
11985
|
-
const
|
|
11986
|
-
const spanName =
|
|
12881
|
+
const details = subAgentDetailsByToolUseId.get(parentToolUseId);
|
|
12882
|
+
const spanName = formatSubAgentSpanName(details);
|
|
12883
|
+
const parentToolSpan = activeToolSpans.get(parentToolUseId);
|
|
12884
|
+
const parentSpan = parentToolSpan ? await parentToolSpan.export() : await rootSpan.export();
|
|
11987
12885
|
const subAgentSpan = startSpan({
|
|
11988
12886
|
event: {
|
|
11989
|
-
metadata:
|
|
11990
|
-
...agentName && { "claude_agent_sdk.agent_type": agentName }
|
|
11991
|
-
}
|
|
12887
|
+
metadata: subAgentDetailsToMetadata(details)
|
|
11992
12888
|
},
|
|
11993
12889
|
name: spanName,
|
|
11994
|
-
parent:
|
|
12890
|
+
parent: parentSpan,
|
|
11995
12891
|
spanAttributes: { type: "task" /* TASK */ }
|
|
11996
12892
|
});
|
|
11997
12893
|
subAgentSpans.set(parentToolUseId, subAgentSpan);
|
|
11998
12894
|
return subAgentSpan;
|
|
11999
12895
|
}
|
|
12896
|
+
async function maybeHandleTaskLifecycleMessage(state, message) {
|
|
12897
|
+
if (message.type !== "system") {
|
|
12898
|
+
return false;
|
|
12899
|
+
}
|
|
12900
|
+
if (message.subtype !== "task_started" && message.subtype !== "task_progress" && message.subtype !== "task_notification") {
|
|
12901
|
+
return false;
|
|
12902
|
+
}
|
|
12903
|
+
const toolUseId = resolveTaskToolUseId(state.taskIdToToolUseId, message);
|
|
12904
|
+
if (!toolUseId) {
|
|
12905
|
+
return true;
|
|
12906
|
+
}
|
|
12907
|
+
const details = upsertSubAgentDetails(
|
|
12908
|
+
state.subAgentDetailsByToolUseId,
|
|
12909
|
+
toolUseId,
|
|
12910
|
+
{
|
|
12911
|
+
description: getStringProperty(message, "description"),
|
|
12912
|
+
taskId: getStringProperty(message, "task_id"),
|
|
12913
|
+
taskType: getStringProperty(message, "task_type"),
|
|
12914
|
+
toolUseId,
|
|
12915
|
+
workflowName: getStringProperty(message, "workflow_name")
|
|
12916
|
+
}
|
|
12917
|
+
);
|
|
12918
|
+
const subAgentSpan = await ensureSubAgentSpan(
|
|
12919
|
+
state.subAgentDetailsByToolUseId,
|
|
12920
|
+
state.span,
|
|
12921
|
+
state.activeToolSpans,
|
|
12922
|
+
state.subAgentSpans,
|
|
12923
|
+
toolUseId
|
|
12924
|
+
);
|
|
12925
|
+
if (state.endedSubAgentSpans.has(toolUseId)) {
|
|
12926
|
+
return true;
|
|
12927
|
+
}
|
|
12928
|
+
const usage = message.usage;
|
|
12929
|
+
const usageTotalTokens = getNumberProperty(usage, "total_tokens");
|
|
12930
|
+
const usageToolUses = getNumberProperty(usage, "tool_uses");
|
|
12931
|
+
const usageDurationMs = getNumberProperty(usage, "duration_ms");
|
|
12932
|
+
const metadata = {
|
|
12933
|
+
...subAgentDetailsToMetadata(details),
|
|
12934
|
+
"claude_agent_sdk.tool_use_id": toolUseId,
|
|
12935
|
+
...usageTotalTokens !== void 0 && {
|
|
12936
|
+
"claude_agent_sdk.total_tokens": usageTotalTokens
|
|
12937
|
+
},
|
|
12938
|
+
...usageToolUses !== void 0 && {
|
|
12939
|
+
"claude_agent_sdk.tool_use_count": usageToolUses
|
|
12940
|
+
},
|
|
12941
|
+
...usageDurationMs !== void 0 && {
|
|
12942
|
+
"claude_agent_sdk.duration_ms": usageDurationMs
|
|
12943
|
+
}
|
|
12944
|
+
};
|
|
12945
|
+
if (message.subtype === "task_started") {
|
|
12946
|
+
const prompt = getStringProperty(message, "prompt");
|
|
12947
|
+
subAgentSpan.log({
|
|
12948
|
+
input: prompt,
|
|
12949
|
+
metadata
|
|
12950
|
+
});
|
|
12951
|
+
return true;
|
|
12952
|
+
}
|
|
12953
|
+
const summary = getStringProperty(message, "summary");
|
|
12954
|
+
if (summary) {
|
|
12955
|
+
metadata["claude_agent_sdk.summary"] = summary;
|
|
12956
|
+
}
|
|
12957
|
+
if (message.subtype === "task_progress") {
|
|
12958
|
+
const lastToolName = getStringProperty(message, "last_tool_name");
|
|
12959
|
+
if (lastToolName) {
|
|
12960
|
+
metadata["claude_agent_sdk.last_tool_name"] = lastToolName;
|
|
12961
|
+
}
|
|
12962
|
+
subAgentSpan.log({
|
|
12963
|
+
metadata,
|
|
12964
|
+
output: summary
|
|
12965
|
+
});
|
|
12966
|
+
return true;
|
|
12967
|
+
}
|
|
12968
|
+
const status = getStringProperty(message, "status");
|
|
12969
|
+
const outputFile = getStringProperty(message, "output_file");
|
|
12970
|
+
if (status) {
|
|
12971
|
+
metadata["claude_agent_sdk.task_status"] = status;
|
|
12972
|
+
}
|
|
12973
|
+
if (outputFile) {
|
|
12974
|
+
metadata["claude_agent_sdk.output_file"] = outputFile;
|
|
12975
|
+
}
|
|
12976
|
+
const output = summary || outputFile ? {
|
|
12977
|
+
...summary && { summary },
|
|
12978
|
+
...outputFile && { output_file: outputFile }
|
|
12979
|
+
} : void 0;
|
|
12980
|
+
try {
|
|
12981
|
+
subAgentSpan.log({
|
|
12982
|
+
metadata,
|
|
12983
|
+
output
|
|
12984
|
+
});
|
|
12985
|
+
} finally {
|
|
12986
|
+
subAgentSpan.end();
|
|
12987
|
+
state.endedSubAgentSpans.add(toolUseId);
|
|
12988
|
+
}
|
|
12989
|
+
return true;
|
|
12990
|
+
}
|
|
12000
12991
|
async function handleStreamMessage(state, message) {
|
|
12001
12992
|
maybeTrackToolUseContext(state, message);
|
|
12993
|
+
if (await maybeHandleTaskLifecycleMessage(state, message)) {
|
|
12994
|
+
return;
|
|
12995
|
+
}
|
|
12002
12996
|
await maybeStartSubAgentSpan(state, message);
|
|
12003
12997
|
const messageId = message.message?.id;
|
|
12004
12998
|
if (messageId && messageId !== state.currentMessageId) {
|
|
@@ -12013,8 +13007,9 @@ async function handleStreamMessage(state, message) {
|
|
|
12013
13007
|
let llmParentSpan = await state.span.export();
|
|
12014
13008
|
if (parentToolUseId) {
|
|
12015
13009
|
const subAgentSpan = await ensureSubAgentSpan(
|
|
12016
|
-
state.
|
|
13010
|
+
state.subAgentDetailsByToolUseId,
|
|
12017
13011
|
state.span,
|
|
13012
|
+
state.activeToolSpans,
|
|
12018
13013
|
state.subAgentSpans,
|
|
12019
13014
|
parentToolUseId
|
|
12020
13015
|
);
|
|
@@ -12094,6 +13089,10 @@ async function finalizeQuerySpan(state) {
|
|
|
12094
13089
|
llmSpan.end();
|
|
12095
13090
|
}
|
|
12096
13091
|
state.activeLlmSpansByParentToolUse.clear();
|
|
13092
|
+
for (const toolSpan of state.activeToolSpans.values()) {
|
|
13093
|
+
toolSpan.end();
|
|
13094
|
+
}
|
|
13095
|
+
state.activeToolSpans.clear();
|
|
12097
13096
|
for (const [id, subAgentSpan] of state.subAgentSpans) {
|
|
12098
13097
|
if (!state.endedSubAgentSpans.has(id)) {
|
|
12099
13098
|
subAgentSpan.end();
|
|
@@ -12167,7 +13166,8 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
12167
13166
|
const latestRootLlmParentRef = {
|
|
12168
13167
|
value: void 0
|
|
12169
13168
|
};
|
|
12170
|
-
const
|
|
13169
|
+
const subAgentDetailsByToolUseId = /* @__PURE__ */ new Map();
|
|
13170
|
+
const taskIdToToolUseId = /* @__PURE__ */ new Map();
|
|
12171
13171
|
const localToolContext = createClaudeLocalToolContext();
|
|
12172
13172
|
const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
|
|
12173
13173
|
const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
|
|
@@ -12184,8 +13184,9 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
12184
13184
|
return parentLlm;
|
|
12185
13185
|
}
|
|
12186
13186
|
const subAgentSpan = await ensureSubAgentSpan(
|
|
12187
|
-
|
|
13187
|
+
subAgentDetailsByToolUseId,
|
|
12188
13188
|
span,
|
|
13189
|
+
activeToolSpans,
|
|
12189
13190
|
subAgentSpans,
|
|
12190
13191
|
parentToolUseId
|
|
12191
13192
|
);
|
|
@@ -12204,6 +13205,7 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
12204
13205
|
activeToolSpans,
|
|
12205
13206
|
localToolHookNames,
|
|
12206
13207
|
skipLocalToolHooks,
|
|
13208
|
+
subAgentDetailsByToolUseId,
|
|
12207
13209
|
subAgentSpans,
|
|
12208
13210
|
endedSubAgentSpans
|
|
12209
13211
|
);
|
|
@@ -12221,12 +13223,13 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
|
|
|
12221
13223
|
finalResults: [],
|
|
12222
13224
|
options: optionsWithHooks,
|
|
12223
13225
|
originalPrompt,
|
|
12224
|
-
pendingSubAgentNames,
|
|
12225
13226
|
processing: Promise.resolve(),
|
|
12226
13227
|
promptDone,
|
|
12227
13228
|
promptStarted: () => promptStarted,
|
|
12228
13229
|
span,
|
|
13230
|
+
subAgentDetailsByToolUseId,
|
|
12229
13231
|
subAgentSpans,
|
|
13232
|
+
taskIdToToolUseId,
|
|
12230
13233
|
latestLlmParentBySubAgentToolUse,
|
|
12231
13234
|
latestRootLlmParentRef,
|
|
12232
13235
|
toolUseToParent,
|
|
@@ -12308,6 +13311,10 @@ var googleGenAIChannels = defineChannels("@google/genai", {
|
|
|
12308
13311
|
generateContentStream: channel({
|
|
12309
13312
|
channelName: "models.generateContentStream",
|
|
12310
13313
|
kind: "async"
|
|
13314
|
+
}),
|
|
13315
|
+
embedContent: channel({
|
|
13316
|
+
channelName: "models.embedContent",
|
|
13317
|
+
kind: "async"
|
|
12311
13318
|
})
|
|
12312
13319
|
});
|
|
12313
13320
|
|
|
@@ -12334,6 +13341,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
12334
13341
|
subscribeToGoogleGenAIChannels() {
|
|
12335
13342
|
this.subscribeToGenerateContentChannel();
|
|
12336
13343
|
this.subscribeToGenerateContentStreamChannel();
|
|
13344
|
+
this.subscribeToEmbedContentChannel();
|
|
12337
13345
|
}
|
|
12338
13346
|
subscribeToGenerateContentChannel() {
|
|
12339
13347
|
const tracingChannel = googleGenAIChannels.generateContent.tracingChannel();
|
|
@@ -12343,8 +13351,8 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
12343
13351
|
states,
|
|
12344
13352
|
(event) => {
|
|
12345
13353
|
const params = event.arguments[0];
|
|
12346
|
-
const input =
|
|
12347
|
-
const metadata =
|
|
13354
|
+
const input = serializeGenerateContentInput(params);
|
|
13355
|
+
const metadata = extractGenerateContentMetadata(params);
|
|
12348
13356
|
const span = startSpan({
|
|
12349
13357
|
name: "generate_content",
|
|
12350
13358
|
spanAttributes: {
|
|
@@ -12362,8 +13370,8 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
12362
13370
|
start: (event) => {
|
|
12363
13371
|
ensureSpanState(states, event, () => {
|
|
12364
13372
|
const params = event.arguments[0];
|
|
12365
|
-
const input =
|
|
12366
|
-
const metadata =
|
|
13373
|
+
const input = serializeGenerateContentInput(params);
|
|
13374
|
+
const metadata = extractGenerateContentMetadata(params);
|
|
12367
13375
|
const span = startSpan({
|
|
12368
13376
|
name: "generate_content",
|
|
12369
13377
|
spanAttributes: {
|
|
@@ -12383,7 +13391,9 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
12383
13391
|
return;
|
|
12384
13392
|
}
|
|
12385
13393
|
try {
|
|
13394
|
+
const responseMetadata = extractResponseMetadata(event.result);
|
|
12386
13395
|
spanState.span.log({
|
|
13396
|
+
...responseMetadata ? { metadata: responseMetadata } : {},
|
|
12387
13397
|
metrics: cleanMetrics(
|
|
12388
13398
|
extractGenerateContentMetrics(
|
|
12389
13399
|
event.result,
|
|
@@ -12413,8 +13423,8 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
12413
13423
|
start: (event) => {
|
|
12414
13424
|
const streamEvent = event;
|
|
12415
13425
|
const params = event.arguments[0];
|
|
12416
|
-
streamEvent.googleGenAIInput =
|
|
12417
|
-
streamEvent.googleGenAIMetadata =
|
|
13426
|
+
streamEvent.googleGenAIInput = serializeGenerateContentInput(params);
|
|
13427
|
+
streamEvent.googleGenAIMetadata = extractGenerateContentMetadata(params);
|
|
12418
13428
|
streamEvent.googleGenAIStartTime = getCurrentUnixTimestamp();
|
|
12419
13429
|
},
|
|
12420
13430
|
asyncEnd: (event) => {
|
|
@@ -12434,6 +13444,76 @@ var GoogleGenAIPlugin = class extends BasePlugin {
|
|
|
12434
13444
|
tracingChannel.unsubscribe(handlers);
|
|
12435
13445
|
});
|
|
12436
13446
|
}
|
|
13447
|
+
subscribeToEmbedContentChannel() {
|
|
13448
|
+
const tracingChannel = googleGenAIChannels.embedContent.tracingChannel();
|
|
13449
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
13450
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
|
|
13451
|
+
tracingChannel,
|
|
13452
|
+
states,
|
|
13453
|
+
(event) => {
|
|
13454
|
+
const params = event.arguments[0];
|
|
13455
|
+
const input = serializeEmbedContentInput(params);
|
|
13456
|
+
const metadata = extractEmbedContentMetadata(params);
|
|
13457
|
+
const span = startSpan({
|
|
13458
|
+
name: "embed_content",
|
|
13459
|
+
spanAttributes: {
|
|
13460
|
+
type: "llm" /* LLM */
|
|
13461
|
+
},
|
|
13462
|
+
event: createWrapperParityEvent({ input, metadata })
|
|
13463
|
+
});
|
|
13464
|
+
return {
|
|
13465
|
+
span,
|
|
13466
|
+
startTime: getCurrentUnixTimestamp()
|
|
13467
|
+
};
|
|
13468
|
+
}
|
|
13469
|
+
);
|
|
13470
|
+
const handlers = {
|
|
13471
|
+
start: (event) => {
|
|
13472
|
+
ensureSpanState(states, event, () => {
|
|
13473
|
+
const params = event.arguments[0];
|
|
13474
|
+
const input = serializeEmbedContentInput(params);
|
|
13475
|
+
const metadata = extractEmbedContentMetadata(params);
|
|
13476
|
+
const span = startSpan({
|
|
13477
|
+
name: "embed_content",
|
|
13478
|
+
spanAttributes: {
|
|
13479
|
+
type: "llm" /* LLM */
|
|
13480
|
+
},
|
|
13481
|
+
event: createWrapperParityEvent({ input, metadata })
|
|
13482
|
+
});
|
|
13483
|
+
return {
|
|
13484
|
+
span,
|
|
13485
|
+
startTime: getCurrentUnixTimestamp()
|
|
13486
|
+
};
|
|
13487
|
+
});
|
|
13488
|
+
},
|
|
13489
|
+
asyncEnd: (event) => {
|
|
13490
|
+
const spanState = states.get(event);
|
|
13491
|
+
if (!spanState) {
|
|
13492
|
+
return;
|
|
13493
|
+
}
|
|
13494
|
+
try {
|
|
13495
|
+
const output = summarizeEmbedContentOutput(event.result);
|
|
13496
|
+
spanState.span.log({
|
|
13497
|
+
...output ? { output } : {},
|
|
13498
|
+
metrics: cleanMetrics(
|
|
13499
|
+
extractEmbedContentMetrics(event.result, spanState.startTime)
|
|
13500
|
+
)
|
|
13501
|
+
});
|
|
13502
|
+
} finally {
|
|
13503
|
+
spanState.span.end();
|
|
13504
|
+
states.delete(event);
|
|
13505
|
+
}
|
|
13506
|
+
},
|
|
13507
|
+
error: (event) => {
|
|
13508
|
+
logErrorAndEndSpan(states, event);
|
|
13509
|
+
}
|
|
13510
|
+
};
|
|
13511
|
+
tracingChannel.subscribe(handlers);
|
|
13512
|
+
this.unsubscribers.push(() => {
|
|
13513
|
+
unbindCurrentSpanStore?.();
|
|
13514
|
+
tracingChannel.unsubscribe(handlers);
|
|
13515
|
+
});
|
|
13516
|
+
}
|
|
12437
13517
|
};
|
|
12438
13518
|
function ensureSpanState(states, event, create) {
|
|
12439
13519
|
const existing = states.get(event);
|
|
@@ -12507,7 +13587,11 @@ function patchGoogleGenAIStreamingResult(args) {
|
|
|
12507
13587
|
finalized = true;
|
|
12508
13588
|
if (options.result) {
|
|
12509
13589
|
const { end, ...metricsWithoutEnd } = options.result.metrics;
|
|
13590
|
+
const responseMetadata = extractResponseMetadata(
|
|
13591
|
+
options.result.aggregated
|
|
13592
|
+
);
|
|
12510
13593
|
span.log({
|
|
13594
|
+
...responseMetadata ? { metadata: responseMetadata } : {},
|
|
12511
13595
|
metrics: cleanMetrics(metricsWithoutEnd),
|
|
12512
13596
|
output: options.result.aggregated
|
|
12513
13597
|
});
|
|
@@ -12610,26 +13694,35 @@ function patchGoogleGenAIStreamingResult(args) {
|
|
|
12610
13694
|
patchIterator(result);
|
|
12611
13695
|
return true;
|
|
12612
13696
|
}
|
|
12613
|
-
function
|
|
13697
|
+
function serializeGenerateContentInput(params) {
|
|
12614
13698
|
const input = {
|
|
12615
13699
|
model: params.model,
|
|
12616
|
-
contents:
|
|
13700
|
+
contents: serializeContentCollection(params.contents)
|
|
12617
13701
|
};
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12621
|
-
|
|
12622
|
-
|
|
12623
|
-
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
13702
|
+
const config = params.config ? tryToDict(params.config) : null;
|
|
13703
|
+
if (config) {
|
|
13704
|
+
const filteredConfig = {};
|
|
13705
|
+
Object.keys(config).forEach((key) => {
|
|
13706
|
+
if (key !== "tools") {
|
|
13707
|
+
filteredConfig[key] = config[key];
|
|
13708
|
+
}
|
|
13709
|
+
});
|
|
13710
|
+
input.config = filteredConfig;
|
|
13711
|
+
}
|
|
13712
|
+
return input;
|
|
13713
|
+
}
|
|
13714
|
+
function serializeEmbedContentInput(params) {
|
|
13715
|
+
const input = {
|
|
13716
|
+
model: params.model,
|
|
13717
|
+
contents: serializeContentCollection(params.contents)
|
|
13718
|
+
};
|
|
13719
|
+
const config = params.config ? tryToDict(params.config) : null;
|
|
13720
|
+
if (config) {
|
|
13721
|
+
input.config = config;
|
|
12629
13722
|
}
|
|
12630
13723
|
return input;
|
|
12631
13724
|
}
|
|
12632
|
-
function
|
|
13725
|
+
function serializeContentCollection(contents) {
|
|
12633
13726
|
if (contents === null || contents === void 0) {
|
|
12634
13727
|
return null;
|
|
12635
13728
|
}
|
|
@@ -12681,22 +13774,26 @@ function serializePart(part) {
|
|
|
12681
13774
|
}
|
|
12682
13775
|
return part;
|
|
12683
13776
|
}
|
|
12684
|
-
function
|
|
12685
|
-
|
|
13777
|
+
function serializeGenerateContentTools(params) {
|
|
13778
|
+
const config = params.config ? tryToDict(params.config) : null;
|
|
13779
|
+
const tools = config?.tools;
|
|
13780
|
+
if (!Array.isArray(tools)) {
|
|
12686
13781
|
return null;
|
|
12687
13782
|
}
|
|
12688
13783
|
try {
|
|
12689
|
-
|
|
12690
|
-
|
|
12691
|
-
|
|
13784
|
+
const serializedTools = [];
|
|
13785
|
+
for (const tool of tools) {
|
|
13786
|
+
const toolDict = tryToDict(tool);
|
|
13787
|
+
if (toolDict) {
|
|
13788
|
+
serializedTools.push(toolDict);
|
|
12692
13789
|
}
|
|
12693
|
-
|
|
12694
|
-
|
|
13790
|
+
}
|
|
13791
|
+
return serializedTools.length > 0 ? serializedTools : null;
|
|
12695
13792
|
} catch {
|
|
12696
13793
|
return null;
|
|
12697
13794
|
}
|
|
12698
13795
|
}
|
|
12699
|
-
function
|
|
13796
|
+
function extractGenerateContentMetadata(params) {
|
|
12700
13797
|
const metadata = {};
|
|
12701
13798
|
if (params.model) {
|
|
12702
13799
|
metadata.model = params.model;
|
|
@@ -12711,12 +13808,25 @@ function extractMetadata(params) {
|
|
|
12711
13808
|
});
|
|
12712
13809
|
}
|
|
12713
13810
|
}
|
|
12714
|
-
const tools =
|
|
13811
|
+
const tools = serializeGenerateContentTools(params);
|
|
12715
13812
|
if (tools) {
|
|
12716
13813
|
metadata.tools = tools;
|
|
12717
13814
|
}
|
|
12718
13815
|
return metadata;
|
|
12719
13816
|
}
|
|
13817
|
+
function extractEmbedContentMetadata(params) {
|
|
13818
|
+
const metadata = {};
|
|
13819
|
+
if (params.model) {
|
|
13820
|
+
metadata.model = params.model;
|
|
13821
|
+
}
|
|
13822
|
+
const config = params.config ? tryToDict(params.config) : null;
|
|
13823
|
+
if (config) {
|
|
13824
|
+
Object.keys(config).forEach((key) => {
|
|
13825
|
+
metadata[key] = config[key];
|
|
13826
|
+
});
|
|
13827
|
+
}
|
|
13828
|
+
return metadata;
|
|
13829
|
+
}
|
|
12720
13830
|
function extractGenerateContentMetrics(response, startTime) {
|
|
12721
13831
|
const metrics = {};
|
|
12722
13832
|
if (startTime !== void 0) {
|
|
@@ -12730,24 +13840,87 @@ function extractGenerateContentMetrics(response, startTime) {
|
|
|
12730
13840
|
}
|
|
12731
13841
|
return metrics;
|
|
12732
13842
|
}
|
|
12733
|
-
function
|
|
12734
|
-
|
|
12735
|
-
|
|
13843
|
+
function extractEmbedContentMetrics(response, startTime) {
|
|
13844
|
+
const metrics = {};
|
|
13845
|
+
if (startTime !== void 0) {
|
|
13846
|
+
const end = getCurrentUnixTimestamp();
|
|
13847
|
+
metrics.start = startTime;
|
|
13848
|
+
metrics.end = end;
|
|
13849
|
+
metrics.duration = end - startTime;
|
|
12736
13850
|
}
|
|
12737
|
-
if (
|
|
12738
|
-
metrics
|
|
13851
|
+
if (response?.usageMetadata) {
|
|
13852
|
+
populateUsageMetrics(metrics, response.usageMetadata);
|
|
12739
13853
|
}
|
|
12740
|
-
|
|
12741
|
-
|
|
13854
|
+
const embeddingTokenCount = extractEmbedPromptTokenCount(response);
|
|
13855
|
+
if (embeddingTokenCount !== void 0) {
|
|
13856
|
+
metrics.prompt_tokens = embeddingTokenCount;
|
|
13857
|
+
metrics.tokens = embeddingTokenCount;
|
|
12742
13858
|
}
|
|
12743
|
-
|
|
12744
|
-
|
|
13859
|
+
return metrics;
|
|
13860
|
+
}
|
|
13861
|
+
function extractEmbedPromptTokenCount(response) {
|
|
13862
|
+
if (!response) {
|
|
13863
|
+
return void 0;
|
|
12745
13864
|
}
|
|
12746
|
-
|
|
12747
|
-
|
|
13865
|
+
const usagePromptTokens = response.usageMetadata?.promptTokenCount;
|
|
13866
|
+
if (typeof usagePromptTokens === "number" && Number.isFinite(usagePromptTokens)) {
|
|
13867
|
+
return usagePromptTokens;
|
|
13868
|
+
}
|
|
13869
|
+
const usageTotalTokens = response.usageMetadata?.totalTokenCount;
|
|
13870
|
+
if (typeof usageTotalTokens === "number" && Number.isFinite(usageTotalTokens)) {
|
|
13871
|
+
return usageTotalTokens;
|
|
13872
|
+
}
|
|
13873
|
+
const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
|
|
13874
|
+
if (embeddings.length === 0) {
|
|
13875
|
+
return void 0;
|
|
13876
|
+
}
|
|
13877
|
+
let total = 0;
|
|
13878
|
+
let sawAny = false;
|
|
13879
|
+
for (const embedding of embeddings) {
|
|
13880
|
+
const embeddingStats = tryToDict(tryToDict(embedding)?.statistics);
|
|
13881
|
+
const tokenCount = embeddingStats?.tokenCount;
|
|
13882
|
+
if (typeof tokenCount === "number" && Number.isFinite(tokenCount)) {
|
|
13883
|
+
total += tokenCount;
|
|
13884
|
+
sawAny = true;
|
|
13885
|
+
}
|
|
12748
13886
|
}
|
|
13887
|
+
return sawAny ? total : void 0;
|
|
12749
13888
|
}
|
|
12750
|
-
function
|
|
13889
|
+
function summarizeEmbedContentOutput(response) {
|
|
13890
|
+
if (!response) {
|
|
13891
|
+
return void 0;
|
|
13892
|
+
}
|
|
13893
|
+
const embeddings = Array.isArray(response.embeddings) ? response.embeddings : response.embedding ? [response.embedding] : [];
|
|
13894
|
+
if (embeddings.length === 0) {
|
|
13895
|
+
return void 0;
|
|
13896
|
+
}
|
|
13897
|
+
const firstValues = embeddings[0]?.values;
|
|
13898
|
+
if (!Array.isArray(firstValues)) {
|
|
13899
|
+
return void 0;
|
|
13900
|
+
}
|
|
13901
|
+
return {
|
|
13902
|
+
embedding_count: embeddings.length,
|
|
13903
|
+
embedding_length: firstValues.length
|
|
13904
|
+
};
|
|
13905
|
+
}
|
|
13906
|
+
function populateUsageMetrics(metrics, usage) {
|
|
13907
|
+
if (usage.promptTokenCount !== void 0) {
|
|
13908
|
+
metrics.prompt_tokens = usage.promptTokenCount;
|
|
13909
|
+
}
|
|
13910
|
+
if (usage.candidatesTokenCount !== void 0) {
|
|
13911
|
+
metrics.completion_tokens = usage.candidatesTokenCount;
|
|
13912
|
+
}
|
|
13913
|
+
if (usage.totalTokenCount !== void 0) {
|
|
13914
|
+
metrics.tokens = usage.totalTokenCount;
|
|
13915
|
+
}
|
|
13916
|
+
if (usage.cachedContentTokenCount !== void 0) {
|
|
13917
|
+
metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
|
|
13918
|
+
}
|
|
13919
|
+
if (usage.thoughtsTokenCount !== void 0) {
|
|
13920
|
+
metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
|
|
13921
|
+
}
|
|
13922
|
+
}
|
|
13923
|
+
function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
|
|
12751
13924
|
const end = getCurrentUnixTimestamp();
|
|
12752
13925
|
const metrics = {
|
|
12753
13926
|
start: startTime,
|
|
@@ -12763,6 +13936,7 @@ function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
|
|
|
12763
13936
|
let text = "";
|
|
12764
13937
|
let thoughtText = "";
|
|
12765
13938
|
const otherParts = [];
|
|
13939
|
+
let groundingMetadata = void 0;
|
|
12766
13940
|
let usageMetadata = null;
|
|
12767
13941
|
let lastResponse = null;
|
|
12768
13942
|
for (const chunk of chunks) {
|
|
@@ -12770,6 +13944,9 @@ function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
|
|
|
12770
13944
|
if (chunk.usageMetadata) {
|
|
12771
13945
|
usageMetadata = chunk.usageMetadata;
|
|
12772
13946
|
}
|
|
13947
|
+
if (chunk.groundingMetadata !== void 0) {
|
|
13948
|
+
groundingMetadata = chunk.groundingMetadata;
|
|
13949
|
+
}
|
|
12773
13950
|
if (chunk.candidates && Array.isArray(chunk.candidates)) {
|
|
12774
13951
|
for (const candidate of chunk.candidates) {
|
|
12775
13952
|
if (candidate.content?.parts) {
|
|
@@ -12815,6 +13992,12 @@ function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
|
|
|
12815
13992
|
if (candidate.finishReason !== void 0) {
|
|
12816
13993
|
candidateDict.finishReason = candidate.finishReason;
|
|
12817
13994
|
}
|
|
13995
|
+
if (candidate.groundingMetadata !== void 0) {
|
|
13996
|
+
candidateDict.groundingMetadata = candidate.groundingMetadata;
|
|
13997
|
+
if (groundingMetadata === void 0) {
|
|
13998
|
+
groundingMetadata = candidate.groundingMetadata;
|
|
13999
|
+
}
|
|
14000
|
+
}
|
|
12818
14001
|
if (candidate.safetyRatings) {
|
|
12819
14002
|
candidateDict.safetyRatings = candidate.safetyRatings;
|
|
12820
14003
|
}
|
|
@@ -12826,6 +14009,9 @@ function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
|
|
|
12826
14009
|
aggregated.usageMetadata = usageMetadata;
|
|
12827
14010
|
populateUsageMetrics(metrics, usageMetadata);
|
|
12828
14011
|
}
|
|
14012
|
+
if (groundingMetadata !== void 0) {
|
|
14013
|
+
aggregated.groundingMetadata = groundingMetadata;
|
|
14014
|
+
}
|
|
12829
14015
|
if (text) {
|
|
12830
14016
|
aggregated.text = text;
|
|
12831
14017
|
}
|
|
@@ -12840,6 +14026,31 @@ function cleanMetrics(metrics) {
|
|
|
12840
14026
|
}
|
|
12841
14027
|
return cleaned;
|
|
12842
14028
|
}
|
|
14029
|
+
function extractResponseMetadata(response) {
|
|
14030
|
+
const responseDict = tryToDict(response);
|
|
14031
|
+
if (!responseDict) {
|
|
14032
|
+
return void 0;
|
|
14033
|
+
}
|
|
14034
|
+
const metadata = {};
|
|
14035
|
+
const responseGroundingMetadata = responseDict.groundingMetadata;
|
|
14036
|
+
const candidateGroundingMetadata = [];
|
|
14037
|
+
if (Array.isArray(responseDict.candidates)) {
|
|
14038
|
+
for (const candidate of responseDict.candidates) {
|
|
14039
|
+
const candidateDict = tryToDict(candidate);
|
|
14040
|
+
if (candidateDict?.groundingMetadata !== void 0) {
|
|
14041
|
+
candidateGroundingMetadata.push(candidateDict.groundingMetadata);
|
|
14042
|
+
}
|
|
14043
|
+
}
|
|
14044
|
+
}
|
|
14045
|
+
if (responseGroundingMetadata !== void 0) {
|
|
14046
|
+
metadata.groundingMetadata = responseGroundingMetadata;
|
|
14047
|
+
} else if (candidateGroundingMetadata.length === 1) {
|
|
14048
|
+
[metadata.groundingMetadata] = candidateGroundingMetadata;
|
|
14049
|
+
} else if (candidateGroundingMetadata.length > 1) {
|
|
14050
|
+
metadata.groundingMetadata = candidateGroundingMetadata;
|
|
14051
|
+
}
|
|
14052
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
14053
|
+
}
|
|
12843
14054
|
function tryToDict(obj) {
|
|
12844
14055
|
if (obj === null || obj === void 0) {
|
|
12845
14056
|
return null;
|
|
@@ -12854,6 +14065,385 @@ function tryToDict(obj) {
|
|
|
12854
14065
|
return null;
|
|
12855
14066
|
}
|
|
12856
14067
|
|
|
14068
|
+
// src/instrumentation/plugins/huggingface-channels.ts
|
|
14069
|
+
var huggingFaceChannels = defineChannels("@huggingface/inference", {
|
|
14070
|
+
chatCompletion: channel({
|
|
14071
|
+
channelName: "chatCompletion",
|
|
14072
|
+
kind: "async"
|
|
14073
|
+
}),
|
|
14074
|
+
chatCompletionStream: channel({
|
|
14075
|
+
channelName: "chatCompletionStream",
|
|
14076
|
+
kind: "sync-stream"
|
|
14077
|
+
}),
|
|
14078
|
+
textGeneration: channel({
|
|
14079
|
+
channelName: "textGeneration",
|
|
14080
|
+
kind: "async"
|
|
14081
|
+
}),
|
|
14082
|
+
textGenerationStream: channel({
|
|
14083
|
+
channelName: "textGenerationStream",
|
|
14084
|
+
kind: "sync-stream"
|
|
14085
|
+
}),
|
|
14086
|
+
featureExtraction: channel({
|
|
14087
|
+
channelName: "featureExtraction",
|
|
14088
|
+
kind: "async"
|
|
14089
|
+
})
|
|
14090
|
+
});
|
|
14091
|
+
|
|
14092
|
+
// src/instrumentation/plugins/huggingface-plugin.ts
|
|
14093
|
+
var REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
14094
|
+
"dimensions",
|
|
14095
|
+
"encoding_format",
|
|
14096
|
+
"endpointUrl",
|
|
14097
|
+
"max_tokens",
|
|
14098
|
+
"model",
|
|
14099
|
+
"provider",
|
|
14100
|
+
"seed",
|
|
14101
|
+
"stop",
|
|
14102
|
+
"stream",
|
|
14103
|
+
"temperature",
|
|
14104
|
+
"top_p"
|
|
14105
|
+
]);
|
|
14106
|
+
var RESPONSE_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
14107
|
+
"created",
|
|
14108
|
+
"id",
|
|
14109
|
+
"model",
|
|
14110
|
+
"object"
|
|
14111
|
+
]);
|
|
14112
|
+
var HuggingFacePlugin = class extends BasePlugin {
|
|
14113
|
+
onEnable() {
|
|
14114
|
+
this.unsubscribers.push(
|
|
14115
|
+
traceAsyncChannel(huggingFaceChannels.chatCompletion, {
|
|
14116
|
+
name: "huggingface.chat_completion",
|
|
14117
|
+
type: "llm" /* LLM */,
|
|
14118
|
+
extractInput: extractChatInputWithMetadata,
|
|
14119
|
+
extractOutput: (result) => result?.choices,
|
|
14120
|
+
extractMetadata: (result) => extractResponseMetadata2(result),
|
|
14121
|
+
extractMetrics: (result) => parseMetricsFromUsage(result?.usage)
|
|
14122
|
+
}),
|
|
14123
|
+
traceSyncStreamChannel(huggingFaceChannels.chatCompletionStream, {
|
|
14124
|
+
name: "huggingface.chat_completion_stream",
|
|
14125
|
+
type: "llm" /* LLM */,
|
|
14126
|
+
extractInput: extractChatInputWithMetadata,
|
|
14127
|
+
patchResult: ({ result, span, startTime }) => patchChatCompletionStream({
|
|
14128
|
+
result,
|
|
14129
|
+
span,
|
|
14130
|
+
startTime
|
|
14131
|
+
})
|
|
14132
|
+
}),
|
|
14133
|
+
traceAsyncChannel(huggingFaceChannels.textGeneration, {
|
|
14134
|
+
name: "huggingface.text_generation",
|
|
14135
|
+
type: "llm" /* LLM */,
|
|
14136
|
+
extractInput: extractTextGenerationInputWithMetadata,
|
|
14137
|
+
extractOutput: (result) => isObject(result) ? { generated_text: result.generated_text } : result,
|
|
14138
|
+
extractMetadata: extractTextGenerationMetadata,
|
|
14139
|
+
extractMetrics: (result) => extractTextGenerationMetrics(result?.details ?? null)
|
|
14140
|
+
}),
|
|
14141
|
+
traceSyncStreamChannel(huggingFaceChannels.textGenerationStream, {
|
|
14142
|
+
name: "huggingface.text_generation_stream",
|
|
14143
|
+
type: "llm" /* LLM */,
|
|
14144
|
+
extractInput: extractTextGenerationInputWithMetadata,
|
|
14145
|
+
patchResult: ({ result, span, startTime }) => patchTextGenerationStream({
|
|
14146
|
+
result,
|
|
14147
|
+
span,
|
|
14148
|
+
startTime
|
|
14149
|
+
})
|
|
14150
|
+
}),
|
|
14151
|
+
traceAsyncChannel(huggingFaceChannels.featureExtraction, {
|
|
14152
|
+
name: "huggingface.feature_extraction",
|
|
14153
|
+
type: "llm" /* LLM */,
|
|
14154
|
+
extractInput: extractFeatureExtractionInputWithMetadata,
|
|
14155
|
+
extractOutput: summarizeFeatureExtractionOutput,
|
|
14156
|
+
extractMetrics: () => ({})
|
|
14157
|
+
})
|
|
14158
|
+
);
|
|
14159
|
+
}
|
|
14160
|
+
onDisable() {
|
|
14161
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
14162
|
+
}
|
|
14163
|
+
};
|
|
14164
|
+
function addProviderMetadata(metadata) {
|
|
14165
|
+
return {
|
|
14166
|
+
...metadata,
|
|
14167
|
+
provider: metadata.provider ?? "huggingface"
|
|
14168
|
+
};
|
|
14169
|
+
}
|
|
14170
|
+
function normalizeArgs(args) {
|
|
14171
|
+
if (Array.isArray(args)) {
|
|
14172
|
+
return args;
|
|
14173
|
+
}
|
|
14174
|
+
if (isArrayLike(args)) {
|
|
14175
|
+
return Array.from(args);
|
|
14176
|
+
}
|
|
14177
|
+
return [args];
|
|
14178
|
+
}
|
|
14179
|
+
function isArrayLike(value) {
|
|
14180
|
+
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
14181
|
+
}
|
|
14182
|
+
function getFirstObjectArg(args) {
|
|
14183
|
+
const firstObjectArg = normalizeArgs(args).find((arg) => isObject(arg));
|
|
14184
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
14185
|
+
}
|
|
14186
|
+
function pickRequestMetadata(params) {
|
|
14187
|
+
if (!params) {
|
|
14188
|
+
return addProviderMetadata({});
|
|
14189
|
+
}
|
|
14190
|
+
const metadata = {};
|
|
14191
|
+
for (const key of REQUEST_METADATA_ALLOWLIST) {
|
|
14192
|
+
const value = params[key];
|
|
14193
|
+
if (value !== void 0) {
|
|
14194
|
+
metadata[key] = value;
|
|
14195
|
+
}
|
|
14196
|
+
}
|
|
14197
|
+
if (isObject(params.parameters)) {
|
|
14198
|
+
metadata.parameters = params.parameters;
|
|
14199
|
+
}
|
|
14200
|
+
return addProviderMetadata(metadata);
|
|
14201
|
+
}
|
|
14202
|
+
function extractChatInputWithMetadata(args) {
|
|
14203
|
+
const params = getFirstObjectArg(args);
|
|
14204
|
+
const { messages, ...rawMetadata } = params ?? {};
|
|
14205
|
+
return {
|
|
14206
|
+
input: messages,
|
|
14207
|
+
metadata: pickRequestMetadata(rawMetadata)
|
|
14208
|
+
};
|
|
14209
|
+
}
|
|
14210
|
+
function extractTextGenerationInputWithMetadata(args) {
|
|
14211
|
+
const params = getFirstObjectArg(args);
|
|
14212
|
+
const { inputs, ...rawMetadata } = params ?? {};
|
|
14213
|
+
return {
|
|
14214
|
+
input: inputs,
|
|
14215
|
+
metadata: pickRequestMetadata(rawMetadata)
|
|
14216
|
+
};
|
|
14217
|
+
}
|
|
14218
|
+
function extractFeatureExtractionInputWithMetadata(args) {
|
|
14219
|
+
const params = getFirstObjectArg(args);
|
|
14220
|
+
const { inputs, ...rawMetadata } = params ?? {};
|
|
14221
|
+
return {
|
|
14222
|
+
input: inputs,
|
|
14223
|
+
metadata: pickRequestMetadata(rawMetadata)
|
|
14224
|
+
};
|
|
14225
|
+
}
|
|
14226
|
+
function extractResponseMetadata2(result) {
|
|
14227
|
+
if (!isObject(result)) {
|
|
14228
|
+
return void 0;
|
|
14229
|
+
}
|
|
14230
|
+
const metadata = {};
|
|
14231
|
+
for (const key of RESPONSE_METADATA_ALLOWLIST) {
|
|
14232
|
+
const value = result[key];
|
|
14233
|
+
if (value !== void 0) {
|
|
14234
|
+
metadata[key] = value;
|
|
14235
|
+
}
|
|
14236
|
+
}
|
|
14237
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
14238
|
+
}
|
|
14239
|
+
function extractTextGenerationMetrics(details) {
|
|
14240
|
+
if (!isObject(details)) {
|
|
14241
|
+
return {};
|
|
14242
|
+
}
|
|
14243
|
+
const promptTokens = Array.isArray(details.prefill) ? details.prefill.length : void 0;
|
|
14244
|
+
const completionTokens = typeof details.generated_tokens === "number" ? details.generated_tokens : Array.isArray(details.tokens) ? details.tokens.length : void 0;
|
|
14245
|
+
const metrics = {};
|
|
14246
|
+
if (promptTokens !== void 0) {
|
|
14247
|
+
metrics.prompt_tokens = promptTokens;
|
|
14248
|
+
}
|
|
14249
|
+
if (completionTokens !== void 0) {
|
|
14250
|
+
metrics.completion_tokens = completionTokens;
|
|
14251
|
+
}
|
|
14252
|
+
if (promptTokens !== void 0 || completionTokens !== void 0) {
|
|
14253
|
+
metrics.tokens = (promptTokens ?? 0) + (completionTokens ?? 0);
|
|
14254
|
+
}
|
|
14255
|
+
return metrics;
|
|
14256
|
+
}
|
|
14257
|
+
function extractTextGenerationMetadata(result) {
|
|
14258
|
+
if (!isObject(result?.details)) {
|
|
14259
|
+
return void 0;
|
|
14260
|
+
}
|
|
14261
|
+
return typeof result.details.finish_reason === "string" ? {
|
|
14262
|
+
finish_reason: result.details.finish_reason
|
|
14263
|
+
} : void 0;
|
|
14264
|
+
}
|
|
14265
|
+
function summarizeFeatureExtractionOutput(result) {
|
|
14266
|
+
if (!Array.isArray(result)) {
|
|
14267
|
+
return void 0;
|
|
14268
|
+
}
|
|
14269
|
+
const first = result[0];
|
|
14270
|
+
if (typeof first === "number") {
|
|
14271
|
+
return { embedding_length: result.length };
|
|
14272
|
+
}
|
|
14273
|
+
if (Array.isArray(first) && first.every((value) => typeof value === "number")) {
|
|
14274
|
+
return {
|
|
14275
|
+
embedding_count: result.length,
|
|
14276
|
+
embedding_length: first.length
|
|
14277
|
+
};
|
|
14278
|
+
}
|
|
14279
|
+
if (Array.isArray(first) && first.length > 0 && Array.isArray(first[0]) && first[0].every((value) => typeof value === "number")) {
|
|
14280
|
+
return {
|
|
14281
|
+
embedding_batch_count: result.length,
|
|
14282
|
+
embedding_count: first.length,
|
|
14283
|
+
embedding_length: first[0].length
|
|
14284
|
+
};
|
|
14285
|
+
}
|
|
14286
|
+
return void 0;
|
|
14287
|
+
}
|
|
14288
|
+
function patchChatCompletionStream(args) {
|
|
14289
|
+
const { result, span, startTime } = args;
|
|
14290
|
+
if (!result || !isAsyncIterable(result)) {
|
|
14291
|
+
return false;
|
|
14292
|
+
}
|
|
14293
|
+
let firstChunkTime;
|
|
14294
|
+
patchStreamIfNeeded(result, {
|
|
14295
|
+
onChunk: () => {
|
|
14296
|
+
if (firstChunkTime === void 0) {
|
|
14297
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
14298
|
+
}
|
|
14299
|
+
},
|
|
14300
|
+
onComplete: (chunks) => {
|
|
14301
|
+
const lastChunk = chunks.at(-1);
|
|
14302
|
+
const responseMetadata = extractResponseMetadata2(lastChunk);
|
|
14303
|
+
const metrics = {
|
|
14304
|
+
...parseMetricsFromUsage(lastChunk?.usage),
|
|
14305
|
+
...firstChunkTime !== void 0 ? { time_to_first_token: firstChunkTime - startTime } : {}
|
|
14306
|
+
};
|
|
14307
|
+
span.log({
|
|
14308
|
+
output: aggregateChatCompletionChunks2(chunks),
|
|
14309
|
+
...responseMetadata ? { metadata: responseMetadata } : {},
|
|
14310
|
+
metrics
|
|
14311
|
+
});
|
|
14312
|
+
span.end();
|
|
14313
|
+
},
|
|
14314
|
+
onError: (error) => {
|
|
14315
|
+
span.log({
|
|
14316
|
+
error: error.message
|
|
14317
|
+
});
|
|
14318
|
+
span.end();
|
|
14319
|
+
}
|
|
14320
|
+
});
|
|
14321
|
+
return true;
|
|
14322
|
+
}
|
|
14323
|
+
function patchTextGenerationStream(args) {
|
|
14324
|
+
const { result, span, startTime } = args;
|
|
14325
|
+
if (!result || !isAsyncIterable(result)) {
|
|
14326
|
+
return false;
|
|
14327
|
+
}
|
|
14328
|
+
let firstChunkTime;
|
|
14329
|
+
patchStreamIfNeeded(result, {
|
|
14330
|
+
onChunk: () => {
|
|
14331
|
+
if (firstChunkTime === void 0) {
|
|
14332
|
+
firstChunkTime = getCurrentUnixTimestamp();
|
|
14333
|
+
}
|
|
14334
|
+
},
|
|
14335
|
+
onComplete: (chunks) => {
|
|
14336
|
+
const lastChunk = chunks.at(-1);
|
|
14337
|
+
const streamMetadata = extractTextGenerationStreamMetadata(chunks);
|
|
14338
|
+
span.log({
|
|
14339
|
+
output: aggregateTextGenerationStreamChunks(chunks),
|
|
14340
|
+
...streamMetadata ? { metadata: streamMetadata } : {},
|
|
14341
|
+
metrics: {
|
|
14342
|
+
...extractTextGenerationMetrics(lastChunk?.details ?? null),
|
|
14343
|
+
...parseMetricsFromUsage(lastChunk?.usage),
|
|
14344
|
+
...firstChunkTime !== void 0 ? { time_to_first_token: firstChunkTime - startTime } : {}
|
|
14345
|
+
}
|
|
14346
|
+
});
|
|
14347
|
+
span.end();
|
|
14348
|
+
},
|
|
14349
|
+
onError: (error) => {
|
|
14350
|
+
span.log({
|
|
14351
|
+
error: error.message
|
|
14352
|
+
});
|
|
14353
|
+
span.end();
|
|
14354
|
+
}
|
|
14355
|
+
});
|
|
14356
|
+
return true;
|
|
14357
|
+
}
|
|
14358
|
+
function aggregateChatCompletionChunks2(chunks) {
|
|
14359
|
+
if (chunks.length === 0) {
|
|
14360
|
+
return void 0;
|
|
14361
|
+
}
|
|
14362
|
+
const aggregatedChoices = /* @__PURE__ */ new Map();
|
|
14363
|
+
for (const chunk of chunks) {
|
|
14364
|
+
for (const choice of chunk.choices ?? []) {
|
|
14365
|
+
const index = typeof choice.index === "number" ? choice.index : 0;
|
|
14366
|
+
const existing = aggregatedChoices.get(index) ?? { content: "" };
|
|
14367
|
+
const delta = isObject(choice.delta) ? choice.delta : void 0;
|
|
14368
|
+
const message = isObject(choice.message) ? choice.message : void 0;
|
|
14369
|
+
if (typeof delta?.content === "string") {
|
|
14370
|
+
existing.content += delta.content;
|
|
14371
|
+
} else if (typeof message?.content === "string") {
|
|
14372
|
+
existing.content = message.content;
|
|
14373
|
+
}
|
|
14374
|
+
if (typeof delta?.role === "string") {
|
|
14375
|
+
existing.role = delta.role;
|
|
14376
|
+
} else if (typeof message?.role === "string") {
|
|
14377
|
+
existing.role = message.role;
|
|
14378
|
+
}
|
|
14379
|
+
if (choice.finish_reason !== void 0) {
|
|
14380
|
+
existing.finish_reason = choice.finish_reason;
|
|
14381
|
+
}
|
|
14382
|
+
aggregatedChoices.set(index, existing);
|
|
14383
|
+
}
|
|
14384
|
+
}
|
|
14385
|
+
return {
|
|
14386
|
+
choices: [...aggregatedChoices.entries()].map(([index, choice]) => ({
|
|
14387
|
+
index,
|
|
14388
|
+
message: {
|
|
14389
|
+
content: choice.content,
|
|
14390
|
+
role: choice.role ?? "assistant"
|
|
14391
|
+
},
|
|
14392
|
+
...choice.finish_reason !== void 0 ? { finish_reason: choice.finish_reason } : {}
|
|
14393
|
+
}))
|
|
14394
|
+
};
|
|
14395
|
+
}
|
|
14396
|
+
function aggregateTextGenerationStreamChunks(chunks) {
|
|
14397
|
+
if (chunks.length === 0) {
|
|
14398
|
+
return void 0;
|
|
14399
|
+
}
|
|
14400
|
+
let generatedText = "";
|
|
14401
|
+
let finishReason;
|
|
14402
|
+
for (const chunk of chunks) {
|
|
14403
|
+
if (typeof chunk.generated_text === "string") {
|
|
14404
|
+
generatedText = chunk.generated_text;
|
|
14405
|
+
} else if (typeof chunk.token?.text === "string" && !chunk.token.special) {
|
|
14406
|
+
generatedText += chunk.token.text;
|
|
14407
|
+
} else if (Array.isArray(chunk.choices)) {
|
|
14408
|
+
for (const choice of chunk.choices) {
|
|
14409
|
+
if (typeof choice.text === "string") {
|
|
14410
|
+
generatedText += choice.text;
|
|
14411
|
+
}
|
|
14412
|
+
if (choice.finish_reason !== void 0) {
|
|
14413
|
+
finishReason = choice.finish_reason;
|
|
14414
|
+
}
|
|
14415
|
+
}
|
|
14416
|
+
}
|
|
14417
|
+
if (isObject(chunk.details) && typeof chunk.details.finish_reason === "string") {
|
|
14418
|
+
finishReason = chunk.details.finish_reason;
|
|
14419
|
+
}
|
|
14420
|
+
}
|
|
14421
|
+
return {
|
|
14422
|
+
generated_text: generatedText,
|
|
14423
|
+
...finishReason !== void 0 ? { finish_reason: finishReason } : {}
|
|
14424
|
+
};
|
|
14425
|
+
}
|
|
14426
|
+
function extractTextGenerationStreamMetadata(chunks) {
|
|
14427
|
+
for (let index = chunks.length - 1; index >= 0; index--) {
|
|
14428
|
+
const chunk = chunks[index];
|
|
14429
|
+
if (isObject(chunk?.details) && typeof chunk.details.finish_reason === "string") {
|
|
14430
|
+
return {
|
|
14431
|
+
finish_reason: chunk.details.finish_reason
|
|
14432
|
+
};
|
|
14433
|
+
}
|
|
14434
|
+
if (!Array.isArray(chunk?.choices)) {
|
|
14435
|
+
continue;
|
|
14436
|
+
}
|
|
14437
|
+
for (let choiceIndex = chunk.choices.length - 1; choiceIndex >= 0; choiceIndex--) {
|
|
14438
|
+
const choice = chunk.choices[choiceIndex];
|
|
14439
|
+
if (choice?.finish_reason !== void 0) {
|
|
14440
|
+
return { finish_reason: choice.finish_reason };
|
|
14441
|
+
}
|
|
14442
|
+
}
|
|
14443
|
+
}
|
|
14444
|
+
return void 0;
|
|
14445
|
+
}
|
|
14446
|
+
|
|
12857
14447
|
// src/instrumentation/plugins/openrouter-agent-channels.ts
|
|
12858
14448
|
var openRouterAgentChannels = defineChannels("@openrouter/agent", {
|
|
12859
14449
|
callModel: channel({
|
|
@@ -12971,20 +14561,20 @@ var OpenRouterAgentPlugin = class extends BasePlugin {
|
|
|
12971
14561
|
});
|
|
12972
14562
|
}
|
|
12973
14563
|
};
|
|
12974
|
-
function
|
|
14564
|
+
function normalizeArgs2(args) {
|
|
12975
14565
|
if (Array.isArray(args)) {
|
|
12976
14566
|
return args;
|
|
12977
14567
|
}
|
|
12978
|
-
if (
|
|
14568
|
+
if (isArrayLike2(args)) {
|
|
12979
14569
|
return Array.from(args);
|
|
12980
14570
|
}
|
|
12981
14571
|
return [args];
|
|
12982
14572
|
}
|
|
12983
|
-
function
|
|
14573
|
+
function isArrayLike2(value) {
|
|
12984
14574
|
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
12985
14575
|
}
|
|
12986
14576
|
function getOpenRouterCallModelRequestArg(args) {
|
|
12987
|
-
const normalizedArgs =
|
|
14577
|
+
const normalizedArgs = normalizeArgs2(args);
|
|
12988
14578
|
const keyedRequestArg = normalizedArgs.find(
|
|
12989
14579
|
(arg) => isObject(arg) && ("input" in arg || "model" in arg || "tools" in arg)
|
|
12990
14580
|
);
|
|
@@ -13270,7 +14860,7 @@ function traceToolExecution(args) {
|
|
|
13270
14860
|
}
|
|
13271
14861
|
}
|
|
13272
14862
|
function publishToolResult(tracingChannel, event, result) {
|
|
13273
|
-
if (
|
|
14863
|
+
if (isPromiseLike(result)) {
|
|
13274
14864
|
return result.then(
|
|
13275
14865
|
(resolved) => {
|
|
13276
14866
|
event.result = resolved;
|
|
@@ -13292,9 +14882,6 @@ function getToolCallId(context) {
|
|
|
13292
14882
|
const toolContext = context;
|
|
13293
14883
|
return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
|
|
13294
14884
|
}
|
|
13295
|
-
function isPromiseLike3(value) {
|
|
13296
|
-
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
13297
|
-
}
|
|
13298
14885
|
var OPENROUTER_WRAPPED_CALL_MODEL_RESULT = Symbol(
|
|
13299
14886
|
"braintrust.openrouter.wrappedCallModelResult"
|
|
13300
14887
|
);
|
|
@@ -13649,7 +15236,13 @@ var openRouterChannels = defineChannels("@openrouter/sdk", {
|
|
|
13649
15236
|
channelName: "embeddings.generate",
|
|
13650
15237
|
kind: "async"
|
|
13651
15238
|
}),
|
|
13652
|
-
|
|
15239
|
+
rerankRerank: channel(
|
|
15240
|
+
{
|
|
15241
|
+
channelName: "rerank.rerank",
|
|
15242
|
+
kind: "async"
|
|
15243
|
+
}
|
|
15244
|
+
),
|
|
15245
|
+
betaResponsesSend: channel({
|
|
13653
15246
|
channelName: "beta.responses.send",
|
|
13654
15247
|
kind: "async"
|
|
13655
15248
|
}),
|
|
@@ -13741,6 +15334,34 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
13741
15334
|
}
|
|
13742
15335
|
})
|
|
13743
15336
|
);
|
|
15337
|
+
this.unsubscribers.push(
|
|
15338
|
+
traceAsyncChannel(openRouterChannels.rerankRerank, {
|
|
15339
|
+
name: "openrouter.rerank.rerank",
|
|
15340
|
+
type: "llm" /* LLM */,
|
|
15341
|
+
extractInput: (args) => {
|
|
15342
|
+
const request = getOpenRouterRequestArg(args);
|
|
15343
|
+
const requestBody = isObject(request?.requestBody) ? request.requestBody : {};
|
|
15344
|
+
const httpReferer = request?.httpReferer;
|
|
15345
|
+
const xTitle = request?.xTitle ?? request?.appTitle;
|
|
15346
|
+
const { documents, query, ...metadata } = requestBody;
|
|
15347
|
+
return {
|
|
15348
|
+
input: {
|
|
15349
|
+
documents,
|
|
15350
|
+
query
|
|
15351
|
+
},
|
|
15352
|
+
metadata: buildOpenRouterRerankMetadata(
|
|
15353
|
+
metadata,
|
|
15354
|
+
documents,
|
|
15355
|
+
httpReferer,
|
|
15356
|
+
xTitle
|
|
15357
|
+
)
|
|
15358
|
+
};
|
|
15359
|
+
},
|
|
15360
|
+
extractOutput: (result) => extractOpenRouterRerankOutput(result),
|
|
15361
|
+
extractMetadata: (result) => extractOpenRouterResponseMetadata2(result),
|
|
15362
|
+
extractMetrics: (result) => isObject(result) ? parseOpenRouterMetricsFromUsage2(result.usage) : {}
|
|
15363
|
+
})
|
|
15364
|
+
);
|
|
13744
15365
|
this.unsubscribers.push(
|
|
13745
15366
|
traceStreamingChannel(openRouterChannels.betaResponsesSend, {
|
|
13746
15367
|
name: "openrouter.beta.responses.send",
|
|
@@ -13860,20 +15481,20 @@ var OpenRouterPlugin = class extends BasePlugin {
|
|
|
13860
15481
|
});
|
|
13861
15482
|
}
|
|
13862
15483
|
};
|
|
13863
|
-
function
|
|
15484
|
+
function normalizeArgs3(args) {
|
|
13864
15485
|
if (Array.isArray(args)) {
|
|
13865
15486
|
return args;
|
|
13866
15487
|
}
|
|
13867
|
-
if (
|
|
15488
|
+
if (isArrayLike3(args)) {
|
|
13868
15489
|
return Array.from(args);
|
|
13869
15490
|
}
|
|
13870
15491
|
return [args];
|
|
13871
15492
|
}
|
|
13872
|
-
function
|
|
15493
|
+
function isArrayLike3(value) {
|
|
13873
15494
|
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
13874
15495
|
}
|
|
13875
15496
|
function getOpenRouterRequestArg(args) {
|
|
13876
|
-
const normalizedArgs =
|
|
15497
|
+
const normalizedArgs = normalizeArgs3(args);
|
|
13877
15498
|
const keyedCandidate = normalizedArgs.find(
|
|
13878
15499
|
(arg) => isObject(arg) && ("chatGenerationParams" in arg || "requestBody" in arg || "openResponsesRequest" in arg)
|
|
13879
15500
|
);
|
|
@@ -13884,7 +15505,7 @@ function getOpenRouterRequestArg(args) {
|
|
|
13884
15505
|
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
13885
15506
|
}
|
|
13886
15507
|
function getOpenRouterCallModelRequestArg2(args) {
|
|
13887
|
-
const firstObjectArg =
|
|
15508
|
+
const firstObjectArg = normalizeArgs3(args).find((arg) => isObject(arg));
|
|
13888
15509
|
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
13889
15510
|
}
|
|
13890
15511
|
var TOKEN_NAME_MAP3 = {
|
|
@@ -14054,6 +15675,13 @@ function buildOpenRouterEmbeddingMetadata(metadata, httpReferer, xTitle) {
|
|
|
14054
15675
|
embedding_model: normalized.model
|
|
14055
15676
|
} : normalized;
|
|
14056
15677
|
}
|
|
15678
|
+
function buildOpenRouterRerankMetadata(metadata, documents, httpReferer, xTitle) {
|
|
15679
|
+
const normalized = buildOpenRouterMetadata2(metadata, httpReferer, xTitle);
|
|
15680
|
+
return {
|
|
15681
|
+
...normalized,
|
|
15682
|
+
...Array.isArray(documents) ? { document_count: documents.length } : {}
|
|
15683
|
+
};
|
|
15684
|
+
}
|
|
14057
15685
|
function extractOpenRouterCallModelInput2(request) {
|
|
14058
15686
|
return isObject(request) && "input" in request ? sanitizeOpenRouterLoggedValue2(request.input) : void 0;
|
|
14059
15687
|
}
|
|
@@ -14073,7 +15701,7 @@ function extractOpenRouterResponseMetadata2(result) {
|
|
|
14073
15701
|
const metadataRecord = isObject(sanitized) ? sanitized : {};
|
|
14074
15702
|
const { model, provider, ...rest } = metadataRecord;
|
|
14075
15703
|
const normalizedModel = parseOpenRouterModelString2(model);
|
|
14076
|
-
const normalizedProvider = (typeof provider === "string" ? provider : void 0) || normalizedModel.provider;
|
|
15704
|
+
const normalizedProvider = (typeof provider === "string" ? provider.toLowerCase() : void 0) || normalizedModel.provider;
|
|
14077
15705
|
const usageMetadata = extractOpenRouterUsageMetadata2(usage);
|
|
14078
15706
|
const combined = {
|
|
14079
15707
|
...rest,
|
|
@@ -14092,6 +15720,15 @@ function extractOpenRouterResponseOutput2(response, fallbackOutput) {
|
|
|
14092
15720
|
}
|
|
14093
15721
|
return void 0;
|
|
14094
15722
|
}
|
|
15723
|
+
function extractOpenRouterRerankOutput(result) {
|
|
15724
|
+
if (!isObject(result) || !Array.isArray(result.results)) {
|
|
15725
|
+
return void 0;
|
|
15726
|
+
}
|
|
15727
|
+
return result.results.slice(0, 100).map((item) => ({
|
|
15728
|
+
index: isObject(item) && typeof item.index === "number" ? item.index : void 0,
|
|
15729
|
+
relevance_score: isObject(item) && typeof item.relevanceScore === "number" ? item.relevanceScore : isObject(item) && typeof item.relevance_score === "number" ? item.relevance_score : void 0
|
|
15730
|
+
}));
|
|
15731
|
+
}
|
|
14095
15732
|
var OPENROUTER_WRAPPED_TOOL2 = Symbol("braintrust.openrouter.wrappedTool");
|
|
14096
15733
|
function patchOpenRouterCallModelRequestTools2(request) {
|
|
14097
15734
|
if (!Array.isArray(request.tools) || request.tools.length === 0) {
|
|
@@ -14162,7 +15799,7 @@ function traceToolExecution2(args) {
|
|
|
14162
15799
|
}
|
|
14163
15800
|
}
|
|
14164
15801
|
function publishToolResult2(tracingChannel, event, result) {
|
|
14165
|
-
if (
|
|
15802
|
+
if (isPromiseLike(result)) {
|
|
14166
15803
|
return result.then(
|
|
14167
15804
|
(resolved) => {
|
|
14168
15805
|
event.result = resolved;
|
|
@@ -14184,9 +15821,6 @@ function getToolCallId2(context) {
|
|
|
14184
15821
|
const toolContext = context;
|
|
14185
15822
|
return typeof toolContext?.toolCall?.id === "string" ? toolContext.toolCall.id : void 0;
|
|
14186
15823
|
}
|
|
14187
|
-
function isPromiseLike4(value) {
|
|
14188
|
-
return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
14189
|
-
}
|
|
14190
15824
|
function aggregateOpenRouterChatChunks(chunks) {
|
|
14191
15825
|
let role;
|
|
14192
15826
|
let content = "";
|
|
@@ -14826,20 +16460,20 @@ var MISTRAL_RESPONSE_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
|
14826
16460
|
function camelToSnake3(value) {
|
|
14827
16461
|
return value.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
|
|
14828
16462
|
}
|
|
14829
|
-
function
|
|
16463
|
+
function normalizeArgs4(args) {
|
|
14830
16464
|
if (Array.isArray(args)) {
|
|
14831
16465
|
return args;
|
|
14832
16466
|
}
|
|
14833
|
-
if (
|
|
16467
|
+
if (isArrayLike4(args)) {
|
|
14834
16468
|
return Array.from(args);
|
|
14835
16469
|
}
|
|
14836
16470
|
return [args];
|
|
14837
16471
|
}
|
|
14838
|
-
function
|
|
16472
|
+
function isArrayLike4(value) {
|
|
14839
16473
|
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
14840
16474
|
}
|
|
14841
16475
|
function getMistralRequestArg(args) {
|
|
14842
|
-
const firstObjectArg =
|
|
16476
|
+
const firstObjectArg = normalizeArgs4(args).find((arg) => isObject(arg));
|
|
14843
16477
|
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
14844
16478
|
}
|
|
14845
16479
|
function addMistralProviderMetadata(metadata) {
|
|
@@ -15144,88 +16778,1326 @@ function aggregateMistralStreamChunks(chunks) {
|
|
|
15144
16778
|
};
|
|
15145
16779
|
}
|
|
15146
16780
|
|
|
15147
|
-
// src/instrumentation/
|
|
15148
|
-
var
|
|
15149
|
-
|
|
15150
|
-
|
|
15151
|
-
|
|
15152
|
-
|
|
15153
|
-
|
|
15154
|
-
|
|
15155
|
-
|
|
15156
|
-
|
|
15157
|
-
|
|
15158
|
-
|
|
15159
|
-
|
|
15160
|
-
|
|
15161
|
-
|
|
16781
|
+
// src/instrumentation/plugins/google-adk-channels.ts
|
|
16782
|
+
var googleADKChannels = defineChannels("@google/adk", {
|
|
16783
|
+
runnerRunAsync: channel({
|
|
16784
|
+
channelName: "runner.runAsync",
|
|
16785
|
+
kind: "sync-stream"
|
|
16786
|
+
}),
|
|
16787
|
+
agentRunAsync: channel({
|
|
16788
|
+
channelName: "agent.runAsync",
|
|
16789
|
+
kind: "sync-stream"
|
|
16790
|
+
}),
|
|
16791
|
+
toolRunAsync: channel({
|
|
16792
|
+
channelName: "tool.runAsync",
|
|
16793
|
+
kind: "async"
|
|
16794
|
+
})
|
|
16795
|
+
});
|
|
16796
|
+
|
|
16797
|
+
// src/instrumentation/plugins/google-adk-plugin.ts
|
|
16798
|
+
var GoogleADKPlugin = class extends BasePlugin {
|
|
16799
|
+
activeRunnerSpans = /* @__PURE__ */ new Map();
|
|
16800
|
+
activeAgentSpans = /* @__PURE__ */ new Map();
|
|
15162
16801
|
onEnable() {
|
|
15163
|
-
|
|
15164
|
-
|
|
15165
|
-
|
|
15166
|
-
this.openaiPlugin.enable();
|
|
15167
|
-
}
|
|
15168
|
-
if (integrations.anthropic !== false) {
|
|
15169
|
-
this.anthropicPlugin = new AnthropicPlugin();
|
|
15170
|
-
this.anthropicPlugin.enable();
|
|
15171
|
-
}
|
|
15172
|
-
if (integrations.aisdk !== false && integrations.vercel !== false) {
|
|
15173
|
-
this.aiSDKPlugin = new AISDKPlugin();
|
|
15174
|
-
this.aiSDKPlugin.enable();
|
|
15175
|
-
}
|
|
15176
|
-
if (integrations.claudeAgentSDK !== false) {
|
|
15177
|
-
this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
|
|
15178
|
-
this.claudeAgentSDKPlugin.enable();
|
|
15179
|
-
}
|
|
15180
|
-
if (integrations.googleGenAI !== false && integrations.google !== false) {
|
|
15181
|
-
this.googleGenAIPlugin = new GoogleGenAIPlugin();
|
|
15182
|
-
this.googleGenAIPlugin.enable();
|
|
15183
|
-
}
|
|
15184
|
-
if (integrations.openrouter !== false) {
|
|
15185
|
-
this.openRouterPlugin = new OpenRouterPlugin();
|
|
15186
|
-
this.openRouterPlugin.enable();
|
|
15187
|
-
}
|
|
15188
|
-
if (integrations.openrouterAgent !== false) {
|
|
15189
|
-
this.openRouterAgentPlugin = new OpenRouterAgentPlugin();
|
|
15190
|
-
this.openRouterAgentPlugin.enable();
|
|
15191
|
-
}
|
|
15192
|
-
if (integrations.mistral !== false) {
|
|
15193
|
-
this.mistralPlugin = new MistralPlugin();
|
|
15194
|
-
this.mistralPlugin.enable();
|
|
15195
|
-
}
|
|
16802
|
+
this.subscribeToRunnerRunAsync();
|
|
16803
|
+
this.subscribeToAgentRunAsync();
|
|
16804
|
+
this.subscribeToToolRunAsync();
|
|
15196
16805
|
}
|
|
15197
16806
|
onDisable() {
|
|
15198
|
-
|
|
15199
|
-
|
|
15200
|
-
this.openaiPlugin = null;
|
|
15201
|
-
}
|
|
15202
|
-
if (this.anthropicPlugin) {
|
|
15203
|
-
this.anthropicPlugin.disable();
|
|
15204
|
-
this.anthropicPlugin = null;
|
|
15205
|
-
}
|
|
15206
|
-
if (this.aiSDKPlugin) {
|
|
15207
|
-
this.aiSDKPlugin.disable();
|
|
15208
|
-
this.aiSDKPlugin = null;
|
|
15209
|
-
}
|
|
15210
|
-
if (this.claudeAgentSDKPlugin) {
|
|
15211
|
-
this.claudeAgentSDKPlugin.disable();
|
|
15212
|
-
this.claudeAgentSDKPlugin = null;
|
|
15213
|
-
}
|
|
15214
|
-
if (this.googleGenAIPlugin) {
|
|
15215
|
-
this.googleGenAIPlugin.disable();
|
|
15216
|
-
this.googleGenAIPlugin = null;
|
|
15217
|
-
}
|
|
15218
|
-
if (this.openRouterPlugin) {
|
|
15219
|
-
this.openRouterPlugin.disable();
|
|
15220
|
-
this.openRouterPlugin = null;
|
|
15221
|
-
}
|
|
15222
|
-
if (this.openRouterAgentPlugin) {
|
|
15223
|
-
this.openRouterAgentPlugin.disable();
|
|
15224
|
-
this.openRouterAgentPlugin = null;
|
|
16807
|
+
for (const unsubscribe of this.unsubscribers) {
|
|
16808
|
+
unsubscribe();
|
|
15225
16809
|
}
|
|
15226
|
-
|
|
15227
|
-
|
|
15228
|
-
|
|
16810
|
+
this.unsubscribers = [];
|
|
16811
|
+
this.activeRunnerSpans.clear();
|
|
16812
|
+
this.activeAgentSpans.clear();
|
|
16813
|
+
}
|
|
16814
|
+
subscribeToRunnerRunAsync() {
|
|
16815
|
+
const tracingChannel = googleADKChannels.runnerRunAsync.tracingChannel();
|
|
16816
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
16817
|
+
const createState = (event) => {
|
|
16818
|
+
const params = event.arguments[0] ?? {};
|
|
16819
|
+
const contextKey = extractRunnerContextKey(params);
|
|
16820
|
+
const span = startSpan({
|
|
16821
|
+
name: "Google ADK Runner",
|
|
16822
|
+
spanAttributes: {
|
|
16823
|
+
type: "task" /* TASK */
|
|
16824
|
+
}
|
|
16825
|
+
});
|
|
16826
|
+
const startTime = getCurrentUnixTimestamp();
|
|
16827
|
+
try {
|
|
16828
|
+
const metadata = extractRunnerMetadata(params);
|
|
16829
|
+
span.log({
|
|
16830
|
+
input: extractRunnerInput(params),
|
|
16831
|
+
metadata
|
|
16832
|
+
});
|
|
16833
|
+
} catch {
|
|
16834
|
+
}
|
|
16835
|
+
if (contextKey) {
|
|
16836
|
+
this.activeRunnerSpans.set(contextKey, span);
|
|
16837
|
+
}
|
|
16838
|
+
return { span, startTime, events: [], contextKey };
|
|
16839
|
+
};
|
|
16840
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart3(
|
|
16841
|
+
tracingChannel,
|
|
16842
|
+
states,
|
|
16843
|
+
createState
|
|
16844
|
+
);
|
|
16845
|
+
const handlers = {
|
|
16846
|
+
start: (event) => {
|
|
16847
|
+
ensureState(states, event, () => createState(event));
|
|
16848
|
+
},
|
|
16849
|
+
end: (event) => {
|
|
16850
|
+
const state = states.get(event);
|
|
16851
|
+
if (!state) {
|
|
16852
|
+
return;
|
|
16853
|
+
}
|
|
16854
|
+
const result = event.result;
|
|
16855
|
+
if (isAsyncIterable(result)) {
|
|
16856
|
+
bindAsyncIterableToCurrentSpan(result, state.span);
|
|
16857
|
+
patchStreamIfNeeded(result, {
|
|
16858
|
+
onChunk: (adkEvent) => {
|
|
16859
|
+
state.events.push(adkEvent);
|
|
16860
|
+
},
|
|
16861
|
+
onComplete: () => {
|
|
16862
|
+
finalizeRunnerSpan(state, this.activeRunnerSpans);
|
|
16863
|
+
states.delete(event);
|
|
16864
|
+
},
|
|
16865
|
+
onError: (error) => {
|
|
16866
|
+
cleanupActiveRunnerSpan(state, this.activeRunnerSpans);
|
|
16867
|
+
state.span.log({ error: error.message });
|
|
16868
|
+
state.span.end();
|
|
16869
|
+
states.delete(event);
|
|
16870
|
+
}
|
|
16871
|
+
});
|
|
16872
|
+
return;
|
|
16873
|
+
}
|
|
16874
|
+
try {
|
|
16875
|
+
state.span.log({ output: result });
|
|
16876
|
+
} finally {
|
|
16877
|
+
cleanupActiveRunnerSpan(state, this.activeRunnerSpans);
|
|
16878
|
+
state.span.end();
|
|
16879
|
+
states.delete(event);
|
|
16880
|
+
}
|
|
16881
|
+
},
|
|
16882
|
+
error: (event) => {
|
|
16883
|
+
const state = states.get(event);
|
|
16884
|
+
if (!state || !event.error) {
|
|
16885
|
+
return;
|
|
16886
|
+
}
|
|
16887
|
+
cleanupActiveRunnerSpan(state, this.activeRunnerSpans);
|
|
16888
|
+
state.span.log({ error: event.error.message });
|
|
16889
|
+
state.span.end();
|
|
16890
|
+
states.delete(event);
|
|
16891
|
+
}
|
|
16892
|
+
};
|
|
16893
|
+
tracingChannel.subscribe(handlers);
|
|
16894
|
+
this.unsubscribers.push(() => {
|
|
16895
|
+
unbindCurrentSpanStore?.();
|
|
16896
|
+
tracingChannel.unsubscribe(handlers);
|
|
16897
|
+
});
|
|
16898
|
+
}
|
|
16899
|
+
subscribeToAgentRunAsync() {
|
|
16900
|
+
const tracingChannel = googleADKChannels.agentRunAsync.tracingChannel();
|
|
16901
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
16902
|
+
const createState = (event) => {
|
|
16903
|
+
const parentContext = event.arguments[0];
|
|
16904
|
+
const agentName = extractAgentName(parentContext);
|
|
16905
|
+
const runnerParentSpan = findRunnerParentSpan(
|
|
16906
|
+
parentContext,
|
|
16907
|
+
this.activeRunnerSpans
|
|
16908
|
+
);
|
|
16909
|
+
const contextKey = extractInvocationContextKey(parentContext);
|
|
16910
|
+
const span = startSpan({
|
|
16911
|
+
name: agentName ? `Agent: ${agentName}` : "Google ADK Agent",
|
|
16912
|
+
spanAttributes: {
|
|
16913
|
+
type: "task" /* TASK */
|
|
16914
|
+
},
|
|
16915
|
+
...runnerParentSpan ? {
|
|
16916
|
+
parentSpanIds: {
|
|
16917
|
+
spanId: runnerParentSpan.spanId,
|
|
16918
|
+
rootSpanId: runnerParentSpan.rootSpanId
|
|
16919
|
+
}
|
|
16920
|
+
} : {}
|
|
16921
|
+
});
|
|
16922
|
+
const startTime = getCurrentUnixTimestamp();
|
|
16923
|
+
try {
|
|
16924
|
+
const metadata = {
|
|
16925
|
+
provider: "google-adk"
|
|
16926
|
+
};
|
|
16927
|
+
if (agentName) {
|
|
16928
|
+
metadata["google_adk.agent_name"] = agentName;
|
|
16929
|
+
}
|
|
16930
|
+
const modelName = extractModelName(parentContext);
|
|
16931
|
+
if (modelName) {
|
|
16932
|
+
metadata.model = modelName;
|
|
16933
|
+
}
|
|
16934
|
+
span.log({ metadata });
|
|
16935
|
+
} catch {
|
|
16936
|
+
}
|
|
16937
|
+
if (contextKey && agentName) {
|
|
16938
|
+
this.activeAgentSpans.set(agentContextKey(contextKey, agentName), span);
|
|
16939
|
+
}
|
|
16940
|
+
return { span, startTime, events: [], contextKey, name: agentName };
|
|
16941
|
+
};
|
|
16942
|
+
const unbindCurrentSpanStore = bindCurrentSpanStoreToStart3(
|
|
16943
|
+
tracingChannel,
|
|
16944
|
+
states,
|
|
16945
|
+
createState
|
|
16946
|
+
);
|
|
16947
|
+
const handlers = {
|
|
16948
|
+
start: (event) => {
|
|
16949
|
+
ensureState(states, event, () => createState(event));
|
|
16950
|
+
},
|
|
16951
|
+
end: (event) => {
|
|
16952
|
+
const state = states.get(event);
|
|
16953
|
+
if (!state) {
|
|
16954
|
+
return;
|
|
16955
|
+
}
|
|
16956
|
+
const result = event.result;
|
|
16957
|
+
if (isAsyncIterable(result)) {
|
|
16958
|
+
bindAsyncIterableToCurrentSpan(result, state.span);
|
|
16959
|
+
patchStreamIfNeeded(result, {
|
|
16960
|
+
onChunk: (adkEvent) => {
|
|
16961
|
+
state.events.push(adkEvent);
|
|
16962
|
+
},
|
|
16963
|
+
onComplete: () => {
|
|
16964
|
+
finalizeAgentSpan(state, this.activeAgentSpans);
|
|
16965
|
+
states.delete(event);
|
|
16966
|
+
},
|
|
16967
|
+
onError: (error) => {
|
|
16968
|
+
cleanupActiveAgentSpan(state, this.activeAgentSpans);
|
|
16969
|
+
state.span.log({ error: error.message });
|
|
16970
|
+
state.span.end();
|
|
16971
|
+
states.delete(event);
|
|
16972
|
+
}
|
|
16973
|
+
});
|
|
16974
|
+
return;
|
|
16975
|
+
}
|
|
16976
|
+
try {
|
|
16977
|
+
state.span.log({ output: result });
|
|
16978
|
+
} finally {
|
|
16979
|
+
cleanupActiveAgentSpan(state, this.activeAgentSpans);
|
|
16980
|
+
state.span.end();
|
|
16981
|
+
states.delete(event);
|
|
16982
|
+
}
|
|
16983
|
+
},
|
|
16984
|
+
error: (event) => {
|
|
16985
|
+
const state = states.get(event);
|
|
16986
|
+
if (!state || !event.error) {
|
|
16987
|
+
return;
|
|
16988
|
+
}
|
|
16989
|
+
cleanupActiveAgentSpan(state, this.activeAgentSpans);
|
|
16990
|
+
state.span.log({ error: event.error.message });
|
|
16991
|
+
state.span.end();
|
|
16992
|
+
states.delete(event);
|
|
16993
|
+
}
|
|
16994
|
+
};
|
|
16995
|
+
tracingChannel.subscribe(handlers);
|
|
16996
|
+
this.unsubscribers.push(() => {
|
|
16997
|
+
unbindCurrentSpanStore?.();
|
|
16998
|
+
tracingChannel.unsubscribe(handlers);
|
|
16999
|
+
});
|
|
17000
|
+
}
|
|
17001
|
+
subscribeToToolRunAsync() {
|
|
17002
|
+
const tracingChannel = googleADKChannels.toolRunAsync.tracingChannel();
|
|
17003
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
17004
|
+
const handlers = {
|
|
17005
|
+
start: (event) => {
|
|
17006
|
+
const req = event.arguments[0] ?? {};
|
|
17007
|
+
const tool = event.self;
|
|
17008
|
+
const toolName = extractToolName(req, tool);
|
|
17009
|
+
const parentSpan = findToolParentSpan(
|
|
17010
|
+
req,
|
|
17011
|
+
this.activeAgentSpans,
|
|
17012
|
+
this.activeRunnerSpans
|
|
17013
|
+
);
|
|
17014
|
+
const createSpan = () => startSpan({
|
|
17015
|
+
name: toolName ? `tool: ${toolName}` : "Google ADK Tool",
|
|
17016
|
+
spanAttributes: {
|
|
17017
|
+
type: "tool" /* TOOL */
|
|
17018
|
+
},
|
|
17019
|
+
event: {
|
|
17020
|
+
input: req.args,
|
|
17021
|
+
metadata: {
|
|
17022
|
+
provider: "google-adk",
|
|
17023
|
+
...toolName && { "google_adk.tool_name": toolName },
|
|
17024
|
+
...extractToolCallId(req) && {
|
|
17025
|
+
"google_adk.tool_call_id": extractToolCallId(req)
|
|
17026
|
+
}
|
|
17027
|
+
}
|
|
17028
|
+
}
|
|
17029
|
+
});
|
|
17030
|
+
const span = parentSpan ? withCurrent(parentSpan, () => createSpan()) : createSpan();
|
|
17031
|
+
const startTime = getCurrentUnixTimestamp();
|
|
17032
|
+
states.set(event, { span, startTime });
|
|
17033
|
+
},
|
|
17034
|
+
asyncEnd: (event) => {
|
|
17035
|
+
const state = states.get(event);
|
|
17036
|
+
if (!state) {
|
|
17037
|
+
return;
|
|
17038
|
+
}
|
|
17039
|
+
try {
|
|
17040
|
+
const metrics = {};
|
|
17041
|
+
const end = getCurrentUnixTimestamp();
|
|
17042
|
+
metrics.start = state.startTime;
|
|
17043
|
+
metrics.end = end;
|
|
17044
|
+
metrics.duration = end - state.startTime;
|
|
17045
|
+
state.span.log({
|
|
17046
|
+
output: event.result,
|
|
17047
|
+
metrics: cleanMetrics2(metrics)
|
|
17048
|
+
});
|
|
17049
|
+
} finally {
|
|
17050
|
+
state.span.end();
|
|
17051
|
+
states.delete(event);
|
|
17052
|
+
}
|
|
17053
|
+
},
|
|
17054
|
+
error: (event) => {
|
|
17055
|
+
const state = states.get(event);
|
|
17056
|
+
if (!state || !event.error) {
|
|
17057
|
+
return;
|
|
17058
|
+
}
|
|
17059
|
+
state.span.log({ error: event.error.message });
|
|
17060
|
+
state.span.end();
|
|
17061
|
+
states.delete(event);
|
|
17062
|
+
}
|
|
17063
|
+
};
|
|
17064
|
+
tracingChannel.subscribe(handlers);
|
|
17065
|
+
this.unsubscribers.push(() => {
|
|
17066
|
+
tracingChannel.unsubscribe(handlers);
|
|
17067
|
+
});
|
|
17068
|
+
}
|
|
17069
|
+
};
|
|
17070
|
+
function ensureState(states, event, create) {
|
|
17071
|
+
const existing = states.get(event);
|
|
17072
|
+
if (existing) {
|
|
17073
|
+
return existing;
|
|
17074
|
+
}
|
|
17075
|
+
const created = create();
|
|
17076
|
+
states.set(event, created);
|
|
17077
|
+
return created;
|
|
17078
|
+
}
|
|
17079
|
+
function bindAsyncIterableToCurrentSpan(stream, span) {
|
|
17080
|
+
if (!isAsyncIterable(stream)) {
|
|
17081
|
+
return stream;
|
|
17082
|
+
}
|
|
17083
|
+
if (Object.isFrozen(stream) || Object.isSealed(stream)) {
|
|
17084
|
+
return stream;
|
|
17085
|
+
}
|
|
17086
|
+
if ("next" in stream && typeof stream.next === "function") {
|
|
17087
|
+
if ("__braintrust_current_span_bound" in stream) {
|
|
17088
|
+
return stream;
|
|
17089
|
+
}
|
|
17090
|
+
try {
|
|
17091
|
+
const iterator = stream;
|
|
17092
|
+
const originalNext = iterator.next.bind(iterator);
|
|
17093
|
+
iterator.next = (...args) => withCurrent(span, () => originalNext(...args));
|
|
17094
|
+
if (typeof iterator.return === "function") {
|
|
17095
|
+
const originalReturn = iterator.return.bind(iterator);
|
|
17096
|
+
iterator.return = (...args) => withCurrent(span, () => originalReturn(...args));
|
|
17097
|
+
}
|
|
17098
|
+
if (typeof iterator.throw === "function") {
|
|
17099
|
+
const originalThrow = iterator.throw.bind(iterator);
|
|
17100
|
+
iterator.throw = (...args) => withCurrent(span, () => originalThrow(...args));
|
|
17101
|
+
}
|
|
17102
|
+
Object.defineProperty(stream, "__braintrust_current_span_bound", {
|
|
17103
|
+
value: true
|
|
17104
|
+
});
|
|
17105
|
+
return stream;
|
|
17106
|
+
} catch {
|
|
17107
|
+
return stream;
|
|
17108
|
+
}
|
|
17109
|
+
}
|
|
17110
|
+
const originalIteratorFn = stream[Symbol.asyncIterator];
|
|
17111
|
+
if ("__braintrust_current_span_bound" in originalIteratorFn && originalIteratorFn.__braintrust_current_span_bound) {
|
|
17112
|
+
return stream;
|
|
17113
|
+
}
|
|
17114
|
+
try {
|
|
17115
|
+
const patchedIteratorFn = function() {
|
|
17116
|
+
const iterator = originalIteratorFn.call(this);
|
|
17117
|
+
const originalNext = iterator.next.bind(iterator);
|
|
17118
|
+
iterator.next = (...args) => withCurrent(span, () => originalNext(...args));
|
|
17119
|
+
if (typeof iterator.return === "function") {
|
|
17120
|
+
const originalReturn = iterator.return.bind(iterator);
|
|
17121
|
+
iterator.return = (...args) => withCurrent(span, () => originalReturn(...args));
|
|
17122
|
+
}
|
|
17123
|
+
if (typeof iterator.throw === "function") {
|
|
17124
|
+
const originalThrow = iterator.throw.bind(iterator);
|
|
17125
|
+
iterator.throw = (...args) => withCurrent(span, () => originalThrow(...args));
|
|
17126
|
+
}
|
|
17127
|
+
return iterator;
|
|
17128
|
+
};
|
|
17129
|
+
Object.defineProperty(
|
|
17130
|
+
patchedIteratorFn,
|
|
17131
|
+
"__braintrust_current_span_bound",
|
|
17132
|
+
{
|
|
17133
|
+
value: true
|
|
17134
|
+
}
|
|
17135
|
+
);
|
|
17136
|
+
stream[Symbol.asyncIterator] = patchedIteratorFn;
|
|
17137
|
+
} catch {
|
|
17138
|
+
return stream;
|
|
17139
|
+
}
|
|
17140
|
+
return stream;
|
|
17141
|
+
}
|
|
17142
|
+
function bindCurrentSpanStoreToStart3(tracingChannel, states, create) {
|
|
17143
|
+
const state = _internalGetGlobalState();
|
|
17144
|
+
const contextManager = state?.contextManager;
|
|
17145
|
+
const startChannel = tracingChannel.start;
|
|
17146
|
+
const currentSpanStore = contextManager ? contextManager[BRAINTRUST_CURRENT_SPAN_STORE] : void 0;
|
|
17147
|
+
if (!startChannel?.bindStore || !currentSpanStore) {
|
|
17148
|
+
return void 0;
|
|
17149
|
+
}
|
|
17150
|
+
startChannel.bindStore(currentSpanStore, (event) => {
|
|
17151
|
+
const span = ensureState(
|
|
17152
|
+
states,
|
|
17153
|
+
event,
|
|
17154
|
+
() => create(event)
|
|
17155
|
+
).span;
|
|
17156
|
+
return contextManager.wrapSpanForStore(span);
|
|
17157
|
+
});
|
|
17158
|
+
return () => {
|
|
17159
|
+
startChannel.unbindStore?.(currentSpanStore);
|
|
17160
|
+
};
|
|
17161
|
+
}
|
|
17162
|
+
function extractRunnerContextKey(paramsOrContext) {
|
|
17163
|
+
const directUserId = "userId" in paramsOrContext ? paramsOrContext.userId : void 0;
|
|
17164
|
+
const directSessionId = "sessionId" in paramsOrContext ? paramsOrContext.sessionId : void 0;
|
|
17165
|
+
if (typeof directUserId === "string" && typeof directSessionId === "string") {
|
|
17166
|
+
return `${directUserId}:${directSessionId}`;
|
|
17167
|
+
}
|
|
17168
|
+
const invocationContext = paramsOrContext;
|
|
17169
|
+
return extractInvocationContextKey(invocationContext);
|
|
17170
|
+
}
|
|
17171
|
+
function extractInvocationContextKey(parentContext) {
|
|
17172
|
+
const session = parentContext?.session;
|
|
17173
|
+
const userId = session?.userId;
|
|
17174
|
+
const sessionId = session?.id;
|
|
17175
|
+
if (typeof userId !== "string" || typeof sessionId !== "string") {
|
|
17176
|
+
return void 0;
|
|
17177
|
+
}
|
|
17178
|
+
return `${userId}:${sessionId}`;
|
|
17179
|
+
}
|
|
17180
|
+
function findRunnerParentSpan(parentContext, activeRunnerSpans) {
|
|
17181
|
+
const contextKey = extractInvocationContextKey(parentContext);
|
|
17182
|
+
return contextKey ? activeRunnerSpans.get(contextKey) : void 0;
|
|
17183
|
+
}
|
|
17184
|
+
function cleanupActiveRunnerSpan(state, activeRunnerSpans) {
|
|
17185
|
+
if (state.contextKey) {
|
|
17186
|
+
activeRunnerSpans.delete(state.contextKey);
|
|
17187
|
+
}
|
|
17188
|
+
}
|
|
17189
|
+
function agentContextKey(contextKey, agentName) {
|
|
17190
|
+
return `${contextKey}:${agentName}`;
|
|
17191
|
+
}
|
|
17192
|
+
function cleanupActiveAgentSpan(state, activeAgentSpans) {
|
|
17193
|
+
if (state.contextKey && state.name) {
|
|
17194
|
+
activeAgentSpans.delete(agentContextKey(state.contextKey, state.name));
|
|
17195
|
+
}
|
|
17196
|
+
}
|
|
17197
|
+
function extractRunnerInput(paramsOrContext) {
|
|
17198
|
+
const content = "newMessage" in paramsOrContext ? paramsOrContext.newMessage : paramsOrContext.userContent;
|
|
17199
|
+
if (!content || typeof content !== "object") {
|
|
17200
|
+
return void 0;
|
|
17201
|
+
}
|
|
17202
|
+
const normalizedContent = content;
|
|
17203
|
+
if (normalizedContent.parts && Array.isArray(normalizedContent.parts)) {
|
|
17204
|
+
const textParts = normalizedContent.parts.filter((p) => p.text !== void 0).map((p) => p.text);
|
|
17205
|
+
if (textParts.length > 0) {
|
|
17206
|
+
return {
|
|
17207
|
+
messages: [
|
|
17208
|
+
{
|
|
17209
|
+
role: normalizedContent.role ?? "user",
|
|
17210
|
+
content: textParts.join("")
|
|
17211
|
+
}
|
|
17212
|
+
]
|
|
17213
|
+
};
|
|
17214
|
+
}
|
|
17215
|
+
}
|
|
17216
|
+
return { messages: [normalizedContent] };
|
|
17217
|
+
}
|
|
17218
|
+
function extractRunnerMetadata(paramsOrContext) {
|
|
17219
|
+
const metadata = {
|
|
17220
|
+
provider: "google-adk"
|
|
17221
|
+
};
|
|
17222
|
+
const directUserId = "userId" in paramsOrContext ? paramsOrContext.userId : void 0;
|
|
17223
|
+
const directSessionId = "sessionId" in paramsOrContext ? paramsOrContext.sessionId : void 0;
|
|
17224
|
+
if (typeof directUserId === "string") {
|
|
17225
|
+
metadata["google_adk.user_id"] = directUserId;
|
|
17226
|
+
}
|
|
17227
|
+
if (typeof directSessionId === "string") {
|
|
17228
|
+
metadata["google_adk.session_id"] = directSessionId;
|
|
17229
|
+
}
|
|
17230
|
+
const session = "session" in paramsOrContext ? paramsOrContext.session : void 0;
|
|
17231
|
+
if (metadata["google_adk.user_id"] === void 0 && typeof session?.userId === "string") {
|
|
17232
|
+
metadata["google_adk.user_id"] = session.userId;
|
|
17233
|
+
}
|
|
17234
|
+
if (metadata["google_adk.session_id"] === void 0 && typeof session?.id === "string") {
|
|
17235
|
+
metadata["google_adk.session_id"] = session.id;
|
|
17236
|
+
}
|
|
17237
|
+
return metadata;
|
|
17238
|
+
}
|
|
17239
|
+
function extractAgentName(parentContext) {
|
|
17240
|
+
if (!parentContext) {
|
|
17241
|
+
return void 0;
|
|
17242
|
+
}
|
|
17243
|
+
const agent = parentContext.agent;
|
|
17244
|
+
return agent?.name;
|
|
17245
|
+
}
|
|
17246
|
+
function extractModelName(parentContext) {
|
|
17247
|
+
if (!parentContext) {
|
|
17248
|
+
return void 0;
|
|
17249
|
+
}
|
|
17250
|
+
const agent = parentContext.agent;
|
|
17251
|
+
if (!agent?.model) {
|
|
17252
|
+
return void 0;
|
|
17253
|
+
}
|
|
17254
|
+
if (typeof agent.model === "string") {
|
|
17255
|
+
return agent.model;
|
|
17256
|
+
}
|
|
17257
|
+
if (typeof agent.model === "object" && "model" in agent.model) {
|
|
17258
|
+
return agent.model.model;
|
|
17259
|
+
}
|
|
17260
|
+
return void 0;
|
|
17261
|
+
}
|
|
17262
|
+
function extractToolCallId(req) {
|
|
17263
|
+
const toolContext = req.toolContext;
|
|
17264
|
+
return toolContext?.functionCallId;
|
|
17265
|
+
}
|
|
17266
|
+
function extractToolName(req, tool) {
|
|
17267
|
+
if (typeof tool?.name === "string" && tool.name.length > 0) {
|
|
17268
|
+
return tool.name;
|
|
17269
|
+
}
|
|
17270
|
+
const toolContext = req.toolContext;
|
|
17271
|
+
const invocationContext = toolContext?.invocationContext;
|
|
17272
|
+
const invocationTool = invocationContext?.tool;
|
|
17273
|
+
const toolName = invocationTool?.name;
|
|
17274
|
+
return typeof toolName === "string" && toolName.length > 0 ? toolName : void 0;
|
|
17275
|
+
}
|
|
17276
|
+
function extractToolAgentName(req) {
|
|
17277
|
+
const toolContext = req.toolContext;
|
|
17278
|
+
const directName = toolContext?.agentName;
|
|
17279
|
+
if (typeof directName === "string" && directName.length > 0) {
|
|
17280
|
+
return directName;
|
|
17281
|
+
}
|
|
17282
|
+
const invocationContext = toolContext?.invocationContext;
|
|
17283
|
+
return extractAgentName(invocationContext);
|
|
17284
|
+
}
|
|
17285
|
+
function findToolParentSpan(req, activeAgentSpans, activeRunnerSpans) {
|
|
17286
|
+
const toolContext = req.toolContext;
|
|
17287
|
+
const invocationContext = toolContext?.invocationContext;
|
|
17288
|
+
const contextKey = extractInvocationContextKey(invocationContext);
|
|
17289
|
+
const agentName = extractToolAgentName(req);
|
|
17290
|
+
if (contextKey && agentName) {
|
|
17291
|
+
const agentSpan = activeAgentSpans.get(
|
|
17292
|
+
agentContextKey(contextKey, agentName)
|
|
17293
|
+
);
|
|
17294
|
+
if (agentSpan) {
|
|
17295
|
+
return agentSpan;
|
|
17296
|
+
}
|
|
17297
|
+
}
|
|
17298
|
+
return contextKey ? activeRunnerSpans.get(contextKey) : void 0;
|
|
17299
|
+
}
|
|
17300
|
+
function finalizeRunnerSpan(state, activeRunnerSpans) {
|
|
17301
|
+
try {
|
|
17302
|
+
const lastEvent = getLastNonPartialEvent(state.events);
|
|
17303
|
+
const metrics = {};
|
|
17304
|
+
const end = getCurrentUnixTimestamp();
|
|
17305
|
+
metrics.start = state.startTime;
|
|
17306
|
+
metrics.end = end;
|
|
17307
|
+
metrics.duration = end - state.startTime;
|
|
17308
|
+
const usage = aggregateUsageFromEvents(state.events);
|
|
17309
|
+
if (usage) {
|
|
17310
|
+
populateUsageMetrics2(metrics, usage);
|
|
17311
|
+
}
|
|
17312
|
+
state.span.log({
|
|
17313
|
+
output: lastEvent ? extractEventOutput(lastEvent) : void 0,
|
|
17314
|
+
metrics: cleanMetrics2(metrics)
|
|
17315
|
+
});
|
|
17316
|
+
} finally {
|
|
17317
|
+
cleanupActiveRunnerSpan(state, activeRunnerSpans);
|
|
17318
|
+
state.span.end();
|
|
17319
|
+
}
|
|
17320
|
+
}
|
|
17321
|
+
function finalizeAgentSpan(state, activeAgentSpans) {
|
|
17322
|
+
try {
|
|
17323
|
+
const lastEvent = getLastNonPartialEvent(state.events);
|
|
17324
|
+
const metrics = {};
|
|
17325
|
+
const end = getCurrentUnixTimestamp();
|
|
17326
|
+
metrics.start = state.startTime;
|
|
17327
|
+
metrics.end = end;
|
|
17328
|
+
metrics.duration = end - state.startTime;
|
|
17329
|
+
state.span.log({
|
|
17330
|
+
output: lastEvent ? extractEventOutput(lastEvent) : void 0,
|
|
17331
|
+
metrics: cleanMetrics2(metrics)
|
|
17332
|
+
});
|
|
17333
|
+
} finally {
|
|
17334
|
+
cleanupActiveAgentSpan(state, activeAgentSpans);
|
|
17335
|
+
state.span.end();
|
|
17336
|
+
}
|
|
17337
|
+
}
|
|
17338
|
+
function getLastNonPartialEvent(events) {
|
|
17339
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
17340
|
+
if (!events[i].partial) {
|
|
17341
|
+
return events[i];
|
|
17342
|
+
}
|
|
17343
|
+
}
|
|
17344
|
+
return events.length > 0 ? events[events.length - 1] : void 0;
|
|
17345
|
+
}
|
|
17346
|
+
function extractEventOutput(event) {
|
|
17347
|
+
if (!event.content) {
|
|
17348
|
+
return void 0;
|
|
17349
|
+
}
|
|
17350
|
+
const output = {};
|
|
17351
|
+
if (event.content.role) {
|
|
17352
|
+
output.role = event.content.role;
|
|
17353
|
+
}
|
|
17354
|
+
if (event.content.parts && Array.isArray(event.content.parts)) {
|
|
17355
|
+
const textParts = event.content.parts.filter((p) => p.text !== void 0 && !p.thought).map((p) => p.text);
|
|
17356
|
+
const thoughtParts = event.content.parts.filter((p) => p.text !== void 0 && p.thought).map((p) => p.text);
|
|
17357
|
+
const functionCalls = event.content.parts.filter((p) => p.functionCall).map((p) => p.functionCall);
|
|
17358
|
+
if (textParts.length > 0) {
|
|
17359
|
+
output.content = textParts.join("");
|
|
17360
|
+
}
|
|
17361
|
+
if (thoughtParts.length > 0) {
|
|
17362
|
+
output.thought = thoughtParts.join("");
|
|
17363
|
+
}
|
|
17364
|
+
if (functionCalls.length > 0) {
|
|
17365
|
+
output.functionCalls = functionCalls;
|
|
17366
|
+
}
|
|
17367
|
+
}
|
|
17368
|
+
if (event.author) {
|
|
17369
|
+
output.author = event.author;
|
|
17370
|
+
}
|
|
17371
|
+
return Object.keys(output).length > 0 ? output : void 0;
|
|
17372
|
+
}
|
|
17373
|
+
function aggregateUsageFromEvents(events) {
|
|
17374
|
+
let hasUsage = false;
|
|
17375
|
+
const aggregated = {};
|
|
17376
|
+
for (const event of events) {
|
|
17377
|
+
if (!event.usageMetadata) {
|
|
17378
|
+
continue;
|
|
17379
|
+
}
|
|
17380
|
+
hasUsage = true;
|
|
17381
|
+
const usage = event.usageMetadata;
|
|
17382
|
+
if (usage.promptTokenCount !== void 0) {
|
|
17383
|
+
aggregated.promptTokenCount = (aggregated.promptTokenCount ?? 0) + usage.promptTokenCount;
|
|
17384
|
+
}
|
|
17385
|
+
if (usage.candidatesTokenCount !== void 0) {
|
|
17386
|
+
aggregated.candidatesTokenCount = (aggregated.candidatesTokenCount ?? 0) + usage.candidatesTokenCount;
|
|
17387
|
+
}
|
|
17388
|
+
if (usage.totalTokenCount !== void 0) {
|
|
17389
|
+
aggregated.totalTokenCount = (aggregated.totalTokenCount ?? 0) + usage.totalTokenCount;
|
|
17390
|
+
}
|
|
17391
|
+
if (usage.cachedContentTokenCount !== void 0) {
|
|
17392
|
+
aggregated.cachedContentTokenCount = (aggregated.cachedContentTokenCount ?? 0) + usage.cachedContentTokenCount;
|
|
17393
|
+
}
|
|
17394
|
+
if (usage.thoughtsTokenCount !== void 0) {
|
|
17395
|
+
aggregated.thoughtsTokenCount = (aggregated.thoughtsTokenCount ?? 0) + usage.thoughtsTokenCount;
|
|
17396
|
+
}
|
|
17397
|
+
}
|
|
17398
|
+
return hasUsage ? aggregated : void 0;
|
|
17399
|
+
}
|
|
17400
|
+
function populateUsageMetrics2(metrics, usage) {
|
|
17401
|
+
if (usage.promptTokenCount !== void 0) {
|
|
17402
|
+
metrics.prompt_tokens = usage.promptTokenCount;
|
|
17403
|
+
}
|
|
17404
|
+
if (usage.candidatesTokenCount !== void 0) {
|
|
17405
|
+
metrics.completion_tokens = usage.candidatesTokenCount;
|
|
17406
|
+
}
|
|
17407
|
+
if (usage.totalTokenCount !== void 0) {
|
|
17408
|
+
metrics.tokens = usage.totalTokenCount;
|
|
17409
|
+
}
|
|
17410
|
+
if (usage.cachedContentTokenCount !== void 0) {
|
|
17411
|
+
metrics.prompt_cached_tokens = usage.cachedContentTokenCount;
|
|
17412
|
+
}
|
|
17413
|
+
if (usage.thoughtsTokenCount !== void 0) {
|
|
17414
|
+
metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
|
|
17415
|
+
}
|
|
17416
|
+
}
|
|
17417
|
+
function cleanMetrics2(metrics) {
|
|
17418
|
+
const cleaned = {};
|
|
17419
|
+
for (const [key, value] of Object.entries(metrics)) {
|
|
17420
|
+
if (value !== null && value !== void 0) {
|
|
17421
|
+
cleaned[key] = value;
|
|
17422
|
+
}
|
|
17423
|
+
}
|
|
17424
|
+
return cleaned;
|
|
17425
|
+
}
|
|
17426
|
+
|
|
17427
|
+
// src/instrumentation/plugins/cohere-channels.ts
|
|
17428
|
+
var cohereChannels = defineChannels("cohere-ai", {
|
|
17429
|
+
chat: channel({
|
|
17430
|
+
channelName: "chat",
|
|
17431
|
+
kind: "async"
|
|
17432
|
+
}),
|
|
17433
|
+
chatStream: channel({
|
|
17434
|
+
channelName: "chatStream",
|
|
17435
|
+
kind: "async"
|
|
17436
|
+
}),
|
|
17437
|
+
embed: channel({
|
|
17438
|
+
channelName: "embed",
|
|
17439
|
+
kind: "async"
|
|
17440
|
+
}),
|
|
17441
|
+
rerank: channel({
|
|
17442
|
+
channelName: "rerank",
|
|
17443
|
+
kind: "async"
|
|
17444
|
+
})
|
|
17445
|
+
});
|
|
17446
|
+
|
|
17447
|
+
// src/instrumentation/plugins/cohere-plugin.ts
|
|
17448
|
+
var CoherePlugin = class extends BasePlugin {
|
|
17449
|
+
onEnable() {
|
|
17450
|
+
this.subscribeToCohereChannels();
|
|
17451
|
+
}
|
|
17452
|
+
onDisable() {
|
|
17453
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
17454
|
+
}
|
|
17455
|
+
subscribeToCohereChannels() {
|
|
17456
|
+
this.unsubscribers.push(
|
|
17457
|
+
traceStreamingChannel(cohereChannels.chat, {
|
|
17458
|
+
name: "cohere.chat",
|
|
17459
|
+
type: "llm" /* LLM */,
|
|
17460
|
+
extractInput: extractChatInputWithMetadata2,
|
|
17461
|
+
extractOutput: (result) => extractCohereChatOutput(result),
|
|
17462
|
+
extractMetadata: (result) => extractCohereResponseMetadata(result),
|
|
17463
|
+
extractMetrics: (result, startTime) => {
|
|
17464
|
+
const metrics = parseCohereMetricsFromUsage(result);
|
|
17465
|
+
if (startTime) {
|
|
17466
|
+
metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
17467
|
+
}
|
|
17468
|
+
return metrics;
|
|
17469
|
+
}
|
|
17470
|
+
})
|
|
17471
|
+
);
|
|
17472
|
+
this.unsubscribers.push(
|
|
17473
|
+
traceStreamingChannel(cohereChannels.chatStream, {
|
|
17474
|
+
name: "cohere.chatStream",
|
|
17475
|
+
type: "llm" /* LLM */,
|
|
17476
|
+
extractInput: extractChatInputWithMetadata2,
|
|
17477
|
+
extractOutput: () => void 0,
|
|
17478
|
+
extractMetadata: () => void 0,
|
|
17479
|
+
extractMetrics: () => ({}),
|
|
17480
|
+
aggregateChunks: aggregateCohereChatStreamChunks
|
|
17481
|
+
})
|
|
17482
|
+
);
|
|
17483
|
+
this.unsubscribers.push(
|
|
17484
|
+
traceAsyncChannel(cohereChannels.embed, {
|
|
17485
|
+
name: "cohere.embed",
|
|
17486
|
+
type: "llm" /* LLM */,
|
|
17487
|
+
extractInput: extractEmbedInputWithMetadata,
|
|
17488
|
+
extractOutput: extractCohereEmbeddingOutput,
|
|
17489
|
+
extractMetadata: (result) => extractCohereResponseMetadata(result),
|
|
17490
|
+
extractMetrics: (result) => parseCohereMetricsFromUsage(result)
|
|
17491
|
+
})
|
|
17492
|
+
);
|
|
17493
|
+
this.unsubscribers.push(
|
|
17494
|
+
traceAsyncChannel(cohereChannels.rerank, {
|
|
17495
|
+
name: "cohere.rerank",
|
|
17496
|
+
type: "llm" /* LLM */,
|
|
17497
|
+
extractInput: extractRerankInputWithMetadata,
|
|
17498
|
+
extractOutput: (result) => {
|
|
17499
|
+
if (!isObject(result) || !Array.isArray(result.results)) {
|
|
17500
|
+
return void 0;
|
|
17501
|
+
}
|
|
17502
|
+
return result.results.slice(0, 100).map((item) => ({
|
|
17503
|
+
index: isObject(item) ? item.index : void 0,
|
|
17504
|
+
relevance_score: isObject(item) ? (typeof item.relevanceScore === "number" ? item.relevanceScore : item.relevance_score) ?? null : null
|
|
17505
|
+
}));
|
|
17506
|
+
},
|
|
17507
|
+
extractMetadata: (result) => extractCohereResponseMetadata(result),
|
|
17508
|
+
extractMetrics: (result) => parseCohereMetricsFromUsage(result)
|
|
17509
|
+
})
|
|
17510
|
+
);
|
|
17511
|
+
}
|
|
17512
|
+
};
|
|
17513
|
+
var CHAT_REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
17514
|
+
"conversationId",
|
|
17515
|
+
"conversation_id",
|
|
17516
|
+
"frequencyPenalty",
|
|
17517
|
+
"frequency_penalty",
|
|
17518
|
+
"k",
|
|
17519
|
+
"maxInputTokens",
|
|
17520
|
+
"max_input_tokens",
|
|
17521
|
+
"maxTokens",
|
|
17522
|
+
"max_tokens",
|
|
17523
|
+
"model",
|
|
17524
|
+
"p",
|
|
17525
|
+
"preamble",
|
|
17526
|
+
"presencePenalty",
|
|
17527
|
+
"presence_penalty",
|
|
17528
|
+
"priority",
|
|
17529
|
+
"promptTruncation",
|
|
17530
|
+
"prompt_truncation",
|
|
17531
|
+
"rawPrompting",
|
|
17532
|
+
"raw_prompting",
|
|
17533
|
+
"responseFormat",
|
|
17534
|
+
"response_format",
|
|
17535
|
+
"safetyMode",
|
|
17536
|
+
"safety_mode",
|
|
17537
|
+
"searchQueriesOnly",
|
|
17538
|
+
"search_queries_only",
|
|
17539
|
+
"seed",
|
|
17540
|
+
"stopSequences",
|
|
17541
|
+
"stop_sequences",
|
|
17542
|
+
"strictTools",
|
|
17543
|
+
"strict_tools",
|
|
17544
|
+
"temperature",
|
|
17545
|
+
"toolChoice",
|
|
17546
|
+
"tool_choice"
|
|
17547
|
+
]);
|
|
17548
|
+
var EMBED_REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
17549
|
+
"embeddingTypes",
|
|
17550
|
+
"embedding_types",
|
|
17551
|
+
"inputType",
|
|
17552
|
+
"input_type",
|
|
17553
|
+
"maxTokens",
|
|
17554
|
+
"max_tokens",
|
|
17555
|
+
"model",
|
|
17556
|
+
"outputDimension",
|
|
17557
|
+
"output_dimension",
|
|
17558
|
+
"priority",
|
|
17559
|
+
"truncate"
|
|
17560
|
+
]);
|
|
17561
|
+
var RERANK_REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
17562
|
+
"maxChunksPerDoc",
|
|
17563
|
+
"max_chunks_per_doc",
|
|
17564
|
+
"maxTokensPerDoc",
|
|
17565
|
+
"max_tokens_per_doc",
|
|
17566
|
+
"model",
|
|
17567
|
+
"priority",
|
|
17568
|
+
"rankFields",
|
|
17569
|
+
"rank_fields",
|
|
17570
|
+
"returnDocuments",
|
|
17571
|
+
"return_documents",
|
|
17572
|
+
"topN",
|
|
17573
|
+
"top_n"
|
|
17574
|
+
]);
|
|
17575
|
+
var RESPONSE_METADATA_ALLOWLIST2 = /* @__PURE__ */ new Set([
|
|
17576
|
+
"finishReason",
|
|
17577
|
+
"finish_reason",
|
|
17578
|
+
"generationId",
|
|
17579
|
+
"generation_id",
|
|
17580
|
+
"id",
|
|
17581
|
+
"responseId",
|
|
17582
|
+
"responseType",
|
|
17583
|
+
"response_id",
|
|
17584
|
+
"response_type"
|
|
17585
|
+
]);
|
|
17586
|
+
function normalizeArgs5(args) {
|
|
17587
|
+
if (Array.isArray(args)) {
|
|
17588
|
+
return args;
|
|
17589
|
+
}
|
|
17590
|
+
if (isArrayLike5(args)) {
|
|
17591
|
+
return Array.from(args);
|
|
17592
|
+
}
|
|
17593
|
+
return [args];
|
|
17594
|
+
}
|
|
17595
|
+
function isArrayLike5(value) {
|
|
17596
|
+
return isObject(value) && "length" in value && typeof value.length === "number" && Number.isInteger(value.length) && value.length >= 0;
|
|
17597
|
+
}
|
|
17598
|
+
function getRequestArg(args) {
|
|
17599
|
+
const firstObjectArg = normalizeArgs5(args).find((arg) => isObject(arg));
|
|
17600
|
+
return isObject(firstObjectArg) ? firstObjectArg : void 0;
|
|
17601
|
+
}
|
|
17602
|
+
function addCohereProviderMetadata(metadata) {
|
|
17603
|
+
return {
|
|
17604
|
+
...metadata,
|
|
17605
|
+
provider: "cohere"
|
|
17606
|
+
};
|
|
17607
|
+
}
|
|
17608
|
+
function pickAllowedMetadata2(metadata, allowlist) {
|
|
17609
|
+
if (!metadata) {
|
|
17610
|
+
return {};
|
|
17611
|
+
}
|
|
17612
|
+
const picked = {};
|
|
17613
|
+
for (const key of allowlist) {
|
|
17614
|
+
const value = metadata[key];
|
|
17615
|
+
if (value !== void 0) {
|
|
17616
|
+
picked[key] = value;
|
|
17617
|
+
}
|
|
17618
|
+
}
|
|
17619
|
+
return picked;
|
|
17620
|
+
}
|
|
17621
|
+
function extractChatInputWithMetadata2(args) {
|
|
17622
|
+
const request = getRequestArg(args);
|
|
17623
|
+
const { message, messages, ...rawMetadata } = request || {};
|
|
17624
|
+
return {
|
|
17625
|
+
input: processInputAttachments(messages ?? message),
|
|
17626
|
+
metadata: addCohereProviderMetadata(
|
|
17627
|
+
pickAllowedMetadata2(rawMetadata, CHAT_REQUEST_METADATA_ALLOWLIST)
|
|
17628
|
+
)
|
|
17629
|
+
};
|
|
17630
|
+
}
|
|
17631
|
+
function extractEmbedInputWithMetadata(args) {
|
|
17632
|
+
const request = getRequestArg(args);
|
|
17633
|
+
const { inputs, texts, images, ...rawMetadata } = request || {};
|
|
17634
|
+
return {
|
|
17635
|
+
input: inputs ?? texts ?? images,
|
|
17636
|
+
metadata: addCohereProviderMetadata(
|
|
17637
|
+
pickAllowedMetadata2(rawMetadata, EMBED_REQUEST_METADATA_ALLOWLIST)
|
|
17638
|
+
)
|
|
17639
|
+
};
|
|
17640
|
+
}
|
|
17641
|
+
function extractRerankInputWithMetadata(args) {
|
|
17642
|
+
const request = getRequestArg(args);
|
|
17643
|
+
const { query, documents, ...rawMetadata } = request || {};
|
|
17644
|
+
return {
|
|
17645
|
+
input: {
|
|
17646
|
+
documents,
|
|
17647
|
+
query
|
|
17648
|
+
},
|
|
17649
|
+
metadata: addCohereProviderMetadata({
|
|
17650
|
+
...pickAllowedMetadata2(rawMetadata, RERANK_REQUEST_METADATA_ALLOWLIST),
|
|
17651
|
+
...Array.isArray(documents) ? { document_count: documents.length } : {}
|
|
17652
|
+
})
|
|
17653
|
+
};
|
|
17654
|
+
}
|
|
17655
|
+
function extractCohereResponseMetadata(result) {
|
|
17656
|
+
if (!isObject(result)) {
|
|
17657
|
+
return void 0;
|
|
17658
|
+
}
|
|
17659
|
+
const responseMetadata = pickAllowedMetadata2(
|
|
17660
|
+
result,
|
|
17661
|
+
RESPONSE_METADATA_ALLOWLIST2
|
|
17662
|
+
);
|
|
17663
|
+
const meta = isObject(result.meta) ? result.meta : void 0;
|
|
17664
|
+
const apiVersion = isObject(meta?.apiVersion) && typeof meta.apiVersion.version === "string" && meta.apiVersion.version || isObject(meta?.api_version) && typeof meta.api_version.version === "string" && meta.api_version.version;
|
|
17665
|
+
const metadata = {
|
|
17666
|
+
...responseMetadata,
|
|
17667
|
+
...apiVersion ? { api_version: apiVersion } : {}
|
|
17668
|
+
};
|
|
17669
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
17670
|
+
}
|
|
17671
|
+
function extractCohereChatOutput(result) {
|
|
17672
|
+
if (!isObject(result)) {
|
|
17673
|
+
return void 0;
|
|
17674
|
+
}
|
|
17675
|
+
if (isObject(result.message)) {
|
|
17676
|
+
return result.message;
|
|
17677
|
+
}
|
|
17678
|
+
if (typeof result.text !== "string") {
|
|
17679
|
+
return void 0;
|
|
17680
|
+
}
|
|
17681
|
+
const toolCalls = Array.isArray(result.toolCalls) ? result.toolCalls : Array.isArray(result.tool_calls) ? result.tool_calls : void 0;
|
|
17682
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
17683
|
+
return {
|
|
17684
|
+
content: result.text,
|
|
17685
|
+
role: "assistant",
|
|
17686
|
+
toolCalls
|
|
17687
|
+
};
|
|
17688
|
+
}
|
|
17689
|
+
return result.text;
|
|
17690
|
+
}
|
|
17691
|
+
function extractCohereEmbeddingOutput(result) {
|
|
17692
|
+
if (!isObject(result)) {
|
|
17693
|
+
return void 0;
|
|
17694
|
+
}
|
|
17695
|
+
const embeddingLength = getFirstEmbeddingLength(result.embeddings);
|
|
17696
|
+
if (embeddingLength === void 0) {
|
|
17697
|
+
return void 0;
|
|
17698
|
+
}
|
|
17699
|
+
return {
|
|
17700
|
+
embedding_length: embeddingLength
|
|
17701
|
+
};
|
|
17702
|
+
}
|
|
17703
|
+
function getFirstEmbeddingLength(value) {
|
|
17704
|
+
if (Array.isArray(value) && Array.isArray(value[0])) {
|
|
17705
|
+
return value[0].length;
|
|
17706
|
+
}
|
|
17707
|
+
if (!isObject(value)) {
|
|
17708
|
+
return void 0;
|
|
17709
|
+
}
|
|
17710
|
+
for (const key of Object.keys(value)) {
|
|
17711
|
+
const entry = value[key];
|
|
17712
|
+
if (Array.isArray(entry) && Array.isArray(entry[0])) {
|
|
17713
|
+
return entry[0].length;
|
|
17714
|
+
}
|
|
17715
|
+
}
|
|
17716
|
+
return void 0;
|
|
17717
|
+
}
|
|
17718
|
+
function setMetricIfNumber(metrics, key, value) {
|
|
17719
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
17720
|
+
metrics[key] = value;
|
|
17721
|
+
}
|
|
17722
|
+
}
|
|
17723
|
+
function mergeUsageMetrics(metrics, usage) {
|
|
17724
|
+
if (!isObject(usage)) {
|
|
17725
|
+
return metrics;
|
|
17726
|
+
}
|
|
17727
|
+
const source = usage;
|
|
17728
|
+
setMetricIfNumber(
|
|
17729
|
+
metrics,
|
|
17730
|
+
"prompt_tokens",
|
|
17731
|
+
source.inputTokens ?? source.input_tokens
|
|
17732
|
+
);
|
|
17733
|
+
setMetricIfNumber(
|
|
17734
|
+
metrics,
|
|
17735
|
+
"completion_tokens",
|
|
17736
|
+
source.outputTokens ?? source.output_tokens
|
|
17737
|
+
);
|
|
17738
|
+
setMetricIfNumber(
|
|
17739
|
+
metrics,
|
|
17740
|
+
"tokens",
|
|
17741
|
+
source.totalTokens ?? source.total_tokens
|
|
17742
|
+
);
|
|
17743
|
+
setMetricIfNumber(
|
|
17744
|
+
metrics,
|
|
17745
|
+
"prompt_cached_tokens",
|
|
17746
|
+
source.cachedTokens ?? source.cached_tokens
|
|
17747
|
+
);
|
|
17748
|
+
const tokenContainer = isObject(source.tokens) ? source.tokens : void 0;
|
|
17749
|
+
if (tokenContainer) {
|
|
17750
|
+
setMetricIfNumber(
|
|
17751
|
+
metrics,
|
|
17752
|
+
"prompt_tokens",
|
|
17753
|
+
tokenContainer.inputTokens ?? tokenContainer.input_tokens
|
|
17754
|
+
);
|
|
17755
|
+
setMetricIfNumber(
|
|
17756
|
+
metrics,
|
|
17757
|
+
"completion_tokens",
|
|
17758
|
+
tokenContainer.outputTokens ?? tokenContainer.output_tokens
|
|
17759
|
+
);
|
|
17760
|
+
setMetricIfNumber(
|
|
17761
|
+
metrics,
|
|
17762
|
+
"tokens",
|
|
17763
|
+
tokenContainer.totalTokens ?? tokenContainer.total_tokens
|
|
17764
|
+
);
|
|
17765
|
+
}
|
|
17766
|
+
const billedUnits = (isObject(source.billedUnits) ? source.billedUnits : void 0) || (isObject(source.billed_units) ? source.billed_units : void 0);
|
|
17767
|
+
if (billedUnits) {
|
|
17768
|
+
setMetricIfNumber(
|
|
17769
|
+
metrics,
|
|
17770
|
+
"prompt_tokens",
|
|
17771
|
+
billedUnits.inputTokens ?? billedUnits.input_tokens
|
|
17772
|
+
);
|
|
17773
|
+
setMetricIfNumber(
|
|
17774
|
+
metrics,
|
|
17775
|
+
"completion_tokens",
|
|
17776
|
+
billedUnits.outputTokens ?? billedUnits.output_tokens
|
|
17777
|
+
);
|
|
17778
|
+
setMetricIfNumber(
|
|
17779
|
+
metrics,
|
|
17780
|
+
"search_units",
|
|
17781
|
+
billedUnits.searchUnits ?? billedUnits.search_units
|
|
17782
|
+
);
|
|
17783
|
+
setMetricIfNumber(metrics, "classifications", billedUnits.classifications);
|
|
17784
|
+
setMetricIfNumber(metrics, "images", billedUnits.images);
|
|
17785
|
+
setMetricIfNumber(
|
|
17786
|
+
metrics,
|
|
17787
|
+
"image_tokens",
|
|
17788
|
+
billedUnits.imageTokens ?? billedUnits.image_tokens
|
|
17789
|
+
);
|
|
17790
|
+
}
|
|
17791
|
+
return metrics;
|
|
17792
|
+
}
|
|
17793
|
+
function parseCohereMetricsFromUsage(source) {
|
|
17794
|
+
if (!isObject(source)) {
|
|
17795
|
+
return {};
|
|
17796
|
+
}
|
|
17797
|
+
const metrics = {};
|
|
17798
|
+
mergeUsageMetrics(metrics, source);
|
|
17799
|
+
if ("usage" in source) {
|
|
17800
|
+
mergeUsageMetrics(metrics, source.usage);
|
|
17801
|
+
}
|
|
17802
|
+
if ("meta" in source) {
|
|
17803
|
+
mergeUsageMetrics(metrics, source.meta);
|
|
17804
|
+
}
|
|
17805
|
+
if (metrics.tokens === void 0 && typeof metrics.prompt_tokens === "number" && typeof metrics.completion_tokens === "number") {
|
|
17806
|
+
metrics.tokens = metrics.prompt_tokens + metrics.completion_tokens;
|
|
17807
|
+
}
|
|
17808
|
+
return metrics;
|
|
17809
|
+
}
|
|
17810
|
+
function toToolCallArray(value) {
|
|
17811
|
+
if (Array.isArray(value)) {
|
|
17812
|
+
return value.filter((item) => isObject(item));
|
|
17813
|
+
}
|
|
17814
|
+
return isObject(value) ? [value] : [];
|
|
17815
|
+
}
|
|
17816
|
+
function getToolCallIndex2(toolCall, fallbackIndex) {
|
|
17817
|
+
return typeof toolCall.index === "number" && Number.isInteger(toolCall.index) ? toolCall.index : fallbackIndex;
|
|
17818
|
+
}
|
|
17819
|
+
function appendToolCallDelta(existing, incoming) {
|
|
17820
|
+
const currentArguments = isObject(existing?.function) && typeof existing.function.arguments === "string" ? existing.function.arguments : "";
|
|
17821
|
+
const incomingArguments = isObject(incoming.function) && typeof incoming.function.arguments === "string" ? incoming.function.arguments : "";
|
|
17822
|
+
return {
|
|
17823
|
+
...existing,
|
|
17824
|
+
...incoming,
|
|
17825
|
+
function: {
|
|
17826
|
+
...isObject(existing?.function) ? existing.function : {},
|
|
17827
|
+
...isObject(incoming.function) ? incoming.function : {},
|
|
17828
|
+
...incomingArguments ? { arguments: `${currentArguments}${incomingArguments}` } : {}
|
|
17829
|
+
}
|
|
17830
|
+
};
|
|
17831
|
+
}
|
|
17832
|
+
function extractV8DeltaText(chunk) {
|
|
17833
|
+
if (!isObject(chunk.delta) || !isObject(chunk.delta.message)) {
|
|
17834
|
+
return void 0;
|
|
17835
|
+
}
|
|
17836
|
+
const content = chunk.delta.message.content;
|
|
17837
|
+
if (typeof content === "string") {
|
|
17838
|
+
return content;
|
|
17839
|
+
}
|
|
17840
|
+
if (isObject(content) && typeof content.text === "string") {
|
|
17841
|
+
return content.text;
|
|
17842
|
+
}
|
|
17843
|
+
return void 0;
|
|
17844
|
+
}
|
|
17845
|
+
function aggregateCohereChatStreamChunks(chunks) {
|
|
17846
|
+
const textDeltas = [];
|
|
17847
|
+
const toolCallsByIndex = {};
|
|
17848
|
+
const toolCallOrder = [];
|
|
17849
|
+
let terminalResponse;
|
|
17850
|
+
let role;
|
|
17851
|
+
let finishReason;
|
|
17852
|
+
let metadata = {};
|
|
17853
|
+
let metrics = {};
|
|
17854
|
+
for (const chunk of chunks) {
|
|
17855
|
+
if (!isObject(chunk)) {
|
|
17856
|
+
continue;
|
|
17857
|
+
}
|
|
17858
|
+
const eventType = typeof chunk.eventType === "string" ? chunk.eventType : typeof chunk.event_type === "string" ? chunk.event_type : typeof chunk.type === "string" ? chunk.type : void 0;
|
|
17859
|
+
if (eventType === "text-generation" && typeof chunk.text === "string") {
|
|
17860
|
+
textDeltas.push(chunk.text);
|
|
17861
|
+
continue;
|
|
17862
|
+
}
|
|
17863
|
+
if (eventType === "tool-calls-generation") {
|
|
17864
|
+
const generatedToolCalls = toToolCallArray(
|
|
17865
|
+
Array.isArray(chunk.toolCalls) ? chunk.toolCalls : chunk.tool_calls
|
|
17866
|
+
);
|
|
17867
|
+
for (const [index, toolCall] of generatedToolCalls.entries()) {
|
|
17868
|
+
const normalizedIndex = getToolCallIndex2(toolCall, index);
|
|
17869
|
+
if (!toolCallOrder.includes(normalizedIndex)) {
|
|
17870
|
+
toolCallOrder.push(normalizedIndex);
|
|
17871
|
+
}
|
|
17872
|
+
toolCallsByIndex[normalizedIndex] = {
|
|
17873
|
+
...toolCallsByIndex[normalizedIndex],
|
|
17874
|
+
...toolCall
|
|
17875
|
+
};
|
|
17876
|
+
}
|
|
17877
|
+
if (typeof chunk.text === "string") {
|
|
17878
|
+
textDeltas.push(chunk.text);
|
|
17879
|
+
}
|
|
17880
|
+
continue;
|
|
17881
|
+
}
|
|
17882
|
+
if (eventType === "stream-end" && isObject(chunk.response)) {
|
|
17883
|
+
terminalResponse = chunk.response;
|
|
17884
|
+
metrics = {
|
|
17885
|
+
...metrics,
|
|
17886
|
+
...parseCohereMetricsFromUsage(chunk.response)
|
|
17887
|
+
};
|
|
17888
|
+
metadata = {
|
|
17889
|
+
...metadata,
|
|
17890
|
+
...extractCohereResponseMetadata(chunk.response) || {}
|
|
17891
|
+
};
|
|
17892
|
+
const responseFinishReason = typeof chunk.response.finishReason === "string" ? chunk.response.finishReason : typeof chunk.response.finish_reason === "string" ? chunk.response.finish_reason : void 0;
|
|
17893
|
+
finishReason = responseFinishReason ?? finishReason;
|
|
17894
|
+
continue;
|
|
17895
|
+
}
|
|
17896
|
+
if (eventType === "message-start") {
|
|
17897
|
+
if (typeof chunk.id === "string") {
|
|
17898
|
+
metadata.id = chunk.id;
|
|
17899
|
+
}
|
|
17900
|
+
if (isObject(chunk.delta) && isObject(chunk.delta.message)) {
|
|
17901
|
+
const messageRole = chunk.delta.message.role;
|
|
17902
|
+
if (typeof messageRole === "string") {
|
|
17903
|
+
role = messageRole;
|
|
17904
|
+
}
|
|
17905
|
+
}
|
|
17906
|
+
continue;
|
|
17907
|
+
}
|
|
17908
|
+
if (eventType === "content-delta") {
|
|
17909
|
+
const text = extractV8DeltaText(chunk);
|
|
17910
|
+
if (text) {
|
|
17911
|
+
textDeltas.push(text);
|
|
17912
|
+
}
|
|
17913
|
+
continue;
|
|
17914
|
+
}
|
|
17915
|
+
if (eventType === "tool-call-start") {
|
|
17916
|
+
const toolCalls = isObject(chunk.delta) && isObject(chunk.delta.message) ? toToolCallArray(
|
|
17917
|
+
Array.isArray(chunk.delta.message.toolCalls) ? chunk.delta.message.toolCalls : chunk.delta.message.toolCalls ?? chunk.delta.message.tool_calls
|
|
17918
|
+
) : [];
|
|
17919
|
+
for (const [index, toolCall] of toolCalls.entries()) {
|
|
17920
|
+
const normalizedIndex = getToolCallIndex2(
|
|
17921
|
+
toolCall,
|
|
17922
|
+
typeof chunk.index === "number" ? chunk.index : index
|
|
17923
|
+
);
|
|
17924
|
+
if (!toolCallOrder.includes(normalizedIndex)) {
|
|
17925
|
+
toolCallOrder.push(normalizedIndex);
|
|
17926
|
+
}
|
|
17927
|
+
toolCallsByIndex[normalizedIndex] = {
|
|
17928
|
+
...toolCallsByIndex[normalizedIndex],
|
|
17929
|
+
...toolCall
|
|
17930
|
+
};
|
|
17931
|
+
}
|
|
17932
|
+
continue;
|
|
17933
|
+
}
|
|
17934
|
+
if (eventType === "tool-call-delta") {
|
|
17935
|
+
const toolCallDelta = isObject(chunk.delta) && isObject(chunk.delta.message) ? toToolCallArray(
|
|
17936
|
+
chunk.delta.message.toolCalls ?? chunk.delta.message.tool_calls
|
|
17937
|
+
) : [];
|
|
17938
|
+
if (toolCallDelta.length > 0) {
|
|
17939
|
+
const delta = toolCallDelta[0];
|
|
17940
|
+
const normalizedIndex = getToolCallIndex2(delta, chunk.index ?? 0);
|
|
17941
|
+
if (!toolCallOrder.includes(normalizedIndex)) {
|
|
17942
|
+
toolCallOrder.push(normalizedIndex);
|
|
17943
|
+
}
|
|
17944
|
+
toolCallsByIndex[normalizedIndex] = appendToolCallDelta(
|
|
17945
|
+
toolCallsByIndex[normalizedIndex],
|
|
17946
|
+
delta
|
|
17947
|
+
);
|
|
17948
|
+
}
|
|
17949
|
+
continue;
|
|
17950
|
+
}
|
|
17951
|
+
if (eventType === "message-end" && isObject(chunk.delta)) {
|
|
17952
|
+
const delta = chunk.delta;
|
|
17953
|
+
if (typeof delta.finishReason === "string") {
|
|
17954
|
+
finishReason = delta.finishReason;
|
|
17955
|
+
} else if (typeof delta.finish_reason === "string") {
|
|
17956
|
+
finishReason = delta.finish_reason;
|
|
17957
|
+
}
|
|
17958
|
+
if (delta.error !== void 0) {
|
|
17959
|
+
metadata.error = delta.error;
|
|
17960
|
+
}
|
|
17961
|
+
metrics = {
|
|
17962
|
+
...metrics,
|
|
17963
|
+
...parseCohereMetricsFromUsage(delta.usage)
|
|
17964
|
+
};
|
|
17965
|
+
}
|
|
17966
|
+
}
|
|
17967
|
+
const mergedToolCalls = toolCallOrder.sort((left, right) => left - right).map((index) => toolCallsByIndex[index]).filter((toolCall) => isObject(toolCall));
|
|
17968
|
+
let output = extractCohereChatOutput(terminalResponse);
|
|
17969
|
+
if (output === void 0) {
|
|
17970
|
+
const mergedText = textDeltas.join("");
|
|
17971
|
+
if (mergedToolCalls.length > 0 || role || mergedText.length > 0) {
|
|
17972
|
+
output = {
|
|
17973
|
+
...role ? { role } : {},
|
|
17974
|
+
...mergedText.length > 0 ? { content: mergedText } : {},
|
|
17975
|
+
...mergedToolCalls.length > 0 ? { toolCalls: mergedToolCalls } : {}
|
|
17976
|
+
};
|
|
17977
|
+
}
|
|
17978
|
+
}
|
|
17979
|
+
if (finishReason) {
|
|
17980
|
+
metadata = {
|
|
17981
|
+
...metadata,
|
|
17982
|
+
finish_reason: finishReason
|
|
17983
|
+
};
|
|
17984
|
+
}
|
|
17985
|
+
return {
|
|
17986
|
+
metadata,
|
|
17987
|
+
metrics,
|
|
17988
|
+
output
|
|
17989
|
+
};
|
|
17990
|
+
}
|
|
17991
|
+
|
|
17992
|
+
// src/instrumentation/braintrust-plugin.ts
|
|
17993
|
+
var BraintrustPlugin = class extends BasePlugin {
|
|
17994
|
+
config;
|
|
17995
|
+
openaiPlugin = null;
|
|
17996
|
+
anthropicPlugin = null;
|
|
17997
|
+
aiSDKPlugin = null;
|
|
17998
|
+
claudeAgentSDKPlugin = null;
|
|
17999
|
+
googleGenAIPlugin = null;
|
|
18000
|
+
huggingFacePlugin = null;
|
|
18001
|
+
openRouterPlugin = null;
|
|
18002
|
+
openRouterAgentPlugin = null;
|
|
18003
|
+
mistralPlugin = null;
|
|
18004
|
+
googleADKPlugin = null;
|
|
18005
|
+
coherePlugin = null;
|
|
18006
|
+
constructor(config = {}) {
|
|
18007
|
+
super();
|
|
18008
|
+
this.config = config;
|
|
18009
|
+
}
|
|
18010
|
+
onEnable() {
|
|
18011
|
+
const integrations = this.config.integrations || {};
|
|
18012
|
+
if (integrations.openai !== false) {
|
|
18013
|
+
this.openaiPlugin = new OpenAIPlugin();
|
|
18014
|
+
this.openaiPlugin.enable();
|
|
18015
|
+
}
|
|
18016
|
+
if (integrations.anthropic !== false) {
|
|
18017
|
+
this.anthropicPlugin = new AnthropicPlugin();
|
|
18018
|
+
this.anthropicPlugin.enable();
|
|
18019
|
+
}
|
|
18020
|
+
if (integrations.aisdk !== false && integrations.vercel !== false) {
|
|
18021
|
+
this.aiSDKPlugin = new AISDKPlugin();
|
|
18022
|
+
this.aiSDKPlugin.enable();
|
|
18023
|
+
}
|
|
18024
|
+
if (integrations.claudeAgentSDK !== false) {
|
|
18025
|
+
this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
|
|
18026
|
+
this.claudeAgentSDKPlugin.enable();
|
|
18027
|
+
}
|
|
18028
|
+
if (integrations.googleGenAI !== false && integrations.google !== false) {
|
|
18029
|
+
this.googleGenAIPlugin = new GoogleGenAIPlugin();
|
|
18030
|
+
this.googleGenAIPlugin.enable();
|
|
18031
|
+
}
|
|
18032
|
+
if (integrations.huggingface !== false) {
|
|
18033
|
+
this.huggingFacePlugin = new HuggingFacePlugin();
|
|
18034
|
+
this.huggingFacePlugin.enable();
|
|
18035
|
+
}
|
|
18036
|
+
if (integrations.openrouter !== false) {
|
|
18037
|
+
this.openRouterPlugin = new OpenRouterPlugin();
|
|
18038
|
+
this.openRouterPlugin.enable();
|
|
18039
|
+
}
|
|
18040
|
+
if (integrations.openrouterAgent !== false) {
|
|
18041
|
+
this.openRouterAgentPlugin = new OpenRouterAgentPlugin();
|
|
18042
|
+
this.openRouterAgentPlugin.enable();
|
|
18043
|
+
}
|
|
18044
|
+
if (integrations.mistral !== false) {
|
|
18045
|
+
this.mistralPlugin = new MistralPlugin();
|
|
18046
|
+
this.mistralPlugin.enable();
|
|
18047
|
+
}
|
|
18048
|
+
if (integrations.googleADK !== false) {
|
|
18049
|
+
this.googleADKPlugin = new GoogleADKPlugin();
|
|
18050
|
+
this.googleADKPlugin.enable();
|
|
18051
|
+
}
|
|
18052
|
+
if (integrations.cohere !== false) {
|
|
18053
|
+
this.coherePlugin = new CoherePlugin();
|
|
18054
|
+
this.coherePlugin.enable();
|
|
18055
|
+
}
|
|
18056
|
+
}
|
|
18057
|
+
onDisable() {
|
|
18058
|
+
if (this.openaiPlugin) {
|
|
18059
|
+
this.openaiPlugin.disable();
|
|
18060
|
+
this.openaiPlugin = null;
|
|
18061
|
+
}
|
|
18062
|
+
if (this.anthropicPlugin) {
|
|
18063
|
+
this.anthropicPlugin.disable();
|
|
18064
|
+
this.anthropicPlugin = null;
|
|
18065
|
+
}
|
|
18066
|
+
if (this.aiSDKPlugin) {
|
|
18067
|
+
this.aiSDKPlugin.disable();
|
|
18068
|
+
this.aiSDKPlugin = null;
|
|
18069
|
+
}
|
|
18070
|
+
if (this.claudeAgentSDKPlugin) {
|
|
18071
|
+
this.claudeAgentSDKPlugin.disable();
|
|
18072
|
+
this.claudeAgentSDKPlugin = null;
|
|
18073
|
+
}
|
|
18074
|
+
if (this.googleGenAIPlugin) {
|
|
18075
|
+
this.googleGenAIPlugin.disable();
|
|
18076
|
+
this.googleGenAIPlugin = null;
|
|
18077
|
+
}
|
|
18078
|
+
if (this.huggingFacePlugin) {
|
|
18079
|
+
this.huggingFacePlugin.disable();
|
|
18080
|
+
this.huggingFacePlugin = null;
|
|
18081
|
+
}
|
|
18082
|
+
if (this.openRouterPlugin) {
|
|
18083
|
+
this.openRouterPlugin.disable();
|
|
18084
|
+
this.openRouterPlugin = null;
|
|
18085
|
+
}
|
|
18086
|
+
if (this.openRouterAgentPlugin) {
|
|
18087
|
+
this.openRouterAgentPlugin.disable();
|
|
18088
|
+
this.openRouterAgentPlugin = null;
|
|
18089
|
+
}
|
|
18090
|
+
if (this.mistralPlugin) {
|
|
18091
|
+
this.mistralPlugin.disable();
|
|
18092
|
+
this.mistralPlugin = null;
|
|
18093
|
+
}
|
|
18094
|
+
if (this.googleADKPlugin) {
|
|
18095
|
+
this.googleADKPlugin.disable();
|
|
18096
|
+
this.googleADKPlugin = null;
|
|
18097
|
+
}
|
|
18098
|
+
if (this.coherePlugin) {
|
|
18099
|
+
this.coherePlugin.disable();
|
|
18100
|
+
this.coherePlugin = null;
|
|
15229
18101
|
}
|
|
15230
18102
|
}
|
|
15231
18103
|
};
|
|
@@ -15298,10 +18170,12 @@ var PluginRegistry = class {
|
|
|
15298
18170
|
vercel: true,
|
|
15299
18171
|
aisdk: true,
|
|
15300
18172
|
google: true,
|
|
18173
|
+
huggingface: true,
|
|
15301
18174
|
claudeAgentSDK: true,
|
|
15302
18175
|
openrouter: true,
|
|
15303
18176
|
openrouterAgent: true,
|
|
15304
|
-
mistral: true
|
|
18177
|
+
mistral: true,
|
|
18178
|
+
cohere: true
|
|
15305
18179
|
};
|
|
15306
18180
|
}
|
|
15307
18181
|
/**
|