braintrust 3.22.0 → 3.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +43 -0
  2. package/dev/dist/index.d.mts +1 -1
  3. package/dev/dist/index.d.ts +1 -1
  4. package/dev/dist/index.js +1354 -654
  5. package/dev/dist/index.mjs +736 -36
  6. package/dist/apply-auto-instrumentation.js +222 -186
  7. package/dist/apply-auto-instrumentation.mjs +37 -1
  8. package/dist/auto-instrumentations/bundler/esbuild.cjs +53 -1
  9. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  10. package/dist/auto-instrumentations/bundler/next.cjs +53 -1
  11. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  12. package/dist/auto-instrumentations/bundler/rollup.cjs +53 -1
  13. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  14. package/dist/auto-instrumentations/bundler/vite.cjs +53 -1
  15. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  16. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +53 -1
  17. package/dist/auto-instrumentations/bundler/webpack.cjs +53 -1
  18. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  19. package/dist/auto-instrumentations/{chunk-TKRPRPGD.mjs → chunk-EXY7QCJD.mjs} +5 -2
  20. package/dist/auto-instrumentations/{chunk-T6J4C7LX.mjs → chunk-KIMLYPRW.mjs} +1 -1
  21. package/dist/auto-instrumentations/{chunk-BRQX23KL.mjs → chunk-YXLNSAMJ.mjs} +51 -0
  22. package/dist/auto-instrumentations/hook.mjs +149 -20
  23. package/dist/auto-instrumentations/index.cjs +52 -0
  24. package/dist/auto-instrumentations/index.d.mts +3 -1
  25. package/dist/auto-instrumentations/index.d.ts +3 -1
  26. package/dist/auto-instrumentations/index.mjs +3 -1
  27. package/dist/browser.d.mts +11 -13
  28. package/dist/browser.d.ts +11 -13
  29. package/dist/browser.js +1098 -205
  30. package/dist/browser.mjs +1098 -205
  31. package/dist/{chunk-KMGUTPB7.mjs → chunk-36IPYKMG.mjs} +20 -1
  32. package/dist/{chunk-MWVVR5LR.js → chunk-B6ZQIAK3.js} +1506 -822
  33. package/dist/{chunk-BFGIH2ZJ.js → chunk-CDIKAHDZ.js} +21 -2
  34. package/dist/{chunk-ZG2O3XVF.mjs → chunk-RBXD2KYN.mjs} +719 -35
  35. package/dist/cli.js +737 -37
  36. package/dist/edge-light.d.mts +1 -1
  37. package/dist/edge-light.d.ts +1 -1
  38. package/dist/edge-light.js +1098 -205
  39. package/dist/edge-light.mjs +1098 -205
  40. package/dist/index.d.mts +11 -13
  41. package/dist/index.d.ts +11 -13
  42. package/dist/index.js +786 -593
  43. package/dist/index.mjs +346 -153
  44. package/dist/instrumentation/index.d.mts +3 -11
  45. package/dist/instrumentation/index.d.ts +3 -11
  46. package/dist/instrumentation/index.js +788 -183
  47. package/dist/instrumentation/index.mjs +788 -183
  48. package/dist/vitest-evals-reporter.js +16 -16
  49. package/dist/vitest-evals-reporter.mjs +2 -2
  50. package/dist/workerd.d.mts +1 -1
  51. package/dist/workerd.d.ts +1 -1
  52. package/dist/workerd.js +1098 -205
  53. package/dist/workerd.mjs +1098 -205
  54. package/package.json +1 -1
package/dist/browser.js CHANGED
@@ -185,6 +185,9 @@ __export(browser_exports, {
185
185
  wrapGoogleGenAI: () => wrapGoogleGenAI,
186
186
  wrapGroq: () => wrapGroq,
187
187
  wrapHuggingFace: () => wrapHuggingFace,
188
+ wrapLangSmithClient: () => wrapLangSmithClient,
189
+ wrapLangSmithRunTrees: () => wrapLangSmithRunTrees,
190
+ wrapLangSmithTraceable: () => wrapLangSmithTraceable,
188
191
  wrapMastraAgent: () => wrapMastraAgent,
189
192
  wrapMistral: () => wrapMistral,
190
193
  wrapOpenAI: () => wrapOpenAI,
@@ -4460,7 +4463,7 @@ var DiskCache = class {
4460
4463
  }
4461
4464
  };
4462
4465
 
4463
- // src/prompt-cache/lru-cache.ts
4466
+ // src/lru-cache.ts
4464
4467
  var LRUCache = class {
4465
4468
  cache;
4466
4469
  maxSize;
@@ -5702,25 +5705,46 @@ var HTTPConnection = class _HTTPConnection {
5702
5705
  })
5703
5706
  );
5704
5707
  }
