braintrust 3.21.0 → 3.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -0
- package/dev/dist/index.d.mts +1030 -1
- package/dev/dist/index.d.ts +1030 -1
- package/dev/dist/index.js +1429 -663
- package/dev/dist/index.mjs +811 -45
- package/dist/apply-auto-instrumentation.js +222 -186
- package/dist/apply-auto-instrumentation.mjs +37 -1
- package/dist/auto-instrumentations/bundler/esbuild.cjs +53 -1
- package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
- package/dist/auto-instrumentations/bundler/next.cjs +53 -1
- package/dist/auto-instrumentations/bundler/next.mjs +3 -3
- package/dist/auto-instrumentations/bundler/rollup.cjs +53 -1
- package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
- package/dist/auto-instrumentations/bundler/vite.cjs +53 -1
- package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
- package/dist/auto-instrumentations/bundler/webpack-loader.cjs +53 -1
- package/dist/auto-instrumentations/bundler/webpack.cjs +53 -1
- package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
- package/dist/auto-instrumentations/{chunk-TKRPRPGD.mjs → chunk-EXY7QCJD.mjs} +5 -2
- package/dist/auto-instrumentations/{chunk-T6J4C7LX.mjs → chunk-KIMLYPRW.mjs} +1 -1
- package/dist/auto-instrumentations/{chunk-BRQX23KL.mjs → chunk-YXLNSAMJ.mjs} +51 -0
- package/dist/auto-instrumentations/hook.mjs +224 -31
- package/dist/auto-instrumentations/index.cjs +52 -0
- package/dist/auto-instrumentations/index.d.mts +3 -1
- package/dist/auto-instrumentations/index.d.ts +3 -1
- package/dist/auto-instrumentations/index.mjs +3 -1
- package/dist/browser.d.mts +3273 -93
- package/dist/browser.d.ts +3273 -93
- package/dist/browser.js +2495 -63
- package/dist/browser.mjs +2495 -63
- package/dist/{chunk-KMGUTPB7.mjs → chunk-36IPYKMG.mjs} +20 -1
- package/dist/{chunk-BFGIH2ZJ.js → chunk-CDIKAHDZ.js} +21 -2
- package/dist/{chunk-FY7DAKA5.js → chunk-FZWPFCVE.js} +1590 -832
- package/dist/{chunk-O2P765XK.mjs → chunk-IXL4PMY4.mjs} +802 -44
- package/dist/cli.js +816 -47
- package/dist/edge-light.d.mts +1 -1
- package/dist/edge-light.d.ts +1 -1
- package/dist/edge-light.js +2495 -63
- package/dist/edge-light.mjs +2495 -63
- package/dist/index.d.mts +3273 -93
- package/dist/index.d.ts +3273 -93
- package/dist/index.js +2078 -416
- package/dist/index.mjs +1664 -2
- package/dist/instrumentation/index.d.mts +912 -2
- package/dist/instrumentation/index.d.ts +912 -2
- package/dist/instrumentation/index.js +2202 -42
- package/dist/instrumentation/index.mjs +2200 -42
- package/dist/vitest-evals-reporter.js +16 -16
- package/dist/vitest-evals-reporter.mjs +2 -2
- package/dist/workerd.d.mts +1 -1
- package/dist/workerd.d.ts +1 -1
- package/dist/workerd.js +2495 -63
- package/dist/workerd.mjs +2495 -63
- package/package.json +5 -2
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
isInstrumentationIntegrationDisabled,
|
|
19
19
|
isomorph_default,
|
|
20
20
|
langChainChannels,
|
|
21
|
+
langSmithChannels,
|
|
21
22
|
mistralChannels,
|
|
22
23
|
openAIAgentsCoreChannels,
|
|
23
24
|
openAIChannels,
|
|
@@ -30,7 +31,7 @@ import {
|
|
|
30
31
|
smithyClientChannels,
|
|
31
32
|
smithyCoreChannels,
|
|
32
33
|
strandsAgentSDKChannels
|
|
33
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-36IPYKMG.mjs";
|
|
34
35
|
|
|
35
36
|
// src/id-gen.ts
|
|
36
37
|
import { v4 as uuidv4 } from "uuid";
|
|
@@ -2064,19 +2065,30 @@ var CallEvent = z6.union([
|
|
|
2064
2065
|
var ChatCompletionContentPartTextWithTitle = z6.object({
|
|
2065
2066
|
text: z6.string().default(""),
|
|
2066
2067
|
type: z6.literal("text"),
|
|
2067
|
-
cache_control: z6.object({
|
|
2068
|
+
cache_control: z6.object({
|
|
2069
|
+
type: z6.literal("ephemeral"),
|
|
2070
|
+
ttl: z6.enum(["5m", "1h"]).optional()
|
|
2071
|
+
}).optional()
|
|
2068
2072
|
});
|
|
2069
2073
|
var ChatCompletionContentPartImageWithTitle = z6.object({
|
|
2070
2074
|
image_url: z6.object({
|
|
2071
2075
|
url: z6.string(),
|
|
2072
2076
|
detail: z6.union([z6.literal("auto"), z6.literal("low"), z6.literal("high")]).optional()
|
|
2073
2077
|
}),
|
|
2074
|
-
type: z6.literal("image_url")
|
|
2078
|
+
type: z6.literal("image_url"),
|
|
2079
|
+
cache_control: z6.object({
|
|
2080
|
+
type: z6.literal("ephemeral"),
|
|
2081
|
+
ttl: z6.enum(["5m", "1h"]).optional()
|
|
2082
|
+
}).optional()
|
|
2075
2083
|
});
|
|
2076
2084
|
var ChatCompletionContentPartFileFile = z6.object({ file_data: z6.string(), filename: z6.string(), file_id: z6.string() }).partial();
|
|
2077
2085
|
var ChatCompletionContentPartFileWithTitle = z6.object({
|
|
2078
2086
|
file: ChatCompletionContentPartFileFile,
|
|
2079
|
-
type: z6.literal("file")
|
|
2087
|
+
type: z6.literal("file"),
|
|
2088
|
+
cache_control: z6.object({
|
|
2089
|
+
type: z6.literal("ephemeral"),
|
|
2090
|
+
ttl: z6.enum(["5m", "1h"]).optional()
|
|
2091
|
+
}).optional()
|
|
2080
2092
|
});
|
|
2081
2093
|
var ChatCompletionContentPart = z6.union([
|
|
2082
2094
|
ChatCompletionContentPartTextWithTitle,
|
|
@@ -2086,7 +2098,10 @@ var ChatCompletionContentPart = z6.union([
|
|
|
2086
2098
|
var ChatCompletionContentPartText = z6.object({
|
|
2087
2099
|
text: z6.string().default(""),
|
|
2088
2100
|
type: z6.literal("text"),
|
|
2089
|
-
cache_control: z6.object({
|
|
2101
|
+
cache_control: z6.object({
|
|
2102
|
+
type: z6.literal("ephemeral"),
|
|
2103
|
+
ttl: z6.enum(["5m", "1h"]).optional()
|
|
2104
|
+
}).optional()
|
|
2090
2105
|
});
|
|
2091
2106
|
var ChatCompletionMessageToolCall = z6.object({
|
|
2092
2107
|
id: z6.string(),
|
|
@@ -4180,7 +4195,7 @@ var DiskCache = class {
|
|
|
4180
4195
|
}
|
|
4181
4196
|
};
|
|
4182
4197
|
|
|
4183
|
-
// src/
|
|
4198
|
+
// src/lru-cache.ts
|
|
4184
4199
|
var LRUCache = class {
|
|
4185
4200
|
cache;
|
|
4186
4201
|
maxSize;
|
|
@@ -4196,13 +4211,23 @@ var LRUCache = class {
|
|
|
4196
4211
|
* @returns The cached value if found, undefined otherwise.
|
|
4197
4212
|
*/
|
|
4198
4213
|
get(key) {
|
|
4199
|
-
const
|
|
4200
|
-
if (
|
|
4214
|
+
const entry = this.cache.get(key);
|
|
4215
|
+
if (entry === void 0) {
|
|
4201
4216
|
return void 0;
|
|
4202
4217
|
}
|
|
4203
4218
|
this.cache.delete(key);
|
|
4204
|
-
this.cache.set(key,
|
|
4205
|
-
return value;
|
|
4219
|
+
this.cache.set(key, entry);
|
|
4220
|
+
return entry.value;
|
|
4221
|
+
}
|
|
4222
|
+
/**
|
|
4223
|
+
* Checks whether a key exists and marks it as most recently used.
|
|
4224
|
+
*/
|
|
4225
|
+
has(key) {
|
|
4226
|
+
if (!this.cache.has(key)) {
|
|
4227
|
+
return false;
|
|
4228
|
+
}
|
|
4229
|
+
this.get(key);
|
|
4230
|
+
return true;
|
|
4206
4231
|
}
|
|
4207
4232
|
/**
|
|
4208
4233
|
* Stores a value in the cache.
|
|
@@ -4219,7 +4244,38 @@ var LRUCache = class {
|
|
|
4219
4244
|
const first = this.cache.keys().next().value;
|
|
4220
4245
|
this.cache.delete(first);
|
|
4221
4246
|
}
|
|
4222
|
-
this.cache.set(key, value);
|
|
4247
|
+
this.cache.set(key, { value });
|
|
4248
|
+
}
|
|
4249
|
+
/**
|
|
4250
|
+
* Removes an item from the cache.
|
|
4251
|
+
*/
|
|
4252
|
+
delete(key) {
|
|
4253
|
+
return this.cache.delete(key);
|
|
4254
|
+
}
|
|
4255
|
+
/**
|
|
4256
|
+
* Iterates over cache entries from least to most recently used.
|
|
4257
|
+
*/
|
|
4258
|
+
*entries() {
|
|
4259
|
+
for (const [key, entry] of this.cache) {
|
|
4260
|
+
yield [key, entry.value];
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4263
|
+
/**
|
|
4264
|
+
* Iterates over cache keys from least to most recently used.
|
|
4265
|
+
*/
|
|
4266
|
+
keys() {
|
|
4267
|
+
return this.cache.keys();
|
|
4268
|
+
}
|
|
4269
|
+
/**
|
|
4270
|
+
* Iterates over cache values from least to most recently used.
|
|
4271
|
+
*/
|
|
4272
|
+
*values() {
|
|
4273
|
+
for (const entry of this.cache.values()) {
|
|
4274
|
+
yield entry.value;
|
|
4275
|
+
}
|
|
4276
|
+
}
|
|
4277
|
+
[Symbol.iterator]() {
|
|
4278
|
+
return this.entries();
|
|
4223
4279
|
}
|
|
4224
4280
|
/**
|
|
4225
4281
|
* Removes all items from the cache.
|
|
@@ -4777,6 +4833,9 @@ function applyMaskingToField(maskingFunction, data, fieldName) {
|
|
|
4777
4833
|
return `ERROR: Failed to mask field '${fieldName}' - ${errorType}`;
|
|
4778
4834
|
}
|
|
4779
4835
|
}
|
|
4836
|
+
var INITIAL_SPAN_WRITE_AS_MERGE = /* @__PURE__ */ Symbol(
|
|
4837
|
+
"braintrust.initial-span-write-as-merge"
|
|
4838
|
+
);
|
|
4780
4839
|
var BRAINTRUST_CURRENT_SPAN_STORE = /* @__PURE__ */ Symbol.for(
|
|
4781
4840
|
"braintrust.currentSpanStore"
|
|
4782
4841
|
);
|
|
@@ -5378,25 +5437,46 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
5378
5437
|
})
|
|
5379
5438
|
);
|
|
5380
5439
|
}
|
|
5381
|
-
async post(path2, params, config) {
|
|
5440
|
+
async post(path2, params, config, retries = 0) {
|
|
5382
5441
|
const { headers, ...rest } = config || {};
|
|
5383
5442
|
const this_fetch = this.fetch;
|
|
5384
5443
|
const this_base_url = this.base_url;
|
|
5385
5444
|
const this_headers = this.headers;
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5445
|
+
const tries = retries + 1;
|
|
5446
|
+
for (let i = 0; i < tries; i++) {
|
|
5447
|
+
try {
|
|
5448
|
+
return await checkResponse(
|
|
5449
|
+
await this_fetch(_urljoin(this_base_url, path2), {
|
|
5450
|
+
method: "POST",
|
|
5451
|
+
headers: {
|
|
5452
|
+
Accept: "application/json",
|
|
5453
|
+
"Content-Type": "application/json",
|
|
5454
|
+
...this_headers,
|
|
5455
|
+
...headers
|
|
5456
|
+
},
|
|
5457
|
+
body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
|
|
5458
|
+
keepalive: true,
|
|
5459
|
+
...rest
|
|
5460
|
+
})
|
|
5461
|
+
);
|
|
5462
|
+
} catch (error) {
|
|
5463
|
+
if (config?.signal?.aborted) {
|
|
5464
|
+
throw getAbortReason(config.signal);
|
|
5465
|
+
}
|
|
5466
|
+
if (i === tries - 1 || !isRetryableHTTPError(error)) {
|
|
5467
|
+
throw error;
|
|
5468
|
+
}
|
|
5469
|
+
debugLogger.debug(
|
|
5470
|
+
`Retrying API request ${path2} after ${formatHTTPError(error)}`
|
|
5471
|
+
);
|
|
5472
|
+
const sleepTimeMs = HTTP_RETRY_BASE_SLEEP_TIME_S * 1e3 * 2 ** i + Math.random() * HTTP_RETRY_JITTER_MS;
|
|
5473
|
+
debugLogger.info(
|
|
5474
|
+
`Sleeping for ${sleepTimeMs}ms before retrying API request`
|
|
5475
|
+
);
|
|
5476
|
+
await waitForRetry(sleepTimeMs, config?.signal);
|
|
5477
|
+
}
|
|
5478
|
+
}
|
|
5479
|
+
throw new Error("Unexpected retry state");
|
|
5400
5480
|
}
|
|
5401
5481
|
async get_json(object_type, args = void 0, retries = 0) {
|
|
5402
5482
|
const tries = retries + 1;
|
|
@@ -6493,6 +6573,45 @@ var TestBackgroundLogger = class {
|
|
|
6493
6573
|
};
|
|
6494
6574
|
var BACKGROUND_LOGGER_BASE_SLEEP_TIME_S = 1;
|
|
6495
6575
|
var HTTP_RETRY_BASE_SLEEP_TIME_S = 1;
|
|
6576
|
+
var HTTP_RETRY_JITTER_MS = 200;
|
|
6577
|
+
var BTQL_HTTP_RETRIES = 3;
|
|
6578
|
+
var RETRYABLE_HTTP_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
|
|
6579
|
+
function isRetryableHTTPError(error) {
|
|
6580
|
+
return !(error instanceof FailedHTTPResponse) || RETRYABLE_HTTP_STATUS_CODES.has(error.status);
|
|
6581
|
+
}
|
|
6582
|
+
function formatHTTPError(error) {
|
|
6583
|
+
if (error instanceof FailedHTTPResponse) {
|
|
6584
|
+
return `${error.status} ${error.text}`;
|
|
6585
|
+
}
|
|
6586
|
+
return error instanceof Error ? error.message : String(error);
|
|
6587
|
+
}
|
|
6588
|
+
function getAbortReason(signal) {
|
|
6589
|
+
return signal.reason ?? new Error("Request aborted");
|
|
6590
|
+
}
|
|
6591
|
+
async function waitForRetry(delayMs, signal) {
|
|
6592
|
+
if (!signal) {
|
|
6593
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
6594
|
+
return;
|
|
6595
|
+
}
|
|
6596
|
+
if (signal.aborted) {
|
|
6597
|
+
throw getAbortReason(signal);
|
|
6598
|
+
}
|
|
6599
|
+
await new Promise((resolve, reject) => {
|
|
6600
|
+
const onAbort = () => {
|
|
6601
|
+
clearTimeout(timeout);
|
|
6602
|
+
signal.removeEventListener("abort", onAbort);
|
|
6603
|
+
reject(getAbortReason(signal));
|
|
6604
|
+
};
|
|
6605
|
+
const timeout = setTimeout(() => {
|
|
6606
|
+
signal.removeEventListener("abort", onAbort);
|
|
6607
|
+
resolve();
|
|
6608
|
+
}, delayMs);
|
|
6609
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
6610
|
+
if (signal.aborted) {
|
|
6611
|
+
onAbort();
|
|
6612
|
+
}
|
|
6613
|
+
});
|
|
6614
|
+
}
|
|
6496
6615
|
var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
|
|
6497
6616
|
apiConn;
|
|
6498
6617
|
queue;
|
|
@@ -8231,15 +8350,15 @@ function parentSpanIdsUsable(spanId, rootSpanId) {
|
|
|
8231
8350
|
return Boolean(spanId) && Boolean(rootSpanId);
|
|
8232
8351
|
}
|
|
8233
8352
|
function logError(span, error) {
|
|
8234
|
-
let
|
|
8353
|
+
let errorMessage2 = "<error>";
|
|
8235
8354
|
let stackTrace = "";
|
|
8236
8355
|
if (error instanceof Error) {
|
|
8237
|
-
|
|
8356
|
+
errorMessage2 = error.message;
|
|
8238
8357
|
stackTrace = error.stack || "";
|
|
8239
8358
|
} else {
|
|
8240
|
-
|
|
8359
|
+
errorMessage2 = String(error);
|
|
8241
8360
|
}
|
|
8242
|
-
span.log({ error: `${
|
|
8361
|
+
span.log({ error: `${errorMessage2}
|
|
8243
8362
|
|
|
8244
8363
|
${stackTrace}` });
|
|
8245
8364
|
}
|
|
@@ -8427,6 +8546,12 @@ var traceable = wrapTraced;
|
|
|
8427
8546
|
function startSpan(args) {
|
|
8428
8547
|
return startSpanAndIsLogger(args).span;
|
|
8429
8548
|
}
|
|
8549
|
+
function _internalStartSpanWithInitialMerge(args) {
|
|
8550
|
+
return startSpanAndIsLogger({
|
|
8551
|
+
...args,
|
|
8552
|
+
[INITIAL_SPAN_WRITE_AS_MERGE]: true
|
|
8553
|
+
}).span;
|
|
8554
|
+
}
|
|
8430
8555
|
async function flush(options) {
|
|
8431
8556
|
const state = options?.state ?? _globalState;
|
|
8432
8557
|
return await state.bgLogger().flush();
|
|
@@ -8820,7 +8945,8 @@ var ObjectFetcher = class {
|
|
|
8820
8945
|
version: this.pinnedVersion
|
|
8821
8946
|
} : {}
|
|
8822
8947
|
},
|
|
8823
|
-
{ headers: { "Accept-Encoding": "gzip" } }
|
|
8948
|
+
{ headers: { "Accept-Encoding": "gzip" } },
|
|
8949
|
+
BTQL_HTTP_RETRIES
|
|
8824
8950
|
);
|
|
8825
8951
|
const respJson = await resp.json();
|
|
8826
8952
|
const mutate = this.mutateRecord;
|
|
@@ -9337,7 +9463,7 @@ var SpanImpl = class _SpanImpl {
|
|
|
9337
9463
|
this._spanId = resolvedIds.spanId;
|
|
9338
9464
|
this._rootSpanId = resolvedIds.rootSpanId;
|
|
9339
9465
|
this._spanParents = resolvedIds.spanParents;
|
|
9340
|
-
this.isMerge =
|
|
9466
|
+
this.isMerge = args[INITIAL_SPAN_WRITE_AS_MERGE] === true;
|
|
9341
9467
|
this.logInternal({ event, internalData });
|
|
9342
9468
|
this.isMerge = true;
|
|
9343
9469
|
}
|
|
@@ -10544,7 +10670,8 @@ async function getPromptVersions(projectId, promptId) {
|
|
|
10544
10670
|
use_columnstore: false,
|
|
10545
10671
|
brainstore_realtime: true
|
|
10546
10672
|
},
|
|
10547
|
-
{ headers: { "Accept-Encoding": "gzip" } }
|
|
10673
|
+
{ headers: { "Accept-Encoding": "gzip" } },
|
|
10674
|
+
BTQL_HTTP_RETRIES
|
|
10548
10675
|
);
|
|
10549
10676
|
if (!response.ok) {
|
|
10550
10677
|
throw new Error(
|
|
@@ -28493,6 +28620,430 @@ function isBraintrustHandler(handler) {
|
|
|
28493
28620
|
return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
|
|
28494
28621
|
}
|
|
28495
28622
|
|
|
28623
|
+
// src/instrumentation/plugins/langsmith-plugin.ts
|
|
28624
|
+
var MAX_COMPLETED_RUNS = 1e4;
|
|
28625
|
+
var BLOCKED_METADATA_KEYS = /* @__PURE__ */ new Set([
|
|
28626
|
+
"__proto__",
|
|
28627
|
+
"constructor",
|
|
28628
|
+
"prototype",
|
|
28629
|
+
"usage_metadata"
|
|
28630
|
+
]);
|
|
28631
|
+
var BLOCKED_METADATA_PREFIXES = ["__pregel_", "langgraph_", "lc_"];
|
|
28632
|
+
var LLM_SETTING_KEYS = [
|
|
28633
|
+
"temperature",
|
|
28634
|
+
"top_p",
|
|
28635
|
+
"max_tokens",
|
|
28636
|
+
"frequency_penalty",
|
|
28637
|
+
"presence_penalty",
|
|
28638
|
+
"stop",
|
|
28639
|
+
"response_format"
|
|
28640
|
+
];
|
|
28641
|
+
var LangSmithPlugin = class extends BasePlugin {
|
|
28642
|
+
activeRuns = /* @__PURE__ */ new Map();
|
|
28643
|
+
completedRuns = new LRUCache({
|
|
28644
|
+
max: MAX_COMPLETED_RUNS
|
|
28645
|
+
});
|
|
28646
|
+
skipLangChainRuns;
|
|
28647
|
+
constructor(options = {}) {
|
|
28648
|
+
super();
|
|
28649
|
+
this.skipLangChainRuns = options.skipLangChainRuns ?? true;
|
|
28650
|
+
}
|
|
28651
|
+
onEnable() {
|
|
28652
|
+
const createChannel = langSmithChannels.createRun.tracingChannel();
|
|
28653
|
+
const createHandlers = {
|
|
28654
|
+
start: (event) => {
|
|
28655
|
+
this.containLifecycleFailure("createRun", () => {
|
|
28656
|
+
this.processCreate(event.arguments[0]);
|
|
28657
|
+
});
|
|
28658
|
+
}
|
|
28659
|
+
};
|
|
28660
|
+
createChannel.subscribe(createHandlers);
|
|
28661
|
+
this.unsubscribers.push(() => createChannel.unsubscribe(createHandlers));
|
|
28662
|
+
const updateChannel = langSmithChannels.updateRun.tracingChannel();
|
|
28663
|
+
const updateHandlers = {
|
|
28664
|
+
start: (event) => {
|
|
28665
|
+
this.containLifecycleFailure("updateRun", () => {
|
|
28666
|
+
this.processUpdate(event.arguments[0], event.arguments[1]);
|
|
28667
|
+
});
|
|
28668
|
+
}
|
|
28669
|
+
};
|
|
28670
|
+
updateChannel.subscribe(updateHandlers);
|
|
28671
|
+
this.unsubscribers.push(() => updateChannel.unsubscribe(updateHandlers));
|
|
28672
|
+
const batchChannel = langSmithChannels.batchIngestRuns.tracingChannel();
|
|
28673
|
+
const batchHandlers = {
|
|
28674
|
+
start: (event) => {
|
|
28675
|
+
this.containLifecycleFailure("batchIngestRuns", () => {
|
|
28676
|
+
this.processBatch(event.arguments[0]);
|
|
28677
|
+
});
|
|
28678
|
+
}
|
|
28679
|
+
};
|
|
28680
|
+
batchChannel.subscribe(batchHandlers);
|
|
28681
|
+
this.unsubscribers.push(() => batchChannel.unsubscribe(batchHandlers));
|
|
28682
|
+
}
|
|
28683
|
+
onDisable() {
|
|
28684
|
+
this.unsubscribers = unsubscribeAll(this.unsubscribers);
|
|
28685
|
+
for (const { span } of this.activeRuns.values()) {
|
|
28686
|
+
span.end();
|
|
28687
|
+
}
|
|
28688
|
+
this.activeRuns.clear();
|
|
28689
|
+
this.completedRuns.clear();
|
|
28690
|
+
}
|
|
28691
|
+
processBatch(batch) {
|
|
28692
|
+
if (!isRecord2(batch)) {
|
|
28693
|
+
return;
|
|
28694
|
+
}
|
|
28695
|
+
const creates = ownValue(batch, "runCreates");
|
|
28696
|
+
if (Array.isArray(creates)) {
|
|
28697
|
+
const parentFirst = [...creates].sort((left, right) => {
|
|
28698
|
+
const leftId = stringValue2(ownValue(left, "id"));
|
|
28699
|
+
const rightId = stringValue2(ownValue(right, "id"));
|
|
28700
|
+
const leftParent = stringValue2(ownValue(left, "parent_run_id"));
|
|
28701
|
+
const rightParent = stringValue2(ownValue(right, "parent_run_id"));
|
|
28702
|
+
if (leftParent && leftParent === rightId) {
|
|
28703
|
+
return 1;
|
|
28704
|
+
}
|
|
28705
|
+
if (rightParent && rightParent === leftId) {
|
|
28706
|
+
return -1;
|
|
28707
|
+
}
|
|
28708
|
+
return dottedOrderDepth(left) - dottedOrderDepth(right);
|
|
28709
|
+
});
|
|
28710
|
+
for (const run of parentFirst) {
|
|
28711
|
+
this.containLifecycleFailure("batchIngestRuns create", () => {
|
|
28712
|
+
this.processCreate(run);
|
|
28713
|
+
});
|
|
28714
|
+
}
|
|
28715
|
+
}
|
|
28716
|
+
const updates = ownValue(batch, "runUpdates");
|
|
28717
|
+
if (Array.isArray(updates)) {
|
|
28718
|
+
for (const run of updates) {
|
|
28719
|
+
this.containLifecycleFailure("batchIngestRuns update", () => {
|
|
28720
|
+
this.processUpdate(stringValue2(ownValue(run, "id")) ?? "", run);
|
|
28721
|
+
});
|
|
28722
|
+
}
|
|
28723
|
+
}
|
|
28724
|
+
}
|
|
28725
|
+
processCreate(run) {
|
|
28726
|
+
const id = stringValue2(ownValue(run, "id"));
|
|
28727
|
+
if (!id || this.completedRuns.get(id)) {
|
|
28728
|
+
return;
|
|
28729
|
+
}
|
|
28730
|
+
if (this.shouldSkipLangChainRun(run)) {
|
|
28731
|
+
this.completedRuns.set(id, true);
|
|
28732
|
+
return;
|
|
28733
|
+
}
|
|
28734
|
+
const active = this.activeRuns.get(id);
|
|
28735
|
+
if (active) {
|
|
28736
|
+
const previous = active.run;
|
|
28737
|
+
active.run = mergeRuns(previous, run);
|
|
28738
|
+
this.logRun(
|
|
28739
|
+
active.span,
|
|
28740
|
+
active.run,
|
|
28741
|
+
previous,
|
|
28742
|
+
timestampSeconds(ownValue(active.run, "end_time")) !== void 0 || errorMessage(ownValue(active.run, "error")) !== void 0
|
|
28743
|
+
);
|
|
28744
|
+
this.endIfComplete(id, active, active.run);
|
|
28745
|
+
return;
|
|
28746
|
+
}
|
|
28747
|
+
const span = this.startRunSpan(id, run);
|
|
28748
|
+
const activeRun = { run, span };
|
|
28749
|
+
this.activeRuns.set(id, activeRun);
|
|
28750
|
+
this.logRun(
|
|
28751
|
+
span,
|
|
28752
|
+
run,
|
|
28753
|
+
void 0,
|
|
28754
|
+
timestampSeconds(ownValue(run, "end_time")) !== void 0 || errorMessage(ownValue(run, "error")) !== void 0
|
|
28755
|
+
);
|
|
28756
|
+
this.endIfComplete(id, activeRun, run);
|
|
28757
|
+
}
|
|
28758
|
+
processUpdate(explicitId, run) {
|
|
28759
|
+
const id = stringValue2(explicitId) ?? stringValue2(ownValue(run, "id"));
|
|
28760
|
+
if (!id || this.completedRuns.get(id)) {
|
|
28761
|
+
return;
|
|
28762
|
+
}
|
|
28763
|
+
if (this.shouldSkipLangChainRun(run)) {
|
|
28764
|
+
const active2 = this.activeRuns.get(id);
|
|
28765
|
+
active2?.span.end();
|
|
28766
|
+
this.activeRuns.delete(id);
|
|
28767
|
+
this.completedRuns.set(id, true);
|
|
28768
|
+
return;
|
|
28769
|
+
}
|
|
28770
|
+
let active = this.activeRuns.get(id);
|
|
28771
|
+
if (!active) {
|
|
28772
|
+
const span = this.startRunSpan(id, run);
|
|
28773
|
+
active = { run, span };
|
|
28774
|
+
this.activeRuns.set(id, active);
|
|
28775
|
+
}
|
|
28776
|
+
const previous = active.run;
|
|
28777
|
+
active.run = mergeRuns(previous, run);
|
|
28778
|
+
this.logRun(active.span, active.run, previous, true);
|
|
28779
|
+
this.endIfComplete(id, active, active.run);
|
|
28780
|
+
}
|
|
28781
|
+
startRunSpan(id, run) {
|
|
28782
|
+
const traceId = stringValue2(ownValue(run, "trace_id")) ?? id;
|
|
28783
|
+
const parentId = stringValue2(ownValue(run, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run, "parent_run"), "id"));
|
|
28784
|
+
const startTime = timestampSeconds(ownValue(run, "start_time"));
|
|
28785
|
+
return startSpan({
|
|
28786
|
+
name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
|
|
28787
|
+
spanId: id,
|
|
28788
|
+
parentSpanIds: {
|
|
28789
|
+
parentSpanIds: parentId ? [parentId] : [],
|
|
28790
|
+
rootSpanId: traceId
|
|
28791
|
+
},
|
|
28792
|
+
spanAttributes: {
|
|
28793
|
+
type: mapRunType(ownValue(run, "run_type"))
|
|
28794
|
+
},
|
|
28795
|
+
...startTime === void 0 ? {} : { startTime },
|
|
28796
|
+
event: { id }
|
|
28797
|
+
});
|
|
28798
|
+
}
|
|
28799
|
+
logRun(span, run, previous, includeOutput) {
|
|
28800
|
+
const inputs = preferOwnValue(run, previous, "inputs");
|
|
28801
|
+
const outputs = preferOwnValue(run, previous, "outputs");
|
|
28802
|
+
const error = errorMessage(preferOwnValue(run, previous, "error"));
|
|
28803
|
+
const metadata = extractMetadata(run, previous);
|
|
28804
|
+
const tags = extractTags(preferOwnValue(run, previous, "tags"));
|
|
28805
|
+
const metrics = extractMetrics(run, previous);
|
|
28806
|
+
span.log({
|
|
28807
|
+
...inputs === void 0 ? {} : { input: sanitizeLoggedValue(inputs) },
|
|
28808
|
+
...includeOutput && outputs !== void 0 ? { output: sanitizeLoggedValue(outputs) } : {},
|
|
28809
|
+
...error === void 0 ? {} : { error },
|
|
28810
|
+
...metadata === void 0 ? {} : { metadata },
|
|
28811
|
+
...tags === void 0 ? {} : { tags },
|
|
28812
|
+
...Object.keys(metrics).length === 0 ? {} : { metrics }
|
|
28813
|
+
});
|
|
28814
|
+
}
|
|
28815
|
+
endIfComplete(id, active, run) {
|
|
28816
|
+
const endTime = timestampSeconds(ownValue(run, "end_time"));
|
|
28817
|
+
if (endTime === void 0 && errorMessage(ownValue(run, "error")) === void 0) {
|
|
28818
|
+
return;
|
|
28819
|
+
}
|
|
28820
|
+
active.span.end(endTime === void 0 ? void 0 : { endTime });
|
|
28821
|
+
this.activeRuns.delete(id);
|
|
28822
|
+
this.completedRuns.set(id, true);
|
|
28823
|
+
}
|
|
28824
|
+
shouldSkipLangChainRun(run) {
|
|
28825
|
+
if (!this.skipLangChainRuns) {
|
|
28826
|
+
return false;
|
|
28827
|
+
}
|
|
28828
|
+
const serialized = ownValue(run, "serialized");
|
|
28829
|
+
return isRecord2(serialized) && ownValue(serialized, "lc") === 1;
|
|
28830
|
+
}
|
|
28831
|
+
containLifecycleFailure(operation, fn) {
|
|
28832
|
+
try {
|
|
28833
|
+
fn();
|
|
28834
|
+
} catch (error) {
|
|
28835
|
+
debugLogger.error(
|
|
28836
|
+
`Failed to process LangSmith ${operation} instrumentation:`,
|
|
28837
|
+
error
|
|
28838
|
+
);
|
|
28839
|
+
}
|
|
28840
|
+
}
|
|
28841
|
+
};
|
|
28842
|
+
function ownValue(value, key) {
|
|
28843
|
+
if (!isRecord2(value)) {
|
|
28844
|
+
return void 0;
|
|
28845
|
+
}
|
|
28846
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
28847
|
+
return descriptor && "value" in descriptor ? descriptor.value : void 0;
|
|
28848
|
+
}
|
|
28849
|
+
function preferOwnValue(current, previous, key) {
|
|
28850
|
+
const currentDescriptor = isRecord2(current) ? Object.getOwnPropertyDescriptor(current, key) : void 0;
|
|
28851
|
+
if (currentDescriptor && "value" in currentDescriptor) {
|
|
28852
|
+
return currentDescriptor.value;
|
|
28853
|
+
}
|
|
28854
|
+
return ownValue(previous, key);
|
|
28855
|
+
}
|
|
28856
|
+
function mergeRuns(previous, current) {
|
|
28857
|
+
const entries = /* @__PURE__ */ new Map();
|
|
28858
|
+
for (const value of [previous, current]) {
|
|
28859
|
+
if (!isRecord2(value)) {
|
|
28860
|
+
continue;
|
|
28861
|
+
}
|
|
28862
|
+
for (const [key, descriptor] of Object.entries(
|
|
28863
|
+
Object.getOwnPropertyDescriptors(value)
|
|
28864
|
+
)) {
|
|
28865
|
+
if (descriptor.enumerable && "value" in descriptor) {
|
|
28866
|
+
entries.set(key, descriptor.value);
|
|
28867
|
+
}
|
|
28868
|
+
}
|
|
28869
|
+
}
|
|
28870
|
+
return Object.fromEntries(entries);
|
|
28871
|
+
}
|
|
28872
|
+
function isRecord2(value) {
|
|
28873
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28874
|
+
}
|
|
28875
|
+
function stringValue2(value) {
|
|
28876
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
28877
|
+
}
|
|
28878
|
+
function timestampSeconds(value) {
|
|
28879
|
+
if (value instanceof Date) {
|
|
28880
|
+
const timestamp = value.getTime();
|
|
28881
|
+
return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
|
|
28882
|
+
}
|
|
28883
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
|
|
28884
|
+
return value > 1e10 ? value / 1e3 : value;
|
|
28885
|
+
}
|
|
28886
|
+
if (typeof value === "string") {
|
|
28887
|
+
const timestamp = Date.parse(value);
|
|
28888
|
+
return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
|
|
28889
|
+
}
|
|
28890
|
+
return void 0;
|
|
28891
|
+
}
|
|
28892
|
+
function dottedOrderDepth(run) {
|
|
28893
|
+
const dottedOrder = stringValue2(ownValue(run, "dotted_order"));
|
|
28894
|
+
return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
|
|
28895
|
+
}
|
|
28896
|
+
function mapRunType(runType) {
|
|
28897
|
+
switch (runType) {
|
|
28898
|
+
case "llm":
|
|
28899
|
+
case "embedding":
|
|
28900
|
+
return "llm" /* LLM */;
|
|
28901
|
+
case "tool":
|
|
28902
|
+
case "retriever":
|
|
28903
|
+
return "tool" /* TOOL */;
|
|
28904
|
+
default:
|
|
28905
|
+
return "task" /* TASK */;
|
|
28906
|
+
}
|
|
28907
|
+
}
|
|
28908
|
+
function extractMetadata(run, previous) {
|
|
28909
|
+
const extra = preferOwnValue(run, previous, "extra");
|
|
28910
|
+
const rawMetadata = ownValue(extra, "metadata");
|
|
28911
|
+
if (!isRecord2(rawMetadata)) {
|
|
28912
|
+
return void 0;
|
|
28913
|
+
}
|
|
28914
|
+
const metadata = {};
|
|
28915
|
+
for (const [key, descriptor] of Object.entries(
|
|
28916
|
+
Object.getOwnPropertyDescriptors(rawMetadata)
|
|
28917
|
+
)) {
|
|
28918
|
+
if (!("value" in descriptor) || !descriptor.enumerable || BLOCKED_METADATA_KEYS.has(key) || BLOCKED_METADATA_PREFIXES.some((prefix) => key.startsWith(prefix)) || key.startsWith("ls_") && key !== "ls_provider" && key !== "ls_model_name" && !LLM_SETTING_KEYS.some((setting) => key === `ls_${setting}`)) {
|
|
28919
|
+
continue;
|
|
28920
|
+
}
|
|
28921
|
+
const normalizedKey = key === "ls_provider" ? "provider" : key === "ls_model_name" ? "model" : key.startsWith("ls_") ? key.slice(3) : key;
|
|
28922
|
+
const sanitized = sanitizeLoggedValue(descriptor.value);
|
|
28923
|
+
if (sanitized !== void 0) {
|
|
28924
|
+
metadata[normalizedKey] = sanitized;
|
|
28925
|
+
}
|
|
28926
|
+
}
|
|
28927
|
+
return Object.keys(metadata).length === 0 ? void 0 : metadata;
|
|
28928
|
+
}
|
|
28929
|
+
function extractTags(value) {
|
|
28930
|
+
if (!Array.isArray(value)) {
|
|
28931
|
+
return void 0;
|
|
28932
|
+
}
|
|
28933
|
+
const tags = value.filter(
|
|
28934
|
+
(tag) => typeof tag === "string" && tag.length > 0
|
|
28935
|
+
);
|
|
28936
|
+
return tags.length > 0 ? tags : void 0;
|
|
28937
|
+
}
|
|
28938
|
+
function extractMetrics(run, previous) {
|
|
28939
|
+
const outputs = preferOwnValue(run, previous, "outputs");
|
|
28940
|
+
const extra = preferOwnValue(run, previous, "extra");
|
|
28941
|
+
const metadata = ownValue(extra, "metadata");
|
|
28942
|
+
const usage = ownValue(outputs, "usage_metadata") ?? ownValue(metadata, "usage_metadata");
|
|
28943
|
+
const metrics = {};
|
|
28944
|
+
assignFirstMetric(metrics, "prompt_tokens", usage, [
|
|
28945
|
+
"input_tokens",
|
|
28946
|
+
"prompt_tokens"
|
|
28947
|
+
]);
|
|
28948
|
+
assignFirstMetric(metrics, "completion_tokens", usage, [
|
|
28949
|
+
"output_tokens",
|
|
28950
|
+
"completion_tokens"
|
|
28951
|
+
]);
|
|
28952
|
+
assignFirstMetric(metrics, "tokens", usage, ["total_tokens", "tokens"]);
|
|
28953
|
+
const inputTokenDetails = ownValue(usage, "input_token_details");
|
|
28954
|
+
assignFirstMetric(metrics, "prompt_cached_tokens", inputTokenDetails, [
|
|
28955
|
+
"cache_read",
|
|
28956
|
+
"cached_tokens"
|
|
28957
|
+
]);
|
|
28958
|
+
if (metrics.prompt_cached_tokens === void 0) {
|
|
28959
|
+
assignFirstMetric(metrics, "prompt_cached_tokens", usage, [
|
|
28960
|
+
"cache_read_input_tokens",
|
|
28961
|
+
"prompt_cached_tokens"
|
|
28962
|
+
]);
|
|
28963
|
+
}
|
|
28964
|
+
assignFirstMetric(
|
|
28965
|
+
metrics,
|
|
28966
|
+
"prompt_cache_creation_tokens",
|
|
28967
|
+
inputTokenDetails,
|
|
28968
|
+
["cache_creation"]
|
|
28969
|
+
);
|
|
28970
|
+
if (metrics.prompt_cache_creation_tokens === void 0) {
|
|
28971
|
+
assignFirstMetric(metrics, "prompt_cache_creation_tokens", usage, [
|
|
28972
|
+
"cache_creation_input_tokens",
|
|
28973
|
+
"prompt_cache_creation_tokens"
|
|
28974
|
+
]);
|
|
28975
|
+
}
|
|
28976
|
+
if (metrics.tokens === void 0 && (metrics.prompt_tokens !== void 0 || metrics.completion_tokens !== void 0)) {
|
|
28977
|
+
metrics.tokens = (metrics.prompt_tokens ?? 0) + (metrics.completion_tokens ?? 0);
|
|
28978
|
+
}
|
|
28979
|
+
const startTime = timestampSeconds(
|
|
28980
|
+
preferOwnValue(run, previous, "start_time")
|
|
28981
|
+
);
|
|
28982
|
+
const events = preferOwnValue(run, previous, "events");
|
|
28983
|
+
if (startTime !== void 0 && Array.isArray(events)) {
|
|
28984
|
+
for (const event of events) {
|
|
28985
|
+
if (ownValue(event, "name") !== "new_token") {
|
|
28986
|
+
continue;
|
|
28987
|
+
}
|
|
28988
|
+
const eventTime2 = timestampSeconds(ownValue(event, "time"));
|
|
28989
|
+
if (eventTime2 !== void 0 && eventTime2 >= startTime) {
|
|
28990
|
+
metrics.time_to_first_token = eventTime2 - startTime;
|
|
28991
|
+
}
|
|
28992
|
+
break;
|
|
28993
|
+
}
|
|
28994
|
+
}
|
|
28995
|
+
return metrics;
|
|
28996
|
+
}
|
|
28997
|
+
function assignFirstMetric(metrics, target, source, keys) {
|
|
28998
|
+
for (const key of keys) {
|
|
28999
|
+
const value = ownValue(source, key);
|
|
29000
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
|
|
29001
|
+
metrics[target] = value;
|
|
29002
|
+
return;
|
|
29003
|
+
}
|
|
29004
|
+
}
|
|
29005
|
+
}
|
|
29006
|
+
function errorMessage(value) {
|
|
29007
|
+
if (typeof value === "string") {
|
|
29008
|
+
return value;
|
|
29009
|
+
}
|
|
29010
|
+
if (value instanceof Error) {
|
|
29011
|
+
return value.message;
|
|
29012
|
+
}
|
|
29013
|
+
return void 0;
|
|
29014
|
+
}
|
|
29015
|
+
function sanitizeLoggedValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
|
|
29016
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
29017
|
+
return value;
|
|
29018
|
+
}
|
|
29019
|
+
if (typeof value === "number") {
|
|
29020
|
+
return Number.isFinite(value) ? value : void 0;
|
|
29021
|
+
}
|
|
29022
|
+
if (value instanceof Date) {
|
|
29023
|
+
return Number.isFinite(value.getTime()) ? value.toISOString() : void 0;
|
|
29024
|
+
}
|
|
29025
|
+
if (typeof value !== "object" || depth >= 20) {
|
|
29026
|
+
return void 0;
|
|
29027
|
+
}
|
|
29028
|
+
if (seen.has(value)) {
|
|
29029
|
+
return "[Circular]";
|
|
29030
|
+
}
|
|
29031
|
+
seen.add(value);
|
|
29032
|
+
if (Array.isArray(value)) {
|
|
29033
|
+
return value.map((item) => sanitizeLoggedValue(item, seen, depth + 1));
|
|
29034
|
+
}
|
|
29035
|
+
const entries = [];
|
|
29036
|
+
for (const [key, descriptor] of Object.entries(
|
|
29037
|
+
Object.getOwnPropertyDescriptors(value)
|
|
29038
|
+
)) {
|
|
29039
|
+
if (!descriptor.enumerable || !("value" in descriptor) || BLOCKED_METADATA_KEYS.has(key)) {
|
|
29040
|
+
continue;
|
|
29041
|
+
}
|
|
29042
|
+
entries.push([key, sanitizeLoggedValue(descriptor.value, seen, depth + 1)]);
|
|
29043
|
+
}
|
|
29044
|
+
return Object.fromEntries(entries);
|
|
29045
|
+
}
|
|
29046
|
+
|
|
28496
29047
|
// src/instrumentation/plugins/pi-coding-agent-plugin.ts
|
|
28497
29048
|
var piStreamPatchStates = /* @__PURE__ */ new WeakMap();
|
|
28498
29049
|
var piPromptContextStore;
|
|
@@ -28861,11 +29412,11 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
|
|
|
28861
29412
|
function recordPiAssistantMessageEvent(promptState, llmState, event) {
|
|
28862
29413
|
recordFirstTokenMetric(llmState, event);
|
|
28863
29414
|
const message = "message" in event ? event.message : void 0;
|
|
28864
|
-
const
|
|
29415
|
+
const errorMessage2 = "error" in event ? event.error : void 0;
|
|
28865
29416
|
if (event.type === "done" && isPiAssistantMessage(message)) {
|
|
28866
29417
|
finishPiLlmSpan(promptState, llmState, message);
|
|
28867
|
-
} else if (event.type === "error" && isPiAssistantMessage(
|
|
28868
|
-
finishPiLlmSpan(promptState, llmState,
|
|
29418
|
+
} else if (event.type === "error" && isPiAssistantMessage(errorMessage2)) {
|
|
29419
|
+
finishPiLlmSpan(promptState, llmState, errorMessage2);
|
|
28869
29420
|
}
|
|
28870
29421
|
}
|
|
28871
29422
|
function recordFirstTokenMetric(state, event) {
|
|
@@ -29367,6 +29918,7 @@ function logInstrumentationError4(context, error) {
|
|
|
29367
29918
|
}
|
|
29368
29919
|
|
|
29369
29920
|
// src/instrumentation/plugins/strands-agent-sdk-plugin.ts
|
|
29921
|
+
var MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES = 32;
|
|
29370
29922
|
var StrandsAgentSDKPlugin = class extends BasePlugin {
|
|
29371
29923
|
activeChildParents = /* @__PURE__ */ new WeakMap();
|
|
29372
29924
|
onEnable() {
|
|
@@ -29511,11 +30063,16 @@ function startAgentStream(event, activeChildParents) {
|
|
|
29511
30063
|
...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
|
|
29512
30064
|
};
|
|
29513
30065
|
const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
|
|
30066
|
+
const attachmentCache = createStrandsAttachmentCache();
|
|
30067
|
+
const input = processStrandsInputAttachments(
|
|
30068
|
+
event.arguments[0],
|
|
30069
|
+
attachmentCache
|
|
30070
|
+
);
|
|
29514
30071
|
const span = parentSpan ? withCurrent(
|
|
29515
30072
|
parentSpan,
|
|
29516
30073
|
() => startSpan({
|
|
29517
30074
|
event: {
|
|
29518
|
-
input
|
|
30075
|
+
input,
|
|
29519
30076
|
metadata
|
|
29520
30077
|
},
|
|
29521
30078
|
name: formatAgentSpanName(agent),
|
|
@@ -29523,7 +30080,7 @@ function startAgentStream(event, activeChildParents) {
|
|
|
29523
30080
|
})
|
|
29524
30081
|
) : startSpan({
|
|
29525
30082
|
event: {
|
|
29526
|
-
input
|
|
30083
|
+
input,
|
|
29527
30084
|
metadata
|
|
29528
30085
|
},
|
|
29529
30086
|
name: formatAgentSpanName(agent),
|
|
@@ -29531,6 +30088,7 @@ function startAgentStream(event, activeChildParents) {
|
|
|
29531
30088
|
});
|
|
29532
30089
|
return {
|
|
29533
30090
|
activeTools: /* @__PURE__ */ new Map(),
|
|
30091
|
+
attachmentCache,
|
|
29534
30092
|
finalized: false,
|
|
29535
30093
|
metadata,
|
|
29536
30094
|
span,
|
|
@@ -29546,11 +30104,12 @@ function startMultiAgentStream(event, operation, activeChildParents) {
|
|
|
29546
30104
|
...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
|
|
29547
30105
|
};
|
|
29548
30106
|
const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
|
|
30107
|
+
const input = processStrandsInputAttachments(event.arguments[0]);
|
|
29549
30108
|
const span = parentSpan ? withCurrent(
|
|
29550
30109
|
parentSpan,
|
|
29551
30110
|
() => startSpan({
|
|
29552
30111
|
event: {
|
|
29553
|
-
input
|
|
30112
|
+
input,
|
|
29554
30113
|
metadata
|
|
29555
30114
|
},
|
|
29556
30115
|
name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
|
|
@@ -29558,7 +30117,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
|
|
|
29558
30117
|
})
|
|
29559
30118
|
) : startSpan({
|
|
29560
30119
|
event: {
|
|
29561
|
-
input
|
|
30120
|
+
input,
|
|
29562
30121
|
metadata
|
|
29563
30122
|
},
|
|
29564
30123
|
name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
|
|
@@ -29667,7 +30226,10 @@ function startModelSpan(state, event) {
|
|
|
29667
30226
|
state.span,
|
|
29668
30227
|
() => startSpan({
|
|
29669
30228
|
event: {
|
|
29670
|
-
input: Array.isArray(event.agent?.messages) ?
|
|
30229
|
+
input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
|
|
30230
|
+
event.agent.messages,
|
|
30231
|
+
state.attachmentCache
|
|
30232
|
+
) : void 0,
|
|
29671
30233
|
metadata
|
|
29672
30234
|
},
|
|
29673
30235
|
name: formatModelSpanName(model),
|
|
@@ -29881,6 +30443,7 @@ function finalizeAgentStream(state, error, output) {
|
|
|
29881
30443
|
...output !== void 0 ? { output } : {}
|
|
29882
30444
|
});
|
|
29883
30445
|
state.span.end();
|
|
30446
|
+
state.attachmentCache.strings.clear();
|
|
29884
30447
|
}
|
|
29885
30448
|
function finalizeMultiAgentStream(state, activeChildParents, error, output) {
|
|
29886
30449
|
if (state.finalized) {
|
|
@@ -30027,6 +30590,166 @@ function extractNodeResultOutput(result) {
|
|
|
30027
30590
|
}
|
|
30028
30591
|
return result;
|
|
30029
30592
|
}
|
|
30593
|
+
var STRANDS_MEDIA_TYPES = {
|
|
30594
|
+
png: "image/png",
|
|
30595
|
+
jpg: "image/jpeg",
|
|
30596
|
+
jpeg: "image/jpeg",
|
|
30597
|
+
gif: "image/gif",
|
|
30598
|
+
webp: "image/webp",
|
|
30599
|
+
mkv: "video/x-matroska",
|
|
30600
|
+
mov: "video/quicktime",
|
|
30601
|
+
mp4: "video/mp4",
|
|
30602
|
+
webm: "video/webm",
|
|
30603
|
+
flv: "video/x-flv",
|
|
30604
|
+
mpeg: "video/mpeg",
|
|
30605
|
+
mpg: "video/mpeg",
|
|
30606
|
+
wmv: "video/x-ms-wmv",
|
|
30607
|
+
"3gp": "video/3gpp",
|
|
30608
|
+
pdf: "application/pdf",
|
|
30609
|
+
csv: "text/csv",
|
|
30610
|
+
doc: "application/msword",
|
|
30611
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
30612
|
+
xls: "application/vnd.ms-excel",
|
|
30613
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
30614
|
+
html: "text/html",
|
|
30615
|
+
txt: "text/plain",
|
|
30616
|
+
md: "text/markdown",
|
|
30617
|
+
json: "application/json",
|
|
30618
|
+
xml: "application/xml"
|
|
30619
|
+
};
|
|
30620
|
+
function createStrandsAttachmentCache() {
|
|
30621
|
+
return {
|
|
30622
|
+
objects: /* @__PURE__ */ new WeakMap(),
|
|
30623
|
+
strings: new LRUCache({
|
|
30624
|
+
max: MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES
|
|
30625
|
+
})
|
|
30626
|
+
};
|
|
30627
|
+
}
|
|
30628
|
+
function processStrandsInputAttachments(input, cache = createStrandsAttachmentCache()) {
|
|
30629
|
+
try {
|
|
30630
|
+
return processStrandsInputNode(input, cache);
|
|
30631
|
+
} catch (error) {
|
|
30632
|
+
logInstrumentationError5("Strands Agent SDK input attachments", error);
|
|
30633
|
+
return input;
|
|
30634
|
+
}
|
|
30635
|
+
}
|
|
30636
|
+
function processStrandsInputNode(value, cache) {
|
|
30637
|
+
if (value instanceof BaseAttachment) {
|
|
30638
|
+
return value;
|
|
30639
|
+
}
|
|
30640
|
+
if (Array.isArray(value)) {
|
|
30641
|
+
return value.map((child) => processStrandsInputNode(child, cache));
|
|
30642
|
+
}
|
|
30643
|
+
if (!isObject(value)) {
|
|
30644
|
+
return value;
|
|
30645
|
+
}
|
|
30646
|
+
const directMedia = processDirectStrandsMediaBlock(value, cache);
|
|
30647
|
+
if (directMedia !== void 0) {
|
|
30648
|
+
return directMedia;
|
|
30649
|
+
}
|
|
30650
|
+
const wrappedMedia = processWrappedStrandsMediaBlock(value, cache);
|
|
30651
|
+
if (wrappedMedia !== void 0) {
|
|
30652
|
+
return wrappedMedia;
|
|
30653
|
+
}
|
|
30654
|
+
if (value.type === "message" && Array.isArray(value.content)) {
|
|
30655
|
+
return {
|
|
30656
|
+
role: value.role,
|
|
30657
|
+
content: value.content.map(
|
|
30658
|
+
(child) => processStrandsInputNode(child, cache)
|
|
30659
|
+
),
|
|
30660
|
+
...value.metadata !== void 0 ? { metadata: value.metadata } : {}
|
|
30661
|
+
};
|
|
30662
|
+
}
|
|
30663
|
+
if (typeof value.toJSON === "function") {
|
|
30664
|
+
return processStrandsInputNode(value.toJSON(), cache);
|
|
30665
|
+
}
|
|
30666
|
+
return Object.fromEntries(
|
|
30667
|
+
Object.entries(value).map(([key, child]) => [
|
|
30668
|
+
key,
|
|
30669
|
+
processStrandsInputNode(child, cache)
|
|
30670
|
+
])
|
|
30671
|
+
);
|
|
30672
|
+
}
|
|
30673
|
+
function processDirectStrandsMediaBlock(block, cache) {
|
|
30674
|
+
if (!isStrandsMediaBlock(block)) {
|
|
30675
|
+
return void 0;
|
|
30676
|
+
}
|
|
30677
|
+
const mediaKey = block.type === "imageBlock" ? "image" : block.type === "videoBlock" ? "video" : "document";
|
|
30678
|
+
return createStrandsMediaAttachment(mediaKey, block, cache);
|
|
30679
|
+
}
|
|
30680
|
+
function isStrandsMediaBlock(block) {
|
|
30681
|
+
return (block.type === "imageBlock" || block.type === "videoBlock" || block.type === "documentBlock") && typeof block.format === "string" && isObject(block.source);
|
|
30682
|
+
}
|
|
30683
|
+
function processWrappedStrandsMediaBlock(block, cache) {
|
|
30684
|
+
for (const mediaKey of ["image", "video", "document"]) {
|
|
30685
|
+
const media = block[mediaKey];
|
|
30686
|
+
if (!Object.hasOwn(block, mediaKey) || !isObject(media)) {
|
|
30687
|
+
continue;
|
|
30688
|
+
}
|
|
30689
|
+
const processed = createStrandsMediaAttachment(mediaKey, media, cache);
|
|
30690
|
+
if (processed !== void 0) {
|
|
30691
|
+
return processed;
|
|
30692
|
+
}
|
|
30693
|
+
}
|
|
30694
|
+
return void 0;
|
|
30695
|
+
}
|
|
30696
|
+
function createStrandsMediaAttachment(mediaKey, media, cache) {
|
|
30697
|
+
const format = media.format;
|
|
30698
|
+
const source = media.source;
|
|
30699
|
+
if (typeof format !== "string" || !isObject(source) || !Object.hasOwn(source, "bytes")) {
|
|
30700
|
+
return void 0;
|
|
30701
|
+
}
|
|
30702
|
+
const contentType = STRANDS_MEDIA_TYPES[format.toLowerCase()];
|
|
30703
|
+
if (!contentType) {
|
|
30704
|
+
return void 0;
|
|
30705
|
+
}
|
|
30706
|
+
const filename = mediaKey === "document" && typeof media.name === "string" && media.name.length > 0 ? media.name : `${mediaKey}.${format.toLowerCase()}`;
|
|
30707
|
+
const attachment = getOrCreateStrandsAttachment(
|
|
30708
|
+
source.bytes,
|
|
30709
|
+
filename,
|
|
30710
|
+
contentType,
|
|
30711
|
+
cache
|
|
30712
|
+
);
|
|
30713
|
+
if (!attachment) {
|
|
30714
|
+
return void 0;
|
|
30715
|
+
}
|
|
30716
|
+
const { type: _type, ...serializedMedia } = media;
|
|
30717
|
+
const { type: _sourceType, ...serializedSource } = source;
|
|
30718
|
+
return {
|
|
30719
|
+
[mediaKey]: {
|
|
30720
|
+
...serializedMedia,
|
|
30721
|
+
source: {
|
|
30722
|
+
...serializedSource,
|
|
30723
|
+
bytes: attachment
|
|
30724
|
+
}
|
|
30725
|
+
}
|
|
30726
|
+
};
|
|
30727
|
+
}
|
|
30728
|
+
function getOrCreateStrandsAttachment(data, filename, contentType, cache) {
|
|
30729
|
+
const key = `${contentType}\0${filename}`;
|
|
30730
|
+
const attachments = typeof data === "string" ? cache.strings.get(data) : isObject(data) ? cache.objects.get(data) : void 0;
|
|
30731
|
+
const cached = attachments?.get(key);
|
|
30732
|
+
if (cached) {
|
|
30733
|
+
return cached;
|
|
30734
|
+
}
|
|
30735
|
+
const blob = convertDataToBlob(data, contentType);
|
|
30736
|
+
if (!blob) {
|
|
30737
|
+
return void 0;
|
|
30738
|
+
}
|
|
30739
|
+
const attachment = new Attachment({
|
|
30740
|
+
data: blob,
|
|
30741
|
+
filename,
|
|
30742
|
+
contentType
|
|
30743
|
+
});
|
|
30744
|
+
const updatedAttachments = attachments ?? /* @__PURE__ */ new Map();
|
|
30745
|
+
updatedAttachments.set(key, attachment);
|
|
30746
|
+
if (typeof data === "string") {
|
|
30747
|
+
cache.strings.set(data, updatedAttachments);
|
|
30748
|
+
} else if (isObject(data)) {
|
|
30749
|
+
cache.objects.set(data, updatedAttachments);
|
|
30750
|
+
}
|
|
30751
|
+
return attachment;
|
|
30752
|
+
}
|
|
30030
30753
|
function normalizeContentBlocks(blocks) {
|
|
30031
30754
|
const text = blocks.map((block) => typeof block.text === "string" ? block.text : void 0).filter((part) => Boolean(part)).join("");
|
|
30032
30755
|
return text.length > 0 ? text : blocks;
|
|
@@ -30156,6 +30879,7 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
30156
30879
|
gitHubCopilotPlugin = null;
|
|
30157
30880
|
fluePlugin = null;
|
|
30158
30881
|
langChainPlugin = null;
|
|
30882
|
+
langSmithPlugin = null;
|
|
30159
30883
|
piCodingAgentPlugin = null;
|
|
30160
30884
|
strandsAgentSDKPlugin = null;
|
|
30161
30885
|
constructor(config = {}) {
|
|
@@ -30252,6 +30976,12 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
30252
30976
|
this.langChainPlugin = new LangChainPlugin();
|
|
30253
30977
|
this.langChainPlugin.enable();
|
|
30254
30978
|
}
|
|
30979
|
+
if (integrations.langsmith !== false) {
|
|
30980
|
+
this.langSmithPlugin = new LangSmithPlugin({
|
|
30981
|
+
skipLangChainRuns: integrations.langchain !== false
|
|
30982
|
+
});
|
|
30983
|
+
this.langSmithPlugin.enable();
|
|
30984
|
+
}
|
|
30255
30985
|
}
|
|
30256
30986
|
onDisable() {
|
|
30257
30987
|
if (this.openaiPlugin) {
|
|
@@ -30342,6 +31072,10 @@ var BraintrustPlugin = class extends BasePlugin {
|
|
|
30342
31072
|
this.langChainPlugin.disable();
|
|
30343
31073
|
this.langChainPlugin = null;
|
|
30344
31074
|
}
|
|
31075
|
+
if (this.langSmithPlugin) {
|
|
31076
|
+
this.langSmithPlugin.disable();
|
|
31077
|
+
this.langSmithPlugin = null;
|
|
31078
|
+
}
|
|
30345
31079
|
}
|
|
30346
31080
|
};
|
|
30347
31081
|
|
|
@@ -30502,6 +31236,15 @@ function modelMetrics(attributes) {
|
|
|
30502
31236
|
}
|
|
30503
31237
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
30504
31238
|
}
|
|
31239
|
+
function timeToFirstTokenSeconds(attributes, spanStartSeconds) {
|
|
31240
|
+
if (!isObject(attributes)) return void 0;
|
|
31241
|
+
if (spanStartSeconds === void 0) return void 0;
|
|
31242
|
+
const raw = attributes.completionStartTime;
|
|
31243
|
+
const completionStart = raw instanceof Date || typeof raw === "string" || typeof raw === "number" ? epochSeconds(raw) : void 0;
|
|
31244
|
+
if (completionStart === void 0) return void 0;
|
|
31245
|
+
const ttft = completionStart - spanStartSeconds;
|
|
31246
|
+
return Number.isFinite(ttft) && ttft >= 0 ? ttft : void 0;
|
|
31247
|
+
}
|
|
30505
31248
|
function buildMetadata(exported) {
|
|
30506
31249
|
const out = {};
|
|
30507
31250
|
if (exported.entityId !== void 0) out.entity_id = exported.entityId;
|
|
@@ -30571,7 +31314,13 @@ var BraintrustObservabilityExporter = class {
|
|
|
30571
31314
|
const args = {
|
|
30572
31315
|
name: exported.name,
|
|
30573
31316
|
spanAttributes: { type: spanTypeFor(exported.type) },
|
|
30574
|
-
startTime: epochSeconds(exported.startTime)
|
|
31317
|
+
startTime: epochSeconds(exported.startTime),
|
|
31318
|
+
// Use the Mastra span id as the Braintrust row id so that
|
|
31319
|
+
// `logFeedback({ id: <mastra span id> })` (and Mastra's score events)
|
|
31320
|
+
// attach to the right row. Without this, `SpanImpl` auto-generates a
|
|
31321
|
+
// row id (`this._id = eventId ?? idGenerator.getSpanId()`) that no
|
|
31322
|
+
// external caller could know.
|
|
31323
|
+
event: { id: exported.id }
|
|
30575
31324
|
};
|
|
30576
31325
|
const parentRecord = exported.parentSpanId ? this.spans.get(exported.parentSpanId) : void 0;
|
|
30577
31326
|
if (!this.capturedParent) {
|
|
@@ -30620,8 +31369,15 @@ var BraintrustObservabilityExporter = class {
|
|
|
30620
31369
|
event.metadata = metadata;
|
|
30621
31370
|
}
|
|
30622
31371
|
const metrics = modelMetrics(exported.attributes);
|
|
30623
|
-
|
|
30624
|
-
|
|
31372
|
+
const ttft = timeToFirstTokenSeconds(
|
|
31373
|
+
exported.attributes,
|
|
31374
|
+
epochSeconds(exported.startTime)
|
|
31375
|
+
);
|
|
31376
|
+
if (metrics || ttft !== void 0) {
|
|
31377
|
+
event.metrics = {
|
|
31378
|
+
...metrics ?? {},
|
|
31379
|
+
...ttft !== void 0 ? { time_to_first_token: ttft } : {}
|
|
31380
|
+
};
|
|
30625
31381
|
}
|
|
30626
31382
|
if (Object.keys(event).length > 0) {
|
|
30627
31383
|
record.span.log(event);
|
|
@@ -31038,6 +31794,7 @@ export {
|
|
|
31038
31794
|
BraintrustStream,
|
|
31039
31795
|
createFinalValuePassThroughStream,
|
|
31040
31796
|
devNullWritableStream,
|
|
31797
|
+
LRUCache,
|
|
31041
31798
|
LOGS3_OVERFLOW_REFERENCE_TYPE,
|
|
31042
31799
|
DEFAULT_MAX_REQUEST_SIZE,
|
|
31043
31800
|
LoginInvalidOrgError,
|
|
@@ -31093,6 +31850,7 @@ export {
|
|
|
31093
31850
|
wrapTraced,
|
|
31094
31851
|
traceable,
|
|
31095
31852
|
startSpan,
|
|
31853
|
+
_internalStartSpanWithInitialMerge,
|
|
31096
31854
|
flush,
|
|
31097
31855
|
setFetch,
|
|
31098
31856
|
withCurrent,
|