braintrust 3.22.0 → 3.23.1

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.
Files changed (54) hide show
  1. package/README.md +43 -0
  2. package/dev/dist/index.d.mts +1 -1
  3. package/dev/dist/index.d.ts +1 -1
  4. package/dev/dist/index.js +1354 -654
  5. package/dev/dist/index.mjs +736 -36
  6. package/dist/apply-auto-instrumentation.js +222 -186
  7. package/dist/apply-auto-instrumentation.mjs +37 -1
  8. package/dist/auto-instrumentations/bundler/esbuild.cjs +53 -1
  9. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  10. package/dist/auto-instrumentations/bundler/next.cjs +53 -1
  11. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  12. package/dist/auto-instrumentations/bundler/rollup.cjs +53 -1
  13. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  14. package/dist/auto-instrumentations/bundler/vite.cjs +53 -1
  15. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  16. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +53 -1
  17. package/dist/auto-instrumentations/bundler/webpack.cjs +53 -1
  18. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  19. package/dist/auto-instrumentations/{chunk-TKRPRPGD.mjs → chunk-EXY7QCJD.mjs} +5 -2
  20. package/dist/auto-instrumentations/{chunk-T6J4C7LX.mjs → chunk-KIMLYPRW.mjs} +1 -1
  21. package/dist/auto-instrumentations/{chunk-BRQX23KL.mjs → chunk-YXLNSAMJ.mjs} +51 -0
  22. package/dist/auto-instrumentations/hook.mjs +149 -20
  23. package/dist/auto-instrumentations/index.cjs +52 -0
  24. package/dist/auto-instrumentations/index.d.mts +3 -1
  25. package/dist/auto-instrumentations/index.d.ts +3 -1
  26. package/dist/auto-instrumentations/index.mjs +3 -1
  27. package/dist/browser.d.mts +11 -13
  28. package/dist/browser.d.ts +11 -13
  29. package/dist/browser.js +1098 -205
  30. package/dist/browser.mjs +1098 -205
  31. package/dist/{chunk-KMGUTPB7.mjs → chunk-36IPYKMG.mjs} +20 -1
  32. package/dist/{chunk-MWVVR5LR.js → chunk-B6ZQIAK3.js} +1506 -822
  33. package/dist/{chunk-BFGIH2ZJ.js → chunk-CDIKAHDZ.js} +21 -2
  34. package/dist/{chunk-ZG2O3XVF.mjs → chunk-RBXD2KYN.mjs} +719 -35
  35. package/dist/cli.js +737 -37
  36. package/dist/edge-light.d.mts +1 -1
  37. package/dist/edge-light.d.ts +1 -1
  38. package/dist/edge-light.js +1098 -205
  39. package/dist/edge-light.mjs +1098 -205
  40. package/dist/index.d.mts +11 -13
  41. package/dist/index.d.ts +11 -13
  42. package/dist/index.js +786 -593
  43. package/dist/index.mjs +346 -153
  44. package/dist/instrumentation/index.d.mts +3 -11
  45. package/dist/instrumentation/index.d.ts +3 -11
  46. package/dist/instrumentation/index.js +788 -183
  47. package/dist/instrumentation/index.mjs +788 -183
  48. package/dist/vitest-evals-reporter.js +16 -16
  49. package/dist/vitest-evals-reporter.mjs +2 -2
  50. package/dist/workerd.d.mts +1 -1
  51. package/dist/workerd.d.ts +1 -1
  52. package/dist/workerd.js +1098 -205
  53. package/dist/workerd.mjs +1098 -205
  54. package/package.json +1 -1
package/dist/browser.mjs CHANGED
@@ -4267,7 +4267,7 @@ var DiskCache = class {
4267
4267
  }
4268
4268
  };
4269
4269
 
4270
- // src/prompt-cache/lru-cache.ts
4270
+ // src/lru-cache.ts
4271
4271
  var LRUCache = class {
4272
4272
  cache;
4273
4273
  maxSize;
@@ -5509,25 +5509,46 @@ var HTTPConnection = class _HTTPConnection {
5509
5509
  })
5510
5510
  );
5511
5511
  }
