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