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/workerd.mjs CHANGED
@@ -4264,7 +4264,7 @@ var DiskCache = class {
4264
4264
  }
4265
4265
  };
4266
4266
 
4267
- // src/prompt-cache/lru-cache.ts
4267
+ // src/lru-cache.ts
4268
4268
  var LRUCache = class {
4269
4269
  cache;
4270
4270
  maxSize;
@@ -5506,25 +5506,46 @@ var HTTPConnection = class _HTTPConnection {
5506
5506
  })
5507
5507
  );
5508
5508
  }
5509
- async post(path, params, config) {
5509
+ async post(path, params, config, retries = 0) {
5510
5510
  const { headers, ...rest } = config || {};
5511
5511
  const this_fetch = this.fetch;
5512
5512
  const this_base_url = this.base_url;
5513
5513
  const this_headers = this.headers;
5514
- return await checkResponse(
5515
- await this_fetch(_urljoin(this_base_url, path), {
5516
- method: "POST",
5517
- headers: {
5518
- Accept: "application/json",
5519
- "Content-Type": "application/json",
5520
- ...this_headers,
5521
- ...headers
5522
- },
5523
- body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
5524
- keepalive: true,
5525
- ...rest
5526
- })
5527
- );
5514
+ const tries = retries + 1;
5515
+ for (let i = 0; i < tries; i++) {
5516
+ try {
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
+ );
5531
+ } catch (error) {
5532
+ if (config?.signal?.aborted) {
5533
+ throw getAbortReason(config.signal);
5534
+ }
5535
+ if (i === tries - 1 || !isRetryableHTTPError(error)) {
5536
+ throw error;
5537
+ }
5538
+ debugLogger.debug(
5539
+ `Retrying API request ${path} after ${formatHTTPError(error)}`
5540
+ );
5541
+ const sleepTimeMs = HTTP_RETRY_BASE_SLEEP_TIME_S * 1e3 * 2 ** i + Math.random() * HTTP_RETRY_JITTER_MS;
5542
+ debugLogger.info(
5543
+ `Sleeping for ${sleepTimeMs}ms before retrying API request`
5544
+ );
5545
+ await waitForRetry(sleepTimeMs, config?.signal);
5546
+ }
5547
+ }
5548
+ throw new Error("Unexpected retry state");
5528
5549
  }
