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
@@ -185,6 +185,9 @@ __export(edge_light_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,
@@ -4457,7 +4460,7 @@ var DiskCache = class {
4457
4460
  }
4458
4461
  };
4459
4462
 
4460
- // src/prompt-cache/lru-cache.ts
4463
+ // src/lru-cache.ts
4461
4464
  var LRUCache = class {
4462
4465
  cache;
4463
4466
  maxSize;
@@ -5699,25 +5702,46 @@ var HTTPConnection = class _HTTPConnection {
5699
5702
  })
5700
5703
  );
5701
5704
  }
5702
- async post(path, params, config) {
5705
+ async post(path, params, config, retries = 0) {
5703
5706
  const { headers, ...rest } = config || {};
5704
5707
  const this_fetch = this.fetch;
5705
5708
  const this_base_url = this.base_url;
5706
5709
  const this_headers = this.headers;
5707
- return await checkResponse(
5708
- await this_fetch(_urljoin(this_base_url, path), {
5709
- method: "POST",
5710
- headers: {
5711
- Accept: "application/json",
5712
- "Content-Type": "application/json",
5713
- ...this_headers,
5714
- ...headers
5715
- },
5716
- body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
5717
- keepalive: true,
5718
- ...rest
5719
- })
5720
- );
5710
+ const tries = retries + 1;
5711
+ for (let i = 0; i < tries; i++) {
5712
+ try {
5713
+ return await checkResponse(
5714
+ await this_fetch(_urljoin(this_base_url, path), {
5715
+ method: "POST",
5716
+ headers: {
5717
+ Accept: "application/json",
5718
+ "Content-Type": "application/json",
5719
+ ...this_headers,
5720
+ ...headers
5721
+ },
5722
+ body: typeof params === "string" ? params : params ? JSON.stringify(params) : void 0,
5723
+ keepalive: true,
5724
+ ...rest
5725
+ })
5726
+ );
5727
+ } catch (error) {
5728
+ if (config?.signal?.aborted) {
5729
+ throw getAbortReason(config.signal);
5730
+ }
5731
+ if (i === tries - 1 || !isRetryableHTTPError(error)) {
5732
+ throw error;
5733
+ }
5734
+ debugLogger.debug(
5735
+ `Retrying API request ${path} after ${formatHTTPError(error)}`
5736
+ );
5737
+ const sleepTimeMs = HTTP_RETRY_BASE_SLEEP_TIME_S * 1e3 * 2 ** i + Math.random() * HTTP_RETRY_JITTER_MS;
5738
+ debugLogger.info(
5739
+ `Sleeping for ${sleepTimeMs}ms before retrying API request`
5740
+ );
5741
+ await waitForRetry(sleepTimeMs, config?.signal);
5742
+ }
5743
+ }
5744
+ throw new Error("Unexpected retry state");
5721
5745
  }
5722
5746
  async get_json(object_type, args = void 0, retries = 0) {
5723
5747
  const tries = retries + 1;
@@ -6814,6 +6838,45 @@ var TestBackgroundLogger = class {
6814
6838
  };
6815
6839
  var BACKGROUND_LOGGER_BASE_SLEEP_TIME_S = 1;
6816
6840
  var HTTP_RETRY_BASE_SLEEP_TIME_S = 1;
6841
+ var HTTP_RETRY_JITTER_MS = 200;
6842
+ var BTQL_HTTP_RETRIES = 3;
6843
+ var RETRYABLE_HTTP_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
6844
+ function isRetryableHTTPError(error) {
6845
+ return !(error instanceof FailedHTTPResponse) || RETRYABLE_HTTP_STATUS_CODES.has(error.status);
6846
+ }
6847
+ function formatHTTPError(error) {
6848
+ if (error instanceof FailedHTTPResponse) {
6849
+ return `${error.status} ${error.text}`;
6850
+ }
6851
+ return error instanceof Error ? error.message : String(error);
6852
+ }
6853
+ function getAbortReason(signal) {
6854
+ return signal.reason ?? new Error("Request aborted");
6855
+ }
6856
+ async function waitForRetry(delayMs, signal) {
6857
+ if (!signal) {
6858
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
6859
+ return;
6860
+ }
6861
+ if (signal.aborted) {
6862
+ throw getAbortReason(signal);
6863
+ }
6864
+ await new Promise((resolve, reject2) => {
6865
+ const onAbort = () => {
6866
+ clearTimeout(timeout);
6867
+ signal.removeEventListener("abort", onAbort);
6868
+ reject2(getAbortReason(signal));
6869
+ };
6870
+ const timeout = setTimeout(() => {
6871
+ signal.removeEventListener("abort", onAbort);
6872
+ resolve();
6873
+ }, delayMs);
6874
+ signal.addEventListener("abort", onAbort, { once: true });
6875
+ if (signal.aborted) {
6876
+ onAbort();
6877
+ }
6878
+ });
6879
+ }
6817
6880
  var HTTPBackgroundLogger = class _HTTPBackgroundLogger {
6818
6881
  apiConn;
6819
6882
  queue;
@@ -8552,15 +8615,15 @@ function parentSpanIdsUsable(spanId, rootSpanId) {
8552
8615
  return Boolean(spanId) && Boolean(rootSpanId);
8553
8616
  }
8554
8617
  function logError(span, error) {
8555
- let errorMessage = "<error>";
8618
+ let errorMessage2 = "<error>";
8556
8619
  let stackTrace = "";
8557
8620
  if (error instanceof Error) {
8558
- errorMessage = error.message;
8621
+ errorMessage2 = error.message;
8559
8622
  stackTrace = error.stack || "";
8560
8623
  } else {
8561
- errorMessage = String(error);
8624
+ errorMessage2 = String(error);
8562
8625
  }
8563
- span.log({ error: `${errorMessage}
8626
+ span.log({ error: `${errorMessage2}
8564
8627
 
8565
8628
  ${stackTrace}` });
8566
8629
  }
@@ -9147,7 +9210,8 @@ var ObjectFetcher = class {
9147
9210
  version: this.pinnedVersion
9148
9211
  } : {}
9149
9212
  },
9150
- { headers: { "Accept-Encoding": "gzip" } }
9213
+ { headers: { "Accept-Encoding": "gzip" } },
9214
+ BTQL_HTTP_RETRIES
9151
9215
  );
9152
9216
  const respJson = await resp.json();
9153
9217
  const mutate = this.mutateRecord;
@@ -10871,7 +10935,8 @@ async function getPromptVersions(projectId, promptId) {
10871
10935
  use_columnstore: false,
10872
10936
  brainstore_realtime: true
10873
10937
  },
10874
- { headers: { "Accept-Encoding": "gzip" } }
10938
+ { headers: { "Accept-Encoding": "gzip" } },
10939
+ BTQL_HTTP_RETRIES
10875
10940
  );
10876
10941
  if (!response.ok) {
10877
10942
  throw new Error(
@@ -29455,6 +29520,446 @@ function isBraintrustHandler(handler) {
29455
29520
  return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
29456
29521
  }
29457
29522
 
29523
+ // src/instrumentation/plugins/langsmith-channels.ts
29524
+ var langSmithChannels = defineChannels("langsmith", {
29525
+ createRun: channel({
29526
+ channelName: "Client.createRun",
29527
+ kind: "async"
29528
+ }),
29529
+ updateRun: channel({
29530
+ channelName: "Client.updateRun",
29531
+ kind: "async"
29532
+ }),
29533
+ batchIngestRuns: channel({
29534
+ channelName: "Client.batchIngestRuns",
29535
+ kind: "async"
29536
+ })
29537
+ });
29538
+
29539
+ // src/instrumentation/plugins/langsmith-plugin.ts
29540
+ var MAX_COMPLETED_RUNS = 1e4;
29541
+ var BLOCKED_METADATA_KEYS = /* @__PURE__ */ new Set([
29542
+ "__proto__",
29543
+ "constructor",
29544
+ "prototype",
29545
+ "usage_metadata"
29546
+ ]);
29547
+ var BLOCKED_METADATA_PREFIXES = ["__pregel_", "langgraph_", "lc_"];
29548
+ var LLM_SETTING_KEYS = [
29549
+ "temperature",
29550
+ "top_p",
29551
+ "max_tokens",
29552
+ "frequency_penalty",
29553
+ "presence_penalty",
29554
+ "stop",
29555
+ "response_format"
29556
+ ];
29557
+ var LangSmithPlugin = class extends BasePlugin {
29558
+ activeRuns = /* @__PURE__ */ new Map();
29559
+ completedRuns = new LRUCache({
29560
+ max: MAX_COMPLETED_RUNS
29561
+ });
29562
+ skipLangChainRuns;
29563
+ constructor(options = {}) {
29564
+ super();
29565
+ this.skipLangChainRuns = options.skipLangChainRuns ?? true;
29566
+ }
29567
+ onEnable() {
29568
+ const createChannel = langSmithChannels.createRun.tracingChannel();
29569
+ const createHandlers = {
29570
+ start: (event) => {
29571
+ this.containLifecycleFailure("createRun", () => {
29572
+ this.processCreate(event.arguments[0]);
29573
+ });
29574
+ }
29575
+ };
29576
+ createChannel.subscribe(createHandlers);
29577
+ this.unsubscribers.push(() => createChannel.unsubscribe(createHandlers));
29578
+ const updateChannel = langSmithChannels.updateRun.tracingChannel();
29579
+ const updateHandlers = {
29580
+ start: (event) => {
29581
+ this.containLifecycleFailure("updateRun", () => {
29582
+ this.processUpdate(event.arguments[0], event.arguments[1]);
29583
+ });
29584
+ }
29585
+ };
29586
+ updateChannel.subscribe(updateHandlers);
29587
+ this.unsubscribers.push(() => updateChannel.unsubscribe(updateHandlers));
29588
+ const batchChannel = langSmithChannels.batchIngestRuns.tracingChannel();
29589
+ const batchHandlers = {
29590
+ start: (event) => {
29591
+ this.containLifecycleFailure("batchIngestRuns", () => {
29592
+ this.processBatch(event.arguments[0]);
29593
+ });
29594
+ }
29595
+ };
29596
+ batchChannel.subscribe(batchHandlers);
29597
+ this.unsubscribers.push(() => batchChannel.unsubscribe(batchHandlers));
29598
+ }
29599
+ onDisable() {
29600
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
29601
+ for (const { span } of this.activeRuns.values()) {
29602
+ span.end();
29603
+ }
29604
+ this.activeRuns.clear();
29605
+ this.completedRuns.clear();
29606
+ }
29607
+ processBatch(batch) {
29608
+ if (!isRecord2(batch)) {
29609
+ return;
29610
+ }
29611
+ const creates = ownValue(batch, "runCreates");
29612
+ if (Array.isArray(creates)) {
29613
+ const parentFirst = [...creates].sort((left, right) => {
29614
+ const leftId = stringValue2(ownValue(left, "id"));
29615
+ const rightId = stringValue2(ownValue(right, "id"));
29616
+ const leftParent = stringValue2(ownValue(left, "parent_run_id"));
29617
+ const rightParent = stringValue2(ownValue(right, "parent_run_id"));
29618
+ if (leftParent && leftParent === rightId) {
29619
+ return 1;
29620
+ }
29621
+ if (rightParent && rightParent === leftId) {
29622
+ return -1;
29623
+ }
29624
+ return dottedOrderDepth(left) - dottedOrderDepth(right);
29625
+ });
29626
+ for (const run of parentFirst) {
29627
+ this.containLifecycleFailure("batchIngestRuns create", () => {
29628
+ this.processCreate(run);
29629
+ });
29630
+ }
29631
+ }
29632
+ const updates = ownValue(batch, "runUpdates");
29633
+ if (Array.isArray(updates)) {
29634
+ for (const run of updates) {
29635
+ this.containLifecycleFailure("batchIngestRuns update", () => {
29636
+ this.processUpdate(stringValue2(ownValue(run, "id")) ?? "", run);
29637
+ });
29638
+ }
29639
+ }
29640
+ }
29641
+ processCreate(run) {
29642
+ const id = stringValue2(ownValue(run, "id"));
29643
+ if (!id || this.completedRuns.get(id)) {
29644
+ return;
29645
+ }
29646
+ if (this.shouldSkipLangChainRun(run)) {
29647
+ this.completedRuns.set(id, true);
29648
+ return;
29649
+ }
29650
+ const active = this.activeRuns.get(id);
29651
+ if (active) {
29652
+ const previous = active.run;
29653
+ active.run = mergeRuns(previous, run);
29654
+ this.logRun(
29655
+ active.span,
29656
+ active.run,
29657
+ previous,
29658
+ timestampSeconds(ownValue(active.run, "end_time")) !== void 0 || errorMessage(ownValue(active.run, "error")) !== void 0
29659
+ );
29660
+ this.endIfComplete(id, active, active.run);
29661
+ return;
29662
+ }
29663
+ const span = this.startRunSpan(id, run);
29664
+ const activeRun = { run, span };
29665
+ this.activeRuns.set(id, activeRun);
29666
+ this.logRun(
29667
+ span,
29668
+ run,
29669
+ void 0,
29670
+ timestampSeconds(ownValue(run, "end_time")) !== void 0 || errorMessage(ownValue(run, "error")) !== void 0
29671
+ );
29672
+ this.endIfComplete(id, activeRun, run);
29673
+ }
29674
+ processUpdate(explicitId, run) {
29675
+ const id = stringValue2(explicitId) ?? stringValue2(ownValue(run, "id"));
29676
+ if (!id || this.completedRuns.get(id)) {
29677
+ return;
29678
+ }
29679
+ if (this.shouldSkipLangChainRun(run)) {
29680
+ const active2 = this.activeRuns.get(id);
29681
+ active2?.span.end();
29682
+ this.activeRuns.delete(id);
29683
+ this.completedRuns.set(id, true);
29684
+ return;
29685
+ }
29686
+ let active = this.activeRuns.get(id);
29687
+ if (!active) {
29688
+ const span = this.startRunSpan(id, run);
29689
+ active = { run, span };
29690
+ this.activeRuns.set(id, active);
29691
+ }
29692
+ const previous = active.run;
29693
+ active.run = mergeRuns(previous, run);
29694
+ this.logRun(active.span, active.run, previous, true);
29695
+ this.endIfComplete(id, active, active.run);
29696
+ }
29697
+ startRunSpan(id, run) {
29698
+ const traceId = stringValue2(ownValue(run, "trace_id")) ?? id;
29699
+ const parentId = stringValue2(ownValue(run, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run, "parent_run"), "id"));
29700
+ const startTime = timestampSeconds(ownValue(run, "start_time"));
29701
+ return startSpan({
29702
+ name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
29703
+ spanId: id,
29704
+ parentSpanIds: {
29705
+ parentSpanIds: parentId ? [parentId] : [],
29706
+ rootSpanId: traceId
29707
+ },
29708
+ spanAttributes: {
29709
+ type: mapRunType(ownValue(run, "run_type"))
29710
+ },
29711
+ ...startTime === void 0 ? {} : { startTime },
29712
+ event: { id }
29713
+ });
29714
+ }
29715
+ logRun(span, run, previous, includeOutput) {
29716
+ const inputs = preferOwnValue(run, previous, "inputs");
29717
+ const outputs = preferOwnValue(run, previous, "outputs");
29718
+ const error = errorMessage(preferOwnValue(run, previous, "error"));
29719
+ const metadata = extractMetadata(run, previous);
29720
+ const tags = extractTags(preferOwnValue(run, previous, "tags"));
29721
+ const metrics = extractMetrics(run, previous);
29722
+ span.log({
29723
+ ...inputs === void 0 ? {} : { input: sanitizeLoggedValue(inputs) },
29724
+ ...includeOutput && outputs !== void 0 ? { output: sanitizeLoggedValue(outputs) } : {},
29725
+ ...error === void 0 ? {} : { error },
29726
+ ...metadata === void 0 ? {} : { metadata },
29727
+ ...tags === void 0 ? {} : { tags },
29728
+ ...Object.keys(metrics).length === 0 ? {} : { metrics }
29729
+ });
29730
+ }
29731
+ endIfComplete(id, active, run) {
29732
+ const endTime = timestampSeconds(ownValue(run, "end_time"));
29733
+ if (endTime === void 0 && errorMessage(ownValue(run, "error")) === void 0) {
29734
+ return;
29735
+ }
29736
+ active.span.end(endTime === void 0 ? void 0 : { endTime });
29737
+ this.activeRuns.delete(id);
29738
+ this.completedRuns.set(id, true);
29739
+ }
29740
+ shouldSkipLangChainRun(run) {
29741
+ if (!this.skipLangChainRuns) {
29742
+ return false;
29743
+ }
29744
+ const serialized = ownValue(run, "serialized");
29745
+ return isRecord2(serialized) && ownValue(serialized, "lc") === 1;
29746
+ }
29747
+ containLifecycleFailure(operation, fn) {
29748
+ try {
29749
+ fn();
29750
+ } catch (error) {
29751
+ debugLogger.error(
29752
+ `Failed to process LangSmith ${operation} instrumentation:`,
29753
+ error
29754
+ );
29755
+ }
29756
+ }
29757
+ };
29758
+ function ownValue(value, key) {
29759
+ if (!isRecord2(value)) {
29760
+ return void 0;
29761
+ }
29762
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
29763
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
29764
+ }
29765
+ function preferOwnValue(current, previous, key) {
29766
+ const currentDescriptor = isRecord2(current) ? Object.getOwnPropertyDescriptor(current, key) : void 0;
29767
+ if (currentDescriptor && "value" in currentDescriptor) {
29768
+ return currentDescriptor.value;
29769
+ }
29770
+ return ownValue(previous, key);
29771
+ }
29772
+ function mergeRuns(previous, current) {
29773
+ const entries = /* @__PURE__ */ new Map();
29774
+ for (const value of [previous, current]) {
29775
+ if (!isRecord2(value)) {
29776
+ continue;
29777
+ }
29778
+ for (const [key, descriptor] of Object.entries(
29779
+ Object.getOwnPropertyDescriptors(value)
29780
+ )) {
29781
+ if (descriptor.enumerable && "value" in descriptor) {
29782
+ entries.set(key, descriptor.value);
29783
+ }
29784
+ }
29785
+ }
29786
+ return Object.fromEntries(entries);
29787
+ }
29788
+ function isRecord2(value) {
29789
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29790
+ }
29791
+ function stringValue2(value) {
29792
+ return typeof value === "string" && value.length > 0 ? value : void 0;
29793
+ }
29794
+ function timestampSeconds(value) {
29795
+ if (value instanceof Date) {
29796
+ const timestamp = value.getTime();
29797
+ return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
29798
+ }
29799
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
29800
+ return value > 1e10 ? value / 1e3 : value;
29801
+ }
29802
+ if (typeof value === "string") {
29803
+ const timestamp = Date.parse(value);
29804
+ return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
29805
+ }
29806
+ return void 0;
29807
+ }
29808
+ function dottedOrderDepth(run) {
29809
+ const dottedOrder = stringValue2(ownValue(run, "dotted_order"));
29810
+ return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
29811
+ }
29812
+ function mapRunType(runType) {
29813
+ switch (runType) {
29814
+ case "llm":
29815
+ case "embedding":
29816
+ return "llm" /* LLM */;
29817
+ case "tool":
29818
+ case "retriever":
29819
+ return "tool" /* TOOL */;
29820
+ default:
29821
+ return "task" /* TASK */;
29822
+ }
29823
+ }
29824
+ function extractMetadata(run, previous) {
29825
+ const extra = preferOwnValue(run, previous, "extra");
29826
+ const rawMetadata = ownValue(extra, "metadata");
29827
+ if (!isRecord2(rawMetadata)) {
29828
+ return void 0;
29829
+ }
29830
+ const metadata = {};
29831
+ for (const [key, descriptor] of Object.entries(
29832
+ Object.getOwnPropertyDescriptors(rawMetadata)
29833
+ )) {
29834
+ 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}`)) {
29835
+ continue;
29836
+ }
29837
+ const normalizedKey = key === "ls_provider" ? "provider" : key === "ls_model_name" ? "model" : key.startsWith("ls_") ? key.slice(3) : key;
29838
+ const sanitized = sanitizeLoggedValue(descriptor.value);
29839
+ if (sanitized !== void 0) {
29840
+ metadata[normalizedKey] = sanitized;
29841
+ }
29842
+ }
29843
+ return Object.keys(metadata).length === 0 ? void 0 : metadata;
29844
+ }
29845
+ function extractTags(value) {
29846
+ if (!Array.isArray(value)) {
29847
+ return void 0;
29848
+ }
29849
+ const tags = value.filter(
29850
+ (tag) => typeof tag === "string" && tag.length > 0
29851
+ );
29852
+ return tags.length > 0 ? tags : void 0;
29853
+ }
29854
+ function extractMetrics(run, previous) {
29855
+ const outputs = preferOwnValue(run, previous, "outputs");
29856
+ const extra = preferOwnValue(run, previous, "extra");
29857
+ const metadata = ownValue(extra, "metadata");
29858
+ const usage = ownValue(outputs, "usage_metadata") ?? ownValue(metadata, "usage_metadata");
29859
+ const metrics = {};
29860
+ assignFirstMetric(metrics, "prompt_tokens", usage, [
29861
+ "input_tokens",
29862
+ "prompt_tokens"
29863
+ ]);
29864
+ assignFirstMetric(metrics, "completion_tokens", usage, [
29865
+ "output_tokens",
29866
+ "completion_tokens"
29867
+ ]);
29868
+ assignFirstMetric(metrics, "tokens", usage, ["total_tokens", "tokens"]);
29869
+ const inputTokenDetails = ownValue(usage, "input_token_details");
29870
+ assignFirstMetric(metrics, "prompt_cached_tokens", inputTokenDetails, [
29871
+ "cache_read",
29872
+ "cached_tokens"
29873
+ ]);
29874
+ if (metrics.prompt_cached_tokens === void 0) {
29875
+ assignFirstMetric(metrics, "prompt_cached_tokens", usage, [
29876
+ "cache_read_input_tokens",
29877
+ "prompt_cached_tokens"
29878
+ ]);
29879
+ }
29880
+ assignFirstMetric(
29881
+ metrics,
29882
+ "prompt_cache_creation_tokens",
29883
+ inputTokenDetails,
29884
+ ["cache_creation"]
29885
+ );
29886
+ if (metrics.prompt_cache_creation_tokens === void 0) {
29887
+ assignFirstMetric(metrics, "prompt_cache_creation_tokens", usage, [
29888
+ "cache_creation_input_tokens",
29889
+ "prompt_cache_creation_tokens"
29890
+ ]);
29891
+ }
29892
+ if (metrics.tokens === void 0 && (metrics.prompt_tokens !== void 0 || metrics.completion_tokens !== void 0)) {
29893
+ metrics.tokens = (metrics.prompt_tokens ?? 0) + (metrics.completion_tokens ?? 0);
29894
+ }
29895
+ const startTime = timestampSeconds(
29896
+ preferOwnValue(run, previous, "start_time")
29897
+ );
29898
+ const events = preferOwnValue(run, previous, "events");
29899
+ if (startTime !== void 0 && Array.isArray(events)) {
29900
+ for (const event of events) {
29901
+ if (ownValue(event, "name") !== "new_token") {
29902
+ continue;
29903
+ }
29904
+ const eventTime3 = timestampSeconds(ownValue(event, "time"));
29905
+ if (eventTime3 !== void 0 && eventTime3 >= startTime) {
29906
+ metrics.time_to_first_token = eventTime3 - startTime;
29907
+ }
29908
+ break;
29909
+ }
29910
+ }
29911
+ return metrics;
29912
+ }
29913
+ function assignFirstMetric(metrics, target, source, keys) {
29914
+ for (const key of keys) {
29915
+ const value = ownValue(source, key);
29916
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
29917
+ metrics[target] = value;
29918
+ return;
29919
+ }
29920
+ }
29921
+ }
29922
+ function errorMessage(value) {
29923
+ if (typeof value === "string") {
29924
+ return value;
29925
+ }
29926
+ if (value instanceof Error) {
29927
+ return value.message;
29928
+ }
29929
+ return void 0;
29930
+ }
29931
+ function sanitizeLoggedValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
29932
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
29933
+ return value;
29934
+ }
29935
+ if (typeof value === "number") {
29936
+ return Number.isFinite(value) ? value : void 0;
29937
+ }
29938
+ if (value instanceof Date) {
29939
+ return Number.isFinite(value.getTime()) ? value.toISOString() : void 0;
29940
+ }
29941
+ if (typeof value !== "object" || depth >= 20) {
29942
+ return void 0;
29943
+ }
29944
+ if (seen.has(value)) {
29945
+ return "[Circular]";
29946
+ }
29947
+ seen.add(value);
29948
+ if (Array.isArray(value)) {
29949
+ return value.map((item) => sanitizeLoggedValue(item, seen, depth + 1));
29950
+ }
29951
+ const entries = [];
29952
+ for (const [key, descriptor] of Object.entries(
29953
+ Object.getOwnPropertyDescriptors(value)
29954
+ )) {
29955
+ if (!descriptor.enumerable || !("value" in descriptor) || BLOCKED_METADATA_KEYS.has(key)) {
29956
+ continue;
29957
+ }
29958
+ entries.push([key, sanitizeLoggedValue(descriptor.value, seen, depth + 1)]);
29959
+ }
29960
+ return Object.fromEntries(entries);
29961
+ }
29962
+
29458
29963
  // src/instrumentation/plugins/pi-coding-agent-channels.ts