5512
- async post(path, params, config) {
5512
+ async post(path, params, config, retries = 0) {
5513
5513
  const { headers, ...rest } = config || {};
5514
5514
  const this_fetch = this.fetch;
5515
5515
  const this_base_url = this.base_url;
5516
5516
  const this_headers = this.headers;
5517
- return await checkResponse(
5518
- await this_fetch(_urljoin(this_base_url, path), {
5519
- method: "POST",
5520
- headers: {
5521
- Accept: "application/json",
5522
- "Content-Type": "application/json",
5523
- ...this_headers,
5524
- ...headers
5525
- },
5526
- body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
5527
- keepalive: true,
5528
- ...rest
5529
- })
5530
- );
5517
+ const tries = retries + 1;
5518
+ for (let i = 0; i < tries; i++) {
5519
+ try {
5520
+ return await checkResponse(
5521
+ await this_fetch(_urljoin(this_base_url, path), {
5522
+ method: "POST",
5523
+ headers: {
5524
+ Accept: "application/json",
5525
+ "Content-Type": "application/json",
5526
+ ...this_headers,
5527
+ ...headers
5528
+ },
5529
+ body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
5530
+ keepalive: true,
5531
+ ...rest
5532
+ })
5533
+ );
5534
+ } catch (error) {
5535
+ if (config?.signal?.aborted) {
5536
+ throw getAbortReason(config.signal);
5537
+ }
5538
+ if (i === tries - 1 || !isRetryableHTTPError(error)) {
5539
+ throw error;
5540
+ }
5541
+ debugLogger.debug(
5542
+ `Retrying API request ${path} after ${formatHTTPError(error)}`
5543
+ );
5544
+ const sleepTimeMs = HTTP_RETRY_BASE_SLEEP_TIME_S * 1e3 * 2 ** i + Math.random() * HTTP_RETRY_JITTER_MS;
5545
+ debugLogger.info(
5546
+ `Sleeping for ${sleepTimeMs}ms before retrying API request`
5547
+ );
5548
+ await waitForRetry(sleepTimeMs, config?.signal);
5549
+ }
5550
+ }
5551
+ throw new Error("Unexpected retry state");
5531
5552
  }
5532
5553
  async get_json(object_type, args = void 0, retries = 0) {
5533
5554
  const tries = retries + 1;
@@ -6624,6 +6645,45 @@ var TestBackgroundLogger = class {
6624
6645
  };
6625
6646
  var BACKGROUND_LOGGER_BASE_SLEEP_TIME_S = 1;
6626
6647
  var HTTP_RETRY_BASE_SLEEP_TIME_S = 1;
6648
+ var HTTP_RETRY_JITTER_MS = 200;
6649
+ var BTQL_HTTP_RETRIES = 3;
6650
+ var RETRYABLE_HTTP_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
6651
+ function isRetryableHTTPError(error) {
6652
+ return !(error instanceof FailedHTTPResponse) || RETRYABLE_HTTP_STATUS_CODES.has(error.status);
6653
+ }
6654
+ function formatHTTPError(error) {
6655
+ if (error instanceof FailedHTTPResponse) {
6656
+ return `${error.status} ${error.text}`;
6657
+ }
6658
+ return error instanceof Error ? error.message : String(error);
6659
+ }
6660
+ function getAbortReason(signal) {
6661
+ return signal.reason ?? new Error("Request aborted");
6662
+ }
6663
+ async function waitForRetry(delayMs, signal) {
6664
+ if (!signal) {
6665
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
6666
+ return;
6667
+ }
6668
+ if (signal.aborted) {
6669
+ throw getAbortReason(signal);
6670
+ }
6671
+ await new Promise((resolve, reject2) => {
6672
+ const onAbort = () => {
6673
+ clearTimeout(timeout);
6674
+ signal.removeEventListener("abort", onAbort);
6675
+ reject2(getAbortReason(signal));
6676
+ };
6677
+ const timeout = setTimeout(() => {
6678
+ signal.removeEventListener("abort", onAbort);
6679
+ resolve();
6680
+ }, delayMs);
6681
+ signal.addEventListener("abort", onAbort, { once: true });
6682
+ if (signal.aborted) {
6683
+ onAbort();
6684
+ }
6685
+ });
6686
+ }
6627
6687
  var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
6628
6688
  apiConn;
6629
6689
  queue;
@@ -8362,15 +8422,15 @@ function parentSpanIdsUsable(spanId, rootSpanId) {
8362
8422
  return Boolean(spanId) && Boolean(rootSpanId);
8363
8423
  }
8364
8424
  function logError(span, error) {
8365
- let errorMessage = "<error>";
8425
+ let errorMessage2 = "<error>";
8366
8426
  let stackTrace = "";
8367
8427
  if (error instanceof Error) {
8368
- errorMessage = error.message;
8428
+ errorMessage2 = error.message;
8369
8429
  stackTrace = error.stack || "";
8370
8430
  } else {
8371
- errorMessage = String(error);
8431
+ errorMessage2 = String(error);
8372
8432
  }
8373
- span.log({ error: `${errorMessage}
8433
+ span.log({ error: `${errorMessage2}
8374
8434
 
8375
8435
  ${stackTrace}` });
8376
8436
  }
@@ -8957,7 +9017,8 @@ var ObjectFetcher = class {
8957
9017
  version: this.pinnedVersion
8958
9018
  } : {}
8959
9019
  },
8960
- { headers: { "Accept-Encoding": "gzip" } }
9020
+ { headers: { "Accept-Encoding": "gzip" } },
9021
+ BTQL_HTTP_RETRIES
8961
9022
  );
8962
9023
  const respJson = await resp.json();
8963
9024
  const mutate = this.mutateRecord;
@@ -10681,7 +10742,8 @@ async function getPromptVersions(projectId, promptId) {
10681
10742
  use_columnstore: false,
10682
10743
  brainstore_realtime: true
10683
10744
  },
10684
- { headers: { "Accept-Encoding": "gzip" } }
10745
+ { headers: { "Accept-Encoding": "gzip" } },
10746
+ BTQL_HTTP_RETRIES
10685
10747
  );
10686
10748
  if (!response.ok) {
10687
10749
  throw new Error(
@@ -17943,8 +18005,6 @@ function filterSerializableOptions(options) {
17943
18005
  "additionalDirectories",
17944
18006
  "permissionMode",
17945
18007
  "debug",
17946
- "apiKey",
17947
- "apiKeySource",
17948
18008
  "agentName",
17949
18009
  "instructions"
17950
18010
  ];
@@ -29142,6 +29202,446 @@ function isBraintrustHandler(handler) {
29142
29202
  return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
29143
29203
  }
29144
29204
 
29205
+ // src/instrumentation/plugins/langsmith-channels.ts
29206
+ var langSmithChannels = defineChannels("langsmith", {
29207
+ createRun: channel({
29208
+ channelName: "Client.createRun",
29209
+ kind: "async"
29210
+ }),
29211
+ updateRun: channel({
29212
+ channelName: "Client.updateRun",
29213
+ kind: "async"
29214
+ }),
29215
+ batchIngestRuns: channel({
29216
+ channelName: "Client.batchIngestRuns",
29217
+ kind: "async"
29218
+ })
29219
+ });
29220
+
29221
+ // src/instrumentation/plugins/langsmith-plugin.ts
29222
+ var MAX_COMPLETED_RUNS = 1e4;
29223
+ var BLOCKED_METADATA_KEYS = /* @__PURE__ */ new Set([
29224
+ "__proto__",
29225
+ "constructor",
29226
+ "prototype",
29227
+ "usage_metadata"
29228
+ ]);
29229
+ var BLOCKED_METADATA_PREFIXES = ["__pregel_", "langgraph_", "lc_"];
29230
+ var LLM_SETTING_KEYS = [
29231
+ "temperature",
29232
+ "top_p",
29233
+ "max_tokens",
29234
+ "frequency_penalty",
29235
+ "presence_penalty",
29236
+ "stop",
29237
+ "response_format"
29238
+ ];
29239
+ var LangSmithPlugin = class extends BasePlugin {
29240
+ activeRuns = /* @__PURE__ */ new Map();
29241
+ completedRuns = new LRUCache({
29242
+ max: MAX_COMPLETED_RUNS
29243
+ });
29244
+ skipLangChainRuns;
29245
+ constructor(options = {}) {
29246
+ super();
29247
+ this.skipLangChainRuns = options.skipLangChainRuns ?? true;
29248
+ }
29249
+ onEnable() {
29250
+ const createChannel = langSmithChannels.createRun.tracingChannel();
29251
+ const createHandlers = {
29252
+ start: (event) => {
29253
+ this.containLifecycleFailure("createRun", () => {
29254
+ this.processCreate(event.arguments[0]);
29255
+ });
29256
+ }
29257
+ };
29258
+ createChannel.subscribe(createHandlers);
29259
+ this.unsubscribers.push(() => createChannel.unsubscribe(createHandlers));
29260
+ const updateChannel = langSmithChannels.updateRun.tracingChannel();
29261
+ const updateHandlers = {
29262
+ start: (event) => {
29263
+ this.containLifecycleFailure("updateRun", () => {
29264
+ this.processUpdate(event.arguments[0], event.arguments[1]);
29265
+ });
29266
+ }
29267
+ };
29268
+ updateChannel.subscribe(updateHandlers);
29269
+ this.unsubscribers.push(() => updateChannel.unsubscribe(updateHandlers));
29270
+ const batchChannel = langSmithChannels.batchIngestRuns.tracingChannel();
29271
+ const batchHandlers = {
29272
+ start: (event) => {
29273
+ this.containLifecycleFailure("batchIngestRuns", () => {
29274
+ this.processBatch(event.arguments[0]);
29275
+ });
29276
+ }
29277
+ };
29278
+ batchChannel.subscribe(batchHandlers);
29279
+ this.unsubscribers.push(() => batchChannel.unsubscribe(batchHandlers));
29280
+ }
29281
+ onDisable() {
29282
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
29283
+ for (const { span } of this.activeRuns.values()) {
29284
+ span.end();
29285
+ }
29286
+ this.activeRuns.clear();
29287
+ this.completedRuns.clear();
29288
+ }
29289
+ processBatch(batch) {
29290
+ if (!isRecord2(batch)) {
29291
+ return;
29292
+ }
29293
+ const creates = ownValue(batch, "runCreates");
29294
+ if (Array.isArray(creates)) {
29295
+ const parentFirst = [...creates].sort((left, right) => {
29296
+ const leftId = stringValue2(ownValue(left, "id"));
29297
+ const rightId = stringValue2(ownValue(right, "id"));
29298
+ const leftParent = stringValue2(ownValue(left, "parent_run_id"));
29299
+ const rightParent = stringValue2(ownValue(right, "parent_run_id"));
29300
+ if (leftParent && leftParent === rightId) {
29301
+ return 1;
29302
+ }
29303
+ if (rightParent && rightParent === leftId) {
29304
+ return -1;
29305
+ }
29306
+ return dottedOrderDepth(left) - dottedOrderDepth(right);
29307
+ });
29308
+ for (const run of parentFirst) {
29309
+ this.containLifecycleFailure("batchIngestRuns create", () => {
29310
+ this.processCreate(run);
29311
+ });
29312
+ }
29313
+ }
29314
+ const updates = ownValue(batch, "runUpdates");
29315
+ if (Array.isArray(updates)) {
29316
+ for (const run of updates) {
29317
+ this.containLifecycleFailure("batchIngestRuns update", () => {
29318
+ this.processUpdate(stringValue2(ownValue(run, "id")) ?? "", run);
29319
+ });
29320
+ }
29321
+ }
29322
+ }
29323
+ processCreate(run) {
29324
+ const id = stringValue2(ownValue(run, "id"));
29325
+ if (!id || this.completedRuns.get(id)) {
29326
+ return;
29327
+ }
29328
+ if (this.shouldSkipLangChainRun(run)) {
29329
+ this.completedRuns.set(id, true);
29330
+ return;
29331
+ }
29332
+ const active = this.activeRuns.get(id);
29333
+ if (active) {
29334
+ const previous = active.run;
29335
+ active.run = mergeRuns(previous, run);
29336
+ this.logRun(
29337
+ active.span,
29338
+ active.run,
29339
+ previous,
29340
+ timestampSeconds(ownValue(active.run, "end_time")) !== void 0 || errorMessage(ownValue(active.run, "error")) !== void 0
29341
+ );
29342
+ this.endIfComplete(id, active, active.run);
29343
+ return;
29344
+ }
29345
+ const span = this.startRunSpan(id, run);
29346
+ const activeRun = { run, span };
29347
+ this.activeRuns.set(id, activeRun);
29348
+ this.logRun(
29349
+ span,
29350
+ run,
29351
+ void 0,
29352
+ timestampSeconds(ownValue(run, "end_time")) !== void 0 || errorMessage(ownValue(run, "error")) !== void 0
29353
+ );
29354
+ this.endIfComplete(id, activeRun, run);
29355
+ }
29356
+ processUpdate(explicitId, run) {
29357
+ const id = stringValue2(explicitId) ?? stringValue2(ownValue(run, "id"));
29358
+ if (!id || this.completedRuns.get(id)) {
29359
+ return;
29360
+ }
29361
+ if (this.shouldSkipLangChainRun(run)) {
29362
+ const active2 = this.activeRuns.get(id);
29363
+ active2?.span.end();
29364
+ this.activeRuns.delete(id);
29365
+ this.completedRuns.set(id, true);
29366
+ return;
29367
+ }
29368
+ let active = this.activeRuns.get(id);
29369
+ if (!active) {
29370
+ const span = this.startRunSpan(id, run);
29371
+ active = { run, span };
29372
+ this.activeRuns.set(id, active);
29373
+ }
29374
+ const previous = active.run;
29375
+ active.run = mergeRuns(previous, run);
29376
+ this.logRun(active.span, active.run, previous, true);
29377
+ this.endIfComplete(id, active, active.run);
29378
+ }
29379
+ startRunSpan(id, run) {
29380
+ const traceId = stringValue2(ownValue(run, "trace_id")) ?? id;
29381
+ const parentId = stringValue2(ownValue(run, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run, "parent_run"), "id"));
29382
+ const startTime = timestampSeconds(ownValue(run, "start_time"));
29383
+ return startSpan({
29384
+ name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
29385
+ spanId: id,
29386
+ parentSpanIds: {
29387
+ parentSpanIds: parentId ? [parentId] : [],
29388
+ rootSpanId: traceId
29389
+ },
29390
+ spanAttributes: {
29391
+ type: mapRunType(ownValue(run, "run_type"))
29392
+ },
29393
+ ...startTime === void 0 ? {} : { startTime },
29394
+ event: { id }
29395
+ });
29396
+ }
29397
+ logRun(span, run, previous, includeOutput) {
29398
+ const inputs = preferOwnValue(run, previous, "inputs");
29399
+ const outputs = preferOwnValue(run, previous, "outputs");
29400
+ const error = errorMessage(preferOwnValue(run, previous, "error"));
29401
+ const metadata = extractMetadata(run, previous);
29402
+ const tags = extractTags(preferOwnValue(run, previous, "tags"));
29403
+ const metrics = extractMetrics(run, previous);
29404
+ span.log({
29405
+ ...inputs === void 0 ? {} : { input: sanitizeLoggedValue(inputs) },
29406
+ ...includeOutput && outputs !== void 0 ? { output: sanitizeLoggedValue(outputs) } : {},
29407
+ ...error === void 0 ? {} : { error },
29408
+ ...metadata === void 0 ? {} : { metadata },
29409
+ ...tags === void 0 ? {} : { tags },
29410
+ ...Object.keys(metrics).length === 0 ? {} : { metrics }
29411
+ });
29412
+ }
29413
+ endIfComplete(id, active, run) {
29414
+ const endTime = timestampSeconds(ownValue(run, "end_time"));
29415
+ if (endTime === void 0 && errorMessage(ownValue(run, "error")) === void 0) {
29416
+ return;
29417
+ }
29418
+ active.span.end(endTime === void 0 ? void 0 : { endTime });
29419
+ this.activeRuns.delete(id);
29420
+ this.completedRuns.set(id, true);
29421
+ }
29422
+ shouldSkipLangChainRun(run) {
29423
+ if (!this.skipLangChainRuns) {
29424
+ return false;
29425
+ }
29426
+ const serialized = ownValue(run, "serialized");
29427
+ return isRecord2(serialized) && ownValue(serialized, "lc") === 1;
29428
+ }
29429
+ containLifecycleFailure(operation, fn) {
29430
+ try {
29431
+ fn();
29432
+ } catch (error) {
29433
+ debugLogger.error(
29434
+ `Failed to process LangSmith ${operation} instrumentation:`,
29435
+ error
29436
+ );
29437
+ }
29438
+ }
29439
+ };
29440
+ function ownValue(value, key) {
29441
+ if (!isRecord2(value)) {
29442
+ return void 0;
29443
+ }
29444
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
29445
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
29446
+ }
29447
+ function preferOwnValue(current, previous, key) {
29448
+ const currentDescriptor = isRecord2(current) ? Object.getOwnPropertyDescriptor(current, key) : void 0;
29449
+ if (currentDescriptor && "value" in currentDescriptor) {
29450
+ return currentDescriptor.value;
29451
+ }
29452
+ return ownValue(previous, key);
29453
+ }
29454
+ function mergeRuns(previous, current) {
29455
+ const entries = /* @__PURE__ */ new Map();
29456
+ for (const value of [previous, current]) {
29457
+ if (!isRecord2(value)) {
29458
+ continue;
29459
+ }
29460
+ for (const [key, descriptor] of Object.entries(
29461
+ Object.getOwnPropertyDescriptors(value)
29462
+ )) {
29463
+ if (descriptor.enumerable && "value" in descriptor) {
29464
+ entries.set(key, descriptor.value);
29465
+ }
29466
+ }
29467
+ }
29468
+ return Object.fromEntries(entries);
29469
+ }
29470
+ function isRecord2(value) {
29471
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29472
+ }
29473
+ function stringValue2(value) {
29474
+ return typeof value === "string" && value.length > 0 ? value : void 0;
29475
+ }
29476
+ function timestampSeconds(value) {
29477
+ if (value instanceof Date) {
29478
+ const timestamp = value.getTime();
29479
+ return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
29480
+ }
29481
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
29482
+ return value > 1e10 ? value / 1e3 : value;
29483
+ }
29484
+ if (typeof value === "string") {
29485
+ const timestamp = Date.parse(value);
29486
+ return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
29487
+ }
29488
+ return void 0;
29489
+ }
29490
+ function dottedOrderDepth(run) {
29491
+ const dottedOrder = stringValue2(ownValue(run, "dotted_order"));
29492
+ return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
29493
+ }
29494
+ function mapRunType(runType) {
29495
+ switch (runType) {
29496
+ case "llm":
29497
+ case "embedding":
29498
+ return "llm" /* LLM */;
29499
+ case "tool":
29500
+ case "retriever":
29501
+ return "tool" /* TOOL */;
29502
+ default:
29503
+ return "task" /* TASK */;
29504
+ }
29505
+ }
29506
+ function extractMetadata(run, previous) {
29507
+ const extra = preferOwnValue(run, previous, "extra");
29508
+ const rawMetadata = ownValue(extra, "metadata");
29509
+ if (!isRecord2(rawMetadata)) {
29510
+ return void 0;
29511
+ }
29512
+ const metadata = {};
29513
+ for (const [key, descriptor] of Object.entries(
29514
+ Object.getOwnPropertyDescriptors(rawMetadata)
29515
+ )) {
29516
+ 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}`)) {
29517
+ continue;
29518
+ }
29519
+ const normalizedKey = key === "ls_provider" ? "provider" : key === "ls_model_name" ? "model" : key.startsWith("ls_") ? key.slice(3) : key;
29520
+ const sanitized = sanitizeLoggedValue(descriptor.value);
29521
+ if (sanitized !== void 0) {
29522
+ metadata[normalizedKey] = sanitized;
29523
+ }
29524
+ }
29525
+ return Object.keys(metadata).length === 0 ? void 0 : metadata;
29526
+ }
29527
+ function extractTags(value) {
29528
+ if (!Array.isArray(value)) {
29529
+ return void 0;
29530
+ }
29531
+ const tags = value.filter(
29532
+ (tag) => typeof tag === "string" && tag.length > 0
29533
+ );
29534
+ return tags.length > 0 ? tags : void 0;
29535
+ }
29536
+ function extractMetrics(run, previous) {
29537
+ const outputs = preferOwnValue(run, previous, "outputs");
29538
+ const extra = preferOwnValue(run, previous, "extra");
29539
+ const metadata = ownValue(extra, "metadata");
29540
+ const usage = ownValue(outputs, "usage_metadata") ?? ownValue(metadata, "usage_metadata");
29541
+ const metrics = {};
29542
+ assignFirstMetric(metrics, "prompt_tokens", usage, [
29543
+ "input_tokens",
29544
+ "prompt_tokens"
29545
+ ]);
29546
+ assignFirstMetric(metrics, "completion_tokens", usage, [
29547
+ "output_tokens",
29548
+ "completion_tokens"
29549
+ ]);
29550
+ assignFirstMetric(metrics, "tokens", usage, ["total_tokens", "tokens"]);
29551
+ const inputTokenDetails = ownValue(usage, "input_token_details");
29552
+ assignFirstMetric(metrics, "prompt_cached_tokens", inputTokenDetails, [
29553
+ "cache_read",
29554
+ "cached_tokens"
29555
+ ]);
29556
+ if (metrics.prompt_cached_tokens === void 0) {
29557
+ assignFirstMetric(metrics, "prompt_cached_tokens", usage, [
29558
+ "cache_read_input_tokens",
29559
+ "prompt_cached_tokens"
29560
+ ]);
29561
+ }
29562
+ assignFirstMetric(
29563
+ metrics,
29564
+ "prompt_cache_creation_tokens",
29565
+ inputTokenDetails,
29566
+ ["cache_creation"]
29567
+ );
29568
+ if (metrics.prompt_cache_creation_tokens === void 0) {
29569
+ assignFirstMetric(metrics, "prompt_cache_creation_tokens", usage, [
29570
+ "cache_creation_input_tokens",
29571
+ "prompt_cache_creation_tokens"
29572
+ ]);
29573
+ }
29574
+ if (metrics.tokens === void 0 && (metrics.prompt_tokens !== void 0 || metrics.completion_tokens !== void 0)) {
29575
+ metrics.tokens = (metrics.prompt_tokens ?? 0) + (metrics.completion_tokens ?? 0);
29576
+ }
29577
+ const startTime = timestampSeconds(
29578
+ preferOwnValue(run, previous, "start_time")
29579
+ );
29580
+ const events = preferOwnValue(run, previous, "events");
29581
+ if (startTime !== void 0 && Array.isArray(events)) {
29582
+ for (const event of events) {
29583
+ if (ownValue(event, "name") !== "new_token") {
29584
+ continue;
29585
+ }
29586
+ const eventTime3 = timestampSeconds(ownValue(event, "time"));
29587
+ if (eventTime3 !== void 0 && eventTime3 >= startTime) {
29588
+ metrics.time_to_first_token = eventTime3 - startTime;
29589
+ }
29590
+ break;
29591
+ }
29592
+ }
29593
+ return metrics;
29594
+ }
29595
+ function assignFirstMetric(metrics, target, source, keys) {
29596
+ for (const key of keys) {
29597
+ const value = ownValue(source, key);
29598
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
29599
+ metrics[target] = value;
29600
+ return;
29601
+ }
29602
+ }
29603
+ }
29604
+ function errorMessage(value) {
29605
+ if (typeof value === "string") {
29606
+ return value;
29607
+ }
29608
+ if (value instanceof Error) {
29609
+ return value.message;
29610
+ }
29611
+ return void 0;
29612
+ }
29613
+ function sanitizeLoggedValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
29614
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
29615
+ return value;
29616
+ }
29617
+ if (typeof value === "number") {
29618
+ return Number.isFinite(value) ? value : void 0;
29619
+ }
29620
+ if (value instanceof Date) {
29621
+ return Number.isFinite(value.getTime()) ? value.toISOString() : void 0;
29622
+ }
29623
+ if (typeof value !== "object" || depth >= 20) {
29624
+ return void 0;
29625
+ }
29626
+ if (seen.has(value)) {
29627
+ return "[Circular]";
29628
+ }
29629
+ seen.add(value);
29630
+ if (Array.isArray(value)) {
29631
+ return value.map((item) => sanitizeLoggedValue(item, seen, depth + 1));
29632
+ }
29633
+ const entries = [];
29634
+ for (const [key, descriptor] of Object.entries(
29635
+ Object.getOwnPropertyDescriptors(value)
29636
+ )) {
29637
+ if (!descriptor.enumerable || !("value" in descriptor) || BLOCKED_METADATA_KEYS.has(key)) {
29638
+ continue;
29639
+ }
29640
+ entries.push([key, sanitizeLoggedValue(descriptor.value, seen, depth + 1)]);
29641
+ }
29642
+ return Object.fromEntries(entries);
29643
+ }
29644
+
29145
29645
  // src/instrumentation/plugins/pi-coding-agent-channels.ts
