braintrust 3.22.0 → 3.23.0

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