29459
29964
  var piCodingAgentChannels = defineChannels(
29460
29965
  "@earendil-works/pi-coding-agent",
@@ -29834,11 +30339,11 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
29834
30339
  function recordPiAssistantMessageEvent(promptState, llmState, event) {
29835
30340
  recordFirstTokenMetric(llmState, event);
29836
30341
  const message = "message" in event ? event.message : void 0;
29837
- const errorMessage = "error" in event ? event.error : void 0;
30342
+ const errorMessage2 = "error" in event ? event.error : void 0;
29838
30343
  if (event.type === "done" && isPiAssistantMessage(message)) {
29839
30344
  finishPiLlmSpan(promptState, llmState, message);
29840
- } else if (event.type === "error" && isPiAssistantMessage(errorMessage)) {
29841
- finishPiLlmSpan(promptState, llmState, errorMessage);
30345
+ } else if (event.type === "error" && isPiAssistantMessage(errorMessage2)) {
30346
+ finishPiLlmSpan(promptState, llmState, errorMessage2);
29842
30347
  }
29843
30348
  }
29844
30349
  function recordFirstTokenMetric(state, event) {
@@ -30356,6 +30861,7 @@ var strandsAgentSDKChannels = defineChannels("@strands-agents/sdk", {
30356
30861
  });
30357
30862
 
30358
30863
  // src/instrumentation/plugins/strands-agent-sdk-plugin.ts
30864
+ var MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES = 32;
30359
30865
  var StrandsAgentSDKPlugin = class extends BasePlugin {
30360
30866
  activeChildParents = /* @__PURE__ */ new WeakMap();
30361
30867
  onEnable() {
@@ -30500,11 +31006,16 @@ function startAgentStream(event, activeChildParents) {
30500
31006
  ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
30501
31007
  };
30502
31008
  const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
31009
+ const attachmentCache = createStrandsAttachmentCache();
31010
+ const input = processStrandsInputAttachments(
31011
+ event.arguments[0],
31012
+ attachmentCache
31013
+ );
30503
31014
  const span = parentSpan ? withCurrent(
30504
31015
  parentSpan,
30505
31016
  () => startSpan({
30506
31017
  event: {
30507
- input: event.arguments[0],
31018
+ input,
30508
31019
  metadata
30509
31020
  },
30510
31021
  name: formatAgentSpanName(agent),
@@ -30512,7 +31023,7 @@ function startAgentStream(event, activeChildParents) {
30512
31023
  })
30513
31024
  ) : startSpan({
30514
31025
  event: {
30515
- input: event.arguments[0],
31026
+ input,
30516
31027
  metadata
30517
31028
  },
30518
31029
  name: formatAgentSpanName(agent),
@@ -30520,6 +31031,7 @@ function startAgentStream(event, activeChildParents) {
30520
31031
  });
30521
31032
  return {
30522
31033
  activeTools: /* @__PURE__ */ new Map(),
31034
+ attachmentCache,
30523
31035
  finalized: false,
30524
31036
  metadata,
30525
31037
  span,
@@ -30535,11 +31047,12 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30535
31047
  ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
30536
31048
  };
30537
31049
  const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
31050
+ const input = processStrandsInputAttachments(event.arguments[0]);
30538
31051
  const span = parentSpan ? withCurrent(
30539
31052
  parentSpan,
30540
31053
  () => startSpan({
30541
31054
  event: {
30542
- input: event.arguments[0],
31055
+ input,
30543
31056
  metadata
30544
31057
  },
30545
31058
  name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
@@ -30547,7 +31060,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30547
31060
  })
30548
31061
  ) : startSpan({
30549
31062
  event: {
30550
- input: event.arguments[0],
31063
+ input,
30551
31064
  metadata
30552
31065
  },
30553
31066
  name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
@@ -30656,7 +31169,10 @@ function startModelSpan(state, event) {
30656
31169
  state.span,
30657
31170
  () => startSpan({
30658
31171
  event: {
30659
- input: Array.isArray(event.agent?.messages) ? event.agent.messages : void 0,
31172
+ input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
31173
+ event.agent.messages,
31174
+ state.attachmentCache
31175
+ ) : void 0,
30660
31176
  metadata
30661
31177
  },
30662
31178
  name: formatModelSpanName(model),
@@ -30870,6 +31386,7 @@ function finalizeAgentStream(state, error, output) {
30870
31386
  ...output !== void 0 ? { output } : {}
30871
31387
  });
30872
31388
  state.span.end();
31389
+ state.attachmentCache.strings.clear();
30873
31390
  }
30874
31391
  function finalizeMultiAgentStream(state, activeChildParents, error, output) {
30875
31392
  if (state.finalized) {
@@ -31016,6 +31533,166 @@ function extractNodeResultOutput(result) {
31016
31533
  }
31017
31534
  return result;
31018
31535
  }
31536
+ var STRANDS_MEDIA_TYPES = {
31537
+ png: "image/png",
31538
+ jpg: "image/jpeg",
31539
+ jpeg: "image/jpeg",
31540
+ gif: "image/gif",
31541
+ webp: "image/webp",
31542
+ mkv: "video/x-matroska",
31543
+ mov: "video/quicktime",
31544
+ mp4: "video/mp4",
31545
+ webm: "video/webm",
31546
+ flv: "video/x-flv",
31547
+ mpeg: "video/mpeg",
31548
+ mpg: "video/mpeg",
31549
+ wmv: "video/x-ms-wmv",
31550
+ "3gp": "video/3gpp",
31551
+ pdf: "application/pdf",
31552
+ csv: "text/csv",
31553
+ doc: "application/msword",
31554
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
31555
+ xls: "application/vnd.ms-excel",
31556
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
31557
+ html: "text/html",
31558
+ txt: "text/plain",
31559
+ md: "text/markdown",
31560
+ json: "application/json",
31561
+ xml: "application/xml"
31562
+ };
31563
+ function createStrandsAttachmentCache() {
31564
+ return {
31565
+ objects: /* @__PURE__ */ new WeakMap(),
31566
+ strings: new LRUCache({
31567
+ max: MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES
31568
+ })
31569
+ };
31570
+ }
31571
+ function processStrandsInputAttachments(input, cache = createStrandsAttachmentCache()) {
31572
+ try {
31573
+ return processStrandsInputNode(input, cache);
31574
+ } catch (error) {
31575
+ logInstrumentationError5("Strands Agent SDK input attachments", error);
31576
+ return input;
31577
+ }
31578
+ }
31579
+ function processStrandsInputNode(value, cache) {
31580
+ if (value instanceof BaseAttachment) {
31581
+ return value;
31582
+ }
31583
+ if (Array.isArray(value)) {
31584
+ return value.map((child) => processStrandsInputNode(child, cache));
31585
+ }
31586
+ if (!isObject(value)) {
31587
+ return value;
31588
+ }
31589
+ const directMedia = processDirectStrandsMediaBlock(value, cache);
31590
+ if (directMedia !== void 0) {
31591
+ return directMedia;
31592
+ }
31593
+ const wrappedMedia = processWrappedStrandsMediaBlock(value, cache);
31594
+ if (wrappedMedia !== void 0) {
31595
+ return wrappedMedia;
31596
+ }
31597
+ if (value.type === "message" && Array.isArray(value.content)) {
31598
+ return {
31599
+ role: value.role,
31600
+ content: value.content.map(
31601
+ (child) => processStrandsInputNode(child, cache)
31602
+ ),
31603
+ ...value.metadata !== void 0 ? { metadata: value.metadata } : {}
31604
+ };
31605
+ }
31606
+ if (typeof value.toJSON === "function") {
31607
+ return processStrandsInputNode(value.toJSON(), cache);
31608
+ }
31609
+ return Object.fromEntries(
31610
+ Object.entries(value).map(([key, child]) => [
31611
+ key,
31612
+ processStrandsInputNode(child, cache)
31613
+ ])
31614
+ );
31615
+ }
31616
+ function processDirectStrandsMediaBlock(block, cache) {
31617
+ if (!isStrandsMediaBlock(block)) {
31618
+ return void 0;
31619
+ }
31620
+ const mediaKey = block.type === "imageBlock" ? "image" : block.type === "videoBlock" ? "video" : "document";
31621
+ return createStrandsMediaAttachment(mediaKey, block, cache);
31622
+ }
31623
+ function isStrandsMediaBlock(block) {
31624
+ return (block.type === "imageBlock" || block.type === "videoBlock" || block.type === "documentBlock") && typeof block.format === "string" && isObject(block.source);
31625
+ }
31626
+ function processWrappedStrandsMediaBlock(block, cache) {
31627
+ for (const mediaKey of ["image", "video", "document"]) {
31628
+ const media = block[mediaKey];
31629
+ if (!Object.hasOwn(block, mediaKey) || !isObject(media)) {
31630
+ continue;
31631
+ }
31632
+ const processed = createStrandsMediaAttachment(mediaKey, media, cache);
31633
+ if (processed !== void 0) {
31634
+ return processed;
31635
+ }
31636
+ }
31637
+ return void 0;
31638
+ }
31639
+ function createStrandsMediaAttachment(mediaKey, media, cache) {
31640
+ const format = media.format;
31641
+ const source = media.source;
31642
+ if (typeof format !== "string" || !isObject(source) || !Object.hasOwn(source, "bytes")) {
31643
+ return void 0;
31644
+ }
31645
+ const contentType = STRANDS_MEDIA_TYPES[format.toLowerCase()];
31646
+ if (!contentType) {
31647
+ return void 0;
31648
+ }
31649
+ const filename = mediaKey === "document" && typeof media.name === "string" && media.name.length > 0 ? media.name : `${mediaKey}.${format.toLowerCase()}`;
31650
+ const attachment = getOrCreateStrandsAttachment(
31651
+ source.bytes,
31652
+ filename,
31653
+ contentType,
31654
+ cache
31655
+ );
31656
+ if (!attachment) {
31657
+ return void 0;
31658
+ }
31659
+ const { type: _type, ...serializedMedia } = media;
31660
+ const { type: _sourceType, ...serializedSource } = source;
31661
+ return {
31662
+ [mediaKey]: {
31663
+ ...serializedMedia,
31664
+ source: {
31665
+ ...serializedSource,
31666
+ bytes: attachment
31667
+ }
31668
+ }
31669
+ };
31670
+ }
31671
+ function getOrCreateStrandsAttachment(data, filename, contentType, cache) {
31672
+ const key = `${contentType}\0${filename}`;
31673
+ const attachments = typeof data === "string" ? cache.strings.get(data) : isObject(data) ? cache.objects.get(data) : void 0;
31674
+ const cached = attachments?.get(key);
31675
+ if (cached) {
31676
+ return cached;
31677
+ }
31678
+ const blob = convertDataToBlob(data, contentType);
31679
+ if (!blob) {
31680
+ return void 0;
31681
+ }
31682
+ const attachment = new Attachment({
31683
+ data: blob,
31684
+ filename,
31685
+ contentType
31686
+ });
31687
+ const updatedAttachments = attachments ?? /* @__PURE__ */ new Map();
31688
+ updatedAttachments.set(key, attachment);
31689
+ if (typeof data === "string") {
31690
+ cache.strings.set(data, updatedAttachments);
31691
+ } else if (isObject(data)) {
31692
+ cache.objects.set(data, updatedAttachments);
31693
+ }
31694
+ return attachment;
31695
+ }
31019
31696
  function normalizeContentBlocks(blocks) {
31020
31697
  const text = blocks.map((block) => typeof block.text === "string" ? block.text : void 0).filter((part) => Boolean(part)).join("");
31021
31698
  return text.length > 0 ? text : blocks;
@@ -31145,6 +31822,7 @@ var BraintrustPlugin = class extends BasePlugin {
31145
31822
  gitHubCopilotPlugin = null;
31146
31823
  fluePlugin = null;
31147
31824
  langChainPlugin = null;
31825
+ langSmithPlugin = null;
31148
31826
  piCodingAgentPlugin = null;
31149
31827
  strandsAgentSDKPlugin = null;
31150
31828
  constructor(config = {}) {
@@ -31241,6 +31919,12 @@ var BraintrustPlugin = class extends BasePlugin {
31241
31919
  this.langChainPlugin = new LangChainPlugin();
31242
31920
  this.langChainPlugin.enable();
31243
31921
  }
31922
+ if (integrations.langsmith !== false) {
31923
+ this.langSmithPlugin = new LangSmithPlugin({
31924
+ skipLangChainRuns: integrations.langchain !== false
31925
+ });
31926
+ this.langSmithPlugin.enable();
31927
+ }
31244
31928
  }
31245
31929
  onDisable() {
31246
31930
  if (this.openaiPlugin) {
@@ -31331,6 +32015,10 @@ var BraintrustPlugin = class extends BasePlugin {
31331
32015
  this.langChainPlugin.disable();
31332
32016
  this.langChainPlugin = null;
31333
32017
  }
32018
+ if (this.langSmithPlugin) {
32019
+ this.langSmithPlugin.disable();
32020
+ this.langSmithPlugin = null;
32021
+ }
31334
32022
  }
31335
32023
  };
31336
32024
 
@@ -31395,7 +32083,8 @@ var envIntegrationAliases = {
31395
32083
  langchain: "langchain",
31396
32084
  "langchain-js": "langchain",
31397
32085
  "@langchain": "langchain",
31398
- langgraph: "langgraph"
32086
+ langgraph: "langgraph",
32087
+ langsmith: "langsmith"
31399
32088
  };
31400
32089
  function getDefaultInstrumentationIntegrations() {
31401
32090
  return {
@@ -31426,6 +32115,7 @@ function getDefaultInstrumentationIntegrations() {
31426
32115
  gitHubCopilot: true,
31427
32116
  langchain: true,
31428
32117
  langgraph: true,
32118
+ langsmith: true,
31429
32119
  piCodingAgent: true,
31430
32120
  strandsAgentSDK: true
31431
32121
  };
@@ -31737,6 +32427,9 @@ __export(exports_exports, {
31737
32427
  wrapGoogleGenAI: () => wrapGoogleGenAI,
31738
32428
  wrapGroq: () => wrapGroq,
31739
32429
  wrapHuggingFace: () => wrapHuggingFace,
32430
+ wrapLangSmithClient: () => wrapLangSmithClient,
32431
+ wrapLangSmithRunTrees: () => wrapLangSmithRunTrees,
32432
+ wrapLangSmithTraceable: () => wrapLangSmithTraceable,
31740
32433
  wrapMastraAgent: () => wrapMastraAgent,
31741
32434
  wrapMistral: () => wrapMistral,
31742
32435
  wrapOpenAI: () => wrapOpenAI,
@@ -33223,9 +33916,6 @@ var EveBridge = class {
33223
33916
  this.state = state;
33224
33917
  }
33225
33918
  eventQueuesBySession = /* @__PURE__ */ new Map();
33226
- sessionsById = new LRUCache({
33227
- max: MAX_EVE_CACHE_ENTRIES
33228
- });
33229
33919
  completedToolKeys = new LRUCache({
33230
33920
  max: MAX_EVE_CACHE_ENTRIES
33231
33921
  });
@@ -33392,7 +34082,7 @@ var EveBridge = class {
33392
34082
  async handleEvent(event, ctx, hookMetadata) {
33393
34083
  switch (event.type) {
33394
34084
  case "session.started":
33395
- await this.handleSessionStarted(event, ctx, hookMetadata);
34085
+ this.handleSessionStarted(event, ctx, hookMetadata);
33396
34086
  return true;
33397
34087
  case "turn.started":
33398
34088
  await this.handleTurnStarted(event, ctx, hookMetadata);
@@ -33428,22 +34118,22 @@ var EveBridge = class {
33428
34118
  this.handleStepFailed(event, ctx);
33429
34119
  return true;
33430
34120
  case "turn.completed":
33431
- await this.handleTurnCompleted(event, ctx);
34121
+ this.handleTurnCompleted(event, ctx);
33432
34122
  return true;
33433
34123
  case "turn.failed":
33434
- await this.handleTurnFailed(event, ctx);
34124
+ this.handleTurnFailed(event, ctx);
33435
34125
  return true;
33436
34126
  case "session.failed":
33437
- await this.handleSessionFailed(event, ctx);
34127
+ this.handleSessionFailed(event, ctx);
33438
34128
  return true;
33439
34129
  case "session.completed":
33440
- await this.handleSessionCompleted(event, ctx);
34130
+ this.handleSessionCompleted(event, ctx);
33441
34131
  return true;
33442
34132
  default:
33443
34133
  return false;
33444
34134
  }
33445
34135
  }
33446
- async handleSessionStarted(event, ctx, hookMetadata) {
34136
+ handleSessionStarted(event, ctx, hookMetadata) {
33447
34137
  const sessionId = sessionIdFromContext(ctx);
33448
34138
  if (!sessionId) {
33449
34139
  return;
@@ -33459,7 +34149,6 @@ var EveBridge = class {
33459
34149
  metadata: { ...normalized.metadata, ...metadata }
33460
34150
  };
33461
34151
  });
33462
- await this.ensureSession(sessionId, ctx, metadata, eventTime2(event));
33463
34152
  for (const [key, turn] of this.turnsByKey) {
33464
34153
  if (!key.startsWith(`${sessionId}:`)) {
33465
34154
  continue;
@@ -33477,21 +34166,19 @@ var EveBridge = class {
33477
34166
  if (!sessionId) {
33478
34167
  return;
33479
34168
  }
33480
- const session = await this.ensureSession(
33481
- sessionId,
33482
- ctx,
33483
- hookMetadata ?? {},
33484
- eventTime2(event)
33485
- );
33486
34169
  const key = turnKey2(sessionId, event.data.turnId);
33487
- const metadata = { ...session.metadata };
34170
+ const metadata = {
34171
+ ...readEveTraceState(this.state).metadata,
34172
+ ...hookMetadata ?? {},
34173
+ "eve.session_id": sessionId
34174
+ };
33488
34175
  const existing = this.turnsByKey.get(key);
33489
34176
  if (existing) {
33490
34177
  existing.metadata = { ...existing.metadata, ...metadata };
33491
34178
  existing.span.log({ metadata: existing.metadata });
33492
34179
  return;
33493
34180
  }
33494
- const span = await this.startTurnSpan(session, event, metadata);
34181
+ const span = await this.startTurnSpan(sessionId, event, ctx, metadata);
33495
34182
  span.log({ metadata });
33496
34183
  this.turnsByKey.set(key, {
33497
34184
  key,
@@ -33529,10 +34216,7 @@ var EveBridge = class {
33529
34216
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
33530
34217
  }
33531
34218
  const stepOrdinal = this.stepOrdinal(event);
33532
- const metadata = {
33533
- ...turn.metadata,
33534
- ...this.sessionsById.get(sessionId)?.metadata ?? {}
33535
- };
34219
+ const metadata = { ...turn.metadata };
33536
34220
  const input = consumeCapturedEveModelInput(
33537
34221
  this.state,
33538
34222
  sessionId,
@@ -33627,6 +34311,28 @@ var EveBridge = class {
33627
34311
  if (!step) {
33628
34312
  return;
33629
34313
  }
34314
+ const toolCallsById = /* @__PURE__ */ new Map();
34315
+ if (Array.isArray(step.output) && isObject(step.output[0])) {
34316
+ const message = step.output[0]["message"];
34317
+ if (isObject(message) && Array.isArray(message["tool_calls"])) {
34318
+ for (const toolCall of message["tool_calls"]) {
34319
+ if (isObject(toolCall) && typeof toolCall["id"] === "string") {
34320
+ toolCallsById.set(toolCall["id"], toolCall);
34321
+ }
34322
+ }
34323
+ }
34324
+ }
34325
+ for (const action of traceActions) {
34326
+ const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
34327
+ toolCallsById.set(action.callId, {
34328
+ function: {
34329
+ arguments: JSON.stringify(action.input),
34330
+ name
34331
+ },
34332
+ id: action.callId,
34333
+ type: "function"
34334
+ });
34335
+ }
33630
34336
  step.output = [
33631
34337
  {
33632
34338
  finish_reason: "tool_calls",
@@ -33634,17 +34340,7 @@ var EveBridge = class {
33634
34340
  message: {
33635
34341
  content: null,
33636
34342
  role: "assistant",
33637
- tool_calls: traceActions.map((action) => {
33638
- const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
33639
- return {
33640
- function: {
33641
- arguments: JSON.stringify(action.input),
33642
- name
33643
- },
33644
- id: action.callId,
33645
- type: "function"
33646
- };
33647
- })
34343
+ tool_calls: [...toolCallsById.values()]
33648
34344
  }
33649
34345
  }
33650
34346
  ];
@@ -33891,17 +34587,11 @@ var EveBridge = class {
33891
34587
  )
33892
34588
  });
33893
34589
  }
33894
- async handleSessionFailed(event, ctx) {
34590
+ handleSessionFailed(event, ctx) {
33895
34591
  const sessionId = event.data.sessionId || sessionIdFromContext(ctx);
33896
34592
  if (!sessionId) {
33897
34593
  return;
33898
34594
  }
33899
- const session = await this.ensureSession(
33900
- sessionId,
33901
- ctx,
33902
- {},
33903
- eventTime2(event)
33904
- );
33905
34595
  const error = errorFromMessage(
33906
34596
  event.data.message,
33907
34597
  event.data.code,
@@ -33918,29 +34608,20 @@ var EveBridge = class {
33918
34608
  }
33919
34609
  for (const [key, tool] of this.toolsByCallKey) {
33920
34610
  if (key.startsWith(`${sessionId}:`)) {
33921
- const endTime2 = eventTime2(event);
34611
+ const endTime = eventTime2(event);
33922
34612
  if (!tool.endedByTurn) {
33923
34613
  tool.span.log({ metadata: tool.metadata });
33924
- tool.span.end(endTime2 === void 0 ? void 0 : { endTime: endTime2 });
34614
+ tool.span.end(endTime === void 0 ? void 0 : { endTime });
33925
34615
  tool.endedByTurn = true;
33926
34616
  }
33927
34617
  }
33928
34618
  }
33929
- session.span.log({ error });
33930
- const endTime = eventTime2(event);
33931
- session.span.end(endTime === void 0 ? void 0 : { endTime });
33932
34619
  }
33933
- async handleSessionCompleted(event, ctx) {
34620
+ handleSessionCompleted(event, ctx) {
33934
34621
  const sessionId = sessionIdFromContext(ctx);
33935
34622
  if (!sessionId) {
33936
34623
  return;
33937
34624
  }
33938
- const session = await this.ensureSession(
33939
- sessionId,
33940
- ctx,
33941
- {},
33942
- eventTime2(event)
33943
- );
33944
34625
  for (const [key, turn] of this.turnsByKey) {
33945
34626
  if (!key.startsWith(`${sessionId}:`)) {
33946
34627
  continue;
@@ -33951,82 +34632,29 @@ var EveBridge = class {
33951
34632
  }
33952
34633
  for (const [key, tool] of this.toolsByCallKey) {
33953
34634
  if (key.startsWith(`${sessionId}:`) && !tool.endedByTurn) {
33954
- const endTime2 = eventTime2(event);
34635
+ const endTime = eventTime2(event);
33955
34636
  tool.span.log({ metadata: tool.metadata });
33956
- tool.span.end(endTime2 === void 0 ? void 0 : { endTime: endTime2 });
34637
+ tool.span.end(endTime === void 0 ? void 0 : { endTime });
33957
34638
  tool.endedByTurn = true;
33958
34639
  }
33959
34640
  }
33960
- session.span.log({ metadata: session.metadata });
33961
- const endTime = eventTime2(event);
33962
- session.span.end(endTime === void 0 ? void 0 : { endTime });
33963
- }
33964
- async ensureSession(sessionId, ctx, metadata, startTime) {
33965
- metadata = {
33966
- ...readEveTraceState(this.state).metadata,
33967
- ...metadata
33968
- };
33969
- const existing = this.sessionsById.get(sessionId);
33970
- if (existing) {
33971
- existing.metadata = { ...existing.metadata, ...metadata };
33972
- existing.span.log({ metadata: existing.metadata });
33973
- return existing;
33974
- }
33975
- const lineage = parentLineageFromContext(ctx);
33976
- const parentSubagent = lineage ? this.toolsByCallKey.get(toolKey3(lineage.sessionId, lineage.callId)) : void 0;
33977
- const activeParent = currentSpan();
33978
- const [
33979
- { rowId: eventId, spanId },
33980
- parentSubagentSpanId,
33981
- fallbackRootSpanId
33982
- ] = await Promise.all([
33983
- generateEveIds("session", sessionId),
33984
- lineage ? spanIdForSubagent(lineage.sessionId, lineage.callId) : Promise.resolve(void 0),
33985
- lineage ? rootSpanIdForSession(lineage.rootSessionId) : rootSpanIdForSession(sessionId)
33986
- ]);
33987
- const span = await this.startEveSpan({
33988
- event: {
33989
- id: eventId,
33990
- metadata
33991
- },
33992
- name: "eve.session",
33993
- parentSpanIds: lineage && parentSubagentSpanId ? {
33994
- rootSpanId: parentSubagent?.span.rootSpanId ?? fallbackRootSpanId,
33995
- spanId: parentSubagentSpanId
33996
- } : !Object.is(activeParent, NOOP_SPAN) ? {
33997
- rootSpanId: activeParent.rootSpanId,
33998
- spanId: activeParent.spanId
33999
- } : {
34000
- parentSpanIds: [],
34001
- rootSpanId: fallbackRootSpanId
34002
- },
34003
- spanAttributes: { type: "task" /* TASK */ },
34004
- spanId,
34005
- startTime
34006
- });
34007
- span.log({ metadata });
34008
- const session = { metadata, sessionId, span };
34009
- this.sessionsById.set(sessionId, session);
34010
- return session;
34011
34641
  }
34012
34642
  async ensureTurn(event, ctx, hookMetadata) {
34013
34643
  const sessionId = sessionIdFromContext(ctx);
34014
34644
  if (!sessionId) {
34015
34645
  return void 0;
34016
34646
  }
34017
- const session = await this.ensureSession(
34018
- sessionId,
34019
- ctx,
34020
- hookMetadata ?? {},
34021
- eventTime2(event)
34022
- );
34023
34647
  const key = turnKey2(sessionId, event.data.turnId);
34024
34648
  const existing = this.turnsByKey.get(key);
34025
34649
  if (existing) {
34026
34650
  return existing;
34027
34651
  }
34028
- const metadata = { ...session.metadata };
34029
- const span = await this.startTurnSpan(session, event, metadata);
34652
+ const metadata = {
34653
+ ...readEveTraceState(this.state).metadata,
34654
+ ...hookMetadata ?? {},
34655
+ "eve.session_id": sessionId
34656
+ };
34657
+ const span = await this.startTurnSpan(sessionId, event, ctx, metadata);
34030
34658
  span.log({ metadata });
34031
34659
  const state = {
34032
34660
  key,
@@ -34213,22 +34841,35 @@ var EveBridge = class {
34213
34841
  this.toolsByCallKey.set(toolKey3(sessionId, result.callId), state);
34214
34842
  return state;
34215
34843
  }
34216
- async startTurnSpan(session, event, metadata) {
34217
- const { rowId: eventId, spanId } = await generateEveIds(
34218
- "turn",
34219
- session.sessionId,
34220
- event.data.turnId
34221
- );
34844
+ async startTurnSpan(sessionId, event, ctx, metadata) {
34845
+ const session = isObject(ctx) ? ctx["session"] : void 0;
34846
+ const parent = isObject(session) ? session["parent"] : void 0;
34847
+ const parentTurn = isObject(parent) ? parent["turn"] : void 0;
34848
+ const parentLineage = isObject(parent) && typeof parent["callId"] === "string" && typeof parent["sessionId"] === "string" && isObject(parentTurn) && typeof parentTurn["id"] === "string" ? {
34849
+ callId: parent["callId"],
34850
+ sessionId: parent["sessionId"],
34851
+ turnId: parentTurn["id"]
34852
+ } : void 0;
34853
+ const [{ rowId: eventId, spanId }, rootSpanId, parentSpanId] = await Promise.all([
34854
+ generateEveIds("turn", sessionId, event.data.turnId),
34855
+ deterministicEveId(
34856
+ "eve:root",
34857
+ parentLineage?.sessionId ?? sessionId,
34858
+ parentLineage?.turnId ?? event.data.turnId
34859
+ ),
34860
+ parentLineage ? deterministicEveId(
34861
+ "eve:subagent",
34862
+ parentLineage.sessionId,
34863
+ parentLineage.callId
34864
+ ) : Promise.resolve(void 0)
34865
+ ]);
34222
34866
  return await this.startEveSpan({
34223
34867
  event: {
34224
34868
  id: eventId,
34225
34869
  metadata
34226
34870
  },
34227
34871
  name: "eve.turn",
34228
- parentSpanIds: {
34229
- rootSpanId: session.span.rootSpanId,
34230
- spanId: session.span.spanId
34231
- },
34872
+ parentSpanIds: parentSpanId ? { rootSpanId, spanId: parentSpanId } : { parentSpanIds: [], rootSpanId },
34232
34873
  spanAttributes: { type: "task" /* TASK */ },
34233
34874
  spanId,
34234
34875
  startTime: eventTime2(event)
@@ -34289,7 +34930,6 @@ var EveBridge = class {
34289
34930
  }
34290
34931
  cleanupSession(sessionId) {
34291
34932
  const keyPrefix = `${sessionId}:`;
34292
- this.sessionsById.delete(sessionId);
34293
34933
  for (const key of this.turnsByKey.keys()) {
34294
34934
  if (key.startsWith(keyPrefix)) {
34295
34935
  this.turnsByKey.delete(key);
@@ -34480,7 +35120,7 @@ function modelMetadataFromRuntime(runtime) {
34480
35120
  return {};
34481
35121
  }
34482
35122
  const modelId = runtime["modelId"];
34483
- return typeof modelId === "string" ? modelMetadataFromModelId(modelId) : {};
35123
+ return typeof modelId === "string" && !modelId.trim().startsWith("dynamic:") ? modelMetadataFromModelId(modelId) : {};
34484
35124
  }
34485
35125
  function modelMetadataFromModelId(modelId) {
34486
35126
  const normalized = modelId.trim();
@@ -34513,26 +35153,6 @@ function toolMetadataFromTurn(turn) {
34513
35153
  const { model: _model, provider: _provider, ...metadata } = turn.metadata;
34514
35154
  return metadata;
34515
35155
  }
34516
- function parentLineageFromContext(ctx) {
34517
- if (!isObject(ctx)) {
34518
- return void 0;
34519
- }
34520
- const session = ctx.session;
34521
- if (!isObject(session)) {
34522
- return void 0;
34523
- }
34524
- const parent = session["parent"];
34525
- if (!isObject(parent)) {
34526
- return void 0;
34527
- }
34528
- const callId = parent["callId"];
34529
- const rootSessionId = parent["rootSessionId"];
34530
- const sessionId = parent["sessionId"];
34531
- if (typeof callId !== "string" || typeof rootSessionId !== "string" || typeof sessionId !== "string") {
34532
- return void 0;
34533
- }
34534
- return { callId, rootSessionId, sessionId };
34535
- }
34536
35156
  function isToolCallAction(action) {
34537
35157
  return isObject(action) && action["kind"] === "tool-call" && typeof action["callId"] === "string" && typeof action["toolName"] === "string" && isObject(action["input"]);
34538
35158
  }
@@ -34588,9 +35208,6 @@ function turnKey2(sessionId, turnId) {
34588
35208
  function toolKey3(sessionId, callId) {
34589
35209
  return `${sessionId}:${callId}`;
34590
35210
  }
34591
- async function rootSpanIdForSession(sessionId) {
34592
- return deterministicEveId("eve:root", sessionId);
34593
- }
34594
35211
  async function generateEveIds(kind, ...parts) {
34595
35212
  const [rowId, spanId] = await Promise.all([
34596
35213
  deterministicEveId(`eve:row:${kind}`, ...parts),
@@ -34598,9 +35215,6 @@ async function generateEveIds(kind, ...parts) {
34598
35215
  ]);
34599
35216
  return { rowId, spanId };
34600
35217
  }
34601
- async function spanIdForSubagent(sessionId, callId) {
34602
- return deterministicEveId("eve:subagent", sessionId, callId);
34603
- }
34604
35218
  async function deterministicEveId(...parts) {
34605
35219
  const data = new TextEncoder().encode(
34606
35220
  parts.map((part) => `${part.length}:${part}`).join("\0")
@@ -34773,6 +35387,15 @@ function modelMetrics(attributes) {
34773
35387
  }
34774
35388
  return Object.keys(out).length > 0 ? out : void 0;
34775
35389
  }
35390
+ function timeToFirstTokenSeconds(attributes, spanStartSeconds) {
35391
+ if (!isObject(attributes)) return void 0;
35392
+ if (spanStartSeconds === void 0) return void 0;
35393
+ const raw = attributes.completionStartTime;
35394
+ const completionStart = raw instanceof Date || typeof raw === "string" || typeof raw === "number" ? epochSeconds(raw) : void 0;
35395
+ if (completionStart === void 0) return void 0;
35396
+ const ttft = completionStart - spanStartSeconds;
35397
+ return Number.isFinite(ttft) && ttft >= 0 ? ttft : void 0;
35398
+ }
34776
35399
  function buildMetadata(exported) {
34777
35400
  const out = {};
34778
35401
  if (exported.entityId !== void 0) out.entity_id = exported.entityId;
@@ -34897,8 +35520,15 @@ var BraintrustObservabilityExporter = class {
34897
35520
  event.metadata = metadata;
34898
35521
  }
34899
35522
  const metrics = modelMetrics(exported.attributes);
34900
- if (metrics) {
34901
- event.metrics = metrics;
35523
+ const ttft = timeToFirstTokenSeconds(
35524
+ exported.attributes,
35525
+ epochSeconds(exported.startTime)
35526
+ );
35527
+ if (metrics || ttft !== void 0) {
35528
+ event.metrics = {
35529
+ ...metrics ?? {},
35530
+ ...ttft !== void 0 ? { time_to_first_token: ttft } : {}
35531
+ };
34902
35532
  }
34903
35533
  if (Object.keys(event).length > 0) {
34904
35534
  record.span.log(event);
@@ -35777,17 +36407,17 @@ function wrapGenkit(genkit) {
35777
36407
  console.warn("Unsupported Genkit object. Not wrapping.");
35778
36408
  return genkit;
35779
36409
  }
35780
- function isRecord2(value) {
36410
+ function isRecord3(value) {
35781
36411
  return typeof value === "object" && value !== null;
35782
36412
  }
35783
36413
  function isPropertyBag(value) {
35784
- return isRecord2(value) || typeof value === "function";
36414
+ return isRecord3(value) || typeof value === "function";
35785
36415
  }
35786
36416
  function hasFunction(value, methodName) {
35787
36417
  return isPropertyBag(value) && methodName in value && typeof value[methodName] === "function";
35788
36418
  }
35789
36419
  function isGenkitInstance(value) {
35790
- return isRecord2(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
36420
+ return isRecord3(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
35791
36421
  }
35792
36422
  function isGenkitModule(value) {
35793
36423
  return hasFunction(value, "genkit");
@@ -35841,7 +36471,7 @@ function patchGenkitRegistry(instance) {
35841
36471
  patchGenkitRegistryConstructor(registry2);
35842
36472
  }
35843
36473
  function patchGenkitRegistryLookup(registry2) {
35844
- if (!isRecord2(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
36474
+ if (!isRecord3(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
35845
36475
  return;
35846
36476
  }
35847
36477
  const originalLookupAction = registry2.lookupAction;
@@ -35867,7 +36497,7 @@ function patchGenkitRegistryLookup(registry2) {
35867
36497
  }
35868
36498
  }
35869
36499
  function patchGenkitRegistryConstructor(registry2) {
35870
- if (!isRecord2(registry2)) {
36500
+ if (!isRecord3(registry2)) {
35871
36501
  return;
35872
36502
  }
35873
36503
  const constructor = registry2.constructor;
@@ -35883,7 +36513,7 @@ function patchGenkitRegistryConstructor(registry2) {
35883
36513
  configurable: true,
35884
36514
  value: (...args) => {
35885
36515
  const childRegistry = originalWithParent.apply(constructor, args);
35886
- if (args.some((arg) => isRecord2(arg) && hasRegistryPatchedFlag(arg))) {
36516
+ if (args.some((arg) => isRecord3(arg) && hasRegistryPatchedFlag(arg))) {
35887
36517
  patchGenkitRegistryLookup(childRegistry);
35888
36518
  patchGenkitRegistryConstructor(childRegistry);
35889
36519
  }
@@ -35982,7 +36612,7 @@ function hasRegistryConstructorPatchedFlag(value) {
35982
36612
  );
35983
36613
  }
35984
36614
  function isPromiseLike2(value) {
35985
- return isRecord2(value) && "then" in value && typeof value.then === "function";
36615
+ return isRecord3(value) && "then" in value && typeof value.then === "function";
35986
36616
  }
35987
36617
 
35988
36618
  // src/wrappers/huggingface.ts
@@ -36345,14 +36975,14 @@ function wrapMistral(mistral) {
36345
36975
  console.warn("Unsupported Mistral library. Not wrapping.");
36346
36976
  return mistral;
36347
36977
  }
36348
- function isRecord3(value) {
36978
+ function isRecord4(value) {
36349
36979
  return typeof value === "object" && value !== null;
36350
36980
  }
36351
36981
  function hasFunction3(value, methodName) {
36352
- return isRecord3(value) && methodName in value && typeof value[methodName] === "function";
36982
+ return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
36353
36983
  }
36354
36984
  function isSupportedMistralClient(value) {
36355
- if (!isRecord3(value)) {
36985
+ if (!isRecord4(value)) {
36356
36986
  return false;
36357
36987
  }
36358
36988
  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);
@@ -36536,14 +37166,14 @@ function wrapCohere(cohere) {
36536
37166
  return cohere;
36537
37167
  }
36538
37168
  var cohereProxyCache = /* @__PURE__ */ new WeakMap();
36539
- function isRecord4(value) {
37169
+ function isRecord5(value) {
36540
37170
  return typeof value === "object" && value !== null;
36541
37171
  }
36542
37172
  function hasFunction4(value, methodName) {
36543
- return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
37173
+ return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
36544
37174
  }
36545
37175
  function isSupportedCohereClient(value) {
36546
- if (!isRecord4(value)) {
37176
+ if (!isRecord5(value)) {
36547
37177
  return false;
36548
37178
  }
36549
37179
  return hasFunction4(value, "chat") || hasFunction4(value, "chatStream") || hasFunction4(value, "embed") || hasFunction4(value, "rerank");
@@ -36603,20 +37233,20 @@ function wrapGroq(groq) {
36603
37233
  console.warn("Unsupported Groq library. Not wrapping.");
36604
37234
  return groq;
36605
37235
  }
36606
- function isRecord5(value) {
37236
+ function isRecord6(value) {
36607
37237
  return typeof value === "object" && value !== null;
36608
37238
  }
36609
37239
  function hasFunction5(value, methodName) {
36610
- return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
37240
+ return isRecord6(value) && methodName in value && typeof value[methodName] === "function";
36611
37241
  }
36612
37242
  function hasChat2(value) {
36613
- return isRecord5(value) && isRecord5(value.completions) && hasFunction5(value.completions, "create");
37243
+ return isRecord6(value) && isRecord6(value.completions) && hasFunction5(value.completions, "create");
36614
37244
  }
36615
37245
  function hasEmbeddings2(value) {
36616
37246
  return hasFunction5(value, "create");
36617
37247
  }
36618
37248
  function isSupportedGroqClient(value) {
36619
- return isRecord5(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
37249
+ return isRecord6(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
36620
37250
  }
36621
37251
  function groqProxy(groq) {
36622
37252
  const privateMethodWorkaroundCache = /* @__PURE__ */ new WeakMap();
@@ -36699,11 +37329,11 @@ var BEDROCK_RUNTIME_OPERATION_METHODS = /* @__PURE__ */ new Set([
36699
37329
  "invokeModelWithBidirectionalStream",
36700
37330
  "invokeModelWithResponseStream"
36701
37331
  ]);
36702
- function isRecord6(value) {
37332
+ function isRecord7(value) {
36703
37333
  return typeof value === "object" && value !== null;
36704
37334
  }
36705
37335
  function isSupportedBedrockRuntimeClient(value) {
36706
- return isRecord6(value) && typeof value.send === "function";
37336
+ return isRecord7(value) && typeof value.send === "function";
36707
37337
  }
36708
37338
  function bedrockRuntimeProxy(client) {
36709
37339
  const cached = bedrockRuntimeProxyCache.get(client);
@@ -36822,6 +37452,271 @@ function wrappedResumeSession(client) {
36822
37452
  );
36823
37453
  }
36824
37454
 
37455
+ // src/wrappers/langsmith.ts
37456
+ var WRAPPED_CLIENT_CLASS = /* @__PURE__ */ Symbol.for(
37457
+ "braintrust.langsmith.wrapped-client-class"
37458
+ );
37459
+ var WRAPPED_CLIENT_INSTANCE = /* @__PURE__ */ Symbol.for(
37460
+ "braintrust.langsmith.wrapped-client-instance"
37461
+ );
37462
+ var WRAPPED_CLIENT_NAMESPACE = /* @__PURE__ */ Symbol.for(
37463
+ "braintrust.langsmith.wrapped-client-namespace"
37464
+ );
37465
+ var WRAPPED_RUN_TREE_CLASS = /* @__PURE__ */ Symbol.for(
37466
+ "braintrust.langsmith.wrapped-run-tree-class"
37467
+ );
37468
+ var WRAPPED_RUN_TREE_INSTANCE = /* @__PURE__ */ Symbol.for(
37469
+ "braintrust.langsmith.wrapped-run-tree-instance"
37470
+ );
37471
+ var WRAPPED_RUN_TREES_NAMESPACE = /* @__PURE__ */ Symbol.for(
37472
+ "braintrust.langsmith.wrapped-run-trees-namespace"
37473
+ );
37474
+ var WRAPPED_TRACEABLE = /* @__PURE__ */ Symbol.for("braintrust.langsmith.wrapped-traceable");
37475
+ var WRAPPED_TRACEABLE_NAMESPACE = /* @__PURE__ */ Symbol.for(
37476
+ "braintrust.langsmith.wrapped-traceable-namespace"
37477
+ );
37478
+ function wrapLangSmithTraceable(namespace) {
37479
+ return wrapNamespaceExport(
37480
+ namespace,
37481
+ "traceable",
37482
+ WRAPPED_TRACEABLE_NAMESPACE,
37483
+ (value) => wrapTraceable(value)
37484
+ );
37485
+ }
37486
+ function wrapLangSmithRunTrees(namespace) {
37487
+ return wrapNamespaceExport(
37488
+ namespace,
37489
+ "RunTree",
37490
+ WRAPPED_RUN_TREES_NAMESPACE,
37491
+ (value) => wrapRunTreeClass(value)
37492
+ );
37493
+ }
37494
+ function wrapLangSmithClient(namespace) {
37495
+ return wrapNamespaceExport(
37496
+ namespace,
37497
+ "Client",
37498
+ WRAPPED_CLIENT_NAMESPACE,
37499
+ (value) => wrapClientClass(value)
37500
+ );
37501
+ }
37502
+ function wrapNamespaceExport(namespace, exportName, marker, wrap2) {
37503
+ if (!namespace || typeof namespace !== "object") {
37504
+ return namespace;
37505
+ }
37506
+ const candidate = namespace;
37507
+ if (candidate[marker] === true) {
37508
+ return namespace;
37509
+ }
37510
+ if (typeof candidate[exportName] !== "function") {
37511
+ console.warn(
37512
+ `Unsupported LangSmith ${exportName} namespace. Not wrapping.`
37513
+ );
37514
+ return namespace;
37515
+ }
37516
+ const target = isModuleNamespace5(namespace) ? Object.setPrototypeOf({}, namespace) : candidate;
37517
+ const moduleNamespace = target !== candidate;
37518
+ let wrappedExport;
37519
+ return new Proxy(target, {
37520
+ get(target2, prop, receiver) {
37521
+ if (prop === marker) {
37522
+ return true;
37523
+ }
37524
+ const value = Reflect.get(target2, prop, receiver);
37525
+ if (prop !== exportName || typeof value !== "function") {
37526
+ return value;
37527
+ }
37528
+ wrappedExport ??= wrap2(value);
37529
+ return wrappedExport;
37530
+ },
37531
+ getOwnPropertyDescriptor(target2, prop) {
37532
+ const descriptor = Reflect.getOwnPropertyDescriptor(target2, prop);
37533
+ if (descriptor || !moduleNamespace) {
37534
+ return descriptor;
37535
+ }
37536
+ const namespaceDescriptor = Reflect.getOwnPropertyDescriptor(
37537
+ candidate,
37538
+ prop
37539
+ );
37540
+ return namespaceDescriptor ? { ...namespaceDescriptor, configurable: true } : void 0;
37541
+ },
37542
+ has(target2, prop) {
37543
+ return Reflect.has(target2, prop) || moduleNamespace && prop in candidate;
37544
+ },
37545
+ ownKeys(target2) {
37546
+ return moduleNamespace ? Reflect.ownKeys(candidate) : Reflect.ownKeys(target2);
37547
+ }
37548
+ });
37549
+ }
37550
+ function isModuleNamespace5(value) {
37551
+ if (!value || typeof value !== "object") {
37552
+ return false;
37553
+ }
37554
+ if (value.constructor?.name === "Module") {
37555
+ return true;
37556
+ }
37557
+ const firstKey = Object.keys(value)[0];
37558
+ if (!firstKey) {
37559
+ return false;
37560
+ }
37561
+ const descriptor = Object.getOwnPropertyDescriptor(value, firstKey);
37562
+ return descriptor ? !descriptor.configurable && !descriptor.writable : false;
37563
+ }
37564
+ function wrapTraceable(traceable2) {
37565
+ if (traceable2[WRAPPED_TRACEABLE]) {
37566
+ return traceable2;
37567
+ }
37568
+ return new Proxy(traceable2, {
37569
+ get(target, prop, receiver) {
37570
+ if (prop === WRAPPED_TRACEABLE) {
37571
+ return true;
37572
+ }
37573
+ return Reflect.get(target, prop, receiver);
37574
+ },
37575
+ apply(target, thisArg, argArray) {
37576
+ const [fn, rawConfig] = argArray;
37577
+ const config = rawConfig && typeof rawConfig === "object" ? rawConfig : void 0;
37578
+ const originalOnEnd = config?.on_end;
37579
+ const wrappedConfig = {
37580
+ ...config,
37581
+ on_end(runTree) {
37582
+ publishRunUpdate(runTree);
37583
+ if (originalOnEnd) {
37584
+ Reflect.apply(originalOnEnd, config, [runTree]);
37585
+ }
37586
+ }
37587
+ };
37588
+ return Reflect.apply(target, thisArg, [fn, wrappedConfig]);
37589
+ }
37590
+ });
37591
+ }
37592
+ function wrapRunTreeClass(RunTree) {
37593
+ if (RunTree[WRAPPED_RUN_TREE_CLASS]) {
37594
+ return RunTree;
37595
+ }
37596
+ return new Proxy(RunTree, {
37597
+ get(target, prop, receiver) {
37598
+ if (prop === WRAPPED_RUN_TREE_CLASS) {
37599
+ return true;
37600
+ }
37601
+ const value = Reflect.get(target, prop, receiver);
37602
+ return typeof value === "function" ? value.bind(target) : value;
37603
+ },
37604
+ construct(target, args, newTarget) {
37605
+ return wrapRunTreeInstance(Reflect.construct(target, args, newTarget));
37606
+ }
37607
+ });
37608
+ }
37609
+ function wrapRunTreeInstance(runTree) {
37610
+ if (runTree[WRAPPED_RUN_TREE_INSTANCE]) {
37611
+ return runTree;
37612
+ }
37613
+ return new Proxy(runTree, {
37614
+ get(target, prop, receiver) {
37615
+ if (prop === WRAPPED_RUN_TREE_INSTANCE) {
37616
+ return true;
37617
+ }
37618
+ const value = Reflect.get(target, prop, receiver);
37619
+ if (typeof value !== "function") {
37620
+ return value;
37621
+ }
37622
+ let wrapped;
37623
+ if (prop === "createChild") {
37624
+ wrapped = (...args) => wrapRunTreeInstance(Reflect.apply(value, target, args));
37625
+ } else if (prop === "postRun") {
37626
+ const method = value;
37627
+ wrapped = (...args) => langSmithChannels.createRun.tracePromise(
37628
+ () => Reflect.apply(method, target, args),
37629
+ { arguments: [target] }
37630
+ );
37631
+ } else if (prop === "patchRun") {
37632
+ const method = value;
37633
+ wrapped = (...args) => langSmithChannels.updateRun.tracePromise(
37634
+ () => Reflect.apply(method, target, args),
37635
+ {
37636
+ arguments: [
37637
+ typeof target.id === "string" ? target.id : "",
37638
+ target
37639
+ ]
37640
+ }
37641
+ );
37642
+ } else {
37643
+ wrapped = value.bind(target);
37644
+ }
37645
+ return wrapped;
37646
+ }
37647
+ });
37648
+ }
37649
+ function wrapClientClass(Client) {
37650
+ if (Client[WRAPPED_CLIENT_CLASS]) {
37651
+ return Client;
37652
+ }
37653
+ return new Proxy(Client, {
37654
+ get(target, prop, receiver) {
37655
+ if (prop === WRAPPED_CLIENT_CLASS) {
37656
+ return true;
37657
+ }
37658
+ const value = Reflect.get(target, prop, receiver);
37659
+ return typeof value === "function" ? value.bind(target) : value;
37660
+ },
37661
+ construct(target, args, newTarget) {
37662
+ return wrapClientInstance(Reflect.construct(target, args, newTarget));
37663
+ }
37664
+ });
37665
+ }
37666
+ function wrapClientInstance(client) {
37667
+ if (client[WRAPPED_CLIENT_INSTANCE]) {
37668
+ return client;
37669
+ }
37670
+ return new Proxy(client, {
37671
+ get(target, prop, receiver) {
37672
+ if (prop === WRAPPED_CLIENT_INSTANCE) {
37673
+ return true;
37674
+ }
37675
+ const value = Reflect.get(target, prop, receiver);
37676
+ if (typeof value !== "function") {
37677
+ return value;
37678
+ }
37679
+ let wrapped;
37680
+ if (prop === "createRun") {
37681
+ const method = value;
37682
+ wrapped = (...args) => langSmithChannels.createRun.tracePromise(
37683
+ () => Reflect.apply(method, target, args),
37684
+ { arguments: args }
37685
+ );
37686
+ } else if (prop === "updateRun") {
37687
+ const method = value;
37688
+ wrapped = (...args) => langSmithChannels.updateRun.tracePromise(
37689
+ () => Reflect.apply(method, target, args),
37690
+ { arguments: args }
37691
+ );
37692
+ } else if (prop === "batchIngestRuns") {
37693
+ const method = value;
37694
+ wrapped = (...args) => langSmithChannels.batchIngestRuns.tracePromise(
37695
+ () => Reflect.apply(method, target, args),
37696
+ { arguments: args }
37697
+ );
37698
+ } else {
37699
+ wrapped = value.bind(target);
37700
+ }
37701
+ return wrapped;
37702
+ }
37703
+ });
37704
+ }
37705
+ function publishRunUpdate(runTree) {
37706
+ if (!runTree || typeof runTree.id !== "string" || !runTree.id) {
37707
+ return;
37708
+ }
37709
+ try {
37710
+ void langSmithChannels.updateRun.tracePromise(() => Promise.resolve(void 0), {
37711
+ arguments: [runTree.id, runTree]
37712
+ }).catch((error) => {
37713
+ debugLogger.error("LangSmith traceable instrumentation failed:", error);
37714
+ });
37715
+ } catch (error) {
37716
+ debugLogger.error("LangSmith traceable instrumentation failed:", error);
37717
+ }
37718
+ }
37719
+
36825
37720
  // src/wrappers/vitest/context-manager.ts
36826
37721
  var VitestContextManager = class {
36827
37722
  /**