5705
- async post(path, params, config) {
5708
+ async post(path, params, config, retries = 0) {
5706
5709
  const { headers, ...rest } = config || {};
5707
5710
  const this_fetch = this.fetch;
5708
5711
  const this_base_url = this.base_url;
5709
5712
  const this_headers = this.headers;
5710
- return await checkResponse(
5711
- await this_fetch(_urljoin(this_base_url, path), {
5712
- method: "POST",
5713
- headers: {
5714
- Accept: "application/json",
5715
- "Content-Type": "application/json",
5716
- ...this_headers,
5717
- ...headers
5718
- },
5719
- body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
5720
- keepalive: true,
5721
- ...rest
5722
- })
5723
- );
5713
+ const tries = retries + 1;
5714
+ for (let i = 0; i < tries; i++) {
5715
+ try {
5716
+ return await checkResponse(
5717
+ await this_fetch(_urljoin(this_base_url, path), {
5718
+ method: "POST",
5719
+ headers: {
5720
+ Accept: "application/json",
5721
+ "Content-Type": "application/json",
5722
+ ...this_headers,
5723
+ ...headers
5724
+ },
5725
+ body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
5726
+ keepalive: true,
5727
+ ...rest
5728
+ })
5729
+ );
5730
+ } catch (error) {
5731
+ if (config?.signal?.aborted) {
5732
+ throw getAbortReason(config.signal);
5733
+ }
5734
+ if (i === tries - 1 || !isRetryableHTTPError(error)) {
5735
+ throw error;
5736
+ }
5737
+ debugLogger.debug(
5738
+ `Retrying API request ${path} after ${formatHTTPError(error)}`
5739
+ );
5740
+ const sleepTimeMs = HTTP_RETRY_BASE_SLEEP_TIME_S * 1e3 * 2 ** i + Math.random() * HTTP_RETRY_JITTER_MS;
5741
+ debugLogger.info(
5742
+ `Sleeping for ${sleepTimeMs}ms before retrying API request`
5743
+ );
5744
+ await waitForRetry(sleepTimeMs, config?.signal);
5745
+ }
5746
+ }
5747
+ throw new Error("Unexpected retry state");
5724
5748
  }
5725
5749
  async get_json(object_type, args = void 0, retries = 0) {
5726
5750
  const tries = retries + 1;
@@ -6817,6 +6841,45 @@ var TestBackgroundLogger = class {
6817
6841
  };
6818
6842
  var BACKGROUND_LOGGER_BASE_SLEEP_TIME_S = 1;
6819
6843
  var HTTP_RETRY_BASE_SLEEP_TIME_S = 1;
6844
+ var HTTP_RETRY_JITTER_MS = 200;
6845
+ var BTQL_HTTP_RETRIES = 3;
6846
+ var RETRYABLE_HTTP_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
6847
+ function isRetryableHTTPError(error) {
6848
+ return !(error instanceof FailedHTTPResponse) || RETRYABLE_HTTP_STATUS_CODES.has(error.status);
6849
+ }
6850
+ function formatHTTPError(error) {
6851
+ if (error instanceof FailedHTTPResponse) {
6852
+ return `${error.status} ${error.text}`;
6853
+ }
6854
+ return error instanceof Error ? error.message : String(error);
6855
+ }
6856
+ function getAbortReason(signal) {
6857
+ return signal.reason ?? new Error("Request aborted");
6858
+ }
6859
+ async function waitForRetry(delayMs, signal) {
6860
+ if (!signal) {
6861
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
6862
+ return;
6863
+ }
6864
+ if (signal.aborted) {
6865
+ throw getAbortReason(signal);
6866
+ }
6867
+ await new Promise((resolve, reject2) => {
6868
+ const onAbort = () => {
6869
+ clearTimeout(timeout);
6870
+ signal.removeEventListener("abort", onAbort);
6871
+ reject2(getAbortReason(signal));
6872
+ };
6873
+ const timeout = setTimeout(() => {
6874
+ signal.removeEventListener("abort", onAbort);
6875
+ resolve();
6876
+ }, delayMs);
6877
+ signal.addEventListener("abort", onAbort, { once: true });
6878
+ if (signal.aborted) {
6879
+ onAbort();
6880
+ }
6881
+ });
6882
+ }
6820
6883
  var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
6821
6884
  apiConn;
6822
6885
  queue;
@@ -8555,15 +8618,15 @@ function parentSpanIdsUsable(spanId, rootSpanId) {
8555
8618
  return Boolean(spanId) && Boolean(rootSpanId);
8556
8619
  }
8557
8620
  function logError(span, error) {
8558
- let errorMessage = "<error>";
8621
+ let errorMessage2 = "<error>";
8559
8622
  let stackTrace = "";
8560
8623
  if (error instanceof Error) {
8561
- errorMessage = error.message;
8624
+ errorMessage2 = error.message;
8562
8625
  stackTrace = error.stack || "";
8563
8626
  } else {
8564
- errorMessage = String(error);
8627
+ errorMessage2 = String(error);
8565
8628
  }
8566
- span.log({ error: `${errorMessage}
8629
+ span.log({ error: `${errorMessage2}
8567
8630
 
8568
8631
  ${stackTrace}` });
8569
8632
  }
@@ -9150,7 +9213,8 @@ var ObjectFetcher = class {
9150
9213
  version: this.pinnedVersion
9151
9214
  } : {}
9152
9215
  },
9153
- { headers: { "Accept-Encoding": "gzip" } }
9216
+ { headers: { "Accept-Encoding": "gzip" } },
9217
+ BTQL_HTTP_RETRIES
9154
9218
  );
9155
9219
  const respJson = await resp.json();
9156
9220
  const mutate = this.mutateRecord;
@@ -10874,7 +10938,8 @@ async function getPromptVersions(projectId, promptId) {
10874
10938
  use_columnstore: false,
10875
10939
  brainstore_realtime: true
10876
10940
  },
10877
- { headers: { "Accept-Encoding": "gzip" } }
10941
+ { headers: { "Accept-Encoding": "gzip" } },
10942
+ BTQL_HTTP_RETRIES
10878
10943
  );
10879
10944
  if (!response.ok) {
10880
10945
  throw new Error(
@@ -18136,8 +18201,6 @@ function filterSerializableOptions(options) {
18136
18201
  "additionalDirectories",
18137
18202
  "permissionMode",
18138
18203
  "debug",
18139
- "apiKey",
18140
- "apiKeySource",
18141
18204
  "agentName",
18142
18205
  "instructions"
18143
18206
  ];
@@ -29335,6 +29398,446 @@ function isBraintrustHandler(handler) {
29335
29398
  return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
29336
29399
  }
29337
29400
 
29401
+ // src/instrumentation/plugins/langsmith-channels.ts
29402
+ var langSmithChannels = defineChannels("langsmith", {
29403
+ createRun: channel({
29404
+ channelName: "Client.createRun",
29405
+ kind: "async"
29406
+ }),
29407
+ updateRun: channel({
29408
+ channelName: "Client.updateRun",
29409
+ kind: "async"
29410
+ }),
29411
+ batchIngestRuns: channel({
29412
+ channelName: "Client.batchIngestRuns",
29413
+ kind: "async"
29414
+ })
29415
+ });
29416
+
29417
+ // src/instrumentation/plugins/langsmith-plugin.ts
29418
+ var MAX_COMPLETED_RUNS = 1e4;
29419
+ var BLOCKED_METADATA_KEYS = /* @__PURE__ */ new Set([
29420
+ "__proto__",
29421
+ "constructor",
29422
+ "prototype",
29423
+ "usage_metadata"
29424
+ ]);
29425
+ var BLOCKED_METADATA_PREFIXES = ["__pregel_", "langgraph_", "lc_"];
29426
+ var LLM_SETTING_KEYS = [
29427
+ "temperature",
29428
+ "top_p",
29429
+ "max_tokens",
29430
+ "frequency_penalty",
29431
+ "presence_penalty",
29432
+ "stop",
29433
+ "response_format"
29434
+ ];
29435
+ var LangSmithPlugin = class extends BasePlugin {
29436
+ activeRuns = /* @__PURE__ */ new Map();
29437
+ completedRuns = new LRUCache({
29438
+ max: MAX_COMPLETED_RUNS
29439
+ });
29440
+ skipLangChainRuns;
29441
+ constructor(options = {}) {
29442
+ super();
29443
+ this.skipLangChainRuns = options.skipLangChainRuns ?? true;
29444
+ }
29445
+ onEnable() {
29446
+ const createChannel = langSmithChannels.createRun.tracingChannel();
29447
+ const createHandlers = {
29448
+ start: (event) => {
29449
+ this.containLifecycleFailure("createRun", () => {
29450
+ this.processCreate(event.arguments[0]);
29451
+ });
29452
+ }
29453
+ };
29454
+ createChannel.subscribe(createHandlers);
29455
+ this.unsubscribers.push(() => createChannel.unsubscribe(createHandlers));
29456
+ const updateChannel = langSmithChannels.updateRun.tracingChannel();
29457
+ const updateHandlers = {
29458
+ start: (event) => {
29459
+ this.containLifecycleFailure("updateRun", () => {
29460
+ this.processUpdate(event.arguments[0], event.arguments[1]);
29461
+ });
29462
+ }
29463
+ };
29464
+ updateChannel.subscribe(updateHandlers);
29465
+ this.unsubscribers.push(() => updateChannel.unsubscribe(updateHandlers));
29466
+ const batchChannel = langSmithChannels.batchIngestRuns.tracingChannel();
29467
+ const batchHandlers = {
29468
+ start: (event) => {
29469
+ this.containLifecycleFailure("batchIngestRuns", () => {
29470
+ this.processBatch(event.arguments[0]);
29471
+ });
29472
+ }
29473
+ };
29474
+ batchChannel.subscribe(batchHandlers);
29475
+ this.unsubscribers.push(() => batchChannel.unsubscribe(batchHandlers));
29476
+ }
29477
+ onDisable() {
29478
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
29479
+ for (const { span } of this.activeRuns.values()) {
29480
+ span.end();
29481
+ }
29482
+ this.activeRuns.clear();
29483
+ this.completedRuns.clear();
29484
+ }
29485
+ processBatch(batch) {
29486
+ if (!isRecord2(batch)) {
29487
+ return;
29488
+ }
29489
+ const creates = ownValue(batch, "runCreates");
29490
+ if (Array.isArray(creates)) {
29491
+ const parentFirst = [...creates].sort((left, right) => {
29492
+ const leftId = stringValue2(ownValue(left, "id"));
29493
+ const rightId = stringValue2(ownValue(right, "id"));
29494
+ const leftParent = stringValue2(ownValue(left, "parent_run_id"));
29495
+ const rightParent = stringValue2(ownValue(right, "parent_run_id"));
29496
+ if (leftParent && leftParent === rightId) {
29497
+ return 1;
29498
+ }
29499
+ if (rightParent && rightParent === leftId) {
29500
+ return -1;
29501
+ }
29502
+ return dottedOrderDepth(left) - dottedOrderDepth(right);
29503
+ });
29504
+ for (const run of parentFirst) {
29505
+ this.containLifecycleFailure("batchIngestRuns create", () => {
29506
+ this.processCreate(run);
29507
+ });
29508
+ }
29509
+ }
29510
+ const updates = ownValue(batch, "runUpdates");
29511
+ if (Array.isArray(updates)) {
29512
+ for (const run of updates) {
29513
+ this.containLifecycleFailure("batchIngestRuns update", () => {
29514
+ this.processUpdate(stringValue2(ownValue(run, "id")) ?? "", run);
29515
+ });
29516
+ }
29517
+ }
29518
+ }
29519
+ processCreate(run) {
29520
+ const id = stringValue2(ownValue(run, "id"));
29521
+ if (!id || this.completedRuns.get(id)) {
29522
+ return;
29523
+ }
29524
+ if (this.shouldSkipLangChainRun(run)) {
29525
+ this.completedRuns.set(id, true);
29526
+ return;
29527
+ }
29528
+ const active = this.activeRuns.get(id);
29529
+ if (active) {
29530
+ const previous = active.run;
29531
+ active.run = mergeRuns(previous, run);
29532
+ this.logRun(
29533
+ active.span,
29534
+ active.run,
29535
+ previous,
29536
+ timestampSeconds(ownValue(active.run, "end_time")) !== void 0 || errorMessage(ownValue(active.run, "error")) !== void 0
29537
+ );
29538
+ this.endIfComplete(id, active, active.run);
29539
+ return;
29540
+ }
29541
+ const span = this.startRunSpan(id, run);
29542
+ const activeRun = { run, span };
29543
+ this.activeRuns.set(id, activeRun);
29544
+ this.logRun(
29545
+ span,
29546
+ run,
29547
+ void 0,
29548
+ timestampSeconds(ownValue(run, "end_time")) !== void 0 || errorMessage(ownValue(run, "error")) !== void 0
29549
+ );
29550
+ this.endIfComplete(id, activeRun, run);
29551
+ }
29552
+ processUpdate(explicitId, run) {
29553
+ const id = stringValue2(explicitId) ?? stringValue2(ownValue(run, "id"));
29554
+ if (!id || this.completedRuns.get(id)) {
29555
+ return;
29556
+ }
29557
+ if (this.shouldSkipLangChainRun(run)) {
29558
+ const active2 = this.activeRuns.get(id);
29559
+ active2?.span.end();
29560
+ this.activeRuns.delete(id);
29561
+ this.completedRuns.set(id, true);
29562
+ return;
29563
+ }
29564
+ let active = this.activeRuns.get(id);
29565
+ if (!active) {
29566
+ const span = this.startRunSpan(id, run);
29567
+ active = { run, span };
29568
+ this.activeRuns.set(id, active);
29569
+ }
29570
+ const previous = active.run;
29571
+ active.run = mergeRuns(previous, run);
29572
+ this.logRun(active.span, active.run, previous, true);
29573
+ this.endIfComplete(id, active, active.run);
29574
+ }
29575
+ startRunSpan(id, run) {
29576
+ const traceId = stringValue2(ownValue(run, "trace_id")) ?? id;
29577
+ const parentId = stringValue2(ownValue(run, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run, "parent_run"), "id"));
29578
+ const startTime = timestampSeconds(ownValue(run, "start_time"));
29579
+ return startSpan({
29580
+ name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
29581
+ spanId: id,
29582
+ parentSpanIds: {
29583
+ parentSpanIds: parentId ? [parentId] : [],
29584
+ rootSpanId: traceId
29585
+ },
29586
+ spanAttributes: {
29587
+ type: mapRunType(ownValue(run, "run_type"))
29588
+ },
29589
+ ...startTime === void 0 ? {} : { startTime },
29590
+ event: { id }
29591
+ });
29592
+ }
29593
+ logRun(span, run, previous, includeOutput) {
29594
+ const inputs = preferOwnValue(run, previous, "inputs");
29595
+ const outputs = preferOwnValue(run, previous, "outputs");
29596
+ const error = errorMessage(preferOwnValue(run, previous, "error"));
29597
+ const metadata = extractMetadata(run, previous);
29598
+ const tags = extractTags(preferOwnValue(run, previous, "tags"));
29599
+ const metrics = extractMetrics(run, previous);
29600
+ span.log({
29601
+ ...inputs === void 0 ? {} : { input: sanitizeLoggedValue(inputs) },
29602
+ ...includeOutput && outputs !== void 0 ? { output: sanitizeLoggedValue(outputs) } : {},
29603
+ ...error === void 0 ? {} : { error },
29604
+ ...metadata === void 0 ? {} : { metadata },
29605
+ ...tags === void 0 ? {} : { tags },
29606
+ ...Object.keys(metrics).length === 0 ? {} : { metrics }
29607
+ });
29608
+ }
29609
+ endIfComplete(id, active, run) {
29610
+ const endTime = timestampSeconds(ownValue(run, "end_time"));
29611
+ if (endTime === void 0 && errorMessage(ownValue(run, "error")) === void 0) {
29612
+ return;
29613
+ }
29614
+ active.span.end(endTime === void 0 ? void 0 : { endTime });
29615
+ this.activeRuns.delete(id);
29616
+ this.completedRuns.set(id, true);
29617
+ }
29618
+ shouldSkipLangChainRun(run) {
29619
+ if (!this.skipLangChainRuns) {
29620
+ return false;
29621
+ }
29622
+ const serialized = ownValue(run, "serialized");
29623
+ return isRecord2(serialized) && ownValue(serialized, "lc") === 1;
29624
+ }
29625
+ containLifecycleFailure(operation, fn) {
29626
+ try {
29627
+ fn();
29628
+ } catch (error) {
29629
+ debugLogger.error(
29630
+ `Failed to process LangSmith ${operation} instrumentation:`,
29631
+ error
29632
+ );
29633
+ }
29634
+ }
29635
+ };
29636
+ function ownValue(value, key) {
29637
+ if (!isRecord2(value)) {
29638
+ return void 0;
29639
+ }
29640
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
29641
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
29642
+ }
29643
+ function preferOwnValue(current, previous, key) {
29644
+ const currentDescriptor = isRecord2(current) ? Object.getOwnPropertyDescriptor(current, key) : void 0;
29645
+ if (currentDescriptor && "value" in currentDescriptor) {
29646
+ return currentDescriptor.value;
29647
+ }
29648
+ return ownValue(previous, key);
29649
+ }
29650
+ function mergeRuns(previous, current) {
29651
+ const entries = /* @__PURE__ */ new Map();
29652
+ for (const value of [previous, current]) {
29653
+ if (!isRecord2(value)) {
29654
+ continue;
29655
+ }
29656
+ for (const [key, descriptor] of Object.entries(
29657
+ Object.getOwnPropertyDescriptors(value)
29658
+ )) {
29659
+ if (descriptor.enumerable && "value" in descriptor) {
29660
+ entries.set(key, descriptor.value);
29661
+ }
29662
+ }
29663
+ }
29664
+ return Object.fromEntries(entries);
29665
+ }
29666
+ function isRecord2(value) {
29667
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29668
+ }
29669
+ function stringValue2(value) {
29670
+ return typeof value === "string" && value.length > 0 ? value : void 0;
29671
+ }
29672
+ function timestampSeconds(value) {
29673
+ if (value instanceof Date) {
29674
+ const timestamp = value.getTime();
29675
+ return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
29676
+ }
29677
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
29678
+ return value > 1e10 ? value / 1e3 : value;
29679
+ }
29680
+ if (typeof value === "string") {
29681
+ const timestamp = Date.parse(value);
29682
+ return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
29683
+ }
29684
+ return void 0;
29685
+ }
29686
+ function dottedOrderDepth(run) {
29687
+ const dottedOrder = stringValue2(ownValue(run, "dotted_order"));
29688
+ return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
29689
+ }
29690
+ function mapRunType(runType) {
29691
+ switch (runType) {
29692
+ case "llm":
29693
+ case "embedding":
29694
+ return "llm" /* LLM */;
29695
+ case "tool":
29696
+ case "retriever":
29697
+ return "tool" /* TOOL */;
29698
+ default:
29699
+ return "task" /* TASK */;
29700
+ }
29701
+ }
29702
+ function extractMetadata(run, previous) {
29703
+ const extra = preferOwnValue(run, previous, "extra");
29704
+ const rawMetadata = ownValue(extra, "metadata");
29705
+ if (!isRecord2(rawMetadata)) {
29706
+ return void 0;
29707
+ }
29708
+ const metadata = {};
29709
+ for (const [key, descriptor] of Object.entries(
29710
+ Object.getOwnPropertyDescriptors(rawMetadata)
29711
+ )) {
29712
+ 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}`)) {
29713
+ continue;
29714
+ }
29715
+ const normalizedKey = key === "ls_provider" ? "provider" : key === "ls_model_name" ? "model" : key.startsWith("ls_") ? key.slice(3) : key;
29716
+ const sanitized = sanitizeLoggedValue(descriptor.value);
29717
+ if (sanitized !== void 0) {
29718
+ metadata[normalizedKey] = sanitized;
29719
+ }
29720
+ }
29721
+ return Object.keys(metadata).length === 0 ? void 0 : metadata;
29722
+ }
29723
+ function extractTags(value) {
29724
+ if (!Array.isArray(value)) {
29725
+ return void 0;
29726
+ }
29727
+ const tags = value.filter(
29728
+ (tag) => typeof tag === "string" && tag.length > 0
29729
+ );
29730
+ return tags.length > 0 ? tags : void 0;
29731
+ }
29732
+ function extractMetrics(run, previous) {
29733
+ const outputs = preferOwnValue(run, previous, "outputs");
29734
+ const extra = preferOwnValue(run, previous, "extra");
29735
+ const metadata = ownValue(extra, "metadata");
29736
+ const usage = ownValue(outputs, "usage_metadata") ?? ownValue(metadata, "usage_metadata");
29737
+ const metrics = {};
29738
+ assignFirstMetric(metrics, "prompt_tokens", usage, [
29739
+ "input_tokens",
29740
+ "prompt_tokens"
29741
+ ]);
29742
+ assignFirstMetric(metrics, "completion_tokens", usage, [
29743
+ "output_tokens",
29744
+ "completion_tokens"
29745
+ ]);
29746
+ assignFirstMetric(metrics, "tokens", usage, ["total_tokens", "tokens"]);
29747
+ const inputTokenDetails = ownValue(usage, "input_token_details");
29748
+ assignFirstMetric(metrics, "prompt_cached_tokens", inputTokenDetails, [
29749
+ "cache_read",
29750
+ "cached_tokens"
29751
+ ]);
29752
+ if (metrics.prompt_cached_tokens === void 0) {
29753
+ assignFirstMetric(metrics, "prompt_cached_tokens", usage, [
29754
+ "cache_read_input_tokens",
29755
+ "prompt_cached_tokens"
29756
+ ]);
29757
+ }
29758
+ assignFirstMetric(
29759
+ metrics,
29760
+ "prompt_cache_creation_tokens",
29761
+ inputTokenDetails,
29762
+ ["cache_creation"]
29763
+ );
29764
+ if (metrics.prompt_cache_creation_tokens === void 0) {
29765
+ assignFirstMetric(metrics, "prompt_cache_creation_tokens", usage, [
29766
+ "cache_creation_input_tokens",
29767
+ "prompt_cache_creation_tokens"
29768
+ ]);
29769
+ }
29770
+ if (metrics.tokens === void 0 && (metrics.prompt_tokens !== void 0 || metrics.completion_tokens !== void 0)) {
29771
+ metrics.tokens = (metrics.prompt_tokens ?? 0) + (metrics.completion_tokens ?? 0);
29772
+ }
29773
+ const startTime = timestampSeconds(
29774
+ preferOwnValue(run, previous, "start_time")
29775
+ );
29776
+ const events = preferOwnValue(run, previous, "events");
29777
+ if (startTime !== void 0 && Array.isArray(events)) {
29778
+ for (const event of events) {
29779
+ if (ownValue(event, "name") !== "new_token") {
29780
+ continue;
29781
+ }
29782
+ const eventTime3 = timestampSeconds(ownValue(event, "time"));
29783
+ if (eventTime3 !== void 0 && eventTime3 >= startTime) {
29784
+ metrics.time_to_first_token = eventTime3 - startTime;
29785
+ }
29786
+ break;
29787
+ }
29788
+ }
29789
+ return metrics;
29790
+ }
29791
+ function assignFirstMetric(metrics, target, source, keys) {
29792
+ for (const key of keys) {
29793
+ const value = ownValue(source, key);
29794
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
29795
+ metrics[target] = value;
29796
+ return;
29797
+ }
29798
+ }
29799
+ }
29800
+ function errorMessage(value) {
29801
+ if (typeof value === "string") {
29802
+ return value;
29803
+ }
29804
+ if (value instanceof Error) {
29805
+ return value.message;
29806
+ }
29807
+ return void 0;
29808
+ }
29809
+ function sanitizeLoggedValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
29810
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
29811
+ return value;
29812
+ }
29813
+ if (typeof value === "number") {
29814
+ return Number.isFinite(value) ? value : void 0;
29815
+ }
29816
+ if (value instanceof Date) {
29817
+ return Number.isFinite(value.getTime()) ? value.toISOString() : void 0;
29818
+ }
29819
+ if (typeof value !== "object" || depth >= 20) {
29820
+ return void 0;
29821
+ }
29822
+ if (seen.has(value)) {
29823
+ return "[Circular]";
29824
+ }
29825
+ seen.add(value);
29826
+ if (Array.isArray(value)) {
29827
+ return value.map((item) => sanitizeLoggedValue(item, seen, depth + 1));
29828
+ }
29829
+ const entries = [];
29830
+ for (const [key, descriptor] of Object.entries(
29831
+ Object.getOwnPropertyDescriptors(value)
29832
+ )) {
29833
+ if (!descriptor.enumerable || !("value" in descriptor) || BLOCKED_METADATA_KEYS.has(key)) {
29834
+ continue;
29835
+ }
29836
+ entries.push([key, sanitizeLoggedValue(descriptor.value, seen, depth + 1)]);
29837
+ }
29838
+ return Object.fromEntries(entries);
29839
+ }
29840
+
29338
29841
  // src/instrumentation/plugins/pi-coding-agent-channels.ts