5529
5550
  async get_json(object_type, args = void 0, retries = 0) {
5530
5551
  const tries = retries + 1;
@@ -6621,6 +6642,45 @@ var TestBackgroundLogger = class {
6621
6642
  };
6622
6643
  var BACKGROUND_LOGGER_BASE_SLEEP_TIME_S = 1;
6623
6644
  var HTTP_RETRY_BASE_SLEEP_TIME_S = 1;
6645
+ var HTTP_RETRY_JITTER_MS = 200;
6646
+ var BTQL_HTTP_RETRIES = 3;
6647
+ var RETRYABLE_HTTP_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
6648
+ function isRetryableHTTPError(error) {
6649
+ return !(error instanceof FailedHTTPResponse) || RETRYABLE_HTTP_STATUS_CODES.has(error.status);
6650
+ }
6651
+ function formatHTTPError(error) {
6652
+ if (error instanceof FailedHTTPResponse) {
6653
+ return `${error.status} ${error.text}`;
6654
+ }
6655
+ return error instanceof Error ? error.message : String(error);
6656
+ }
6657
+ function getAbortReason(signal) {
6658
+ return signal.reason ?? new Error("Request aborted");
6659
+ }
6660
+ async function waitForRetry(delayMs, signal) {
6661
+ if (!signal) {
6662
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
6663
+ return;
6664
+ }
6665
+ if (signal.aborted) {
6666
+ throw getAbortReason(signal);
6667
+ }
6668
+ await new Promise((resolve, reject2) => {
6669
+ const onAbort = () => {
6670
+ clearTimeout(timeout);
6671
+ signal.removeEventListener("abort", onAbort);
6672
+ reject2(getAbortReason(signal));
6673
+ };
6674
+ const timeout = setTimeout(() => {
6675
+ signal.removeEventListener("abort", onAbort);
6676
+ resolve();
6677
+ }, delayMs);
6678
+ signal.addEventListener("abort", onAbort, { once: true });
6679
+ if (signal.aborted) {
6680
+ onAbort();
6681
+ }
6682
+ });
6683
+ }
6624
6684
  var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
6625
6685
  apiConn;
6626
6686
  queue;
@@ -8359,15 +8419,15 @@ function parentSpanIdsUsable(spanId, rootSpanId) {
8359
8419
  return Boolean(spanId) && Boolean(rootSpanId);
8360
8420
  }
8361
8421
  function logError(span, error) {
8362
- let errorMessage = "<error>";
8422
+ let errorMessage2 = "<error>";
8363
8423
  let stackTrace = "";
8364
8424
  if (error instanceof Error) {
8365
- errorMessage = error.message;
8425
+ errorMessage2 = error.message;
8366
8426
  stackTrace = error.stack || "";
8367
8427
  } else {
8368
- errorMessage = String(error);
8428
+ errorMessage2 = String(error);
8369
8429
  }
8370
- span.log({ error: `${errorMessage}
8430
+ span.log({ error: `${errorMessage2}
8371
8431
 
8372
8432
  ${stackTrace}` });
8373
8433
  }
@@ -8954,7 +9014,8 @@ var ObjectFetcher = class {
8954
9014
  version: this.pinnedVersion
8955
9015
  } : {}
8956
9016
  },
8957
- { headers: { "Accept-Encoding": "gzip" } }
9017
+ { headers: { "Accept-Encoding": "gzip" } },
9018
+ BTQL_HTTP_RETRIES
8958
9019
  );
8959
9020
  const respJson = await resp.json();
8960
9021
  const mutate = this.mutateRecord;
@@ -10678,7 +10739,8 @@ async function getPromptVersions(projectId, promptId) {
10678
10739
  use_columnstore: false,
10679
10740
  brainstore_realtime: true
10680
10741
  },
10681
- { headers: { "Accept-Encoding": "gzip" } }
10742
+ { headers: { "Accept-Encoding": "gzip" } },
10743
+ BTQL_HTTP_RETRIES
10682
10744
  );
10683
10745
  if (!response.ok) {
10684
10746
  throw new Error(
@@ -18063,8 +18125,6 @@ function filterSerializableOptions(options) {
18063
18125
  "additionalDirectories",
18064
18126
  "permissionMode",
18065
18127
  "debug",
18066
- "apiKey",
18067
- "apiKeySource",
18068
18128
  "agentName",
18069
18129
  "instructions"
18070
18130
  ];
@@ -29262,6 +29322,446 @@ function isBraintrustHandler(handler) {
29262
29322
  return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
29263
29323
  }
29264
29324
 
29325
+ // src/instrumentation/plugins/langsmith-channels.ts
29326
+ var langSmithChannels = defineChannels("langsmith", {
29327
+ createRun: channel({
29328
+ channelName: "Client.createRun",
29329
+ kind: "async"
29330
+ }),
29331
+ updateRun: channel({
29332
+ channelName: "Client.updateRun",
29333
+ kind: "async"
29334
+ }),
29335
+ batchIngestRuns: channel({
29336
+ channelName: "Client.batchIngestRuns",
29337
+ kind: "async"
29338
+ })
29339
+ });
29340
+
29341
+ // src/instrumentation/plugins/langsmith-plugin.ts
29342
+ var MAX_COMPLETED_RUNS = 1e4;
29343
+ var BLOCKED_METADATA_KEYS = /* @__PURE__ */ new Set([
29344
+ "__proto__",
29345
+ "constructor",
29346
+ "prototype",
29347
+ "usage_metadata"
29348
+ ]);
29349
+ var BLOCKED_METADATA_PREFIXES = ["__pregel_", "langgraph_", "lc_"];
29350
+ var LLM_SETTING_KEYS = [
29351
+ "temperature",
29352
+ "top_p",
29353
+ "max_tokens",
29354
+ "frequency_penalty",
29355
+ "presence_penalty",
29356
+ "stop",
29357
+ "response_format"
29358
+ ];
29359
+ var LangSmithPlugin = class extends BasePlugin {
29360
+ activeRuns = /* @__PURE__ */ new Map();
29361
+ completedRuns = new LRUCache({
29362
+ max: MAX_COMPLETED_RUNS
29363
+ });
29364
+ skipLangChainRuns;
29365
+ constructor(options = {}) {
29366
+ super();
29367
+ this.skipLangChainRuns = options.skipLangChainRuns ?? true;
29368
+ }
29369
+ onEnable() {
29370
+ const createChannel = langSmithChannels.createRun.tracingChannel();
29371
+ const createHandlers = {
29372
+ start: (event) => {
29373
+ this.containLifecycleFailure("createRun", () => {
29374
+ this.processCreate(event.arguments[0]);
29375
+ });
29376
+ }
29377
+ };
29378
+ createChannel.subscribe(createHandlers);
29379
+ this.unsubscribers.push(() => createChannel.unsubscribe(createHandlers));
29380
+ const updateChannel = langSmithChannels.updateRun.tracingChannel();
29381
+ const updateHandlers = {
29382
+ start: (event) => {
29383
+ this.containLifecycleFailure("updateRun", () => {
29384
+ this.processUpdate(event.arguments[0], event.arguments[1]);
29385
+ });
29386
+ }
29387
+ };
29388
+ updateChannel.subscribe(updateHandlers);
29389
+ this.unsubscribers.push(() => updateChannel.unsubscribe(updateHandlers));
29390
+ const batchChannel = langSmithChannels.batchIngestRuns.tracingChannel();
29391
+ const batchHandlers = {
29392
+ start: (event) => {
29393
+ this.containLifecycleFailure("batchIngestRuns", () => {
29394
+ this.processBatch(event.arguments[0]);
29395
+ });
29396
+ }
29397
+ };
29398
+ batchChannel.subscribe(batchHandlers);
29399
+ this.unsubscribers.push(() => batchChannel.unsubscribe(batchHandlers));
29400
+ }
29401
+ onDisable() {
29402
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
29403
+ for (const { span } of this.activeRuns.values()) {
29404
+ span.end();
29405
+ }
29406
+ this.activeRuns.clear();
29407
+ this.completedRuns.clear();
29408
+ }
29409
+ processBatch(batch) {
29410
+ if (!isRecord2(batch)) {
29411
+ return;
29412
+ }
29413
+ const creates = ownValue(batch, "runCreates");
29414
+ if (Array.isArray(creates)) {
29415
+ const parentFirst = [...creates].sort((left, right) => {
29416
+ const leftId = stringValue2(ownValue(left, "id"));
29417
+ const rightId = stringValue2(ownValue(right, "id"));
29418
+ const leftParent = stringValue2(ownValue(left, "parent_run_id"));
29419
+ const rightParent = stringValue2(ownValue(right, "parent_run_id"));
29420
+ if (leftParent && leftParent === rightId) {
29421
+ return 1;
29422
+ }
29423
+ if (rightParent && rightParent === leftId) {
29424
+ return -1;
29425
+ }
29426
+ return dottedOrderDepth(left) - dottedOrderDepth(right);
29427
+ });
29428
+ for (const run of parentFirst) {
29429
+ this.containLifecycleFailure("batchIngestRuns create", () => {
29430
+ this.processCreate(run);
29431
+ });
29432
+ }
29433
+ }
29434
+ const updates = ownValue(batch, "runUpdates");
29435
+ if (Array.isArray(updates)) {
29436
+ for (const run of updates) {
29437
+ this.containLifecycleFailure("batchIngestRuns update", () => {
29438
+ this.processUpdate(stringValue2(ownValue(run, "id")) ?? "", run);
29439
+ });
29440
+ }
29441
+ }
29442
+ }
29443
+ processCreate(run) {
29444
+ const id = stringValue2(ownValue(run, "id"));
29445
+ if (!id || this.completedRuns.get(id)) {
29446
+ return;
29447
+ }
29448
+ if (this.shouldSkipLangChainRun(run)) {
29449
+ this.completedRuns.set(id, true);
29450
+ return;
29451
+ }
29452
+ const active = this.activeRuns.get(id);
29453
+ if (active) {
29454
+ const previous = active.run;
29455
+ active.run = mergeRuns(previous, run);
29456
+ this.logRun(
29457
+ active.span,
29458
+ active.run,
29459
+ previous,
29460
+ timestampSeconds(ownValue(active.run, "end_time")) !== void 0 || errorMessage(ownValue(active.run, "error")) !== void 0
29461
+ );
29462
+ this.endIfComplete(id, active, active.run);
29463
+ return;
29464
+ }
29465
+ const span = this.startRunSpan(id, run);
29466
+ const activeRun = { run, span };
29467
+ this.activeRuns.set(id, activeRun);
29468
+ this.logRun(
29469
+ span,
29470
+ run,
29471
+ void 0,
29472
+ timestampSeconds(ownValue(run, "end_time")) !== void 0 || errorMessage(ownValue(run, "error")) !== void 0
29473
+ );
29474
+ this.endIfComplete(id, activeRun, run);
29475
+ }
29476
+ processUpdate(explicitId, run) {
29477
+ const id = stringValue2(explicitId) ?? stringValue2(ownValue(run, "id"));
29478
+ if (!id || this.completedRuns.get(id)) {
29479
+ return;
29480
+ }
29481
+ if (this.shouldSkipLangChainRun(run)) {
29482
+ const active2 = this.activeRuns.get(id);
29483
+ active2?.span.end();
29484
+ this.activeRuns.delete(id);
29485
+ this.completedRuns.set(id, true);
29486
+ return;
29487
+ }
29488
+ let active = this.activeRuns.get(id);
29489
+ if (!active) {
29490
+ const span = this.startRunSpan(id, run);
29491
+ active = { run, span };
29492
+ this.activeRuns.set(id, active);
29493
+ }
29494
+ const previous = active.run;
29495
+ active.run = mergeRuns(previous, run);
29496
+ this.logRun(active.span, active.run, previous, true);
29497
+ this.endIfComplete(id, active, active.run);
29498
+ }
29499
+ startRunSpan(id, run) {
29500
+ const traceId = stringValue2(ownValue(run, "trace_id")) ?? id;
29501
+ const parentId = stringValue2(ownValue(run, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run, "parent_run"), "id"));
29502
+ const startTime = timestampSeconds(ownValue(run, "start_time"));
29503
+ return startSpan({
29504
+ name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
29505
+ spanId: id,
29506
+ parentSpanIds: {
29507
+ parentSpanIds: parentId ? [parentId] : [],
29508
+ rootSpanId: traceId
29509
+ },
29510
+ spanAttributes: {
29511
+ type: mapRunType(ownValue(run, "run_type"))
29512
+ },
29513
+ ...startTime === void 0 ? {} : { startTime },
29514
+ event: { id }
29515
+ });
29516
+ }
29517
+ logRun(span, run, previous, includeOutput) {
29518
+ const inputs = preferOwnValue(run, previous, "inputs");
29519
+ const outputs = preferOwnValue(run, previous, "outputs");
29520
+ const error = errorMessage(preferOwnValue(run, previous, "error"));
29521
+ const metadata = extractMetadata(run, previous);
29522
+ const tags = extractTags(preferOwnValue(run, previous, "tags"));
29523
+ const metrics = extractMetrics(run, previous);
29524
+ span.log({
29525
+ ...inputs === void 0 ? {} : { input: sanitizeLoggedValue(inputs) },
29526
+ ...includeOutput && outputs !== void 0 ? { output: sanitizeLoggedValue(outputs) } : {},
29527
+ ...error === void 0 ? {} : { error },
29528
+ ...metadata === void 0 ? {} : { metadata },
29529
+ ...tags === void 0 ? {} : { tags },
29530
+ ...Object.keys(metrics).length === 0 ? {} : { metrics }
29531
+ });
29532
+ }
29533
+ endIfComplete(id, active, run) {
29534
+ const endTime = timestampSeconds(ownValue(run, "end_time"));
29535
+ if (endTime === void 0 && errorMessage(ownValue(run, "error")) === void 0) {
29536
+ return;
29537
+ }
29538
+ active.span.end(endTime === void 0 ? void 0 : { endTime });
29539
+ this.activeRuns.delete(id);
29540
+ this.completedRuns.set(id, true);
29541
+ }
29542
+ shouldSkipLangChainRun(run) {
29543
+ if (!this.skipLangChainRuns) {
29544
+ return false;
29545
+ }
29546
+ const serialized = ownValue(run, "serialized");
29547
+ return isRecord2(serialized) && ownValue(serialized, "lc") === 1;
29548
+ }
29549
+ containLifecycleFailure(operation, fn) {
29550
+ try {
29551
+ fn();
29552
+ } catch (error) {
29553
+ debugLogger.error(
29554
+ `Failed to process LangSmith ${operation} instrumentation:`,
29555
+ error
29556
+ );
29557
+ }
29558
+ }
29559
+ };
29560
+ function ownValue(value, key) {
29561
+ if (!isRecord2(value)) {
29562
+ return void 0;
29563
+ }
29564
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
29565
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
29566
+ }
29567
+ function preferOwnValue(current, previous, key) {
29568
+ const currentDescriptor = isRecord2(current) ? Object.getOwnPropertyDescriptor(current, key) : void 0;
29569
+ if (currentDescriptor && "value" in currentDescriptor) {
29570
+ return currentDescriptor.value;
29571
+ }
29572
+ return ownValue(previous, key);
29573
+ }
29574
+ function mergeRuns(previous, current) {
29575
+ const entries = /* @__PURE__ */ new Map();
29576
+ for (const value of [previous, current]) {
29577
+ if (!isRecord2(value)) {
29578
+ continue;
29579
+ }
29580
+ for (const [key, descriptor] of Object.entries(
29581
+ Object.getOwnPropertyDescriptors(value)
29582
+ )) {
29583
+ if (descriptor.enumerable && "value" in descriptor) {
29584
+ entries.set(key, descriptor.value);
29585
+ }
29586
+ }
29587
+ }
29588
+ return Object.fromEntries(entries);
29589
+ }
29590
+ function isRecord2(value) {
29591
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29592
+ }
29593
+ function stringValue2(value) {
29594
+ return typeof value === "string" && value.length > 0 ? value : void 0;
29595
+ }
29596
+ function timestampSeconds(value) {
29597
+ if (value instanceof Date) {
29598
+ const timestamp = value.getTime();
29599
+ return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
29600
+ }
29601
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
29602
+ return value > 1e10 ? value / 1e3 : value;
29603
+ }
29604
+ if (typeof value === "string") {
29605
+ const timestamp = Date.parse(value);
29606
+ return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
29607
+ }
29608
+ return void 0;
29609
+ }
29610
+ function dottedOrderDepth(run) {
29611
+ const dottedOrder = stringValue2(ownValue(run, "dotted_order"));
29612
+ return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
29613
+ }
29614
+ function mapRunType(runType) {
29615
+ switch (runType) {
29616
+ case "llm":
29617
+ case "embedding":
29618
+ return "llm" /* LLM */;
29619
+ case "tool":
29620
+ case "retriever":
29621
+ return "tool" /* TOOL */;
29622
+ default:
29623
+ return "task" /* TASK */;
29624
+ }
29625
+ }
29626
+ function extractMetadata(run, previous) {
29627
+ const extra = preferOwnValue(run, previous, "extra");
29628
+ const rawMetadata = ownValue(extra, "metadata");
29629
+ if (!isRecord2(rawMetadata)) {
29630
+ return void 0;
29631
+ }
29632
+ const metadata = {};
29633
+ for (const [key, descriptor] of Object.entries(
29634
+ Object.getOwnPropertyDescriptors(rawMetadata)
29635
+ )) {
29636
+ 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}`)) {
29637
+ continue;
29638
+ }
29639
+ const normalizedKey = key === "ls_provider" ? "provider" : key === "ls_model_name" ? "model" : key.startsWith("ls_") ? key.slice(3) : key;
29640
+ const sanitized = sanitizeLoggedValue(descriptor.value);
29641
+ if (sanitized !== void 0) {
29642
+ metadata[normalizedKey] = sanitized;
29643
+ }
29644
+ }
29645
+ return Object.keys(metadata).length === 0 ? void 0 : metadata;
29646
+ }
29647
+ function extractTags(value) {
29648
+ if (!Array.isArray(value)) {
29649
+ return void 0;
29650
+ }
29651
+ const tags = value.filter(
29652
+ (tag) => typeof tag === "string" && tag.length > 0
29653
+ );
29654
+ return tags.length > 0 ? tags : void 0;
29655
+ }
29656
+ function extractMetrics(run, previous) {
29657
+ const outputs = preferOwnValue(run, previous, "outputs");
29658
+ const extra = preferOwnValue(run, previous, "extra");
29659
+ const metadata = ownValue(extra, "metadata");
29660
+ const usage = ownValue(outputs, "usage_metadata") ?? ownValue(metadata, "usage_metadata");
29661
+ const metrics = {};
29662
+ assignFirstMetric(metrics, "prompt_tokens", usage, [
29663
+ "input_tokens",
29664
+ "prompt_tokens"
29665
+ ]);
29666
+ assignFirstMetric(metrics, "completion_tokens", usage, [
29667
+ "output_tokens",
29668
+ "completion_tokens"
29669
+ ]);
29670
+ assignFirstMetric(metrics, "tokens", usage, ["total_tokens", "tokens"]);
29671
+ const inputTokenDetails = ownValue(usage, "input_token_details");
29672
+ assignFirstMetric(metrics, "prompt_cached_tokens", inputTokenDetails, [
29673
+ "cache_read",
29674
+ "cached_tokens"
29675
+ ]);
29676
+ if (metrics.prompt_cached_tokens === void 0) {
29677
+ assignFirstMetric(metrics, "prompt_cached_tokens", usage, [
29678
+ "cache_read_input_tokens",
29679
+ "prompt_cached_tokens"
29680
+ ]);
29681
+ }
29682
+ assignFirstMetric(
29683
+ metrics,
29684
+ "prompt_cache_creation_tokens",
29685
+ inputTokenDetails,
29686
+ ["cache_creation"]
29687
+ );
29688
+ if (metrics.prompt_cache_creation_tokens === void 0) {
29689
+ assignFirstMetric(metrics, "prompt_cache_creation_tokens", usage, [
29690
+ "cache_creation_input_tokens",
29691
+ "prompt_cache_creation_tokens"
29692
+ ]);
29693
+ }
29694
+ if (metrics.tokens === void 0 && (metrics.prompt_tokens !== void 0 || metrics.completion_tokens !== void 0)) {
29695
+ metrics.tokens = (metrics.prompt_tokens ?? 0) + (metrics.completion_tokens ?? 0);
29696
+ }
29697
+ const startTime = timestampSeconds(
29698
+ preferOwnValue(run, previous, "start_time")
29699
+ );
29700
+ const events = preferOwnValue(run, previous, "events");
29701
+ if (startTime !== void 0 && Array.isArray(events)) {
29702
+ for (const event of events) {
29703
+ if (ownValue(event, "name") !== "new_token") {
29704
+ continue;
29705
+ }
29706
+ const eventTime3 = timestampSeconds(ownValue(event, "time"));
29707
+ if (eventTime3 !== void 0 && eventTime3 >= startTime) {
29708
+ metrics.time_to_first_token = eventTime3 - startTime;
29709
+ }
29710
+ break;
29711
+ }
29712
+ }
29713
+ return metrics;
29714
+ }
29715
+ function assignFirstMetric(metrics, target, source, keys) {
29716
+ for (const key of keys) {
29717
+ const value = ownValue(source, key);
29718
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
29719
+ metrics[target] = value;
29720
+ return;
29721
+ }
29722
+ }
29723
+ }
29724
+ function errorMessage(value) {
29725
+ if (typeof value === "string") {
29726
+ return value;
29727
+ }
29728
+ if (value instanceof Error) {
29729
+ return value.message;
29730
+ }
29731
+ return void 0;
29732
+ }
29733
+ function sanitizeLoggedValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
29734
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
29735
+ return value;
29736
+ }
29737
+ if (typeof value === "number") {
29738
+ return Number.isFinite(value) ? value : void 0;
29739
+ }
29740
+ if (value instanceof Date) {
29741
+ return Number.isFinite(value.getTime()) ? value.toISOString() : void 0;
29742
+ }
29743
+ if (typeof value !== "object" || depth >= 20) {
29744
+ return void 0;
29745
+ }
29746
+ if (seen.has(value)) {
29747
+ return "[Circular]";
29748
+ }
29749
+ seen.add(value);
29750
+ if (Array.isArray(value)) {
29751
+ return value.map((item) => sanitizeLoggedValue(item, seen, depth + 1));
29752
+ }
29753
+ const entries = [];
29754
+ for (const [key, descriptor] of Object.entries(
29755
+ Object.getOwnPropertyDescriptors(value)
29756
+ )) {
29757
+ if (!descriptor.enumerable || !("value" in descriptor) || BLOCKED_METADATA_KEYS.has(key)) {
29758
+ continue;
29759
+ }
29760
+ entries.push([key, sanitizeLoggedValue(descriptor.value, seen, depth + 1)]);
29761
+ }
29762
+ return Object.fromEntries(entries);
29763
+ }
29764
+
29265
29765
  // src/instrumentation/plugins/pi-coding-agent-channels.ts