29146
29646
  var piCodingAgentChannels = defineChannels(
29147
29647
  "@earendil-works/pi-coding-agent",
@@ -29521,11 +30021,11 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
29521
30021
  function recordPiAssistantMessageEvent(promptState, llmState, event) {
29522
30022
  recordFirstTokenMetric(llmState, event);
29523
30023
  const message = "message" in event ? event.message : void 0;
29524
- const errorMessage = "error" in event ? event.error : void 0;
30024
+ const errorMessage2 = "error" in event ? event.error : void 0;
29525
30025
  if (event.type === "done" && isPiAssistantMessage(message)) {
29526
30026
  finishPiLlmSpan(promptState, llmState, message);
29527
- } else if (event.type === "error" && isPiAssistantMessage(errorMessage)) {
29528
- finishPiLlmSpan(promptState, llmState, errorMessage);
30027
+ } else if (event.type === "error" && isPiAssistantMessage(errorMessage2)) {
30028
+ finishPiLlmSpan(promptState, llmState, errorMessage2);
29529
30029
  }
29530
30030
  }
29531
30031
  function recordFirstTokenMetric(state, event) {
@@ -30043,6 +30543,7 @@ var strandsAgentSDKChannels = defineChannels("@strands-agents/sdk", {
30043
30543
  });
30044
30544
 
30045
30545
  // src/instrumentation/plugins/strands-agent-sdk-plugin.ts
30546
+ var MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES = 32;
30046
30547
  var StrandsAgentSDKPlugin = class extends BasePlugin {
30047
30548
  activeChildParents = /* @__PURE__ */ new WeakMap();
30048
30549
  onEnable() {
@@ -30187,11 +30688,16 @@ function startAgentStream(event, activeChildParents) {
30187
30688
  ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
30188
30689
  };
30189
30690
  const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
30691
+ const attachmentCache = createStrandsAttachmentCache();
30692
+ const input = processStrandsInputAttachments(
30693
+ event.arguments[0],
30694
+ attachmentCache
30695
+ );
30190
30696
  const span = parentSpan ? withCurrent(
30191
30697
  parentSpan,
30192
30698
  () => startSpan({
30193
30699
  event: {
30194
- input: event.arguments[0],
30700
+ input,
30195
30701
  metadata
30196
30702
  },
30197
30703
  name: formatAgentSpanName(agent),
@@ -30199,7 +30705,7 @@ function startAgentStream(event, activeChildParents) {
30199
30705
  })
30200
30706
  ) : startSpan({
30201
30707
  event: {
30202
- input: event.arguments[0],
30708
+ input,
30203
30709
  metadata
30204
30710
  },
30205
30711
  name: formatAgentSpanName(agent),
@@ -30207,6 +30713,7 @@ function startAgentStream(event, activeChildParents) {
30207
30713
  });
30208
30714
  return {
30209
30715
  activeTools: /* @__PURE__ */ new Map(),
30716
+ attachmentCache,
30210
30717
  finalized: false,
30211
30718
  metadata,
30212
30719
  span,
@@ -30222,11 +30729,12 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30222
30729
  ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
30223
30730
  };
30224
30731
  const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
30732
+ const input = processStrandsInputAttachments(event.arguments[0]);
30225
30733
  const span = parentSpan ? withCurrent(
30226
30734
  parentSpan,
30227
30735
  () => startSpan({
30228
30736
  event: {
30229
- input: event.arguments[0],
30737
+ input,
30230
30738
  metadata
30231
30739
  },
30232
30740
  name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
@@ -30234,7 +30742,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30234
30742
  })
30235
30743
  ) : startSpan({
30236
30744
  event: {
30237
- input: event.arguments[0],
30745
+ input,
30238
30746
  metadata
30239
30747
  },
30240
30748
  name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
@@ -30343,7 +30851,10 @@ function startModelSpan(state, event) {
30343
30851
  state.span,
30344
30852
  () => startSpan({
30345
30853
  event: {
30346
- input: Array.isArray(event.agent?.messages) ? event.agent.messages : void 0,
30854
+ input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
30855
+ event.agent.messages,
30856
+ state.attachmentCache
30857
+ ) : void 0,
30347
30858
  metadata
30348
30859
  },
30349
30860
  name: formatModelSpanName(model),
@@ -30557,6 +31068,7 @@ function finalizeAgentStream(state, error, output) {
30557
31068
  ...output !== void 0 ? { output } : {}
30558
31069
  });
30559
31070
  state.span.end();
31071
+ state.attachmentCache.strings.clear();
30560
31072
  }
30561
31073
  function finalizeMultiAgentStream(state, activeChildParents, error, output) {
30562
31074
  if (state.finalized) {
@@ -30703,6 +31215,166 @@ function extractNodeResultOutput(result) {
30703
31215
  }
30704
31216
  return result;
30705
31217
  }
31218
+ var STRANDS_MEDIA_TYPES = {
31219
+ png: "image/png",
31220
+ jpg: "image/jpeg",
31221
+ jpeg: "image/jpeg",
31222
+ gif: "image/gif",
31223
+ webp: "image/webp",
31224
+ mkv: "video/x-matroska",
31225
+ mov: "video/quicktime",
31226
+ mp4: "video/mp4",
31227
+ webm: "video/webm",
31228
+ flv: "video/x-flv",
31229
+ mpeg: "video/mpeg",
31230
+ mpg: "video/mpeg",
31231
+ wmv: "video/x-ms-wmv",
31232
+ "3gp": "video/3gpp",
31233
+ pdf: "application/pdf",
31234
+ csv: "text/csv",
31235
+ doc: "application/msword",
31236
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
31237
+ xls: "application/vnd.ms-excel",
31238
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
31239
+ html: "text/html",
31240
+ txt: "text/plain",
31241
+ md: "text/markdown",
31242
+ json: "application/json",
31243
+ xml: "application/xml"
31244
+ };
31245
+ function createStrandsAttachmentCache() {
31246
+ return {
31247
+ objects: /* @__PURE__ */ new WeakMap(),
31248
+ strings: new LRUCache({
31249
+ max: MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES
31250
+ })
31251
+ };
31252
+ }
31253
+ function processStrandsInputAttachments(input, cache = createStrandsAttachmentCache()) {
31254
+ try {
31255
+ return processStrandsInputNode(input, cache);
31256
+ } catch (error) {
31257
+ logInstrumentationError5("Strands Agent SDK input attachments", error);
31258
+ return input;
31259
+ }
31260
+ }
31261
+ function processStrandsInputNode(value, cache) {
31262
+ if (value instanceof BaseAttachment) {
31263
+ return value;
31264
+ }
31265
+ if (Array.isArray(value)) {
31266
+ return value.map((child) => processStrandsInputNode(child, cache));
31267
+ }
31268
+ if (!isObject(value)) {
31269
+ return value;
31270
+ }
31271
+ const directMedia = processDirectStrandsMediaBlock(value, cache);
31272
+ if (directMedia !== void 0) {
31273
+ return directMedia;
31274
+ }
31275
+ const wrappedMedia = processWrappedStrandsMediaBlock(value, cache);
31276
+ if (wrappedMedia !== void 0) {
31277
+ return wrappedMedia;
31278
+ }
31279
+ if (value.type === "message" && Array.isArray(value.content)) {
31280
+ return {
31281
+ role: value.role,
31282
+ content: value.content.map(
31283
+ (child) => processStrandsInputNode(child, cache)
31284
+ ),
31285
+ ...value.metadata !== void 0 ? { metadata: value.metadata } : {}
31286
+ };
31287
+ }
31288
+ if (typeof value.toJSON === "function") {
31289
+ return processStrandsInputNode(value.toJSON(), cache);
31290
+ }
31291
+ return Object.fromEntries(
31292
+ Object.entries(value).map(([key, child]) => [
31293
+ key,
31294
+ processStrandsInputNode(child, cache)
31295
+ ])
31296
+ );
31297
+ }
31298
+ function processDirectStrandsMediaBlock(block, cache) {
31299
+ if (!isStrandsMediaBlock(block)) {
31300
+ return void 0;
31301
+ }
31302
+ const mediaKey = block.type === "imageBlock" ? "image" : block.type === "videoBlock" ? "video" : "document";
31303
+ return createStrandsMediaAttachment(mediaKey, block, cache);
31304
+ }
31305
+ function isStrandsMediaBlock(block) {
31306
+ return (block.type === "imageBlock" || block.type === "videoBlock" || block.type === "documentBlock") && typeof block.format === "string" && isObject(block.source);
31307
+ }
31308
+ function processWrappedStrandsMediaBlock(block, cache) {
31309
+ for (const mediaKey of ["image", "video", "document"]) {
31310
+ const media = block[mediaKey];
31311
+ if (!Object.hasOwn(block, mediaKey) || !isObject(media)) {
31312
+ continue;
31313
+ }
31314
+ const processed = createStrandsMediaAttachment(mediaKey, media, cache);
31315
+ if (processed !== void 0) {
31316
+ return processed;
31317
+ }
31318
+ }
31319
+ return void 0;
31320
+ }
31321
+ function createStrandsMediaAttachment(mediaKey, media, cache) {
31322
+ const format = media.format;
31323
+ const source = media.source;
31324
+ if (typeof format !== "string" || !isObject(source) || !Object.hasOwn(source, "bytes")) {
31325
+ return void 0;
31326
+ }
31327
+ const contentType = STRANDS_MEDIA_TYPES[format.toLowerCase()];
31328
+ if (!contentType) {
31329
+ return void 0;
31330
+ }
31331
+ const filename = mediaKey === "document" && typeof media.name === "string" && media.name.length > 0 ? media.name : `${mediaKey}.${format.toLowerCase()}`;
31332
+ const attachment = getOrCreateStrandsAttachment(
31333
+ source.bytes,
31334
+ filename,
31335
+ contentType,
31336
+ cache
31337
+ );
31338
+ if (!attachment) {
31339
+ return void 0;
31340
+ }
31341
+ const { type: _type, ...serializedMedia } = media;
31342
+ const { type: _sourceType, ...serializedSource } = source;
31343
+ return {
31344
+ [mediaKey]: {
31345
+ ...serializedMedia,
31346
+ source: {
31347
+ ...serializedSource,
31348
+ bytes: attachment
31349
+ }
31350
+ }
31351
+ };
31352
+ }
31353
+ function getOrCreateStrandsAttachment(data, filename, contentType, cache) {
31354
+ const key = `${contentType}\0${filename}`;
31355
+ const attachments = typeof data === "string" ? cache.strings.get(data) : isObject(data) ? cache.objects.get(data) : void 0;
31356
+ const cached = attachments?.get(key);
31357
+ if (cached) {
31358
+ return cached;
31359
+ }
31360
+ const blob = convertDataToBlob(data, contentType);
31361
+ if (!blob) {
31362
+ return void 0;
31363
+ }
31364
+ const attachment = new Attachment({
31365
+ data: blob,
31366
+ filename,
31367
+ contentType
31368
+ });
31369
+ const updatedAttachments = attachments ?? /* @__PURE__ */ new Map();
31370
+ updatedAttachments.set(key, attachment);
31371
+ if (typeof data === "string") {
31372
+ cache.strings.set(data, updatedAttachments);
31373
+ } else if (isObject(data)) {
31374
+ cache.objects.set(data, updatedAttachments);
31375
+ }
31376
+ return attachment;
31377
+ }
30706
31378
  function normalizeContentBlocks(blocks) {
30707
31379
  const text = blocks.map((block) => typeof block.text === "string" ? block.text : void 0).filter((part) => Boolean(part)).join("");
30708
31380
  return text.length > 0 ? text : blocks;
@@ -30832,6 +31504,7 @@ var BraintrustPlugin = class extends BasePlugin {
30832
31504
  gitHubCopilotPlugin = null;
30833
31505
  fluePlugin = null;
30834
31506
  langChainPlugin = null;
31507
+ langSmithPlugin = null;
30835
31508
  piCodingAgentPlugin = null;
30836
31509
  strandsAgentSDKPlugin = null;
30837
31510
  constructor(config = {}) {
@@ -30928,6 +31601,12 @@ var BraintrustPlugin = class extends BasePlugin {
30928
31601
  this.langChainPlugin = new LangChainPlugin();
30929
31602
  this.langChainPlugin.enable();
30930
31603
  }
31604
+ if (integrations.langsmith !== false) {
31605
+ this.langSmithPlugin = new LangSmithPlugin({
31606
+ skipLangChainRuns: integrations.langchain !== false
31607
+ });
31608
+ this.langSmithPlugin.enable();
31609
+ }
30931
31610
  }
30932
31611
  onDisable() {
30933
31612
  if (this.openaiPlugin) {
@@ -31018,6 +31697,10 @@ var BraintrustPlugin = class extends BasePlugin {
31018
31697
  this.langChainPlugin.disable();
31019
31698
  this.langChainPlugin = null;
31020
31699
  }
31700
+ if (this.langSmithPlugin) {
31701
+ this.langSmithPlugin.disable();
31702
+ this.langSmithPlugin = null;
31703
+ }
31021
31704
  }
31022
31705
  };
31023
31706
 
@@ -31082,7 +31765,8 @@ var envIntegrationAliases = {
31082
31765
  langchain: "langchain",
31083
31766
  "langchain-js": "langchain",
31084
31767
  "@langchain": "langchain",
31085
- langgraph: "langgraph"
31768
+ langgraph: "langgraph",
31769
+ langsmith: "langsmith"
31086
31770
  };
31087
31771
  function getDefaultInstrumentationIntegrations() {
31088
31772
  return {
@@ -31113,6 +31797,7 @@ function getDefaultInstrumentationIntegrations() {
31113
31797
  gitHubCopilot: true,
31114
31798
  langchain: true,
31115
31799
  langgraph: true,
31800
+ langsmith: true,
31116
31801
  piCodingAgent: true,
31117
31802
  strandsAgentSDK: true
31118
31803
  };
@@ -31509,6 +32194,9 @@ __export(exports_exports, {
31509
32194
  wrapGoogleGenAI: () => wrapGoogleGenAI,
31510
32195
  wrapGroq: () => wrapGroq,
31511
32196
  wrapHuggingFace: () => wrapHuggingFace,
32197
+ wrapLangSmithClient: () => wrapLangSmithClient,
32198
+ wrapLangSmithRunTrees: () => wrapLangSmithRunTrees,
32199
+ wrapLangSmithTraceable: () => wrapLangSmithTraceable,
31512
32200
  wrapMastraAgent: () => wrapMastraAgent,
31513
32201
  wrapMistral: () => wrapMistral,
31514
32202
  wrapOpenAI: () => wrapOpenAI,
@@ -32995,9 +33683,6 @@ var EveBridge = class {
32995
33683
  this.state = state;
32996
33684
  }
32997
33685
  eventQueuesBySession = /* @__PURE__ */ new Map();
32998
- sessionsById = new LRUCache({
32999
- max: MAX_EVE_CACHE_ENTRIES
33000
- });
33001
33686
  completedToolKeys = new LRUCache({
33002
33687
  max: MAX_EVE_CACHE_ENTRIES
33003
33688
  });
@@ -33164,7 +33849,7 @@ var EveBridge = class {
33164
33849
  async handleEvent(event, ctx, hookMetadata) {
33165
33850
  switch (event.type) {
33166
33851
  case "session.started":
33167
- await this.handleSessionStarted(event, ctx, hookMetadata);
33852
+ this.handleSessionStarted(event, ctx, hookMetadata);
33168
33853
  return true;
33169
33854
  case "turn.started":
33170
33855
  await this.handleTurnStarted(event, ctx, hookMetadata);
@@ -33200,22 +33885,22 @@ var EveBridge = class {
33200
33885
  this.handleStepFailed(event, ctx);
33201
33886
  return true;
33202
33887
  case "turn.completed":
33203
- await this.handleTurnCompleted(event, ctx);
33888
+ this.handleTurnCompleted(event, ctx);
33204
33889
  return true;
33205
33890
  case "turn.failed":
33206
- await this.handleTurnFailed(event, ctx);
33891
+ this.handleTurnFailed(event, ctx);
33207
33892
  return true;
33208
33893
  case "session.failed":
33209
- await this.handleSessionFailed(event, ctx);
33894
+ this.handleSessionFailed(event, ctx);
33210
33895
  return true;
33211
33896
  case "session.completed":
33212
- await this.handleSessionCompleted(event, ctx);
33897
+ this.handleSessionCompleted(event, ctx);
33213
33898
  return true;
33214
33899
  default:
33215
33900
  return false;
33216
33901
  }
33217
33902
  }
33218
- async handleSessionStarted(event, ctx, hookMetadata) {
33903
+ handleSessionStarted(event, ctx, hookMetadata) {
33219
33904
  const sessionId = sessionIdFromContext(ctx);
33220
33905
  if (!sessionId) {
33221
33906
  return;
@@ -33231,7 +33916,6 @@ var EveBridge = class {
33231
33916
  metadata: { ...normalized.metadata, ...metadata }
33232
33917
  };
33233
33918
  });
33234
- await this.ensureSession(sessionId, ctx, metadata, eventTime2(event));
33235
33919
  for (const [key, turn] of this.turnsByKey) {
33236
33920
  if (!key.startsWith(`${sessionId}:`)) {
33237
33921
  continue;
@@ -33249,21 +33933,19 @@ var EveBridge = class {
33249
33933
  if (!sessionId) {
33250
33934
  return;
33251
33935
  }
33252
- const session = await this.ensureSession(
33253
- sessionId,
33254
- ctx,
33255
- hookMetadata ?? {},
33256
- eventTime2(event)
33257
- );
33258
33936
  const key = turnKey2(sessionId, event.data.turnId);
33259
- const metadata = { ...session.metadata };
33937
+ const metadata = {
33938
+ ...readEveTraceState(this.state).metadata,
33939
+ ...hookMetadata ?? {},
33940
+ "eve.session_id": sessionId
33941
+ };
33260
33942
  const existing = this.turnsByKey.get(key);
33261
33943
  if (existing) {
33262
33944
  existing.metadata = { ...existing.metadata, ...metadata };
33263
33945
  existing.span.log({ metadata: existing.metadata });
33264
33946
  return;
33265
33947
  }
33266
- const span = await this.startTurnSpan(session, event, metadata);
33948
+ const span = await this.startTurnSpan(sessionId, event, ctx, metadata);
33267
33949
  span.log({ metadata });
33268
33950
  this.turnsByKey.set(key, {
33269
33951
  key,
@@ -33301,10 +33983,7 @@ var EveBridge = class {
33301
33983
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
33302
33984
  }
33303
33985
  const stepOrdinal = this.stepOrdinal(event);
33304
- const metadata = {
33305
- ...turn.metadata,
33306
- ...this.sessionsById.get(sessionId)?.metadata ?? {}
33307
- };
33986
+ const metadata = { ...turn.metadata };
33308
33987
  const input = consumeCapturedEveModelInput(
33309
33988
  this.state,
33310
33989
  sessionId,
@@ -33399,6 +34078,28 @@ var EveBridge = class {
33399
34078
  if (!step) {
33400
34079
  return;
33401
34080
  }
34081
+ const toolCallsById = /* @__PURE__ */ new Map();
34082
+ if (Array.isArray(step.output) && isObject(step.output[0])) {
34083
+ const message = step.output[0]["message"];
34084
+ if (isObject(message) && Array.isArray(message["tool_calls"])) {
34085
+ for (const toolCall of message["tool_calls"]) {
34086
+ if (isObject(toolCall) && typeof toolCall["id"] === "string") {
34087
+ toolCallsById.set(toolCall["id"], toolCall);
34088
+ }
34089
+ }
34090
+ }
34091
+ }
34092
+ for (const action of traceActions) {
34093
+ const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
34094
+ toolCallsById.set(action.callId, {
34095
+ function: {
34096
+ arguments: JSON.stringify(action.input),
34097
+ name
34098
+ },
34099
+ id: action.callId,
34100
+ type: "function"
34101
+ });
34102
+ }
33402
34103
  step.output = [
33403
34104
  {
33404
34105
  finish_reason: "tool_calls",
@@ -33406,17 +34107,7 @@ var EveBridge = class {
33406
34107
  message: {
33407
34108
  content: null,
33408
34109
  role: "assistant",
33409
- tool_calls: traceActions.map((action) => {
33410
- const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
33411
- return {
33412
- function: {
33413
- arguments: JSON.stringify(action.input),
33414
- name
33415
- },
33416
- id: action.callId,
33417
- type: "function"
33418
- };
33419
- })
34110
+ tool_calls: [...toolCallsById.values()]
33420
34111
  }
33421
34112
  }
33422
34113
  ];
@@ -33663,17 +34354,11 @@ var EveBridge = class {
33663
34354
  )
33664
34355
  });
33665
34356
  }
33666
- async handleSessionFailed(event, ctx) {
34357
+ handleSessionFailed(event, ctx) {
33667
34358
  const sessionId = event.data.sessionId || sessionIdFromContext(ctx);
33668
34359
  if (!sessionId) {
33669
34360
  return;
33670
34361
  }
33671
- const session = await this.ensureSession(
33672
- sessionId,
33673
- ctx,
33674
- {},
33675
- eventTime2(event)
33676
- );
33677
34362
  const error = errorFromMessage(
33678
34363
  event.data.message,
33679
34364
  event.data.code,
@@ -33690,29 +34375,20 @@ var EveBridge = class {
33690
34375
  }
33691
34376
  for (const [key, tool] of this.toolsByCallKey) {
33692
34377
  if (key.startsWith(`${sessionId}:`)) {
33693
- const endTime2 = eventTime2(event);
34378
+ const endTime = eventTime2(event);
33694
34379
  if (!tool.endedByTurn) {
33695
34380
  tool.span.log({ metadata: tool.metadata });
33696
- tool.span.end(endTime2 === void 0 ? void 0 : { endTime: endTime2 });
34381
+ tool.span.end(endTime === void 0 ? void 0 : { endTime });
33697
34382
  tool.endedByTurn = true;
33698
34383
  }
33699
34384
  }
33700
34385
  }
33701
- session.span.log({ error });
33702
- const endTime = eventTime2(event);
33703
- session.span.end(endTime === void 0 ? void 0 : { endTime });
33704
34386
  }
33705
- async handleSessionCompleted(event, ctx) {
34387
+ handleSessionCompleted(event, ctx) {
33706
34388
  const sessionId = sessionIdFromContext(ctx);
33707
34389
  if (!sessionId) {
33708
34390
  return;
33709
34391
  }
33710
- const session = await this.ensureSession(
33711
- sessionId,
33712
- ctx,
33713
- {},
33714
- eventTime2(event)
33715
- );
33716
34392
  for (const [key, turn] of this.turnsByKey) {
33717
34393
  if (!key.startsWith(`${sessionId}:`)) {
33718
34394
  continue;
@@ -33723,82 +34399,29 @@ var EveBridge = class {
33723
34399
  }
33724
34400
  for (const [key, tool] of this.toolsByCallKey) {
33725
34401
  if (key.startsWith(`${sessionId}:`) && !tool.endedByTurn) {
33726
- const endTime2 = eventTime2(event);
34402
+ const endTime = eventTime2(event);
33727
34403
  tool.span.log({ metadata: tool.metadata });
33728
- tool.span.end(endTime2 === void 0 ? void 0 : { endTime: endTime2 });
34404
+ tool.span.end(endTime === void 0 ? void 0 : { endTime });
33729
34405
  tool.endedByTurn = true;
33730
34406
  }
33731
34407
  }
33732
- session.span.log({ metadata: session.metadata });
33733
- const endTime = eventTime2(event);
33734
- session.span.end(endTime === void 0 ? void 0 : { endTime });
33735
- }
33736
- async ensureSession(sessionId, ctx, metadata, startTime) {
33737
- metadata = {
33738
- ...readEveTraceState(this.state).metadata,
33739
- ...metadata
33740
- };
33741
- const existing = this.sessionsById.get(sessionId);
33742
- if (existing) {
33743
- existing.metadata = { ...existing.metadata, ...metadata };
33744
- existing.span.log({ metadata: existing.metadata });
33745
- return existing;
33746
- }
33747
- const lineage = parentLineageFromContext(ctx);
33748
- const parentSubagent = lineage ? this.toolsByCallKey.get(toolKey3(lineage.sessionId, lineage.callId)) : void 0;
33749
- const activeParent = currentSpan();
33750
- const [
33751
- { rowId: eventId, spanId },
33752
- parentSubagentSpanId,
33753
- fallbackRootSpanId
33754
- ] = await Promise.all([
33755
- generateEveIds("session", sessionId),
33756
- lineage ? spanIdForSubagent(lineage.sessionId, lineage.callId) : Promise.resolve(void 0),
33757
- lineage ? rootSpanIdForSession(lineage.rootSessionId) : rootSpanIdForSession(sessionId)
33758
- ]);
33759
- const span = await this.startEveSpan({
33760
- event: {
33761
- id: eventId,
33762
- metadata
33763
- },
33764
- name: "eve.session",
33765
- parentSpanIds: lineage && parentSubagentSpanId ? {
33766
- rootSpanId: parentSubagent?.span.rootSpanId ?? fallbackRootSpanId,
33767
- spanId: parentSubagentSpanId
33768
- } : !Object.is(activeParent, NOOP_SPAN) ? {
33769
- rootSpanId: activeParent.rootSpanId,
33770
- spanId: activeParent.spanId
33771
- } : {
33772
- parentSpanIds: [],
33773
- rootSpanId: fallbackRootSpanId
33774
- },
33775
- spanAttributes: { type: "task" /* TASK */ },
33776
- spanId,
33777
- startTime
33778
- });
33779
- span.log({ metadata });
33780
- const session = { metadata, sessionId, span };
33781
- this.sessionsById.set(sessionId, session);
33782
- return session;
33783
34408
  }
33784
34409
  async ensureTurn(event, ctx, hookMetadata) {
33785
34410
  const sessionId = sessionIdFromContext(ctx);
33786
34411
  if (!sessionId) {
33787
34412
  return void 0;
33788
34413
  }
33789
- const session = await this.ensureSession(
33790
- sessionId,
33791
- ctx,
33792
- hookMetadata ?? {},
33793
- eventTime2(event)
33794
- );
33795
34414
  const key = turnKey2(sessionId, event.data.turnId);
33796
34415
  const existing = this.turnsByKey.get(key);
33797
34416
  if (existing) {
33798
34417
  return existing;
33799
34418
  }
33800
- const metadata = { ...session.metadata };
33801
- const span = await this.startTurnSpan(session, event, metadata);
34419
+ const metadata = {
34420
+ ...readEveTraceState(this.state).metadata,
34421
+ ...hookMetadata ?? {},
34422
+ "eve.session_id": sessionId
34423
+ };
34424
+ const span = await this.startTurnSpan(sessionId, event, ctx, metadata);
33802
34425
  span.log({ metadata });
33803
34426
  const state = {
33804
34427
  key,
@@ -33985,22 +34608,35 @@ var EveBridge = class {
33985
34608
  this.toolsByCallKey.set(toolKey3(sessionId, result.callId), state);
33986
34609
  return state;
33987
34610
  }
33988
- async startTurnSpan(session, event, metadata) {
33989
- const { rowId: eventId, spanId } = await generateEveIds(
33990
- "turn",
33991
- session.sessionId,
33992
- event.data.turnId
33993
- );
34611
+ async startTurnSpan(sessionId, event, ctx, metadata) {
34612
+ const session = isObject(ctx) ? ctx["session"] : void 0;
34613
+ const parent = isObject(session) ? session["parent"] : void 0;
34614
+ const parentTurn = isObject(parent) ? parent["turn"] : void 0;
34615
+ const parentLineage = isObject(parent) && typeof parent["callId"] === "string" && typeof parent["sessionId"] === "string" && isObject(parentTurn) && typeof parentTurn["id"] === "string" ? {
34616
+ callId: parent["callId"],
34617
+ sessionId: parent["sessionId"],
34618
+ turnId: parentTurn["id"]
34619
+ } : void 0;
34620
+ const [{ rowId: eventId, spanId }, rootSpanId, parentSpanId] = await Promise.all([
34621
+ generateEveIds("turn", sessionId, event.data.turnId),
34622
+ deterministicEveId(
34623
+ "eve:root",
34624
+ parentLineage?.sessionId ?? sessionId,
34625
+ parentLineage?.turnId ?? event.data.turnId
34626
+ ),
34627
+ parentLineage ? deterministicEveId(
34628
+ "eve:subagent",
34629
+ parentLineage.sessionId,
34630
+ parentLineage.callId
34631
+ ) : Promise.resolve(void 0)
34632
+ ]);
33994
34633
  return await this.startEveSpan({
33995
34634
  event: {
33996
34635
  id: eventId,
33997
34636
  metadata
33998
34637
  },
33999
34638
  name: "eve.turn",
34000
- parentSpanIds: {
34001
- rootSpanId: session.span.rootSpanId,
34002
- spanId: session.span.spanId
34003
- },
34639
+ parentSpanIds: parentSpanId ? { rootSpanId, spanId: parentSpanId } : { parentSpanIds: [], rootSpanId },
34004
34640
  spanAttributes: { type: "task" /* TASK */ },
34005
34641
  spanId,
34006
34642
  startTime: eventTime2(event)
@@ -34061,7 +34697,6 @@ var EveBridge = class {
34061
34697
  }
34062
34698
  cleanupSession(sessionId) {
34063
34699
  const keyPrefix = `${sessionId}:`;
34064
- this.sessionsById.delete(sessionId);
34065
34700
  for (const key of this.turnsByKey.keys()) {
34066
34701
  if (key.startsWith(keyPrefix)) {
34067
34702
  this.turnsByKey.delete(key);
@@ -34252,7 +34887,7 @@ function modelMetadataFromRuntime(runtime) {
34252
34887
  return {};
34253
34888
  }
34254
34889
  const modelId = runtime["modelId"];
34255
- return typeof modelId === "string" ? modelMetadataFromModelId(modelId) : {};
34890
+ return typeof modelId === "string" && !modelId.trim().startsWith("dynamic:") ? modelMetadataFromModelId(modelId) : {};
34256
34891
  }
34257
34892
  function modelMetadataFromModelId(modelId) {
34258
34893
  const normalized = modelId.trim();
@@ -34285,26 +34920,6 @@ function toolMetadataFromTurn(turn) {
34285
34920
  const { model: _model, provider: _provider, ...metadata } = turn.metadata;
34286
34921
  return metadata;
34287
34922
  }
34288
- function parentLineageFromContext(ctx) {
34289
- if (!isObject(ctx)) {
34290
- return void 0;
34291
- }
34292
- const session = ctx.session;
34293
- if (!isObject(session)) {
34294
- return void 0;
34295
- }
34296
- const parent = session["parent"];
34297
- if (!isObject(parent)) {
34298
- return void 0;
34299
- }
34300
- const callId = parent["callId"];
34301
- const rootSessionId = parent["rootSessionId"];
34302
- const sessionId = parent["sessionId"];
34303
- if (typeof callId !== "string" || typeof rootSessionId !== "string" || typeof sessionId !== "string") {
34304
- return void 0;
34305
- }
34306
- return { callId, rootSessionId, sessionId };
34307
- }
34308
34923
  function isToolCallAction(action) {
34309
34924
  return isObject(action) && action["kind"] === "tool-call" && typeof action["callId"] === "string" && typeof action["toolName"] === "string" && isObject(action["input"]);
34310
34925
  }
@@ -34360,9 +34975,6 @@ function turnKey2(sessionId, turnId) {
34360
34975
  function toolKey3(sessionId, callId) {
34361
34976
  return `${sessionId}:${callId}`;
34362
34977
  }
34363
- async function rootSpanIdForSession(sessionId) {
34364
- return deterministicEveId("eve:root", sessionId);
34365
- }
34366
34978
  async function generateEveIds(kind, ...parts) {
34367
34979
  const [rowId, spanId] = await Promise.all([
34368
34980
  deterministicEveId(`eve:row:${kind}`, ...parts),
@@ -34370,9 +34982,6 @@ async function generateEveIds(kind, ...parts) {
34370
34982
  ]);
34371
34983
  return { rowId, spanId };
34372
34984
  }
34373
- async function spanIdForSubagent(sessionId, callId) {
34374
- return deterministicEveId("eve:subagent", sessionId, callId);
34375
- }
34376
34985
  async function deterministicEveId(...parts) {
34377
34986
  const data = new TextEncoder().encode(
34378
34987
  parts.map((part) => `${part.length}:${part}`).join("\0")
@@ -34545,6 +35154,15 @@ function modelMetrics(attributes) {
34545
35154
  }
34546
35155
  return Object.keys(out).length > 0 ? out : void 0;
34547
35156
  }
35157
+ function timeToFirstTokenSeconds(attributes, spanStartSeconds) {
35158
+ if (!isObject(attributes)) return void 0;
35159
+ if (spanStartSeconds === void 0) return void 0;
35160
+ const raw = attributes.completionStartTime;
35161
+ const completionStart = raw instanceof Date || typeof raw === "string" || typeof raw === "number" ? epochSeconds(raw) : void 0;
35162
+ if (completionStart === void 0) return void 0;
35163
+ const ttft = completionStart - spanStartSeconds;
35164
+ return Number.isFinite(ttft) && ttft >= 0 ? ttft : void 0;
35165
+ }
34548
35166
  function buildMetadata(exported) {
34549
35167
  const out = {};
34550
35168
  if (exported.entityId !== void 0) out.entity_id = exported.entityId;
@@ -34669,8 +35287,15 @@ var BraintrustObservabilityExporter = class {
34669
35287
  event.metadata = metadata;
34670
35288
  }
34671
35289
  const metrics = modelMetrics(exported.attributes);
34672
- if (metrics) {
34673
- event.metrics = metrics;
35290
+ const ttft = timeToFirstTokenSeconds(
35291
+ exported.attributes,
35292
+ epochSeconds(exported.startTime)
35293
+ );
35294
+ if (metrics || ttft !== void 0) {
35295
+ event.metrics = {
35296
+ ...metrics ?? {},
35297
+ ...ttft !== void 0 ? { time_to_first_token: ttft } : {}
35298
+ };
34674
35299
  }
34675
35300
  if (Object.keys(event).length > 0) {
34676
35301
  record.span.log(event);
@@ -35549,17 +36174,17 @@ function wrapGenkit(genkit) {
35549
36174
  console.warn("Unsupported Genkit object. Not wrapping.");
35550
36175
  return genkit;
35551
36176
  }
35552
- function isRecord2(value) {
36177
+ function isRecord3(value) {
35553
36178
  return typeof value === "object" && value !== null;
35554
36179
  }
35555
36180
  function isPropertyBag(value) {
35556
- return isRecord2(value) || typeof value === "function";
36181
+ return isRecord3(value) || typeof value === "function";
35557
36182
  }
35558
36183
  function hasFunction(value, methodName) {
35559
36184
  return isPropertyBag(value) && methodName in value && typeof value[methodName] === "function";
35560
36185
  }
35561
36186
  function isGenkitInstance(value) {
35562
- return isRecord2(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
36187
+ return isRecord3(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
35563
36188
  }
35564
36189
  function isGenkitModule(value) {
35565
36190
  return hasFunction(value, "genkit");
@@ -35613,7 +36238,7 @@ function patchGenkitRegistry(instance) {
35613
36238
  patchGenkitRegistryConstructor(registry2);
35614
36239
  }
35615
36240
  function patchGenkitRegistryLookup(registry2) {
35616
- if (!isRecord2(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
36241
+ if (!isRecord3(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
35617
36242
  return;
35618
36243
  }
35619
36244
  const originalLookupAction = registry2.lookupAction;
@@ -35639,7 +36264,7 @@ function patchGenkitRegistryLookup(registry2) {
35639
36264
  }
35640
36265
  }
35641
36266
  function patchGenkitRegistryConstructor(registry2) {
35642
- if (!isRecord2(registry2)) {
36267
+ if (!isRecord3(registry2)) {
35643
36268
  return;
35644
36269
  }
35645
36270
  const constructor = registry2.constructor;
@@ -35655,7 +36280,7 @@ function patchGenkitRegistryConstructor(registry2) {
35655
36280
  configurable: true,
35656
36281
  value: (...args) => {
35657
36282
  const childRegistry = originalWithParent.apply(constructor, args);
35658
- if (args.some((arg) => isRecord2(arg) && hasRegistryPatchedFlag(arg))) {
36283
+ if (args.some((arg) => isRecord3(arg) && hasRegistryPatchedFlag(arg))) {
35659
36284
  patchGenkitRegistryLookup(childRegistry);
35660
36285
  patchGenkitRegistryConstructor(childRegistry);
35661
36286
  }
@@ -35754,7 +36379,7 @@ function hasRegistryConstructorPatchedFlag(value) {
35754
36379
  );
35755
36380
  }
35756
36381
  function isPromiseLike2(value) {
35757
- return isRecord2(value) && "then" in value && typeof value.then === "function";
36382
+ return isRecord3(value) && "then" in value && typeof value.then === "function";
35758
36383
  }
35759
36384
 
35760
36385
  // src/wrappers/huggingface.ts
@@ -36117,14 +36742,14 @@ function wrapMistral(mistral) {
36117
36742
  console.warn("Unsupported Mistral library. Not wrapping.");
36118
36743
  return mistral;
36119
36744
  }
36120
- function isRecord3(value) {
36745
+ function isRecord4(value) {
36121
36746
  return typeof value === "object" && value !== null;
36122
36747
  }
36123
36748
  function hasFunction3(value, methodName) {
36124
- return isRecord3(value) && methodName in value && typeof value[methodName] === "function";
36749
+ return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
36125
36750
  }
36126
36751
  function isSupportedMistralClient(value) {
36127
- if (!isRecord3(value)) {
36752
+ if (!isRecord4(value)) {
36128
36753
  return false;
36129
36754
  }
36130
36755
  return value.chat !== void 0 && hasChat(value.chat) || value.embeddings !== void 0 && hasEmbeddings(value.embeddings) || value.fim !== void 0 && hasFim(value.fim) || value.agents !== void 0 && hasAgents(value.agents) || value.classifiers !== void 0 && hasClassifiers(value.classifiers);
@@ -36308,14 +36933,14 @@ function wrapCohere(cohere) {
36308
36933
  return cohere;
36309
36934
  }
36310
36935
  var cohereProxyCache = /* @__PURE__ */ new WeakMap();
36311
- function isRecord4(value) {
36936
+ function isRecord5(value) {
36312
36937
  return typeof value === "object" && value !== null;
36313
36938
  }
36314
36939
  function hasFunction4(value, methodName) {
36315
- return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
36940
+ return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
36316
36941
  }
36317
36942
  function isSupportedCohereClient(value) {
36318
- if (!isRecord4(value)) {
36943
+ if (!isRecord5(value)) {
36319
36944
  return false;
36320
36945
  }
36321
36946
  return hasFunction4(value, "chat") || hasFunction4(value, "chatStream") || hasFunction4(value, "embed") || hasFunction4(value, "rerank");
@@ -36375,20 +37000,20 @@ function wrapGroq(groq) {
36375
37000
  console.warn("Unsupported Groq library. Not wrapping.");
36376
37001
  return groq;
36377
37002
  }
36378
- function isRecord5(value) {
37003
+ function isRecord6(value) {
36379
37004
  return typeof value === "object" && value !== null;
36380
37005
  }
36381
37006
  function hasFunction5(value, methodName) {
36382
- return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
37007
+ return isRecord6(value) && methodName in value && typeof value[methodName] === "function";
36383
37008
  }
36384
37009
  function hasChat2(value) {
36385
- return isRecord5(value) && isRecord5(value.completions) && hasFunction5(value.completions, "create");
37010
+ return isRecord6(value) && isRecord6(value.completions) && hasFunction5(value.completions, "create");
36386
37011
  }
36387
37012
  function hasEmbeddings2(value) {
36388
37013
  return hasFunction5(value, "create");
36389
37014
  }
36390
37015
  function isSupportedGroqClient(value) {
36391
- return isRecord5(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
37016
+ return isRecord6(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
36392
37017
  }
36393
37018
  function groqProxy(groq) {
36394
37019
  const privateMethodWorkaroundCache = /* @__PURE__ */ new WeakMap();
@@ -36471,11 +37096,11 @@ var BEDROCK_RUNTIME_OPERATION_METHODS = /* @__PURE__ */ new Set([
36471
37096
  "invokeModelWithBidirectionalStream",
36472
37097
  "invokeModelWithResponseStream"
36473
37098
  ]);
36474
- function isRecord6(value) {
37099
+ function isRecord7(value) {
36475
37100
  return typeof value === "object" && value !== null;
36476
37101
  }
36477
37102
  function isSupportedBedrockRuntimeClient(value) {
36478
- return isRecord6(value) && typeof value.send === "function";
37103
+ return isRecord7(value) && typeof value.send === "function";
36479
37104
  }
36480
37105
  function bedrockRuntimeProxy(client) {
36481
37106
  const cached = bedrockRuntimeProxyCache.get(client);
@@ -36594,6 +37219,271 @@ function wrappedResumeSession(client) {
36594
37219
  );
36595
37220
  }
36596
37221
 
37222
+ // src/wrappers/langsmith.ts
37223
+ var WRAPPED_CLIENT_CLASS = /* @__PURE__ */ Symbol.for(
37224
+ "braintrust.langsmith.wrapped-client-class"
37225
+ );
37226
+ var WRAPPED_CLIENT_INSTANCE = /* @__PURE__ */ Symbol.for(
37227
+ "braintrust.langsmith.wrapped-client-instance"
37228
+ );
37229
+ var WRAPPED_CLIENT_NAMESPACE = /* @__PURE__ */ Symbol.for(
37230
+ "braintrust.langsmith.wrapped-client-namespace"
37231
+ );
37232
+ var WRAPPED_RUN_TREE_CLASS = /* @__PURE__ */ Symbol.for(
37233
+ "braintrust.langsmith.wrapped-run-tree-class"
37234
+ );
37235
+ var WRAPPED_RUN_TREE_INSTANCE = /* @__PURE__ */ Symbol.for(
37236
+ "braintrust.langsmith.wrapped-run-tree-instance"
37237
+ );
37238
+ var WRAPPED_RUN_TREES_NAMESPACE = /* @__PURE__ */ Symbol.for(
37239
+ "braintrust.langsmith.wrapped-run-trees-namespace"
37240
+ );
37241
+ var WRAPPED_TRACEABLE = /* @__PURE__ */ Symbol.for("braintrust.langsmith.wrapped-traceable");
37242
+ var WRAPPED_TRACEABLE_NAMESPACE = /* @__PURE__ */ Symbol.for(
37243
+ "braintrust.langsmith.wrapped-traceable-namespace"
37244
+ );
37245
+ function wrapLangSmithTraceable(namespace) {
37246
+ return wrapNamespaceExport(
37247
+ namespace,
37248
+ "traceable",
37249
+ WRAPPED_TRACEABLE_NAMESPACE,
37250
+ (value) => wrapTraceable(value)
37251
+ );
37252
+ }
37253
+ function wrapLangSmithRunTrees(namespace) {
37254
+ return wrapNamespaceExport(
37255
+ namespace,
37256
+ "RunTree",
37257
+ WRAPPED_RUN_TREES_NAMESPACE,
37258
+ (value) => wrapRunTreeClass(value)
37259
+ );
37260
+ }
37261
+ function wrapLangSmithClient(namespace) {
37262
+ return wrapNamespaceExport(
37263
+ namespace,
37264
+ "Client",
37265
+ WRAPPED_CLIENT_NAMESPACE,
37266
+ (value) => wrapClientClass(value)
37267
+ );
37268
+ }
37269
+ function wrapNamespaceExport(namespace, exportName, marker, wrap2) {
37270
+ if (!namespace || typeof namespace !== "object") {
37271
+ return namespace;
37272
+ }
37273
+ const candidate = namespace;
37274
+ if (candidate[marker] === true) {
37275
+ return namespace;
37276
+ }
37277
+ if (typeof candidate[exportName] !== "function") {
37278
+ console.warn(
37279
+ `Unsupported LangSmith ${exportName} namespace. Not wrapping.`
37280
+ );
37281
+ return namespace;
37282
+ }
37283
+ const target = isModuleNamespace5(namespace) ? Object.setPrototypeOf({}, namespace) : candidate;
37284
+ const moduleNamespace = target !== candidate;
37285
+ let wrappedExport;
37286
+ return new Proxy(target, {
37287
+ get(target2, prop, receiver) {
37288
+ if (prop === marker) {
37289
+ return true;
37290
+ }
37291
+ const value = Reflect.get(target2, prop, receiver);
37292
+ if (prop !== exportName || typeof value !== "function") {
37293
+ return value;
37294
+ }
37295
+ wrappedExport ??= wrap2(value);
37296
+ return wrappedExport;
37297
+ },
37298
+ getOwnPropertyDescriptor(target2, prop) {
37299
+ const descriptor = Reflect.getOwnPropertyDescriptor(target2, prop);
37300
+ if (descriptor || !moduleNamespace) {
37301
+ return descriptor;
37302
+ }
37303
+ const namespaceDescriptor = Reflect.getOwnPropertyDescriptor(
37304
+ candidate,
37305
+ prop
37306
+ );
37307
+ return namespaceDescriptor ? { ...namespaceDescriptor, configurable: true } : void 0;
37308
+ },
37309
+ has(target2, prop) {
37310
+ return Reflect.has(target2, prop) || moduleNamespace && prop in candidate;
37311
+ },
37312
+ ownKeys(target2) {
37313
+ return moduleNamespace ? Reflect.ownKeys(candidate) : Reflect.ownKeys(target2);
37314
+ }
37315
+ });
37316
+ }
37317
+ function isModuleNamespace5(value) {
37318
+ if (!value || typeof value !== "object") {
37319
+ return false;
37320
+ }
37321
+ if (value.constructor?.name === "Module") {
37322
+ return true;
37323
+ }
37324
+ const firstKey = Object.keys(value)[0];
37325
+ if (!firstKey) {
37326
+ return false;
37327
+ }
37328
+ const descriptor = Object.getOwnPropertyDescriptor(value, firstKey);
37329
+ return descriptor ? !descriptor.configurable && !descriptor.writable : false;
37330
+ }
37331
+ function wrapTraceable(traceable2) {
37332
+ if (traceable2[WRAPPED_TRACEABLE]) {
37333
+ return traceable2;
37334
+ }
37335
+ return new Proxy(traceable2, {
37336
+ get(target, prop, receiver) {
37337
+ if (prop === WRAPPED_TRACEABLE) {
37338
+ return true;
37339
+ }
37340
+ return Reflect.get(target, prop, receiver);
37341
+ },
37342
+ apply(target, thisArg, argArray) {
37343
+ const [fn, rawConfig] = argArray;
37344
+ const config = rawConfig && typeof rawConfig === "object" ? rawConfig : void 0;
37345
+ const originalOnEnd = config?.on_end;
37346
+ const wrappedConfig = {
37347
+ ...config,
37348
+ on_end(runTree) {
37349
+ publishRunUpdate(runTree);
37350
+ if (originalOnEnd) {
37351
+ Reflect.apply(originalOnEnd, config, [runTree]);
37352
+ }
37353
+ }
37354
+ };
37355
+ return Reflect.apply(target, thisArg, [fn, wrappedConfig]);
37356
+ }
37357
+ });
37358
+ }
37359
+ function wrapRunTreeClass(RunTree) {
37360
+ if (RunTree[WRAPPED_RUN_TREE_CLASS]) {
37361
+ return RunTree;
37362
+ }
37363
+ return new Proxy(RunTree, {
37364
+ get(target, prop, receiver) {
37365
+ if (prop === WRAPPED_RUN_TREE_CLASS) {
37366
+ return true;
37367
+ }
37368
+ const value = Reflect.get(target, prop, receiver);
37369
+ return typeof value === "function" ? value.bind(target) : value;
37370
+ },
37371
+ construct(target, args, newTarget) {
37372
+ return wrapRunTreeInstance(Reflect.construct(target, args, newTarget));
37373
+ }
37374
+ });
37375
+ }
37376
+ function wrapRunTreeInstance(runTree) {
37377
+ if (runTree[WRAPPED_RUN_TREE_INSTANCE]) {
37378
+ return runTree;
37379
+ }
37380
+ return new Proxy(runTree, {
37381
+ get(target, prop, receiver) {
37382
+ if (prop === WRAPPED_RUN_TREE_INSTANCE) {
37383
+ return true;
37384
+ }
37385
+ const value = Reflect.get(target, prop, receiver);
37386
+ if (typeof value !== "function") {
37387
+ return value;
37388
+ }
37389
+ let wrapped;
37390
+ if (prop === "createChild") {
37391
+ wrapped = (...args) => wrapRunTreeInstance(Reflect.apply(value, target, args));
37392
+ } else if (prop === "postRun") {
37393
+ const method = value;
37394
+ wrapped = (...args) => langSmithChannels.createRun.tracePromise(
37395
+ () => Reflect.apply(method, target, args),
37396
+ { arguments: [target] }
37397
+ );
37398
+ } else if (prop === "patchRun") {
37399
+ const method = value;
37400
+ wrapped = (...args) => langSmithChannels.updateRun.tracePromise(
37401
+ () => Reflect.apply(method, target, args),
37402
+ {
37403
+ arguments: [
37404
+ typeof target.id === "string" ? target.id : "",
37405
+ target
37406
+ ]
37407
+ }
37408
+ );
37409
+ } else {
37410
+ wrapped = value.bind(target);
37411
+ }
37412
+ return wrapped;
37413
+ }
37414
+ });
37415
+ }
37416
+ function wrapClientClass(Client) {
37417
+ if (Client[WRAPPED_CLIENT_CLASS]) {
37418
+ return Client;
37419
+ }
37420
+ return new Proxy(Client, {
37421
+ get(target, prop, receiver) {
37422
+ if (prop === WRAPPED_CLIENT_CLASS) {
37423
+ return true;
37424
+ }
37425
+ const value = Reflect.get(target, prop, receiver);
37426
+ return typeof value === "function" ? value.bind(target) : value;
37427
+ },
37428
+ construct(target, args, newTarget) {
37429
+ return wrapClientInstance(Reflect.construct(target, args, newTarget));
37430
+ }
37431
+ });
37432
+ }
37433
+ function wrapClientInstance(client) {
37434
+ if (client[WRAPPED_CLIENT_INSTANCE]) {
37435
+ return client;
37436
+ }
37437
+ return new Proxy(client, {
37438
+ get(target, prop, receiver) {
37439
+ if (prop === WRAPPED_CLIENT_INSTANCE) {
37440
+ return true;
37441
+ }
37442
+ const value = Reflect.get(target, prop, receiver);
37443
+ if (typeof value !== "function") {
37444
+ return value;
37445
+ }
37446
+ let wrapped;
37447
+ if (prop === "createRun") {
37448
+ const method = value;
37449
+ wrapped = (...args) => langSmithChannels.createRun.tracePromise(
37450
+ () => Reflect.apply(method, target, args),
37451
+ { arguments: args }
37452
+ );
37453
+ } else if (prop === "updateRun") {
37454
+ const method = value;
37455
+ wrapped = (...args) => langSmithChannels.updateRun.tracePromise(
37456
+ () => Reflect.apply(method, target, args),
37457
+ { arguments: args }
37458
+ );
37459
+ } else if (prop === "batchIngestRuns") {
37460
+ const method = value;
37461
+ wrapped = (...args) => langSmithChannels.batchIngestRuns.tracePromise(
37462
+ () => Reflect.apply(method, target, args),
37463
+ { arguments: args }
37464
+ );
37465
+ } else {
37466
+ wrapped = value.bind(target);
37467
+ }
37468
+ return wrapped;
37469
+ }
37470
+ });
37471
+ }
37472
+ function publishRunUpdate(runTree) {
37473
+ if (!runTree || typeof runTree.id !== "string" || !runTree.id) {
37474
+ return;
37475
+ }
37476
+ try {
37477
+ void langSmithChannels.updateRun.tracePromise(() => Promise.resolve(void 0), {
37478
+ arguments: [runTree.id, runTree]
37479
+ }).catch((error) => {
37480
+ debugLogger.error("LangSmith traceable instrumentation failed:", error);
37481
+ });
37482
+ } catch (error) {
37483
+ debugLogger.error("LangSmith traceable instrumentation failed:", error);
37484
+ }
37485
+ }
37486
+
36597
37487
  // src/wrappers/vitest/context-manager.ts
36598
37488
  var VitestContextManager = class {
36599
37489
  /**
@@ -41047,6 +41937,9 @@ export {
41047
41937
  wrapGoogleGenAI,
41048
41938
  wrapGroq,
41049
41939
  wrapHuggingFace,
41940
+ wrapLangSmithClient,
41941
+ wrapLangSmithRunTrees,
41942
+ wrapLangSmithTraceable,
41050
41943
  wrapMastraAgent,
41051
41944
  wrapMistral,
41052
41945
  wrapOpenAI,