29339
29842
  var piCodingAgentChannels = defineChannels(
29340
29843
  "@earendil-works/pi-coding-agent",
@@ -29714,11 +30217,11 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
29714
30217
  function recordPiAssistantMessageEvent(promptState, llmState, event) {
29715
30218
  recordFirstTokenMetric(llmState, event);
29716
30219
  const message = "message" in event ? event.message : void 0;
29717
- const errorMessage = "error" in event ? event.error : void 0;
30220
+ const errorMessage2 = "error" in event ? event.error : void 0;
29718
30221
  if (event.type === "done" && isPiAssistantMessage(message)) {
29719
30222
  finishPiLlmSpan(promptState, llmState, message);
29720
- } else if (event.type === "error" && isPiAssistantMessage(errorMessage)) {
29721
- finishPiLlmSpan(promptState, llmState, errorMessage);
30223
+ } else if (event.type === "error" && isPiAssistantMessage(errorMessage2)) {
30224
+ finishPiLlmSpan(promptState, llmState, errorMessage2);
29722
30225
  }
29723
30226
  }
29724
30227
  function recordFirstTokenMetric(state, event) {
@@ -30236,6 +30739,7 @@ var strandsAgentSDKChannels = defineChannels("@strands-agents/sdk", {
30236
30739
  });
30237
30740
 
30238
30741
  // src/instrumentation/plugins/strands-agent-sdk-plugin.ts
30742
+ var MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES = 32;
30239
30743
  var StrandsAgentSDKPlugin = class extends BasePlugin {
30240
30744
  activeChildParents = /* @__PURE__ */ new WeakMap();
30241
30745
  onEnable() {
@@ -30380,11 +30884,16 @@ function startAgentStream(event, activeChildParents) {
30380
30884
  ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
30381
30885
  };
30382
30886
  const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
30887
+ const attachmentCache = createStrandsAttachmentCache();
30888
+ const input = processStrandsInputAttachments(
30889
+ event.arguments[0],
30890
+ attachmentCache
30891
+ );
30383
30892
  const span = parentSpan ? withCurrent(
30384
30893
  parentSpan,
30385
30894
  () => startSpan({
30386
30895
  event: {
30387
- input: event.arguments[0],
30896
+ input,
30388
30897
  metadata
30389
30898
  },
30390
30899
  name: formatAgentSpanName(agent),
@@ -30392,7 +30901,7 @@ function startAgentStream(event, activeChildParents) {
30392
30901
  })
30393
30902
  ) : startSpan({
30394
30903
  event: {
30395
- input: event.arguments[0],
30904
+ input,
30396
30905
  metadata
30397
30906
  },
30398
30907
  name: formatAgentSpanName(agent),
@@ -30400,6 +30909,7 @@ function startAgentStream(event, activeChildParents) {
30400
30909
  });
30401
30910
  return {
30402
30911
  activeTools: /* @__PURE__ */ new Map(),
30912
+ attachmentCache,
30403
30913
  finalized: false,
30404
30914
  metadata,
30405
30915
  span,
@@ -30415,11 +30925,12 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30415
30925
  ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
30416
30926
  };
30417
30927
  const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
30928
+ const input = processStrandsInputAttachments(event.arguments[0]);
30418
30929
  const span = parentSpan ? withCurrent(
30419
30930
  parentSpan,
30420
30931
  () => startSpan({
30421
30932
  event: {
30422
- input: event.arguments[0],
30933
+ input,
30423
30934
  metadata
30424
30935
  },
30425
30936
  name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
@@ -30427,7 +30938,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30427
30938
  })
30428
30939
  ) : startSpan({
30429
30940
  event: {
30430
- input: event.arguments[0],
30941
+ input,
30431
30942
  metadata
30432
30943
  },
30433
30944
  name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
@@ -30536,7 +31047,10 @@ function startModelSpan(state, event) {
30536
31047
  state.span,
30537
31048
  () => startSpan({
30538
31049
  event: {
30539
- input: Array.isArray(event.agent?.messages) ? event.agent.messages : void 0,
31050
+ input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
31051
+ event.agent.messages,
31052
+ state.attachmentCache
31053
+ ) : void 0,
30540
31054
  metadata
30541
31055
  },
30542
31056
  name: formatModelSpanName(model),
@@ -30750,6 +31264,7 @@ function finalizeAgentStream(state, error, output) {
30750
31264
  ...output !== void 0 ? { output } : {}
30751
31265
  });
30752
31266
  state.span.end();
31267
+ state.attachmentCache.strings.clear();
30753
31268
  }
30754
31269
  function finalizeMultiAgentStream(state, activeChildParents, error, output) {
30755
31270
  if (state.finalized) {
@@ -30896,6 +31411,166 @@ function extractNodeResultOutput(result) {
30896
31411
  }
30897
31412
  return result;
30898
31413
  }
31414
+ var STRANDS_MEDIA_TYPES = {
31415
+ png: "image/png",
31416
+ jpg: "image/jpeg",
31417
+ jpeg: "image/jpeg",
31418
+ gif: "image/gif",
31419
+ webp: "image/webp",
31420
+ mkv: "video/x-matroska",
31421
+ mov: "video/quicktime",
31422
+ mp4: "video/mp4",
31423
+ webm: "video/webm",
31424
+ flv: "video/x-flv",
31425
+ mpeg: "video/mpeg",
31426
+ mpg: "video/mpeg",
31427
+ wmv: "video/x-ms-wmv",
31428
+ "3gp": "video/3gpp",
31429
+ pdf: "application/pdf",
31430
+ csv: "text/csv",
31431
+ doc: "application/msword",
31432
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
31433
+ xls: "application/vnd.ms-excel",
31434
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
31435
+ html: "text/html",
31436
+ txt: "text/plain",
31437
+ md: "text/markdown",
31438
+ json: "application/json",
31439
+ xml: "application/xml"
31440
+ };
31441
+ function createStrandsAttachmentCache() {
31442
+ return {
31443
+ objects: /* @__PURE__ */ new WeakMap(),
31444
+ strings: new LRUCache({
31445
+ max: MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES
31446
+ })
31447
+ };
31448
+ }
31449
+ function processStrandsInputAttachments(input, cache = createStrandsAttachmentCache()) {
31450
+ try {
31451
+ return processStrandsInputNode(input, cache);
31452
+ } catch (error) {
31453
+ logInstrumentationError5("Strands Agent SDK input attachments", error);
31454
+ return input;
31455
+ }
31456
+ }
31457
+ function processStrandsInputNode(value, cache) {
31458
+ if (value instanceof BaseAttachment) {
31459
+ return value;
31460
+ }
31461
+ if (Array.isArray(value)) {
31462
+ return value.map((child) => processStrandsInputNode(child, cache));
31463
+ }
31464
+ if (!isObject(value)) {
31465
+ return value;
31466
+ }
31467
+ const directMedia = processDirectStrandsMediaBlock(value, cache);
31468
+ if (directMedia !== void 0) {
31469
+ return directMedia;
31470
+ }
31471
+ const wrappedMedia = processWrappedStrandsMediaBlock(value, cache);
31472
+ if (wrappedMedia !== void 0) {
31473
+ return wrappedMedia;
31474
+ }
31475
+ if (value.type === "message" && Array.isArray(value.content)) {
31476
+ return {
31477
+ role: value.role,
31478
+ content: value.content.map(
31479
+ (child) => processStrandsInputNode(child, cache)
31480
+ ),
31481
+ ...value.metadata !== void 0 ? { metadata: value.metadata } : {}
31482
+ };
31483
+ }
31484
+ if (typeof value.toJSON === "function") {
31485
+ return processStrandsInputNode(value.toJSON(), cache);
31486
+ }
31487
+ return Object.fromEntries(
31488
+ Object.entries(value).map(([key, child]) => [
31489
+ key,
31490
+ processStrandsInputNode(child, cache)
31491
+ ])
31492
+ );
31493
+ }
31494
+ function processDirectStrandsMediaBlock(block, cache) {
31495
+ if (!isStrandsMediaBlock(block)) {
31496
+ return void 0;
31497
+ }
31498
+ const mediaKey = block.type === "imageBlock" ? "image" : block.type === "videoBlock" ? "video" : "document";
31499
+ return createStrandsMediaAttachment(mediaKey, block, cache);
31500
+ }
31501
+ function isStrandsMediaBlock(block) {
31502
+ return (block.type === "imageBlock" || block.type === "videoBlock" || block.type === "documentBlock") && typeof block.format === "string" && isObject(block.source);
31503
+ }
31504
+ function processWrappedStrandsMediaBlock(block, cache) {
31505
+ for (const mediaKey of ["image", "video", "document"]) {
31506
+ const media = block[mediaKey];
31507
+ if (!Object.hasOwn(block, mediaKey) || !isObject(media)) {
31508
+ continue;
31509
+ }
31510
+ const processed = createStrandsMediaAttachment(mediaKey, media, cache);
31511
+ if (processed !== void 0) {
31512
+ return processed;
31513
+ }
31514
+ }
31515
+ return void 0;
31516
+ }
31517
+ function createStrandsMediaAttachment(mediaKey, media, cache) {
31518
+ const format = media.format;
31519
+ const source = media.source;
31520
+ if (typeof format !== "string" || !isObject(source) || !Object.hasOwn(source, "bytes")) {
31521
+ return void 0;
31522
+ }
31523
+ const contentType = STRANDS_MEDIA_TYPES[format.toLowerCase()];
31524
+ if (!contentType) {
31525
+ return void 0;
31526
+ }
31527
+ const filename = mediaKey === "document" && typeof media.name === "string" && media.name.length > 0 ? media.name : `${mediaKey}.${format.toLowerCase()}`;
31528
+ const attachment = getOrCreateStrandsAttachment(
31529
+ source.bytes,
31530
+ filename,
31531
+ contentType,
31532
+ cache
31533
+ );
31534
+ if (!attachment) {
31535
+ return void 0;
31536
+ }
31537
+ const { type: _type, ...serializedMedia } = media;
31538
+ const { type: _sourceType, ...serializedSource } = source;
31539
+ return {
31540
+ [mediaKey]: {
31541
+ ...serializedMedia,
31542
+ source: {
31543
+ ...serializedSource,
31544
+ bytes: attachment
31545
+ }
31546
+ }
31547
+ };
31548
+ }
31549
+ function getOrCreateStrandsAttachment(data, filename, contentType, cache) {
31550
+ const key = `${contentType}\0${filename}`;
31551
+ const attachments = typeof data === "string" ? cache.strings.get(data) : isObject(data) ? cache.objects.get(data) : void 0;
31552
+ const cached = attachments?.get(key);
31553
+ if (cached) {
31554
+ return cached;
31555
+ }
31556
+ const blob = convertDataToBlob(data, contentType);
31557
+ if (!blob) {
31558
+ return void 0;
31559
+ }
31560
+ const attachment = new Attachment({
31561
+ data: blob,
31562
+ filename,
31563
+ contentType
31564
+ });
31565
+ const updatedAttachments = attachments ?? /* @__PURE__ */ new Map();
31566
+ updatedAttachments.set(key, attachment);
31567
+ if (typeof data === "string") {
31568
+ cache.strings.set(data, updatedAttachments);
31569
+ } else if (isObject(data)) {
31570
+ cache.objects.set(data, updatedAttachments);
31571
+ }
31572
+ return attachment;
31573
+ }
30899
31574
  function normalizeContentBlocks(blocks) {
30900
31575
  const text = blocks.map((block) => typeof block.text === "string" ? block.text : void 0).filter((part) => Boolean(part)).join("");
30901
31576
  return text.length > 0 ? text : blocks;
@@ -31025,6 +31700,7 @@ var BraintrustPlugin = class extends BasePlugin {
31025
31700
  gitHubCopilotPlugin = null;
31026
31701
  fluePlugin = null;
31027
31702
  langChainPlugin = null;
31703
+ langSmithPlugin = null;
31028
31704
  piCodingAgentPlugin = null;
31029
31705
  strandsAgentSDKPlugin = null;
31030
31706
  constructor(config = {}) {
@@ -31121,6 +31797,12 @@ var BraintrustPlugin = class extends BasePlugin {
31121
31797
  this.langChainPlugin = new LangChainPlugin();
31122
31798
  this.langChainPlugin.enable();
31123
31799
  }
31800
+ if (integrations.langsmith !== false) {
31801
+ this.langSmithPlugin = new LangSmithPlugin({
31802
+ skipLangChainRuns: integrations.langchain !== false
31803
+ });
31804
+ this.langSmithPlugin.enable();
31805
+ }
31124
31806
  }
31125
31807
  onDisable() {
31126
31808
  if (this.openaiPlugin) {
@@ -31211,6 +31893,10 @@ var BraintrustPlugin = class extends BasePlugin {
31211
31893
  this.langChainPlugin.disable();
31212
31894
  this.langChainPlugin = null;
31213
31895
  }
31896
+ if (this.langSmithPlugin) {
31897
+ this.langSmithPlugin.disable();
31898
+ this.langSmithPlugin = null;
31899
+ }
31214
31900
  }
31215
31901
  };
31216
31902
 
@@ -31275,7 +31961,8 @@ var envIntegrationAliases = {
31275
31961
  langchain: "langchain",
31276
31962
  "langchain-js": "langchain",
31277
31963
  "@langchain": "langchain",
31278
- langgraph: "langgraph"
31964
+ langgraph: "langgraph",
31965
+ langsmith: "langsmith"
31279
31966
  };
31280
31967
  function getDefaultInstrumentationIntegrations() {
31281
31968
  return {
@@ -31306,6 +31993,7 @@ function getDefaultInstrumentationIntegrations() {
31306
31993
  gitHubCopilot: true,
31307
31994
  langchain: true,
31308
31995
  langgraph: true,
31996
+ langsmith: true,
31309
31997
  piCodingAgent: true,
31310
31998
  strandsAgentSDK: true
31311
31999
  };
@@ -31702,6 +32390,9 @@ __export(exports_exports, {
31702
32390
  wrapGoogleGenAI: () => wrapGoogleGenAI,
31703
32391
  wrapGroq: () => wrapGroq,
31704
32392
  wrapHuggingFace: () => wrapHuggingFace,
32393
+ wrapLangSmithClient: () => wrapLangSmithClient,
32394
+ wrapLangSmithRunTrees: () => wrapLangSmithRunTrees,
32395
+ wrapLangSmithTraceable: () => wrapLangSmithTraceable,
31705
32396
  wrapMastraAgent: () => wrapMastraAgent,
31706
32397
  wrapMistral: () => wrapMistral,
31707
32398
  wrapOpenAI: () => wrapOpenAI,
@@ -33188,9 +33879,6 @@ var EveBridge = class {
33188
33879
  this.state = state;
33189
33880
  }
33190
33881
  eventQueuesBySession = /* @__PURE__ */ new Map();
33191
- sessionsById = new LRUCache({
33192
- max: MAX_EVE_CACHE_ENTRIES
33193
- });
33194
33882
  completedToolKeys = new LRUCache({
33195
33883
  max: MAX_EVE_CACHE_ENTRIES
33196
33884
  });
@@ -33357,7 +34045,7 @@ var EveBridge = class {
33357
34045
  async handleEvent(event, ctx, hookMetadata) {
33358
34046
  switch (event.type) {
33359
34047
  case "session.started":
33360
- await this.handleSessionStarted(event, ctx, hookMetadata);
34048
+ this.handleSessionStarted(event, ctx, hookMetadata);
33361
34049
  return true;
33362
34050
  case "turn.started":
33363
34051
  await this.handleTurnStarted(event, ctx, hookMetadata);
@@ -33393,22 +34081,22 @@ var EveBridge = class {
33393
34081
  this.handleStepFailed(event, ctx);
33394
34082
  return true;
33395
34083
  case "turn.completed":
33396
- await this.handleTurnCompleted(event, ctx);
34084
+ this.handleTurnCompleted(event, ctx);
33397
34085
  return true;
33398
34086
  case "turn.failed":
33399
- await this.handleTurnFailed(event, ctx);
34087
+ this.handleTurnFailed(event, ctx);
33400
34088
  return true;
33401
34089
  case "session.failed":
33402
- await this.handleSessionFailed(event, ctx);
34090
+ this.handleSessionFailed(event, ctx);
33403
34091
  return true;
33404
34092
  case "session.completed":
33405
- await this.handleSessionCompleted(event, ctx);
34093
+ this.handleSessionCompleted(event, ctx);
33406
34094
  return true;
33407
34095
  default:
33408
34096
  return false;
33409
34097
  }
33410
34098
  }
33411
- async handleSessionStarted(event, ctx, hookMetadata) {
34099
+ handleSessionStarted(event, ctx, hookMetadata) {
33412
34100
  const sessionId = sessionIdFromContext(ctx);
33413
34101
  if (!sessionId) {
33414
34102
  return;
@@ -33424,7 +34112,6 @@ var EveBridge = class {
33424
34112
  metadata: { ...normalized.metadata, ...metadata }
33425
34113
  };
33426
34114
  });
33427
- await this.ensureSession(sessionId, ctx, metadata, eventTime2(event));
33428
34115
  for (const [key, turn] of this.turnsByKey) {
33429
34116
  if (!key.startsWith(`${sessionId}:`)) {
33430
34117
  continue;
@@ -33442,21 +34129,19 @@ var EveBridge = class {
33442
34129
  if (!sessionId) {
33443
34130
  return;
33444
34131
  }
33445
- const session = await this.ensureSession(
33446
- sessionId,
33447
- ctx,
33448
- hookMetadata ?? {},
33449
- eventTime2(event)
33450
- );
33451
34132
  const key = turnKey2(sessionId, event.data.turnId);
33452
- const metadata = { ...session.metadata };
34133
+ const metadata = {
34134
+ ...readEveTraceState(this.state).metadata,
34135
+ ...hookMetadata ?? {},
34136
+ "eve.session_id": sessionId
34137
+ };
33453
34138
  const existing = this.turnsByKey.get(key);
33454
34139
  if (existing) {
33455
34140
  existing.metadata = { ...existing.metadata, ...metadata };
33456
34141
  existing.span.log({ metadata: existing.metadata });
33457
34142
  return;
33458
34143
  }
33459
- const span = await this.startTurnSpan(session, event, metadata);
34144
+ const span = await this.startTurnSpan(sessionId, event, ctx, metadata);
33460
34145
  span.log({ metadata });
33461
34146
  this.turnsByKey.set(key, {
33462
34147
  key,
@@ -33494,10 +34179,7 @@ var EveBridge = class {
33494
34179
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
33495
34180
  }
33496
34181
  const stepOrdinal = this.stepOrdinal(event);
33497
- const metadata = {
33498
- ...turn.metadata,
33499
- ...this.sessionsById.get(sessionId)?.metadata ?? {}
33500
- };
34182
+ const metadata = { ...turn.metadata };
33501
34183
  const input = consumeCapturedEveModelInput(
33502
34184
  this.state,
33503
34185
  sessionId,
@@ -33592,6 +34274,28 @@ var EveBridge = class {
33592
34274
  if (!step) {
33593
34275
  return;
33594
34276
  }
34277
+ const toolCallsById = /* @__PURE__ */ new Map();
34278
+ if (Array.isArray(step.output) && isObject(step.output[0])) {
34279
+ const message = step.output[0]["message"];
34280
+ if (isObject(message) && Array.isArray(message["tool_calls"])) {
34281
+ for (const toolCall of message["tool_calls"]) {
34282
+ if (isObject(toolCall) && typeof toolCall["id"] === "string") {
34283
+ toolCallsById.set(toolCall["id"], toolCall);
34284
+ }
34285
+ }
34286
+ }
34287
+ }
34288
+ for (const action of traceActions) {
34289
+ const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
34290
+ toolCallsById.set(action.callId, {
34291
+ function: {
34292
+ arguments: JSON.stringify(action.input),
34293
+ name
34294
+ },
34295
+ id: action.callId,
34296
+ type: "function"
34297
+ });
34298
+ }
33595
34299
  step.output = [
33596
34300
  {
33597
34301
  finish_reason: "tool_calls",
@@ -33599,17 +34303,7 @@ var EveBridge = class {
33599
34303
  message: {
33600
34304
  content: null,
33601
34305
  role: "assistant",
33602
- tool_calls: traceActions.map((action) => {
33603
- const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
33604
- return {
33605
- function: {
33606
- arguments: JSON.stringify(action.input),
33607
- name
33608
- },
33609
- id: action.callId,
33610
- type: "function"
33611
- };
33612
- })
34306
+ tool_calls: [...toolCallsById.values()]
33613
34307
  }
33614
34308
  }
33615
34309
  ];
@@ -33856,17 +34550,11 @@ var EveBridge = class {
33856
34550
  )
33857
34551
  });
33858
34552
  }
33859
- async handleSessionFailed(event, ctx) {
34553
+ handleSessionFailed(event, ctx) {
33860
34554
  const sessionId = event.data.sessionId || sessionIdFromContext(ctx);
33861
34555
  if (!sessionId) {
33862
34556
  return;
33863
34557
  }
33864
- const session = await this.ensureSession(
33865
- sessionId,
33866
- ctx,
33867
- {},
33868
- eventTime2(event)
33869
- );
33870
34558
  const error = errorFromMessage(
33871
34559
  event.data.message,
33872
34560
  event.data.code,
@@ -33883,29 +34571,20 @@ var EveBridge = class {
33883
34571
  }
33884
34572
  for (const [key, tool] of this.toolsByCallKey) {
33885
34573
  if (key.startsWith(`${sessionId}:`)) {
33886
- const endTime2 = eventTime2(event);
34574
+ const endTime = eventTime2(event);
33887
34575
  if (!tool.endedByTurn) {
33888
34576
  tool.span.log({ metadata: tool.metadata });
33889
- tool.span.end(endTime2 === void 0 ? void 0 : { endTime: endTime2 });
34577
+ tool.span.end(endTime === void 0 ? void 0 : { endTime });
33890
34578
  tool.endedByTurn = true;
33891
34579
  }
33892
34580
  }
33893
34581
  }
33894
- session.span.log({ error });
33895
- const endTime = eventTime2(event);
33896
- session.span.end(endTime === void 0 ? void 0 : { endTime });
33897
34582
  }
33898
- async handleSessionCompleted(event, ctx) {
34583
+ handleSessionCompleted(event, ctx) {
33899
34584
  const sessionId = sessionIdFromContext(ctx);
33900
34585
  if (!sessionId) {
33901
34586
  return;
33902
34587
  }
33903
- const session = await this.ensureSession(
33904
- sessionId,
33905
- ctx,
33906
- {},
33907
- eventTime2(event)
33908
- );
33909
34588
  for (const [key, turn] of this.turnsByKey) {
33910
34589
  if (!key.startsWith(`${sessionId}:`)) {
33911
34590
  continue;
@@ -33916,82 +34595,29 @@ var EveBridge = class {
33916
34595
  }
33917
34596
  for (const [key, tool] of this.toolsByCallKey) {
33918
34597
  if (key.startsWith(`${sessionId}:`) && !tool.endedByTurn) {
33919
- const endTime2 = eventTime2(event);
34598
+ const endTime = eventTime2(event);
33920
34599
  tool.span.log({ metadata: tool.metadata });
33921
- tool.span.end(endTime2 === void 0 ? void 0 : { endTime: endTime2 });
34600
+ tool.span.end(endTime === void 0 ? void 0 : { endTime });
33922
34601
  tool.endedByTurn = true;
33923
34602
  }
33924
34603
  }
33925
- session.span.log({ metadata: session.metadata });
33926
- const endTime = eventTime2(event);
33927
- session.span.end(endTime === void 0 ? void 0 : { endTime });
33928
- }
33929
- async ensureSession(sessionId, ctx, metadata, startTime) {
33930
- metadata = {
33931
- ...readEveTraceState(this.state).metadata,
33932
- ...metadata
33933
- };
33934
- const existing = this.sessionsById.get(sessionId);
33935
- if (existing) {
33936
- existing.metadata = { ...existing.metadata, ...metadata };
33937
- existing.span.log({ metadata: existing.metadata });
33938
- return existing;
33939
- }
33940
- const lineage = parentLineageFromContext(ctx);
33941
- const parentSubagent = lineage ? this.toolsByCallKey.get(toolKey3(lineage.sessionId, lineage.callId)) : void 0;
33942
- const activeParent = currentSpan();
33943
- const [
33944
- { rowId: eventId, spanId },
33945
- parentSubagentSpanId,
33946
- fallbackRootSpanId
33947
- ] = await Promise.all([
33948
- generateEveIds("session", sessionId),
33949
- lineage ? spanIdForSubagent(lineage.sessionId, lineage.callId) : Promise.resolve(void 0),
33950
- lineage ? rootSpanIdForSession(lineage.rootSessionId) : rootSpanIdForSession(sessionId)
33951
- ]);
33952
- const span = await this.startEveSpan({
33953
- event: {
33954
- id: eventId,
33955
- metadata
33956
- },
33957
- name: "eve.session",
33958
- parentSpanIds: lineage && parentSubagentSpanId ? {
33959
- rootSpanId: parentSubagent?.span.rootSpanId ?? fallbackRootSpanId,
33960
- spanId: parentSubagentSpanId
33961
- } : !Object.is(activeParent, NOOP_SPAN) ? {
33962
- rootSpanId: activeParent.rootSpanId,
33963
- spanId: activeParent.spanId
33964
- } : {
33965
- parentSpanIds: [],
33966
- rootSpanId: fallbackRootSpanId
33967
- },
33968
- spanAttributes: { type: "task" /* TASK */ },
33969
- spanId,
33970
- startTime
33971
- });
33972
- span.log({ metadata });
33973
- const session = { metadata, sessionId, span };
33974
- this.sessionsById.set(sessionId, session);
33975
- return session;
33976
34604
  }
33977
34605
  async ensureTurn(event, ctx, hookMetadata) {
33978
34606
  const sessionId = sessionIdFromContext(ctx);
33979
34607
  if (!sessionId) {
33980
34608
  return void 0;
33981
34609
  }
33982
- const session = await this.ensureSession(
33983
- sessionId,
33984
- ctx,
33985
- hookMetadata ?? {},
33986
- eventTime2(event)
33987
- );
33988
34610
  const key = turnKey2(sessionId, event.data.turnId);
33989
34611
  const existing = this.turnsByKey.get(key);
33990
34612
  if (existing) {
33991
34613
  return existing;
33992
34614
  }
33993
- const metadata = { ...session.metadata };
33994
- const span = await this.startTurnSpan(session, event, metadata);
34615
+ const metadata = {
34616
+ ...readEveTraceState(this.state).metadata,
34617
+ ...hookMetadata ?? {},
34618
+ "eve.session_id": sessionId
34619
+ };
34620
+ const span = await this.startTurnSpan(sessionId, event, ctx, metadata);
33995
34621
  span.log({ metadata });
33996
34622
  const state = {
33997
34623
  key,
@@ -34178,22 +34804,35 @@ var EveBridge = class {
34178
34804
  this.toolsByCallKey.set(toolKey3(sessionId, result.callId), state);
34179
34805
  return state;
34180
34806
  }
34181
- async startTurnSpan(session, event, metadata) {
34182
- const { rowId: eventId, spanId } = await generateEveIds(
34183
- "turn",
34184
- session.sessionId,
34185
- event.data.turnId
34186
- );
34807
+ async startTurnSpan(sessionId, event, ctx, metadata) {
34808
+ const session = isObject(ctx) ? ctx["session"] : void 0;
34809
+ const parent = isObject(session) ? session["parent"] : void 0;
34810
+ const parentTurn = isObject(parent) ? parent["turn"] : void 0;
34811
+ const parentLineage = isObject(parent) && typeof parent["callId"] === "string" && typeof parent["sessionId"] === "string" && isObject(parentTurn) && typeof parentTurn["id"] === "string" ? {
34812
+ callId: parent["callId"],
34813
+ sessionId: parent["sessionId"],
34814
+ turnId: parentTurn["id"]
34815
+ } : void 0;
34816
+ const [{ rowId: eventId, spanId }, rootSpanId, parentSpanId] = await Promise.all([
34817
+ generateEveIds("turn", sessionId, event.data.turnId),
34818
+ deterministicEveId(
34819
+ "eve:root",
34820
+ parentLineage?.sessionId ?? sessionId,
34821
+ parentLineage?.turnId ?? event.data.turnId
34822
+ ),
34823
+ parentLineage ? deterministicEveId(
34824
+ "eve:subagent",
34825
+ parentLineage.sessionId,
34826
+ parentLineage.callId
34827
+ ) : Promise.resolve(void 0)
34828
+ ]);
34187
34829
  return await this.startEveSpan({
34188
34830
  event: {
34189
34831
  id: eventId,
34190
34832
  metadata
34191
34833
  },
34192
34834
  name: "eve.turn",
34193
- parentSpanIds: {
34194
- rootSpanId: session.span.rootSpanId,
34195
- spanId: session.span.spanId
34196
- },
34835
+ parentSpanIds: parentSpanId ? { rootSpanId, spanId: parentSpanId } : { parentSpanIds: [], rootSpanId },
34197
34836
  spanAttributes: { type: "task" /* TASK */ },
34198
34837
  spanId,
34199
34838
  startTime: eventTime2(event)
@@ -34254,7 +34893,6 @@ var EveBridge = class {
34254
34893
  }
34255
34894
  cleanupSession(sessionId) {
34256
34895
  const keyPrefix = `${sessionId}:`;
34257
- this.sessionsById.delete(sessionId);
34258
34896
  for (const key of this.turnsByKey.keys()) {
34259
34897
  if (key.startsWith(keyPrefix)) {
34260
34898
  this.turnsByKey.delete(key);
@@ -34445,7 +35083,7 @@ function modelMetadataFromRuntime(runtime) {
34445
35083
  return {};
34446
35084
  }
34447
35085
  const modelId = runtime["modelId"];
34448
- return typeof modelId === "string" ? modelMetadataFromModelId(modelId) : {};
35086
+ return typeof modelId === "string" && !modelId.trim().startsWith("dynamic:") ? modelMetadataFromModelId(modelId) : {};
34449
35087
  }
34450
35088
  function modelMetadataFromModelId(modelId) {
34451
35089
  const normalized = modelId.trim();
@@ -34478,26 +35116,6 @@ function toolMetadataFromTurn(turn) {
34478
35116
  const { model: _model, provider: _provider, ...metadata } = turn.metadata;
34479
35117
  return metadata;
34480
35118
  }
34481
- function parentLineageFromContext(ctx) {
34482
- if (!isObject(ctx)) {
34483
- return void 0;
34484
- }
34485
- const session = ctx.session;
34486
- if (!isObject(session)) {
34487
- return void 0;
34488
- }
34489
- const parent = session["parent"];
34490
- if (!isObject(parent)) {
34491
- return void 0;
34492
- }
34493
- const callId = parent["callId"];
34494
- const rootSessionId = parent["rootSessionId"];
34495
- const sessionId = parent["sessionId"];
34496
- if (typeof callId !== "string" || typeof rootSessionId !== "string" || typeof sessionId !== "string") {
34497
- return void 0;
34498
- }
34499
- return { callId, rootSessionId, sessionId };
34500
- }
34501
35119
  function isToolCallAction(action) {
34502
35120
  return isObject(action) && action["kind"] === "tool-call" && typeof action["callId"] === "string" && typeof action["toolName"] === "string" && isObject(action["input"]);
34503
35121
  }
@@ -34553,9 +35171,6 @@ function turnKey2(sessionId, turnId) {
34553
35171
  function toolKey3(sessionId, callId) {
34554
35172
  return `${sessionId}:${callId}`;
34555
35173
  }
34556
- async function rootSpanIdForSession(sessionId) {
34557
- return deterministicEveId("eve:root", sessionId);
34558
- }
34559
35174
  async function generateEveIds(kind, ...parts) {
34560
35175
  const [rowId, spanId] = await Promise.all([
34561
35176
  deterministicEveId(`eve:row:${kind}`, ...parts),
@@ -34563,9 +35178,6 @@ async function generateEveIds(kind, ...parts) {
34563
35178
  ]);
34564
35179
  return { rowId, spanId };
34565
35180
  }
34566
- async function spanIdForSubagent(sessionId, callId) {
34567
- return deterministicEveId("eve:subagent", sessionId, callId);
34568
- }
34569
35181
  async function deterministicEveId(...parts) {
34570
35182
  const data = new TextEncoder().encode(
34571
35183
  parts.map((part) => `${part.length}:${part}`).join("\0")
@@ -34738,6 +35350,15 @@ function modelMetrics(attributes) {
34738
35350
  }
34739
35351
  return Object.keys(out).length > 0 ? out : void 0;
34740
35352
  }
35353
+ function timeToFirstTokenSeconds(attributes, spanStartSeconds) {
35354
+ if (!isObject(attributes)) return void 0;
35355
+ if (spanStartSeconds === void 0) return void 0;
35356
+ const raw = attributes.completionStartTime;
35357
+ const completionStart = raw instanceof Date || typeof raw === "string" || typeof raw === "number" ? epochSeconds(raw) : void 0;
35358
+ if (completionStart === void 0) return void 0;
35359
+ const ttft = completionStart - spanStartSeconds;
35360
+ return Number.isFinite(ttft) && ttft >= 0 ? ttft : void 0;
35361
+ }
34741
35362
  function buildMetadata(exported) {
34742
35363
  const out = {};
34743
35364
  if (exported.entityId !== void 0) out.entity_id = exported.entityId;
@@ -34862,8 +35483,15 @@ var BraintrustObservabilityExporter = class {
34862
35483
  event.metadata = metadata;
34863
35484
  }
34864
35485
  const metrics = modelMetrics(exported.attributes);
34865
- if (metrics) {
34866
- event.metrics = metrics;
35486
+ const ttft = timeToFirstTokenSeconds(
35487
+ exported.attributes,
35488
+ epochSeconds(exported.startTime)
35489
+ );
35490
+ if (metrics || ttft !== void 0) {
35491
+ event.metrics = {
35492
+ ...metrics ?? {},
35493
+ ...ttft !== void 0 ? { time_to_first_token: ttft } : {}
35494
+ };
34867
35495
  }
34868
35496
  if (Object.keys(event).length > 0) {
34869
35497
  record.span.log(event);
@@ -35742,17 +36370,17 @@ function wrapGenkit(genkit) {
35742
36370
  console.warn("Unsupported Genkit object. Not wrapping.");
35743
36371
  return genkit;
35744
36372
  }
35745
- function isRecord2(value) {
36373
+ function isRecord3(value) {
35746
36374
  return typeof value === "object" && value !== null;
35747
36375
  }
35748
36376
  function isPropertyBag(value) {
35749
- return isRecord2(value) || typeof value === "function";
36377
+ return isRecord3(value) || typeof value === "function";
35750
36378
  }
35751
36379
  function hasFunction(value, methodName) {
35752
36380
  return isPropertyBag(value) && methodName in value && typeof value[methodName] === "function";
35753
36381
  }
35754
36382
  function isGenkitInstance(value) {
35755
- return isRecord2(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
36383
+ return isRecord3(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
35756
36384
  }
35757
36385
  function isGenkitModule(value) {
35758
36386
  return hasFunction(value, "genkit");
@@ -35806,7 +36434,7 @@ function patchGenkitRegistry(instance) {
35806
36434
  patchGenkitRegistryConstructor(registry2);
35807
36435
  }
35808
36436
  function patchGenkitRegistryLookup(registry2) {
35809
- if (!isRecord2(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
36437
+ if (!isRecord3(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
35810
36438
  return;
35811
36439
  }
35812
36440
  const originalLookupAction = registry2.lookupAction;
@@ -35832,7 +36460,7 @@ function patchGenkitRegistryLookup(registry2) {
35832
36460
  }
35833
36461
  }
35834
36462
  function patchGenkitRegistryConstructor(registry2) {
35835
- if (!isRecord2(registry2)) {
36463
+ if (!isRecord3(registry2)) {
35836
36464
  return;
35837
36465
  }
35838
36466
  const constructor = registry2.constructor;
@@ -35848,7 +36476,7 @@ function patchGenkitRegistryConstructor(registry2) {
35848
36476
  configurable: true,
35849
36477
  value: (...args) => {
35850
36478
  const childRegistry = originalWithParent.apply(constructor, args);
35851
- if (args.some((arg) => isRecord2(arg) && hasRegistryPatchedFlag(arg))) {
36479
+ if (args.some((arg) => isRecord3(arg) && hasRegistryPatchedFlag(arg))) {
35852
36480
  patchGenkitRegistryLookup(childRegistry);
35853
36481
  patchGenkitRegistryConstructor(childRegistry);
35854
36482
  }
@@ -35947,7 +36575,7 @@ function hasRegistryConstructorPatchedFlag(value) {
35947
36575
  );
35948
36576
  }
35949
36577
  function isPromiseLike2(value) {
35950
- return isRecord2(value) && "then" in value && typeof value.then === "function";
36578
+ return isRecord3(value) && "then" in value && typeof value.then === "function";
35951
36579
  }
35952
36580
 
35953
36581
  // src/wrappers/huggingface.ts
@@ -36310,14 +36938,14 @@ function wrapMistral(mistral) {
36310
36938
  console.warn("Unsupported Mistral library. Not wrapping.");
36311
36939
  return mistral;
36312
36940
  }
36313
- function isRecord3(value) {
36941
+ function isRecord4(value) {
36314
36942
  return typeof value === "object" && value !== null;
36315
36943
  }
36316
36944
  function hasFunction3(value, methodName) {
36317
- return isRecord3(value) && methodName in value && typeof value[methodName] === "function";
36945
+ return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
36318
36946
  }
36319
36947
  function isSupportedMistralClient(value) {
36320
- if (!isRecord3(value)) {
36948
+ if (!isRecord4(value)) {
36321
36949
  return false;
36322
36950
  }
36323
36951
  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);
@@ -36501,14 +37129,14 @@ function wrapCohere(cohere) {
36501
37129
  return cohere;
36502
37130
  }
36503
37131
  var cohereProxyCache = /* @__PURE__ */ new WeakMap();
36504
- function isRecord4(value) {
37132
+ function isRecord5(value) {
36505
37133
  return typeof value === "object" && value !== null;
36506
37134
  }
36507
37135
  function hasFunction4(value, methodName) {
36508
- return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
37136
+ return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
36509
37137
  }
36510
37138
  function isSupportedCohereClient(value) {
36511
- if (!isRecord4(value)) {
37139
+ if (!isRecord5(value)) {
36512
37140
  return false;
36513
37141
  }
36514
37142
  return hasFunction4(value, "chat") || hasFunction4(value, "chatStream") || hasFunction4(value, "embed") || hasFunction4(value, "rerank");
@@ -36568,20 +37196,20 @@ function wrapGroq(groq) {
36568
37196
  console.warn("Unsupported Groq library. Not wrapping.");
36569
37197
  return groq;
36570
37198
  }
36571
- function isRecord5(value) {
37199
+ function isRecord6(value) {
36572
37200
  return typeof value === "object" && value !== null;
36573
37201
  }
36574
37202
  function hasFunction5(value, methodName) {
36575
- return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
37203
+ return isRecord6(value) && methodName in value && typeof value[methodName] === "function";
36576
37204
  }
36577
37205
  function hasChat2(value) {
36578
- return isRecord5(value) && isRecord5(value.completions) && hasFunction5(value.completions, "create");
37206
+ return isRecord6(value) && isRecord6(value.completions) && hasFunction5(value.completions, "create");
36579
37207
  }
36580
37208
  function hasEmbeddings2(value) {
36581
37209
  return hasFunction5(value, "create");
36582
37210
  }
36583
37211
  function isSupportedGroqClient(value) {
36584
- return isRecord5(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
37212
+ return isRecord6(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
36585
37213
  }
36586
37214
  function groqProxy(groq) {
36587
37215
  const privateMethodWorkaroundCache = /* @__PURE__ */ new WeakMap();
@@ -36664,11 +37292,11 @@ var BEDROCK_RUNTIME_OPERATION_METHODS = /* @__PURE__ */ new Set([
36664
37292
  "invokeModelWithBidirectionalStream",
36665
37293
  "invokeModelWithResponseStream"
36666
37294
  ]);
36667
- function isRecord6(value) {
37295
+ function isRecord7(value) {
36668
37296
  return typeof value === "object" && value !== null;
36669
37297
  }
36670
37298
  function isSupportedBedrockRuntimeClient(value) {
36671
- return isRecord6(value) && typeof value.send === "function";
37299
+ return isRecord7(value) && typeof value.send === "function";
36672
37300
  }
36673
37301
  function bedrockRuntimeProxy(client) {
36674
37302
  const cached = bedrockRuntimeProxyCache.get(client);
@@ -36787,6 +37415,271 @@ function wrappedResumeSession(client) {
36787
37415
  );
36788
37416
  }
36789
37417
 
37418
+ // src/wrappers/langsmith.ts
37419
+ var WRAPPED_CLIENT_CLASS = /* @__PURE__ */ Symbol.for(
37420
+ "braintrust.langsmith.wrapped-client-class"
37421
+ );
37422
+ var WRAPPED_CLIENT_INSTANCE = /* @__PURE__ */ Symbol.for(
37423
+ "braintrust.langsmith.wrapped-client-instance"
37424
+ );
37425
+ var WRAPPED_CLIENT_NAMESPACE = /* @__PURE__ */ Symbol.for(
37426
+ "braintrust.langsmith.wrapped-client-namespace"
37427
+ );
37428
+ var WRAPPED_RUN_TREE_CLASS = /* @__PURE__ */ Symbol.for(
37429
+ "braintrust.langsmith.wrapped-run-tree-class"
37430
+ );
37431
+ var WRAPPED_RUN_TREE_INSTANCE = /* @__PURE__ */ Symbol.for(
37432
+ "braintrust.langsmith.wrapped-run-tree-instance"
37433
+ );
37434
+ var WRAPPED_RUN_TREES_NAMESPACE = /* @__PURE__ */ Symbol.for(
37435
+ "braintrust.langsmith.wrapped-run-trees-namespace"
37436
+ );
37437
+ var WRAPPED_TRACEABLE = /* @__PURE__ */ Symbol.for("braintrust.langsmith.wrapped-traceable");
37438
+ var WRAPPED_TRACEABLE_NAMESPACE = /* @__PURE__ */ Symbol.for(
37439
+ "braintrust.langsmith.wrapped-traceable-namespace"
37440
+ );
37441
+ function wrapLangSmithTraceable(namespace) {
37442
+ return wrapNamespaceExport(
37443
+ namespace,
37444
+ "traceable",
37445
+ WRAPPED_TRACEABLE_NAMESPACE,
37446
+ (value) => wrapTraceable(value)
37447
+ );
37448
+ }
37449
+ function wrapLangSmithRunTrees(namespace) {
37450
+ return wrapNamespaceExport(
37451
+ namespace,
37452
+ "RunTree",
37453
+ WRAPPED_RUN_TREES_NAMESPACE,
37454
+ (value) => wrapRunTreeClass(value)
37455
+ );
37456
+ }
37457
+ function wrapLangSmithClient(namespace) {
37458
+ return wrapNamespaceExport(
37459
+ namespace,
37460
+ "Client",
37461
+ WRAPPED_CLIENT_NAMESPACE,
37462
+ (value) => wrapClientClass(value)
37463
+ );
37464
+ }
37465
+ function wrapNamespaceExport(namespace, exportName, marker, wrap2) {
37466
+ if (!namespace || typeof namespace !== "object") {
37467
+ return namespace;
37468
+ }
37469
+ const candidate = namespace;
37470
+ if (candidate[marker] === true) {
37471
+ return namespace;
37472
+ }
37473
+ if (typeof candidate[exportName] !== "function") {
37474
+ console.warn(
37475
+ `Unsupported LangSmith ${exportName} namespace. Not wrapping.`
37476
+ );
37477
+ return namespace;
37478
+ }
37479
+ const target = isModuleNamespace5(namespace) ? Object.setPrototypeOf({}, namespace) : candidate;
37480
+ const moduleNamespace = target !== candidate;
37481
+ let wrappedExport;
37482
+ return new Proxy(target, {
37483
+ get(target2, prop, receiver) {
37484
+ if (prop === marker) {
37485
+ return true;
37486
+ }
37487
+ const value = Reflect.get(target2, prop, receiver);
37488
+ if (prop !== exportName || typeof value !== "function") {
37489
+ return value;
37490
+ }
37491
+ wrappedExport ??= wrap2(value);
37492
+ return wrappedExport;
37493
+ },
37494
+ getOwnPropertyDescriptor(target2, prop) {
37495
+ const descriptor = Reflect.getOwnPropertyDescriptor(target2, prop);
37496
+ if (descriptor || !moduleNamespace) {
37497
+ return descriptor;
37498
+ }
37499
+ const namespaceDescriptor = Reflect.getOwnPropertyDescriptor(
37500
+ candidate,
37501
+ prop
37502
+ );
37503
+ return namespaceDescriptor ? { ...namespaceDescriptor, configurable: true } : void 0;
37504
+ },
37505
+ has(target2, prop) {
37506
+ return Reflect.has(target2, prop) || moduleNamespace && prop in candidate;
37507
+ },
37508
+ ownKeys(target2) {
37509
+ return moduleNamespace ? Reflect.ownKeys(candidate) : Reflect.ownKeys(target2);
37510
+ }
37511
+ });
37512
+ }
37513
+ function isModuleNamespace5(value) {
37514
+ if (!value || typeof value !== "object") {
37515
+ return false;
37516
+ }
37517
+ if (value.constructor?.name === "Module") {
37518
+ return true;
37519
+ }
37520
+ const firstKey = Object.keys(value)[0];
37521
+ if (!firstKey) {
37522
+ return false;
37523
+ }
37524
+ const descriptor = Object.getOwnPropertyDescriptor(value, firstKey);
37525
+ return descriptor ? !descriptor.configurable && !descriptor.writable : false;
37526
+ }
37527
+ function wrapTraceable(traceable2) {
37528
+ if (traceable2[WRAPPED_TRACEABLE]) {
37529
+ return traceable2;
37530
+ }
37531
+ return new Proxy(traceable2, {
37532
+ get(target, prop, receiver) {
37533
+ if (prop === WRAPPED_TRACEABLE) {
37534
+ return true;
37535
+ }
37536
+ return Reflect.get(target, prop, receiver);
37537
+ },
37538
+ apply(target, thisArg, argArray) {
37539
+ const [fn, rawConfig] = argArray;
37540
+ const config = rawConfig && typeof rawConfig === "object" ? rawConfig : void 0;
37541
+ const originalOnEnd = config?.on_end;
37542
+ const wrappedConfig = {
37543
+ ...config,
37544
+ on_end(runTree) {
37545
+ publishRunUpdate(runTree);
37546
+ if (originalOnEnd) {
37547
+ Reflect.apply(originalOnEnd, config, [runTree]);
37548
+ }
37549
+ }
37550
+ };
37551
+ return Reflect.apply(target, thisArg, [fn, wrappedConfig]);
37552
+ }
37553
+ });
37554
+ }
37555
+ function wrapRunTreeClass(RunTree) {
37556
+ if (RunTree[WRAPPED_RUN_TREE_CLASS]) {
37557
+ return RunTree;
37558
+ }
37559
+ return new Proxy(RunTree, {
37560
+ get(target, prop, receiver) {
37561
+ if (prop === WRAPPED_RUN_TREE_CLASS) {
37562
+ return true;
37563
+ }
37564
+ const value = Reflect.get(target, prop, receiver);
37565
+ return typeof value === "function" ? value.bind(target) : value;
37566
+ },
37567
+ construct(target, args, newTarget) {
37568
+ return wrapRunTreeInstance(Reflect.construct(target, args, newTarget));
37569
+ }
37570
+ });
37571
+ }
37572
+ function wrapRunTreeInstance(runTree) {
37573
+ if (runTree[WRAPPED_RUN_TREE_INSTANCE]) {
37574
+ return runTree;
37575
+ }
37576
+ return new Proxy(runTree, {
37577
+ get(target, prop, receiver) {
37578
+ if (prop === WRAPPED_RUN_TREE_INSTANCE) {
37579
+ return true;
37580
+ }
37581
+ const value = Reflect.get(target, prop, receiver);
37582
+ if (typeof value !== "function") {
37583
+ return value;
37584
+ }
37585
+ let wrapped;
37586
+ if (prop === "createChild") {
37587
+ wrapped = (...args) => wrapRunTreeInstance(Reflect.apply(value, target, args));
37588
+ } else if (prop === "postRun") {
37589
+ const method = value;
37590
+ wrapped = (...args) => langSmithChannels.createRun.tracePromise(
37591
+ () => Reflect.apply(method, target, args),
37592
+ { arguments: [target] }
37593
+ );
37594
+ } else if (prop === "patchRun") {
37595
+ const method = value;
37596
+ wrapped = (...args) => langSmithChannels.updateRun.tracePromise(
37597
+ () => Reflect.apply(method, target, args),
37598
+ {
37599
+ arguments: [
37600
+ typeof target.id === "string" ? target.id : "",
37601
+ target
37602
+ ]
37603
+ }
37604
+ );
37605
+ } else {
37606
+ wrapped = value.bind(target);
37607
+ }
37608
+ return wrapped;
37609
+ }
37610
+ });
37611
+ }
37612
+ function wrapClientClass(Client) {
37613
+ if (Client[WRAPPED_CLIENT_CLASS]) {
37614
+ return Client;
37615
+ }
37616
+ return new Proxy(Client, {
37617
+ get(target, prop, receiver) {
37618
+ if (prop === WRAPPED_CLIENT_CLASS) {
37619
+ return true;
37620
+ }
37621
+ const value = Reflect.get(target, prop, receiver);
37622
+ return typeof value === "function" ? value.bind(target) : value;
37623
+ },
37624
+ construct(target, args, newTarget) {
37625
+ return wrapClientInstance(Reflect.construct(target, args, newTarget));
37626
+ }
37627
+ });
37628
+ }
37629
+ function wrapClientInstance(client) {
37630
+ if (client[WRAPPED_CLIENT_INSTANCE]) {
37631
+ return client;
37632
+ }
37633
+ return new Proxy(client, {
37634
+ get(target, prop, receiver) {
37635
+ if (prop === WRAPPED_CLIENT_INSTANCE) {
37636
+ return true;
37637
+ }
37638
+ const value = Reflect.get(target, prop, receiver);
37639
+ if (typeof value !== "function") {
37640
+ return value;
37641
+ }
37642
+ let wrapped;
37643
+ if (prop === "createRun") {
37644
+ const method = value;
37645
+ wrapped = (...args) => langSmithChannels.createRun.tracePromise(
37646
+ () => Reflect.apply(method, target, args),
37647
+ { arguments: args }
37648
+ );
37649
+ } else if (prop === "updateRun") {
37650
+ const method = value;
37651
+ wrapped = (...args) => langSmithChannels.updateRun.tracePromise(
37652
+ () => Reflect.apply(method, target, args),
37653
+ { arguments: args }
37654
+ );
37655
+ } else if (prop === "batchIngestRuns") {
37656
+ const method = value;
37657
+ wrapped = (...args) => langSmithChannels.batchIngestRuns.tracePromise(
37658
+ () => Reflect.apply(method, target, args),
37659
+ { arguments: args }
37660
+ );
37661
+ } else {
37662
+ wrapped = value.bind(target);
37663
+ }
37664
+ return wrapped;
37665
+ }
37666
+ });
37667
+ }
37668
+ function publishRunUpdate(runTree) {
37669
+ if (!runTree || typeof runTree.id !== "string" || !runTree.id) {
37670
+ return;
37671
+ }
37672
+ try {
37673
+ void langSmithChannels.updateRun.tracePromise(() => Promise.resolve(void 0), {
37674
+ arguments: [runTree.id, runTree]
37675
+ }).catch((error) => {
37676
+ debugLogger.error("LangSmith traceable instrumentation failed:", error);
37677
+ });
37678
+ } catch (error) {
37679
+ debugLogger.error("LangSmith traceable instrumentation failed:", error);
37680
+ }
37681
+ }
37682
+
36790
37683
  // src/wrappers/vitest/context-manager.ts
36791
37684
  var VitestContextManager = class {
36792
37685
  /**