29266
29766
  var piCodingAgentChannels = defineChannels(
29267
29767
  "@earendil-works/pi-coding-agent",
@@ -29641,11 +30141,11 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
29641
30141
  function recordPiAssistantMessageEvent(promptState, llmState, event) {
29642
30142
  recordFirstTokenMetric(llmState, event);
29643
30143
  const message = "message" in event ? event.message : void 0;
29644
- const errorMessage = "error" in event ? event.error : void 0;
30144
+ const errorMessage2 = "error" in event ? event.error : void 0;
29645
30145
  if (event.type === "done" && isPiAssistantMessage(message)) {
29646
30146
  finishPiLlmSpan(promptState, llmState, message);
29647
- } else if (event.type === "error" && isPiAssistantMessage(errorMessage)) {
29648
- finishPiLlmSpan(promptState, llmState, errorMessage);
30147
+ } else if (event.type === "error" && isPiAssistantMessage(errorMessage2)) {
30148
+ finishPiLlmSpan(promptState, llmState, errorMessage2);
29649
30149
  }
29650
30150
  }
29651
30151
  function recordFirstTokenMetric(state, event) {
@@ -30163,6 +30663,7 @@ var strandsAgentSDKChannels = defineChannels("@strands-agents/sdk", {
30163
30663
  });
30164
30664
 
30165
30665
  // src/instrumentation/plugins/strands-agent-sdk-plugin.ts
30666
+ var MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES = 32;
30166
30667
  var StrandsAgentSDKPlugin = class extends BasePlugin {
30167
30668
  activeChildParents = /* @__PURE__ */ new WeakMap();
30168
30669
  onEnable() {
@@ -30307,11 +30808,16 @@ function startAgentStream(event, activeChildParents) {
30307
30808
  ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
30308
30809
  };
30309
30810
  const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
30811
+ const attachmentCache = createStrandsAttachmentCache();
30812
+ const input = processStrandsInputAttachments(
30813
+ event.arguments[0],
30814
+ attachmentCache
30815
+ );
30310
30816
  const span = parentSpan ? withCurrent(
30311
30817
  parentSpan,
30312
30818
  () => startSpan({
30313
30819
  event: {
30314
- input: event.arguments[0],
30820
+ input,
30315
30821
  metadata
30316
30822
  },
30317
30823
  name: formatAgentSpanName(agent),
@@ -30319,7 +30825,7 @@ function startAgentStream(event, activeChildParents) {
30319
30825
  })
30320
30826
  ) : startSpan({
30321
30827
  event: {
30322
- input: event.arguments[0],
30828
+ input,
30323
30829
  metadata
30324
30830
  },
30325
30831
  name: formatAgentSpanName(agent),
@@ -30327,6 +30833,7 @@ function startAgentStream(event, activeChildParents) {
30327
30833
  });
30328
30834
  return {
30329
30835
  activeTools: /* @__PURE__ */ new Map(),
30836
+ attachmentCache,
30330
30837
  finalized: false,
30331
30838
  metadata,
30332
30839
  span,
@@ -30342,11 +30849,12 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30342
30849
  ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
30343
30850
  };
30344
30851
  const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
30852
+ const input = processStrandsInputAttachments(event.arguments[0]);
30345
30853
  const span = parentSpan ? withCurrent(
30346
30854
  parentSpan,
30347
30855
  () => startSpan({
30348
30856
  event: {
30349
- input: event.arguments[0],
30857
+ input,
30350
30858
  metadata
30351
30859
  },
30352
30860
  name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
@@ -30354,7 +30862,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30354
30862
  })
30355
30863
  ) : startSpan({
30356
30864
  event: {
30357
- input: event.arguments[0],
30865
+ input,
30358
30866
  metadata
30359
30867
  },
30360
30868
  name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
@@ -30463,7 +30971,10 @@ function startModelSpan(state, event) {
30463
30971
  state.span,
30464
30972
  () => startSpan({
30465
30973
  event: {
30466
- input: Array.isArray(event.agent?.messages) ? event.agent.messages : void 0,
30974
+ input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
30975
+ event.agent.messages,
30976
+ state.attachmentCache
30977
+ ) : void 0,
30467
30978
  metadata
30468
30979
  },
30469
30980
  name: formatModelSpanName(model),
@@ -30677,6 +31188,7 @@ function finalizeAgentStream(state, error, output) {
30677
31188
  ...output !== void 0 ? { output } : {}
30678
31189
  });
30679
31190
  state.span.end();
31191
+ state.attachmentCache.strings.clear();
30680
31192
  }
30681
31193
  function finalizeMultiAgentStream(state, activeChildParents, error, output) {
30682
31194
  if (state.finalized) {
@@ -30823,6 +31335,166 @@ function extractNodeResultOutput(result) {
30823
31335
  }
30824
31336
  return result;
30825
31337
  }
31338
+ var STRANDS_MEDIA_TYPES = {
31339
+ png: "image/png",
31340
+ jpg: "image/jpeg",
31341
+ jpeg: "image/jpeg",
31342
+ gif: "image/gif",
31343
+ webp: "image/webp",
31344
+ mkv: "video/x-matroska",
31345
+ mov: "video/quicktime",
31346
+ mp4: "video/mp4",
31347
+ webm: "video/webm",
31348
+ flv: "video/x-flv",
31349
+ mpeg: "video/mpeg",
31350
+ mpg: "video/mpeg",
31351
+ wmv: "video/x-ms-wmv",
31352
+ "3gp": "video/3gpp",
31353
+ pdf: "application/pdf",
31354
+ csv: "text/csv",
31355
+ doc: "application/msword",
31356
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
31357
+ xls: "application/vnd.ms-excel",
31358
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
31359
+ html: "text/html",
31360
+ txt: "text/plain",
31361
+ md: "text/markdown",
31362
+ json: "application/json",
31363
+ xml: "application/xml"
31364
+ };
31365
+ function createStrandsAttachmentCache() {
31366
+ return {
31367
+ objects: /* @__PURE__ */ new WeakMap(),
31368
+ strings: new LRUCache({
31369
+ max: MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES
31370
+ })
31371
+ };
31372
+ }
31373
+ function processStrandsInputAttachments(input, cache = createStrandsAttachmentCache()) {
31374
+ try {
31375
+ return processStrandsInputNode(input, cache);
31376
+ } catch (error) {
31377
+ logInstrumentationError5("Strands Agent SDK input attachments", error);
31378
+ return input;
31379
+ }
31380
+ }
31381
+ function processStrandsInputNode(value, cache) {
31382
+ if (value instanceof BaseAttachment) {
31383
+ return value;
31384
+ }
31385
+ if (Array.isArray(value)) {
31386
+ return value.map((child) => processStrandsInputNode(child, cache));
31387
+ }
31388
+ if (!isObject(value)) {
31389
+ return value;
31390
+ }
31391
+ const directMedia = processDirectStrandsMediaBlock(value, cache);
31392
+ if (directMedia !== void 0) {
31393
+ return directMedia;
31394
+ }
31395
+ const wrappedMedia = processWrappedStrandsMediaBlock(value, cache);
31396
+ if (wrappedMedia !== void 0) {
31397
+ return wrappedMedia;
31398
+ }
31399
+ if (value.type === "message" && Array.isArray(value.content)) {
31400
+ return {
31401
+ role: value.role,
31402
+ content: value.content.map(
31403
+ (child) => processStrandsInputNode(child, cache)
31404
+ ),
31405
+ ...value.metadata !== void 0 ? { metadata: value.metadata } : {}
31406
+ };
31407
+ }
31408
+ if (typeof value.toJSON === "function") {
31409
+ return processStrandsInputNode(value.toJSON(), cache);
31410
+ }
31411
+ return Object.fromEntries(
31412
+ Object.entries(value).map(([key, child]) => [
31413
+ key,
31414
+ processStrandsInputNode(child, cache)
31415
+ ])
31416
+ );
31417
+ }
31418
+ function processDirectStrandsMediaBlock(block, cache) {
31419
+ if (!isStrandsMediaBlock(block)) {
31420
+ return void 0;
31421
+ }
31422
+ const mediaKey = block.type === "imageBlock" ? "image" : block.type === "videoBlock" ? "video" : "document";
31423
+ return createStrandsMediaAttachment(mediaKey, block, cache);
31424
+ }
31425
+ function isStrandsMediaBlock(block) {
31426
+ return (block.type === "imageBlock" || block.type === "videoBlock" || block.type === "documentBlock") && typeof block.format === "string" && isObject(block.source);
31427
+ }
31428
+ function processWrappedStrandsMediaBlock(block, cache) {
31429
+ for (const mediaKey of ["image", "video", "document"]) {
31430
+ const media = block[mediaKey];
31431
+ if (!Object.hasOwn(block, mediaKey) || !isObject(media)) {
31432
+ continue;
31433
+ }
31434
+ const processed = createStrandsMediaAttachment(mediaKey, media, cache);
31435
+ if (processed !== void 0) {
31436
+ return processed;
31437
+ }
31438
+ }
31439
+ return void 0;
31440
+ }
31441
+ function createStrandsMediaAttachment(mediaKey, media, cache) {
31442
+ const format = media.format;
31443
+ const source = media.source;
31444
+ if (typeof format !== "string" || !isObject(source) || !Object.hasOwn(source, "bytes")) {
31445
+ return void 0;
31446
+ }
31447
+ const contentType = STRANDS_MEDIA_TYPES[format.toLowerCase()];
31448
+ if (!contentType) {
31449
+ return void 0;
31450
+ }
31451
+ const filename = mediaKey === "document" && typeof media.name === "string" && media.name.length > 0 ? media.name : `${mediaKey}.${format.toLowerCase()}`;
31452
+ const attachment = getOrCreateStrandsAttachment(
31453
+ source.bytes,
31454
+ filename,
31455
+ contentType,
31456
+ cache
31457
+ );
31458
+ if (!attachment) {
31459
+ return void 0;
31460
+ }
31461
+ const { type: _type, ...serializedMedia } = media;
31462
+ const { type: _sourceType, ...serializedSource } = source;
31463
+ return {
31464
+ [mediaKey]: {
31465
+ ...serializedMedia,
31466
+ source: {
31467
+ ...serializedSource,
31468
+ bytes: attachment
31469
+ }
31470
+ }
31471
+ };
31472
+ }
31473
+ function getOrCreateStrandsAttachment(data, filename, contentType, cache) {
31474
+ const key = `${contentType}\0${filename}`;
31475
+ const attachments = typeof data === "string" ? cache.strings.get(data) : isObject(data) ? cache.objects.get(data) : void 0;
31476
+ const cached = attachments?.get(key);
31477
+ if (cached) {
31478
+ return cached;
31479
+ }
31480
+ const blob = convertDataToBlob(data, contentType);
31481
+ if (!blob) {
31482
+ return void 0;
31483
+ }
31484
+ const attachment = new Attachment({
31485
+ data: blob,
31486
+ filename,
31487
+ contentType
31488
+ });
31489
+ const updatedAttachments = attachments ?? /* @__PURE__ */ new Map();
31490
+ updatedAttachments.set(key, attachment);
31491
+ if (typeof data === "string") {
31492
+ cache.strings.set(data, updatedAttachments);
31493
+ } else if (isObject(data)) {
31494
+ cache.objects.set(data, updatedAttachments);
31495
+ }
31496
+ return attachment;
31497
+ }
30826
31498
  function normalizeContentBlocks(blocks) {
30827
31499
  const text = blocks.map((block) => typeof block.text === "string" ? block.text : void 0).filter((part) => Boolean(part)).join("");
30828
31500
  return text.length > 0 ? text : blocks;
@@ -30952,6 +31624,7 @@ var BraintrustPlugin = class extends BasePlugin {
30952
31624
  gitHubCopilotPlugin = null;
30953
31625
  fluePlugin = null;
30954
31626
  langChainPlugin = null;
31627
+ langSmithPlugin = null;
30955
31628
  piCodingAgentPlugin = null;
30956
31629
  strandsAgentSDKPlugin = null;
30957
31630
  constructor(config = {}) {
@@ -31048,6 +31721,12 @@ var BraintrustPlugin = class extends BasePlugin {
31048
31721
  this.langChainPlugin = new LangChainPlugin();
31049
31722
  this.langChainPlugin.enable();
31050
31723
  }
31724
+ if (integrations.langsmith !== false) {
31725
+ this.langSmithPlugin = new LangSmithPlugin({
31726
+ skipLangChainRuns: integrations.langchain !== false
31727
+ });
31728
+ this.langSmithPlugin.enable();
31729
+ }
31051
31730
  }
31052
31731
  onDisable() {
31053
31732
  if (this.openaiPlugin) {
@@ -31138,6 +31817,10 @@ var BraintrustPlugin = class extends BasePlugin {
31138
31817
  this.langChainPlugin.disable();
31139
31818
  this.langChainPlugin = null;
31140
31819
  }
31820
+ if (this.langSmithPlugin) {
31821
+ this.langSmithPlugin.disable();
31822
+ this.langSmithPlugin = null;
31823
+ }
31141
31824
  }
31142
31825
  };
31143
31826
 
@@ -31202,7 +31885,8 @@ var envIntegrationAliases = {
31202
31885
  langchain: "langchain",
31203
31886
  "langchain-js": "langchain",
31204
31887
  "@langchain": "langchain",
31205
- langgraph: "langgraph"
31888
+ langgraph: "langgraph",
31889
+ langsmith: "langsmith"
31206
31890
  };
31207
31891
  function getDefaultInstrumentationIntegrations() {
31208
31892
  return {
@@ -31233,6 +31917,7 @@ function getDefaultInstrumentationIntegrations() {
31233
31917
  gitHubCopilot: true,
31234
31918
  langchain: true,
31235
31919
  langgraph: true,
31920
+ langsmith: true,
31236
31921
  piCodingAgent: true,
31237
31922
  strandsAgentSDK: true
31238
31923
  };
@@ -31544,6 +32229,9 @@ __export(exports_exports, {
31544
32229
  wrapGoogleGenAI: () => wrapGoogleGenAI,
31545
32230
  wrapGroq: () => wrapGroq,
31546
32231
  wrapHuggingFace: () => wrapHuggingFace,
32232
+ wrapLangSmithClient: () => wrapLangSmithClient,
32233
+ wrapLangSmithRunTrees: () => wrapLangSmithRunTrees,
32234
+ wrapLangSmithTraceable: () => wrapLangSmithTraceable,
31547
32235
  wrapMastraAgent: () => wrapMastraAgent,
31548
32236
  wrapMistral: () => wrapMistral,
31549
32237
  wrapOpenAI: () => wrapOpenAI,
@@ -33030,9 +33718,6 @@ var EveBridge = class {
33030
33718
  this.state = state;
33031
33719
  }
33032
33720
  eventQueuesBySession = /* @__PURE__ */ new Map();
33033
- sessionsById = new LRUCache({
33034
- max: MAX_EVE_CACHE_ENTRIES
33035
- });
33036
33721
  completedToolKeys = new LRUCache({
33037
33722
  max: MAX_EVE_CACHE_ENTRIES
33038
33723
  });
@@ -33199,7 +33884,7 @@ var EveBridge = class {
33199
33884
  async handleEvent(event, ctx, hookMetadata) {
33200
33885
  switch (event.type) {
33201
33886
  case "session.started":
33202
- await this.handleSessionStarted(event, ctx, hookMetadata);
33887
+ this.handleSessionStarted(event, ctx, hookMetadata);
33203
33888
  return true;
33204
33889
  case "turn.started":
33205
33890
  await this.handleTurnStarted(event, ctx, hookMetadata);
@@ -33235,22 +33920,22 @@ var EveBridge = class {
33235
33920
  this.handleStepFailed(event, ctx);
33236
33921
  return true;
33237
33922
  case "turn.completed":
33238
- await this.handleTurnCompleted(event, ctx);
33923
+ this.handleTurnCompleted(event, ctx);
33239
33924
  return true;
33240
33925
  case "turn.failed":
33241
- await this.handleTurnFailed(event, ctx);
33926
+ this.handleTurnFailed(event, ctx);
33242
33927
  return true;
33243
33928
  case "session.failed":
33244
- await this.handleSessionFailed(event, ctx);
33929
+ this.handleSessionFailed(event, ctx);
33245
33930
  return true;
33246
33931
  case "session.completed":
33247
- await this.handleSessionCompleted(event, ctx);
33932
+ this.handleSessionCompleted(event, ctx);
33248
33933
  return true;
33249
33934
  default:
33250
33935
  return false;
33251
33936
  }
33252
33937
  }
33253
- async handleSessionStarted(event, ctx, hookMetadata) {
33938
+ handleSessionStarted(event, ctx, hookMetadata) {
33254
33939
  const sessionId = sessionIdFromContext(ctx);
33255
33940
  if (!sessionId) {
33256
33941
  return;
@@ -33266,7 +33951,6 @@ var EveBridge = class {
33266
33951
  metadata: { ...normalized.metadata, ...metadata }
33267
33952
  };
33268
33953
  });
33269
- await this.ensureSession(sessionId, ctx, metadata, eventTime2(event));
33270
33954
  for (const [key, turn] of this.turnsByKey) {
33271
33955
  if (!key.startsWith(`${sessionId}:`)) {
33272
33956
  continue;
@@ -33284,21 +33968,19 @@ var EveBridge = class {
33284
33968
  if (!sessionId) {
33285
33969
  return;
33286
33970
  }
33287
- const session = await this.ensureSession(
33288
- sessionId,
33289
- ctx,
33290
- hookMetadata ?? {},
33291
- eventTime2(event)
33292
- );
33293
33971
  const key = turnKey2(sessionId, event.data.turnId);
33294
- const metadata = { ...session.metadata };
33972
+ const metadata = {
33973
+ ...readEveTraceState(this.state).metadata,
33974
+ ...hookMetadata ?? {},
33975
+ "eve.session_id": sessionId
33976
+ };
33295
33977
  const existing = this.turnsByKey.get(key);
33296
33978
  if (existing) {
33297
33979
  existing.metadata = { ...existing.metadata, ...metadata };
33298
33980
  existing.span.log({ metadata: existing.metadata });
33299
33981
  return;
33300
33982
  }
33301
- const span = await this.startTurnSpan(session, event, metadata);
33983
+ const span = await this.startTurnSpan(sessionId, event, ctx, metadata);
33302
33984
  span.log({ metadata });
33303
33985
  this.turnsByKey.set(key, {
33304
33986
  key,
@@ -33336,10 +34018,7 @@ var EveBridge = class {
33336
34018
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
33337
34019
  }
33338
34020
  const stepOrdinal = this.stepOrdinal(event);
33339
- const metadata = {
33340
- ...turn.metadata,
33341
- ...this.sessionsById.get(sessionId)?.metadata ?? {}
33342
- };
34021
+ const metadata = { ...turn.metadata };
33343
34022
  const input = consumeCapturedEveModelInput(
33344
34023
  this.state,
33345
34024
  sessionId,
@@ -33434,6 +34113,28 @@ var EveBridge = class {
33434
34113
  if (!step) {
33435
34114
  return;
33436
34115
  }
34116
+ const toolCallsById = /* @__PURE__ */ new Map();
34117
+ if (Array.isArray(step.output) && isObject(step.output[0])) {
34118
+ const message = step.output[0]["message"];
34119
+ if (isObject(message) && Array.isArray(message["tool_calls"])) {
34120
+ for (const toolCall of message["tool_calls"]) {
34121
+ if (isObject(toolCall) && typeof toolCall["id"] === "string") {
34122
+ toolCallsById.set(toolCall["id"], toolCall);
34123
+ }
34124
+ }
34125
+ }
34126
+ }
34127
+ for (const action of traceActions) {
34128
+ const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
34129
+ toolCallsById.set(action.callId, {
34130
+ function: {
34131
+ arguments: JSON.stringify(action.input),
34132
+ name
34133
+ },
34134
+ id: action.callId,
34135
+ type: "function"
34136
+ });
34137
+ }
33437
34138
  step.output = [
33438
34139
  {
33439
34140
  finish_reason: "tool_calls",
@@ -33441,17 +34142,7 @@ var EveBridge = class {
33441
34142
  message: {
33442
34143
  content: null,
33443
34144
  role: "assistant",
33444
- tool_calls: traceActions.map((action) => {
33445
- const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
33446
- return {
33447
- function: {
33448
- arguments: JSON.stringify(action.input),
33449
- name
33450
- },
33451
- id: action.callId,
33452
- type: "function"
33453
- };
33454
- })
34145
+ tool_calls: [...toolCallsById.values()]
33455
34146
  }
33456
34147
  }
33457
34148
  ];
@@ -33698,17 +34389,11 @@ var EveBridge = class {
33698
34389
  )
33699
34390
  });
33700
34391
  }
33701
- async handleSessionFailed(event, ctx) {
34392
+ handleSessionFailed(event, ctx) {
33702
34393
  const sessionId = event.data.sessionId || sessionIdFromContext(ctx);
33703
34394
  if (!sessionId) {
33704
34395
  return;
33705
34396
  }
33706
- const session = await this.ensureSession(
33707
- sessionId,
33708
- ctx,
33709
- {},
33710
- eventTime2(event)
33711
- );
33712
34397
  const error = errorFromMessage(
33713
34398
  event.data.message,
33714
34399
  event.data.code,
@@ -33725,29 +34410,20 @@ var EveBridge = class {
33725
34410
  }
33726
34411
  for (const [key, tool] of this.toolsByCallKey) {
33727
34412
  if (key.startsWith(`${sessionId}:`)) {
33728
- const endTime2 = eventTime2(event);
34413
+ const endTime = eventTime2(event);
33729
34414
  if (!tool.endedByTurn) {
33730
34415
  tool.span.log({ metadata: tool.metadata });
33731
- tool.span.end(endTime2 === void 0 ? void 0 : { endTime: endTime2 });
34416
+ tool.span.end(endTime === void 0 ? void 0 : { endTime });
33732
34417
  tool.endedByTurn = true;
33733
34418
  }
33734
34419
  }
33735
34420
  }
33736
- session.span.log({ error });
33737
- const endTime = eventTime2(event);
33738
- session.span.end(endTime === void 0 ? void 0 : { endTime });
33739
34421
  }
33740
- async handleSessionCompleted(event, ctx) {
34422
+ handleSessionCompleted(event, ctx) {
33741
34423
  const sessionId = sessionIdFromContext(ctx);
33742
34424
  if (!sessionId) {
33743
34425
  return;
33744
34426
  }
33745
- const session = await this.ensureSession(
33746
- sessionId,
33747
- ctx,
33748
- {},
33749
- eventTime2(event)
33750
- );
33751
34427
  for (const [key, turn] of this.turnsByKey) {
33752
34428
  if (!key.startsWith(`${sessionId}:`)) {
33753
34429
  continue;
@@ -33758,82 +34434,29 @@ var EveBridge = class {
33758
34434
  }
33759
34435
  for (const [key, tool] of this.toolsByCallKey) {
33760
34436
  if (key.startsWith(`${sessionId}:`) && !tool.endedByTurn) {
33761
- const endTime2 = eventTime2(event);
34437
+ const endTime = eventTime2(event);
33762
34438
  tool.span.log({ metadata: tool.metadata });
33763
- tool.span.end(endTime2 === void 0 ? void 0 : { endTime: endTime2 });
34439
+ tool.span.end(endTime === void 0 ? void 0 : { endTime });
33764
34440
  tool.endedByTurn = true;
33765
34441
  }
33766
34442
  }
33767
- session.span.log({ metadata: session.metadata });
33768
- const endTime = eventTime2(event);
33769
- session.span.end(endTime === void 0 ? void 0 : { endTime });
33770
- }
33771
- async ensureSession(sessionId, ctx, metadata, startTime) {
33772
- metadata = {
33773
- ...readEveTraceState(this.state).metadata,
33774
- ...metadata
33775
- };
33776
- const existing = this.sessionsById.get(sessionId);
33777
- if (existing) {
33778
- existing.metadata = { ...existing.metadata, ...metadata };
33779
- existing.span.log({ metadata: existing.metadata });
33780
- return existing;
33781
- }
33782
- const lineage = parentLineageFromContext(ctx);
33783
- const parentSubagent = lineage ? this.toolsByCallKey.get(toolKey3(lineage.sessionId, lineage.callId)) : void 0;
33784
- const activeParent = currentSpan();
33785
- const [
33786
- { rowId: eventId, spanId },
33787
- parentSubagentSpanId,
33788
- fallbackRootSpanId
33789
- ] = await Promise.all([
33790
- generateEveIds("session", sessionId),
33791
- lineage ? spanIdForSubagent(lineage.sessionId, lineage.callId) : Promise.resolve(void 0),
33792
- lineage ? rootSpanIdForSession(lineage.rootSessionId) : rootSpanIdForSession(sessionId)
33793
- ]);
33794
- const span = await this.startEveSpan({
33795
- event: {
33796
- id: eventId,
33797
- metadata
33798
- },
33799
- name: "eve.session",
33800
- parentSpanIds: lineage && parentSubagentSpanId ? {
33801
- rootSpanId: parentSubagent?.span.rootSpanId ?? fallbackRootSpanId,
33802
- spanId: parentSubagentSpanId
33803
- } : !Object.is(activeParent, NOOP_SPAN) ? {
33804
- rootSpanId: activeParent.rootSpanId,
33805
- spanId: activeParent.spanId
33806
- } : {
33807
- parentSpanIds: [],
33808
- rootSpanId: fallbackRootSpanId
33809
- },
33810
- spanAttributes: { type: "task" /* TASK */ },
33811
- spanId,
33812
- startTime
33813
- });
33814
- span.log({ metadata });
33815
- const session = { metadata, sessionId, span };
33816
- this.sessionsById.set(sessionId, session);
33817
- return session;
33818
34443
  }
33819
34444
  async ensureTurn(event, ctx, hookMetadata) {
33820
34445
  const sessionId = sessionIdFromContext(ctx);
33821
34446
  if (!sessionId) {
33822
34447
  return void 0;
33823
34448
  }
33824
- const session = await this.ensureSession(
33825
- sessionId,
33826
- ctx,
33827
- hookMetadata ?? {},
33828
- eventTime2(event)
33829
- );
33830
34449
  const key = turnKey2(sessionId, event.data.turnId);
33831
34450
  const existing = this.turnsByKey.get(key);
33832
34451
  if (existing) {
33833
34452
  return existing;
33834
34453
  }
33835
- const metadata = { ...session.metadata };
33836
- const span = await this.startTurnSpan(session, event, metadata);
34454
+ const metadata = {
34455
+ ...readEveTraceState(this.state).metadata,
34456
+ ...hookMetadata ?? {},
34457
+ "eve.session_id": sessionId
34458
+ };
34459
+ const span = await this.startTurnSpan(sessionId, event, ctx, metadata);
33837
34460
  span.log({ metadata });
33838
34461
  const state = {
33839
34462
  key,
@@ -34020,22 +34643,35 @@ var EveBridge = class {
34020
34643
  this.toolsByCallKey.set(toolKey3(sessionId, result.callId), state);
34021
34644
  return state;
34022
34645
  }
34023
- async startTurnSpan(session, event, metadata) {
34024
- const { rowId: eventId, spanId } = await generateEveIds(
34025
- "turn",
34026
- session.sessionId,
34027
- event.data.turnId
34028
- );
34646
+ async startTurnSpan(sessionId, event, ctx, metadata) {
34647
+ const session = isObject(ctx) ? ctx["session"] : void 0;
34648
+ const parent = isObject(session) ? session["parent"] : void 0;
34649
+ const parentTurn = isObject(parent) ? parent["turn"] : void 0;
34650
+ const parentLineage = isObject(parent) && typeof parent["callId"] === "string" && typeof parent["sessionId"] === "string" && isObject(parentTurn) && typeof parentTurn["id"] === "string" ? {
34651
+ callId: parent["callId"],
34652
+ sessionId: parent["sessionId"],
34653
+ turnId: parentTurn["id"]
34654
+ } : void 0;
34655
+ const [{ rowId: eventId, spanId }, rootSpanId, parentSpanId] = await Promise.all([
34656
+ generateEveIds("turn", sessionId, event.data.turnId),
34657
+ deterministicEveId(
34658
+ "eve:root",
34659
+ parentLineage?.sessionId ?? sessionId,
34660
+ parentLineage?.turnId ?? event.data.turnId
34661
+ ),
34662
+ parentLineage ? deterministicEveId(
34663
+ "eve:subagent",
34664
+ parentLineage.sessionId,
34665
+ parentLineage.callId
34666
+ ) : Promise.resolve(void 0)
34667
+ ]);
34029
34668
  return await this.startEveSpan({
34030
34669
  event: {
34031
34670
  id: eventId,
34032
34671
  metadata
34033
34672
  },
34034
34673
  name: "eve.turn",
34035
- parentSpanIds: {
34036
- rootSpanId: session.span.rootSpanId,
34037
- spanId: session.span.spanId
34038
- },
34674
+ parentSpanIds: parentSpanId ? { rootSpanId, spanId: parentSpanId } : { parentSpanIds: [], rootSpanId },
34039
34675
  spanAttributes: { type: "task" /* TASK */ },
34040
34676
  spanId,
34041
34677
  startTime: eventTime2(event)
@@ -34096,7 +34732,6 @@ var EveBridge = class {
34096
34732
  }
34097
34733
  cleanupSession(sessionId) {
34098
34734
  const keyPrefix = `${sessionId}:`;
34099
- this.sessionsById.delete(sessionId);
34100
34735
  for (const key of this.turnsByKey.keys()) {
34101
34736
  if (key.startsWith(keyPrefix)) {
34102
34737
  this.turnsByKey.delete(key);
@@ -34287,7 +34922,7 @@ function modelMetadataFromRuntime(runtime) {
34287
34922
  return {};
34288
34923
  }
34289
34924
  const modelId = runtime["modelId"];
34290
- return typeof modelId === "string" ? modelMetadataFromModelId(modelId) : {};
34925
+ return typeof modelId === "string" && !modelId.trim().startsWith("dynamic:") ? modelMetadataFromModelId(modelId) : {};
34291
34926
  }
34292
34927
  function modelMetadataFromModelId(modelId) {
34293
34928
  const normalized = modelId.trim();
@@ -34320,26 +34955,6 @@ function toolMetadataFromTurn(turn) {
34320
34955
  const { model: _model, provider: _provider, ...metadata } = turn.metadata;
34321
34956
  return metadata;
34322
34957
  }
34323
- function parentLineageFromContext(ctx) {
34324
- if (!isObject(ctx)) {
34325
- return void 0;
34326
- }
34327
- const session = ctx.session;
34328
- if (!isObject(session)) {
34329
- return void 0;
34330
- }
34331
- const parent = session["parent"];
34332
- if (!isObject(parent)) {
34333
- return void 0;
34334
- }
34335
- const callId = parent["callId"];
34336
- const rootSessionId = parent["rootSessionId"];
34337
- const sessionId = parent["sessionId"];
34338
- if (typeof callId !== "string" || typeof rootSessionId !== "string" || typeof sessionId !== "string") {
34339
- return void 0;
34340
- }
34341
- return { callId, rootSessionId, sessionId };
34342
- }
34343
34958
  function isToolCallAction(action) {
34344
34959
  return isObject(action) && action["kind"] === "tool-call" && typeof action["callId"] === "string" && typeof action["toolName"] === "string" && isObject(action["input"]);
34345
34960
  }
@@ -34395,9 +35010,6 @@ function turnKey2(sessionId, turnId) {
34395
35010
  function toolKey3(sessionId, callId) {
34396
35011
  return `${sessionId}:${callId}`;
34397
35012
  }
34398
- async function rootSpanIdForSession(sessionId) {
34399
- return deterministicEveId("eve:root", sessionId);
34400
- }
34401
35013
  async function generateEveIds(kind, ...parts) {
34402
35014
  const [rowId, spanId] = await Promise.all([
34403
35015
  deterministicEveId(`eve:row:${kind}`, ...parts),
@@ -34405,9 +35017,6 @@ async function generateEveIds(kind, ...parts) {
34405
35017
  ]);
34406
35018
  return { rowId, spanId };
34407
35019
  }
34408
- async function spanIdForSubagent(sessionId, callId) {
34409
- return deterministicEveId("eve:subagent", sessionId, callId);
34410
- }
34411
35020
  async function deterministicEveId(...parts) {
34412
35021
  const data = new TextEncoder().encode(
34413
35022
  parts.map((part) => `${part.length}:${part}`).join("\0")
@@ -34580,6 +35189,15 @@ function modelMetrics(attributes) {
34580
35189
  }
34581
35190
  return Object.keys(out).length > 0 ? out : void 0;
34582
35191
  }
35192
+ function timeToFirstTokenSeconds(attributes, spanStartSeconds) {
35193
+ if (!isObject(attributes)) return void 0;
35194
+ if (spanStartSeconds === void 0) return void 0;
35195
+ const raw = attributes.completionStartTime;
35196
+ const completionStart = raw instanceof Date || typeof raw === "string" || typeof raw === "number" ? epochSeconds(raw) : void 0;
35197
+ if (completionStart === void 0) return void 0;
35198
+ const ttft = completionStart - spanStartSeconds;
35199
+ return Number.isFinite(ttft) && ttft >= 0 ? ttft : void 0;
35200
+ }
34583
35201
  function buildMetadata(exported) {
34584
35202
  const out = {};
34585
35203
  if (exported.entityId !== void 0) out.entity_id = exported.entityId;
@@ -34704,8 +35322,15 @@ var BraintrustObservabilityExporter = class {
34704
35322
  event.metadata = metadata;
34705
35323
  }
34706
35324
  const metrics = modelMetrics(exported.attributes);
34707
- if (metrics) {
34708
- event.metrics = metrics;
35325
+ const ttft = timeToFirstTokenSeconds(
35326
+ exported.attributes,
35327
+ epochSeconds(exported.startTime)
35328
+ );
35329
+ if (metrics || ttft !== void 0) {
35330
+ event.metrics = {
35331
+ ...metrics ?? {},
35332
+ ...ttft !== void 0 ? { time_to_first_token: ttft } : {}
35333
+ };
34709
35334
  }
34710
35335
  if (Object.keys(event).length > 0) {
34711
35336
  record.span.log(event);
@@ -35584,17 +36209,17 @@ function wrapGenkit(genkit) {
35584
36209
  console.warn("Unsupported Genkit object. Not wrapping.");
35585
36210
  return genkit;
35586
36211
  }
35587
- function isRecord2(value) {
36212
+ function isRecord3(value) {
35588
36213
  return typeof value === "object" && value !== null;
35589
36214
  }
35590
36215
  function isPropertyBag(value) {
35591
- return isRecord2(value) || typeof value === "function";
36216
+ return isRecord3(value) || typeof value === "function";
35592
36217
  }
35593
36218
  function hasFunction(value, methodName) {
35594
36219
  return isPropertyBag(value) && methodName in value && typeof value[methodName] === "function";
35595
36220
  }
35596
36221
  function isGenkitInstance(value) {
35597
- return isRecord2(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
36222
+ return isRecord3(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
35598
36223
  }
35599
36224
  function isGenkitModule(value) {
35600
36225
  return hasFunction(value, "genkit");
@@ -35648,7 +36273,7 @@ function patchGenkitRegistry(instance) {
35648
36273
  patchGenkitRegistryConstructor(registry2);
35649
36274
  }
35650
36275
  function patchGenkitRegistryLookup(registry2) {
35651
- if (!isRecord2(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
36276
+ if (!isRecord3(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
35652
36277
  return;
35653
36278
  }
35654
36279
  const originalLookupAction = registry2.lookupAction;
@@ -35674,7 +36299,7 @@ function patchGenkitRegistryLookup(registry2) {
35674
36299
  }
35675
36300
  }
35676
36301
  function patchGenkitRegistryConstructor(registry2) {
35677
- if (!isRecord2(registry2)) {
36302
+ if (!isRecord3(registry2)) {
35678
36303
  return;
35679
36304
  }
35680
36305
  const constructor = registry2.constructor;
@@ -35690,7 +36315,7 @@ function patchGenkitRegistryConstructor(registry2) {
35690
36315
  configurable: true,
35691
36316
  value: (...args) => {
35692
36317
  const childRegistry = originalWithParent.apply(constructor, args);
35693
- if (args.some((arg) => isRecord2(arg) && hasRegistryPatchedFlag(arg))) {
36318
+ if (args.some((arg) => isRecord3(arg) && hasRegistryPatchedFlag(arg))) {
35694
36319
  patchGenkitRegistryLookup(childRegistry);
35695
36320
  patchGenkitRegistryConstructor(childRegistry);
35696
36321
  }
@@ -35789,7 +36414,7 @@ function hasRegistryConstructorPatchedFlag(value) {
35789
36414
  );
35790
36415
  }
35791
36416
  function isPromiseLike2(value) {
35792
- return isRecord2(value) && "then" in value && typeof value.then === "function";
36417
+ return isRecord3(value) && "then" in value && typeof value.then === "function";
35793
36418
  }
35794
36419
 
35795
36420
  // src/wrappers/huggingface.ts
@@ -36152,14 +36777,14 @@ function wrapMistral(mistral) {
36152
36777
  console.warn("Unsupported Mistral library. Not wrapping.");
36153
36778
  return mistral;
36154
36779
  }
36155
- function isRecord3(value) {
36780
+ function isRecord4(value) {
36156
36781
  return typeof value === "object" && value !== null;
36157
36782
  }
36158
36783
  function hasFunction3(value, methodName) {
36159
- return isRecord3(value) && methodName in value && typeof value[methodName] === "function";
36784
+ return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
36160
36785
  }
36161
36786
  function isSupportedMistralClient(value) {
36162
- if (!isRecord3(value)) {
36787
+ if (!isRecord4(value)) {
36163
36788
  return false;
36164
36789
  }
36165
36790
  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);
@@ -36343,14 +36968,14 @@ function wrapCohere(cohere) {
36343
36968
  return cohere;
36344
36969
  }
36345
36970
  var cohereProxyCache = /* @__PURE__ */ new WeakMap();
36346
- function isRecord4(value) {
36971
+ function isRecord5(value) {
36347
36972
  return typeof value === "object" && value !== null;
36348
36973
  }
36349
36974
  function hasFunction4(value, methodName) {
36350
- return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
36975
+ return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
36351
36976
  }
36352
36977
  function isSupportedCohereClient(value) {
36353
- if (!isRecord4(value)) {
36978
+ if (!isRecord5(value)) {
36354
36979
  return false;
36355
36980
  }
36356
36981
  return hasFunction4(value, "chat") || hasFunction4(value, "chatStream") || hasFunction4(value, "embed") || hasFunction4(value, "rerank");
@@ -36410,20 +37035,20 @@ function wrapGroq(groq) {
36410
37035
  console.warn("Unsupported Groq library. Not wrapping.");
36411
37036
  return groq;
36412
37037
  }
36413
- function isRecord5(value) {
37038
+ function isRecord6(value) {
36414
37039
  return typeof value === "object" && value !== null;
36415
37040
  }
36416
37041
  function hasFunction5(value, methodName) {
36417
- return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
37042
+ return isRecord6(value) && methodName in value && typeof value[methodName] === "function";
36418
37043
  }
36419
37044
  function hasChat2(value) {
36420
- return isRecord5(value) && isRecord5(value.completions) && hasFunction5(value.completions, "create");
37045
+ return isRecord6(value) && isRecord6(value.completions) && hasFunction5(value.completions, "create");
36421
37046
  }
36422
37047
  function hasEmbeddings2(value) {
36423
37048
  return hasFunction5(value, "create");
36424
37049
  }
36425
37050
  function isSupportedGroqClient(value) {
36426
- return isRecord5(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
37051
+ return isRecord6(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
36427
37052
  }
36428
37053
  function groqProxy(groq) {
36429
37054
  const privateMethodWorkaroundCache = /* @__PURE__ */ new WeakMap();
@@ -36506,11 +37131,11 @@ var BEDROCK_RUNTIME_OPERATION_METHODS = /* @__PURE__ */ new Set([
36506
37131
  "invokeModelWithBidirectionalStream",
36507
37132
  "invokeModelWithResponseStream"
36508
37133
  ]);
36509
- function isRecord6(value) {
37134
+ function isRecord7(value) {
36510
37135
  return typeof value === "object" && value !== null;
36511
37136
  }
36512
37137
  function isSupportedBedrockRuntimeClient(value) {
36513
- return isRecord6(value) && typeof value.send === "function";
37138
+ return isRecord7(value) && typeof value.send === "function";
36514
37139
  }
36515
37140
  function bedrockRuntimeProxy(client) {
36516
37141
  const cached = bedrockRuntimeProxyCache.get(client);
@@ -36629,6 +37254,271 @@ function wrappedResumeSession(client) {
36629
37254
  );
36630
37255
  }
36631
37256
 
37257
+ // src/wrappers/langsmith.ts
37258
+ var WRAPPED_CLIENT_CLASS = /* @__PURE__ */ Symbol.for(
37259
+ "braintrust.langsmith.wrapped-client-class"
37260
+ );
37261
+ var WRAPPED_CLIENT_INSTANCE = /* @__PURE__ */ Symbol.for(
37262
+ "braintrust.langsmith.wrapped-client-instance"
37263
+ );
37264
+ var WRAPPED_CLIENT_NAMESPACE = /* @__PURE__ */ Symbol.for(
37265
+ "braintrust.langsmith.wrapped-client-namespace"
37266
+ );
37267
+ var WRAPPED_RUN_TREE_CLASS = /* @__PURE__ */ Symbol.for(
37268
+ "braintrust.langsmith.wrapped-run-tree-class"
37269
+ );
37270
+ var WRAPPED_RUN_TREE_INSTANCE = /* @__PURE__ */ Symbol.for(
37271
+ "braintrust.langsmith.wrapped-run-tree-instance"
37272
+ );
37273
+ var WRAPPED_RUN_TREES_NAMESPACE = /* @__PURE__ */ Symbol.for(
37274
+ "braintrust.langsmith.wrapped-run-trees-namespace"
37275
+ );
37276
+ var WRAPPED_TRACEABLE = /* @__PURE__ */ Symbol.for("braintrust.langsmith.wrapped-traceable");
37277
+ var WRAPPED_TRACEABLE_NAMESPACE = /* @__PURE__ */ Symbol.for(
37278
+ "braintrust.langsmith.wrapped-traceable-namespace"
37279
+ );
37280
+ function wrapLangSmithTraceable(namespace) {
37281
+ return wrapNamespaceExport(
37282
+ namespace,
37283
+ "traceable",
37284
+ WRAPPED_TRACEABLE_NAMESPACE,
37285
+ (value) => wrapTraceable(value)
37286
+ );
37287
+ }
37288
+ function wrapLangSmithRunTrees(namespace) {
37289
+ return wrapNamespaceExport(
37290
+ namespace,
37291
+ "RunTree",
37292
+ WRAPPED_RUN_TREES_NAMESPACE,
37293
+ (value) => wrapRunTreeClass(value)
37294
+ );
37295
+ }
37296
+ function wrapLangSmithClient(namespace) {
37297
+ return wrapNamespaceExport(
37298
+ namespace,
37299
+ "Client",
37300
+ WRAPPED_CLIENT_NAMESPACE,
37301
+ (value) => wrapClientClass(value)
37302
+ );
37303
+ }
37304
+ function wrapNamespaceExport(namespace, exportName, marker, wrap2) {
37305
+ if (!namespace || typeof namespace !== "object") {
37306
+ return namespace;
37307
+ }
37308
+ const candidate = namespace;
37309
+ if (candidate[marker] === true) {
37310
+ return namespace;
37311
+ }
37312
+ if (typeof candidate[exportName] !== "function") {
37313
+ console.warn(
37314
+ `Unsupported LangSmith ${exportName} namespace. Not wrapping.`
37315
+ );
37316
+ return namespace;
37317
+ }
37318
+ const target = isModuleNamespace5(namespace) ? Object.setPrototypeOf({}, namespace) : candidate;
37319
+ const moduleNamespace = target !== candidate;
37320
+ let wrappedExport;
37321
+ return new Proxy(target, {
37322
+ get(target2, prop, receiver) {
37323
+ if (prop === marker) {
37324
+ return true;
37325
+ }
37326
+ const value = Reflect.get(target2, prop, receiver);
37327
+ if (prop !== exportName || typeof value !== "function") {
37328
+ return value;
37329
+ }
37330
+ wrappedExport ??= wrap2(value);
37331
+ return wrappedExport;
37332
+ },
37333
+ getOwnPropertyDescriptor(target2, prop) {
37334
+ const descriptor = Reflect.getOwnPropertyDescriptor(target2, prop);
37335
+ if (descriptor || !moduleNamespace) {
37336
+ return descriptor;
37337
+ }
37338
+ const namespaceDescriptor = Reflect.getOwnPropertyDescriptor(
37339
+ candidate,
37340
+ prop
37341
+ );
37342
+ return namespaceDescriptor ? { ...namespaceDescriptor, configurable: true } : void 0;
37343
+ },
37344
+ has(target2, prop) {
37345
+ return Reflect.has(target2, prop) || moduleNamespace && prop in candidate;
37346
+ },
37347
+ ownKeys(target2) {
37348
+ return moduleNamespace ? Reflect.ownKeys(candidate) : Reflect.ownKeys(target2);
37349
+ }
37350
+ });
37351
+ }
37352
+ function isModuleNamespace5(value) {
37353
+ if (!value || typeof value !== "object") {
37354
+ return false;
37355
+ }
37356
+ if (value.constructor?.name === "Module") {
37357
+ return true;
37358
+ }
37359
+ const firstKey = Object.keys(value)[0];
37360
+ if (!firstKey) {
37361
+ return false;
37362
+ }
37363
+ const descriptor = Object.getOwnPropertyDescriptor(value, firstKey);
37364
+ return descriptor ? !descriptor.configurable && !descriptor.writable : false;
37365
+ }
37366
+ function wrapTraceable(traceable2) {
37367
+ if (traceable2[WRAPPED_TRACEABLE]) {
37368
+ return traceable2;
37369
+ }
37370
+ return new Proxy(traceable2, {
37371
+ get(target, prop, receiver) {
37372
+ if (prop === WRAPPED_TRACEABLE) {
37373
+ return true;
37374
+ }
37375
+ return Reflect.get(target, prop, receiver);
37376
+ },
37377
+ apply(target, thisArg, argArray) {
37378
+ const [fn, rawConfig] = argArray;
37379
+ const config = rawConfig && typeof rawConfig === "object" ? rawConfig : void 0;
37380
+ const originalOnEnd = config?.on_end;
37381
+ const wrappedConfig = {
37382
+ ...config,
37383
+ on_end(runTree) {
37384
+ publishRunUpdate(runTree);
37385
+ if (originalOnEnd) {
37386
+ Reflect.apply(originalOnEnd, config, [runTree]);
37387
+ }
37388
+ }
37389
+ };
37390
+ return Reflect.apply(target, thisArg, [fn, wrappedConfig]);
37391
+ }
37392
+ });
37393
+ }
37394
+ function wrapRunTreeClass(RunTree) {
37395
+ if (RunTree[WRAPPED_RUN_TREE_CLASS]) {
37396
+ return RunTree;
37397
+ }
37398
+ return new Proxy(RunTree, {
37399
+ get(target, prop, receiver) {
37400
+ if (prop === WRAPPED_RUN_TREE_CLASS) {
37401
+ return true;
37402
+ }
37403
+ const value = Reflect.get(target, prop, receiver);
37404
+ return typeof value === "function" ? value.bind(target) : value;
37405
+ },
37406
+ construct(target, args, newTarget) {
37407
+ return wrapRunTreeInstance(Reflect.construct(target, args, newTarget));
37408
+ }
37409
+ });
37410
+ }
37411
+ function wrapRunTreeInstance(runTree) {
37412
+ if (runTree[WRAPPED_RUN_TREE_INSTANCE]) {
37413
+ return runTree;
37414
+ }
37415
+ return new Proxy(runTree, {
37416
+ get(target, prop, receiver) {
37417
+ if (prop === WRAPPED_RUN_TREE_INSTANCE) {
37418
+ return true;
37419
+ }
37420
+ const value = Reflect.get(target, prop, receiver);
37421
+ if (typeof value !== "function") {
37422
+ return value;
37423
+ }
37424
+ let wrapped;
37425
+ if (prop === "createChild") {
37426
+ wrapped = (...args) => wrapRunTreeInstance(Reflect.apply(value, target, args));
37427
+ } else if (prop === "postRun") {
37428
+ const method = value;
37429
+ wrapped = (...args) => langSmithChannels.createRun.tracePromise(
37430
+ () => Reflect.apply(method, target, args),
37431
+ { arguments: [target] }
37432
+ );
37433
+ } else if (prop === "patchRun") {
37434
+ const method = value;
37435
+ wrapped = (...args) => langSmithChannels.updateRun.tracePromise(
37436
+ () => Reflect.apply(method, target, args),
37437
+ {
37438
+ arguments: [
37439
+ typeof target.id === "string" ? target.id : "",
37440
+ target
37441
+ ]
37442
+ }
37443
+ );
37444
+ } else {
37445
+ wrapped = value.bind(target);
37446
+ }
37447
+ return wrapped;
37448
+ }
37449
+ });
37450
+ }
37451
+ function wrapClientClass(Client) {
37452
+ if (Client[WRAPPED_CLIENT_CLASS]) {
37453
+ return Client;
37454
+ }
37455
+ return new Proxy(Client, {
37456
+ get(target, prop, receiver) {
37457
+ if (prop === WRAPPED_CLIENT_CLASS) {
37458
+ return true;
37459
+ }
37460
+ const value = Reflect.get(target, prop, receiver);
37461
+ return typeof value === "function" ? value.bind(target) : value;
37462
+ },
37463
+ construct(target, args, newTarget) {
37464
+ return wrapClientInstance(Reflect.construct(target, args, newTarget));
37465
+ }
37466
+ });
37467
+ }
37468
+ function wrapClientInstance(client) {
37469
+ if (client[WRAPPED_CLIENT_INSTANCE]) {
37470
+ return client;
37471
+ }
37472
+ return new Proxy(client, {
37473
+ get(target, prop, receiver) {
37474
+ if (prop === WRAPPED_CLIENT_INSTANCE) {
37475
+ return true;
37476
+ }
37477
+ const value = Reflect.get(target, prop, receiver);
37478
+ if (typeof value !== "function") {
37479
+ return value;
37480
+ }
37481
+ let wrapped;
37482
+ if (prop === "createRun") {
37483
+ const method = value;
37484
+ wrapped = (...args) => langSmithChannels.createRun.tracePromise(
37485
+ () => Reflect.apply(method, target, args),
37486
+ { arguments: args }
37487
+ );
37488
+ } else if (prop === "updateRun") {
37489
+ const method = value;
37490
+ wrapped = (...args) => langSmithChannels.updateRun.tracePromise(
37491
+ () => Reflect.apply(method, target, args),
37492
+ { arguments: args }
37493
+ );
37494
+ } else if (prop === "batchIngestRuns") {
37495
+ const method = value;
37496
+ wrapped = (...args) => langSmithChannels.batchIngestRuns.tracePromise(
37497
+ () => Reflect.apply(method, target, args),
37498
+ { arguments: args }
37499
+ );
37500
+ } else {
37501
+ wrapped = value.bind(target);
37502
+ }
37503
+ return wrapped;
37504
+ }
37505
+ });
37506
+ }
37507
+ function publishRunUpdate(runTree) {
37508
+ if (!runTree || typeof runTree.id !== "string" || !runTree.id) {
37509
+ return;
37510
+ }
37511
+ try {
37512
+ void langSmithChannels.updateRun.tracePromise(() => Promise.resolve(void 0), {
37513
+ arguments: [runTree.id, runTree]
37514
+ }).catch((error) => {
37515
+ debugLogger.error("LangSmith traceable instrumentation failed:", error);
37516
+ });
37517
+ } catch (error) {
37518
+ debugLogger.error("LangSmith traceable instrumentation failed:", error);
37519
+ }
37520
+ }
37521
+
36632
37522
  // src/wrappers/vitest/context-manager.ts
36633
37523
  var VitestContextManager = class {
36634
37524
  /**
@@ -41082,6 +41972,9 @@ export {
41082
41972
  wrapGoogleGenAI,
41083
41973
  wrapGroq,
41084
41974
  wrapHuggingFace,
41975
+ wrapLangSmithClient,
41976
+ wrapLangSmithRunTrees,
41977
+ wrapLangSmithTraceable,
41085
41978
  wrapMastraAgent,
41086
41979
  wrapMistral,
41087
41980
  wrapOpenAI,