braintrust 3.22.0 → 3.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +43 -0
  2. package/dev/dist/index.d.mts +1 -1
  3. package/dev/dist/index.d.ts +1 -1
  4. package/dev/dist/index.js +1354 -654
  5. package/dev/dist/index.mjs +736 -36
  6. package/dist/apply-auto-instrumentation.js +222 -186
  7. package/dist/apply-auto-instrumentation.mjs +37 -1
  8. package/dist/auto-instrumentations/bundler/esbuild.cjs +53 -1
  9. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  10. package/dist/auto-instrumentations/bundler/next.cjs +53 -1
  11. package/dist/auto-instrumentations/bundler/next.mjs +3 -3
  12. package/dist/auto-instrumentations/bundler/rollup.cjs +53 -1
  13. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  14. package/dist/auto-instrumentations/bundler/vite.cjs +53 -1
  15. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  16. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +53 -1
  17. package/dist/auto-instrumentations/bundler/webpack.cjs +53 -1
  18. package/dist/auto-instrumentations/bundler/webpack.mjs +3 -3
  19. package/dist/auto-instrumentations/{chunk-TKRPRPGD.mjs → chunk-EXY7QCJD.mjs} +5 -2
  20. package/dist/auto-instrumentations/{chunk-T6J4C7LX.mjs → chunk-KIMLYPRW.mjs} +1 -1
  21. package/dist/auto-instrumentations/{chunk-BRQX23KL.mjs → chunk-YXLNSAMJ.mjs} +51 -0
  22. package/dist/auto-instrumentations/hook.mjs +149 -20
  23. package/dist/auto-instrumentations/index.cjs +52 -0
  24. package/dist/auto-instrumentations/index.d.mts +3 -1
  25. package/dist/auto-instrumentations/index.d.ts +3 -1
  26. package/dist/auto-instrumentations/index.mjs +3 -1
  27. package/dist/browser.d.mts +11 -13
  28. package/dist/browser.d.ts +11 -13
  29. package/dist/browser.js +1098 -205
  30. package/dist/browser.mjs +1098 -205
  31. package/dist/{chunk-KMGUTPB7.mjs → chunk-36IPYKMG.mjs} +20 -1
  32. package/dist/{chunk-MWVVR5LR.js → chunk-B6ZQIAK3.js} +1506 -822
  33. package/dist/{chunk-BFGIH2ZJ.js → chunk-CDIKAHDZ.js} +21 -2
  34. package/dist/{chunk-ZG2O3XVF.mjs → chunk-RBXD2KYN.mjs} +719 -35
  35. package/dist/cli.js +737 -37
  36. package/dist/edge-light.d.mts +1 -1
  37. package/dist/edge-light.d.ts +1 -1
  38. package/dist/edge-light.js +1098 -205
  39. package/dist/edge-light.mjs +1098 -205
  40. package/dist/index.d.mts +11 -13
  41. package/dist/index.d.ts +11 -13
  42. package/dist/index.js +786 -593
  43. package/dist/index.mjs +346 -153
  44. package/dist/instrumentation/index.d.mts +3 -11
  45. package/dist/instrumentation/index.d.ts +3 -11
  46. package/dist/instrumentation/index.js +788 -183
  47. package/dist/instrumentation/index.mjs +788 -183
  48. package/dist/vitest-evals-reporter.js +16 -16
  49. package/dist/vitest-evals-reporter.mjs +2 -2
  50. package/dist/workerd.d.mts +1 -1
  51. package/dist/workerd.d.ts +1 -1
  52. package/dist/workerd.js +1098 -205
  53. package/dist/workerd.mjs +1098 -205
  54. package/package.json +1 -1
package/dist/workerd.js CHANGED
@@ -185,6 +185,9 @@ __export(workerd_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(
@@ -18256,8 +18321,6 @@ function filterSerializableOptions(options) {
18256
18321
  "additionalDirectories",
18257
18322
  "permissionMode",
18258
18323
  "debug",
18259
- "apiKey",
18260
- "apiKeySource",
18261
18324
  "agentName",
18262
18325
  "instructions"
18263
18326
  ];
@@ -29455,6 +29518,446 @@ function isBraintrustHandler(handler) {
29455
29518
  return Reflect.get(handler, "name") === BRAINTRUST_LANGCHAIN_CALLBACK_HANDLER_NAME;
29456
29519
  }
29457
29520
 
29521
+ // src/instrumentation/plugins/langsmith-channels.ts
29522
+ var langSmithChannels = defineChannels("langsmith", {
29523
+ createRun: channel({
29524
+ channelName: "Client.createRun",
29525
+ kind: "async"
29526
+ }),
29527
+ updateRun: channel({
29528
+ channelName: "Client.updateRun",
29529
+ kind: "async"
29530
+ }),
29531
+ batchIngestRuns: channel({
29532
+ channelName: "Client.batchIngestRuns",
29533
+ kind: "async"
29534
+ })
29535
+ });
29536
+
29537
+ // src/instrumentation/plugins/langsmith-plugin.ts
29538
+ var MAX_COMPLETED_RUNS = 1e4;
29539
+ var BLOCKED_METADATA_KEYS = /* @__PURE__ */ new Set([
29540
+ "__proto__",
29541
+ "constructor",
29542
+ "prototype",
29543
+ "usage_metadata"
29544
+ ]);
29545
+ var BLOCKED_METADATA_PREFIXES = ["__pregel_", "langgraph_", "lc_"];
29546
+ var LLM_SETTING_KEYS = [
29547
+ "temperature",
29548
+ "top_p",
29549
+ "max_tokens",
29550
+ "frequency_penalty",
29551
+ "presence_penalty",
29552
+ "stop",
29553
+ "response_format"
29554
+ ];
29555
+ var LangSmithPlugin = class extends BasePlugin {
29556
+ activeRuns = /* @__PURE__ */ new Map();
29557
+ completedRuns = new LRUCache({
29558
+ max: MAX_COMPLETED_RUNS
29559
+ });
29560
+ skipLangChainRuns;
29561
+ constructor(options = {}) {
29562
+ super();
29563
+ this.skipLangChainRuns = options.skipLangChainRuns ?? true;
29564
+ }
29565
+ onEnable() {
29566
+ const createChannel = langSmithChannels.createRun.tracingChannel();
29567
+ const createHandlers = {
29568
+ start: (event) => {
29569
+ this.containLifecycleFailure("createRun", () => {
29570
+ this.processCreate(event.arguments[0]);
29571
+ });
29572
+ }
29573
+ };
29574
+ createChannel.subscribe(createHandlers);
29575
+ this.unsubscribers.push(() => createChannel.unsubscribe(createHandlers));
29576
+ const updateChannel = langSmithChannels.updateRun.tracingChannel();
29577
+ const updateHandlers = {
29578
+ start: (event) => {
29579
+ this.containLifecycleFailure("updateRun", () => {
29580
+ this.processUpdate(event.arguments[0], event.arguments[1]);
29581
+ });
29582
+ }
29583
+ };
29584
+ updateChannel.subscribe(updateHandlers);
29585
+ this.unsubscribers.push(() => updateChannel.unsubscribe(updateHandlers));
29586
+ const batchChannel = langSmithChannels.batchIngestRuns.tracingChannel();
29587
+ const batchHandlers = {
29588
+ start: (event) => {
29589
+ this.containLifecycleFailure("batchIngestRuns", () => {
29590
+ this.processBatch(event.arguments[0]);
29591
+ });
29592
+ }
29593
+ };
29594
+ batchChannel.subscribe(batchHandlers);
29595
+ this.unsubscribers.push(() => batchChannel.unsubscribe(batchHandlers));
29596
+ }
29597
+ onDisable() {
29598
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
29599
+ for (const { span } of this.activeRuns.values()) {
29600
+ span.end();
29601
+ }
29602
+ this.activeRuns.clear();
29603
+ this.completedRuns.clear();
29604
+ }
29605
+ processBatch(batch) {
29606
+ if (!isRecord2(batch)) {
29607
+ return;
29608
+ }
29609
+ const creates = ownValue(batch, "runCreates");
29610
+ if (Array.isArray(creates)) {
29611
+ const parentFirst = [...creates].sort((left, right) => {
29612
+ const leftId = stringValue2(ownValue(left, "id"));
29613
+ const rightId = stringValue2(ownValue(right, "id"));
29614
+ const leftParent = stringValue2(ownValue(left, "parent_run_id"));
29615
+ const rightParent = stringValue2(ownValue(right, "parent_run_id"));
29616
+ if (leftParent && leftParent === rightId) {
29617
+ return 1;
29618
+ }
29619
+ if (rightParent && rightParent === leftId) {
29620
+ return -1;
29621
+ }
29622
+ return dottedOrderDepth(left) - dottedOrderDepth(right);
29623
+ });
29624
+ for (const run of parentFirst) {
29625
+ this.containLifecycleFailure("batchIngestRuns create", () => {
29626
+ this.processCreate(run);
29627
+ });
29628
+ }
29629
+ }
29630
+ const updates = ownValue(batch, "runUpdates");
29631
+ if (Array.isArray(updates)) {
29632
+ for (const run of updates) {
29633
+ this.containLifecycleFailure("batchIngestRuns update", () => {
29634
+ this.processUpdate(stringValue2(ownValue(run, "id")) ?? "", run);
29635
+ });
29636
+ }
29637
+ }
29638
+ }
29639
+ processCreate(run) {
29640
+ const id = stringValue2(ownValue(run, "id"));
29641
+ if (!id || this.completedRuns.get(id)) {
29642
+ return;
29643
+ }
29644
+ if (this.shouldSkipLangChainRun(run)) {
29645
+ this.completedRuns.set(id, true);
29646
+ return;
29647
+ }
29648
+ const active = this.activeRuns.get(id);
29649
+ if (active) {
29650
+ const previous = active.run;
29651
+ active.run = mergeRuns(previous, run);
29652
+ this.logRun(
29653
+ active.span,
29654
+ active.run,
29655
+ previous,
29656
+ timestampSeconds(ownValue(active.run, "end_time")) !== void 0 || errorMessage(ownValue(active.run, "error")) !== void 0
29657
+ );
29658
+ this.endIfComplete(id, active, active.run);
29659
+ return;
29660
+ }
29661
+ const span = this.startRunSpan(id, run);
29662
+ const activeRun = { run, span };
29663
+ this.activeRuns.set(id, activeRun);
29664
+ this.logRun(
29665
+ span,
29666
+ run,
29667
+ void 0,
29668
+ timestampSeconds(ownValue(run, "end_time")) !== void 0 || errorMessage(ownValue(run, "error")) !== void 0
29669
+ );
29670
+ this.endIfComplete(id, activeRun, run);
29671
+ }
29672
+ processUpdate(explicitId, run) {
29673
+ const id = stringValue2(explicitId) ?? stringValue2(ownValue(run, "id"));
29674
+ if (!id || this.completedRuns.get(id)) {
29675
+ return;
29676
+ }
29677
+ if (this.shouldSkipLangChainRun(run)) {
29678
+ const active2 = this.activeRuns.get(id);
29679
+ active2?.span.end();
29680
+ this.activeRuns.delete(id);
29681
+ this.completedRuns.set(id, true);
29682
+ return;
29683
+ }
29684
+ let active = this.activeRuns.get(id);
29685
+ if (!active) {
29686
+ const span = this.startRunSpan(id, run);
29687
+ active = { run, span };
29688
+ this.activeRuns.set(id, active);
29689
+ }
29690
+ const previous = active.run;
29691
+ active.run = mergeRuns(previous, run);
29692
+ this.logRun(active.span, active.run, previous, true);
29693
+ this.endIfComplete(id, active, active.run);
29694
+ }
29695
+ startRunSpan(id, run) {
29696
+ const traceId = stringValue2(ownValue(run, "trace_id")) ?? id;
29697
+ const parentId = stringValue2(ownValue(run, "parent_run_id")) ?? stringValue2(ownValue(ownValue(run, "parent_run"), "id"));
29698
+ const startTime = timestampSeconds(ownValue(run, "start_time"));
29699
+ return startSpan({
29700
+ name: stringValue2(ownValue(run, "name")) ?? "LangSmith run",
29701
+ spanId: id,
29702
+ parentSpanIds: {
29703
+ parentSpanIds: parentId ? [parentId] : [],
29704
+ rootSpanId: traceId
29705
+ },
29706
+ spanAttributes: {
29707
+ type: mapRunType(ownValue(run, "run_type"))
29708
+ },
29709
+ ...startTime === void 0 ? {} : { startTime },
29710
+ event: { id }
29711
+ });
29712
+ }
29713
+ logRun(span, run, previous, includeOutput) {
29714
+ const inputs = preferOwnValue(run, previous, "inputs");
29715
+ const outputs = preferOwnValue(run, previous, "outputs");
29716
+ const error = errorMessage(preferOwnValue(run, previous, "error"));
29717
+ const metadata = extractMetadata(run, previous);
29718
+ const tags = extractTags(preferOwnValue(run, previous, "tags"));
29719
+ const metrics = extractMetrics(run, previous);
29720
+ span.log({
29721
+ ...inputs === void 0 ? {} : { input: sanitizeLoggedValue(inputs) },
29722
+ ...includeOutput && outputs !== void 0 ? { output: sanitizeLoggedValue(outputs) } : {},
29723
+ ...error === void 0 ? {} : { error },
29724
+ ...metadata === void 0 ? {} : { metadata },
29725
+ ...tags === void 0 ? {} : { tags },
29726
+ ...Object.keys(metrics).length === 0 ? {} : { metrics }
29727
+ });
29728
+ }
29729
+ endIfComplete(id, active, run) {
29730
+ const endTime = timestampSeconds(ownValue(run, "end_time"));
29731
+ if (endTime === void 0 && errorMessage(ownValue(run, "error")) === void 0) {
29732
+ return;
29733
+ }
29734
+ active.span.end(endTime === void 0 ? void 0 : { endTime });
29735
+ this.activeRuns.delete(id);
29736
+ this.completedRuns.set(id, true);
29737
+ }
29738
+ shouldSkipLangChainRun(run) {
29739
+ if (!this.skipLangChainRuns) {
29740
+ return false;
29741
+ }
29742
+ const serialized = ownValue(run, "serialized");
29743
+ return isRecord2(serialized) && ownValue(serialized, "lc") === 1;
29744
+ }
29745
+ containLifecycleFailure(operation, fn) {
29746
+ try {
29747
+ fn();
29748
+ } catch (error) {
29749
+ debugLogger.error(
29750
+ `Failed to process LangSmith ${operation} instrumentation:`,
29751
+ error
29752
+ );
29753
+ }
29754
+ }
29755
+ };
29756
+ function ownValue(value, key) {
29757
+ if (!isRecord2(value)) {
29758
+ return void 0;
29759
+ }
29760
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
29761
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
29762
+ }
29763
+ function preferOwnValue(current, previous, key) {
29764
+ const currentDescriptor = isRecord2(current) ? Object.getOwnPropertyDescriptor(current, key) : void 0;
29765
+ if (currentDescriptor && "value" in currentDescriptor) {
29766
+ return currentDescriptor.value;
29767
+ }
29768
+ return ownValue(previous, key);
29769
+ }
29770
+ function mergeRuns(previous, current) {
29771
+ const entries = /* @__PURE__ */ new Map();
29772
+ for (const value of [previous, current]) {
29773
+ if (!isRecord2(value)) {
29774
+ continue;
29775
+ }
29776
+ for (const [key, descriptor] of Object.entries(
29777
+ Object.getOwnPropertyDescriptors(value)
29778
+ )) {
29779
+ if (descriptor.enumerable && "value" in descriptor) {
29780
+ entries.set(key, descriptor.value);
29781
+ }
29782
+ }
29783
+ }
29784
+ return Object.fromEntries(entries);
29785
+ }
29786
+ function isRecord2(value) {
29787
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29788
+ }
29789
+ function stringValue2(value) {
29790
+ return typeof value === "string" && value.length > 0 ? value : void 0;
29791
+ }
29792
+ function timestampSeconds(value) {
29793
+ if (value instanceof Date) {
29794
+ const timestamp = value.getTime();
29795
+ return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
29796
+ }
29797
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
29798
+ return value > 1e10 ? value / 1e3 : value;
29799
+ }
29800
+ if (typeof value === "string") {
29801
+ const timestamp = Date.parse(value);
29802
+ return Number.isFinite(timestamp) ? timestamp / 1e3 : void 0;
29803
+ }
29804
+ return void 0;
29805
+ }
29806
+ function dottedOrderDepth(run) {
29807
+ const dottedOrder = stringValue2(ownValue(run, "dotted_order"));
29808
+ return dottedOrder ? dottedOrder.split(".").length : Number.MAX_SAFE_INTEGER;
29809
+ }
29810
+ function mapRunType(runType) {
29811
+ switch (runType) {
29812
+ case "llm":
29813
+ case "embedding":
29814
+ return "llm" /* LLM */;
29815
+ case "tool":
29816
+ case "retriever":
29817
+ return "tool" /* TOOL */;
29818
+ default:
29819
+ return "task" /* TASK */;
29820
+ }
29821
+ }
29822
+ function extractMetadata(run, previous) {
29823
+ const extra = preferOwnValue(run, previous, "extra");
29824
+ const rawMetadata = ownValue(extra, "metadata");
29825
+ if (!isRecord2(rawMetadata)) {
29826
+ return void 0;
29827
+ }
29828
+ const metadata = {};
29829
+ for (const [key, descriptor] of Object.entries(
29830
+ Object.getOwnPropertyDescriptors(rawMetadata)
29831
+ )) {
29832
+ 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}`)) {
29833
+ continue;
29834
+ }
29835
+ const normalizedKey = key === "ls_provider" ? "provider" : key === "ls_model_name" ? "model" : key.startsWith("ls_") ? key.slice(3) : key;
29836
+ const sanitized = sanitizeLoggedValue(descriptor.value);
29837
+ if (sanitized !== void 0) {
29838
+ metadata[normalizedKey] = sanitized;
29839
+ }
29840
+ }
29841
+ return Object.keys(metadata).length === 0 ? void 0 : metadata;
29842
+ }
29843
+ function extractTags(value) {
29844
+ if (!Array.isArray(value)) {
29845
+ return void 0;
29846
+ }
29847
+ const tags = value.filter(
29848
+ (tag) => typeof tag === "string" && tag.length > 0
29849
+ );
29850
+ return tags.length > 0 ? tags : void 0;
29851
+ }
29852
+ function extractMetrics(run, previous) {
29853
+ const outputs = preferOwnValue(run, previous, "outputs");
29854
+ const extra = preferOwnValue(run, previous, "extra");
29855
+ const metadata = ownValue(extra, "metadata");
29856
+ const usage = ownValue(outputs, "usage_metadata") ?? ownValue(metadata, "usage_metadata");
29857
+ const metrics = {};
29858
+ assignFirstMetric(metrics, "prompt_tokens", usage, [
29859
+ "input_tokens",
29860
+ "prompt_tokens"
29861
+ ]);
29862
+ assignFirstMetric(metrics, "completion_tokens", usage, [
29863
+ "output_tokens",
29864
+ "completion_tokens"
29865
+ ]);
29866
+ assignFirstMetric(metrics, "tokens", usage, ["total_tokens", "tokens"]);
29867
+ const inputTokenDetails = ownValue(usage, "input_token_details");
29868
+ assignFirstMetric(metrics, "prompt_cached_tokens", inputTokenDetails, [
29869
+ "cache_read",
29870
+ "cached_tokens"
29871
+ ]);
29872
+ if (metrics.prompt_cached_tokens === void 0) {
29873
+ assignFirstMetric(metrics, "prompt_cached_tokens", usage, [
29874
+ "cache_read_input_tokens",
29875
+ "prompt_cached_tokens"
29876
+ ]);
29877
+ }
29878
+ assignFirstMetric(
29879
+ metrics,
29880
+ "prompt_cache_creation_tokens",
29881
+ inputTokenDetails,
29882
+ ["cache_creation"]
29883
+ );
29884
+ if (metrics.prompt_cache_creation_tokens === void 0) {
29885
+ assignFirstMetric(metrics, "prompt_cache_creation_tokens", usage, [
29886
+ "cache_creation_input_tokens",
29887
+ "prompt_cache_creation_tokens"
29888
+ ]);
29889
+ }
29890
+ if (metrics.tokens === void 0 && (metrics.prompt_tokens !== void 0 || metrics.completion_tokens !== void 0)) {
29891
+ metrics.tokens = (metrics.prompt_tokens ?? 0) + (metrics.completion_tokens ?? 0);
29892
+ }
29893
+ const startTime = timestampSeconds(
29894
+ preferOwnValue(run, previous, "start_time")
29895
+ );
29896
+ const events = preferOwnValue(run, previous, "events");
29897
+ if (startTime !== void 0 && Array.isArray(events)) {
29898
+ for (const event of events) {
29899
+ if (ownValue(event, "name") !== "new_token") {
29900
+ continue;
29901
+ }
29902
+ const eventTime3 = timestampSeconds(ownValue(event, "time"));
29903
+ if (eventTime3 !== void 0 && eventTime3 >= startTime) {
29904
+ metrics.time_to_first_token = eventTime3 - startTime;
29905
+ }
29906
+ break;
29907
+ }
29908
+ }
29909
+ return metrics;
29910
+ }
29911
+ function assignFirstMetric(metrics, target, source, keys) {
29912
+ for (const key of keys) {
29913
+ const value = ownValue(source, key);
29914
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
29915
+ metrics[target] = value;
29916
+ return;
29917
+ }
29918
+ }
29919
+ }
29920
+ function errorMessage(value) {
29921
+ if (typeof value === "string") {
29922
+ return value;
29923
+ }
29924
+ if (value instanceof Error) {
29925
+ return value.message;
29926
+ }
29927
+ return void 0;
29928
+ }
29929
+ function sanitizeLoggedValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
29930
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
29931
+ return value;
29932
+ }
29933
+ if (typeof value === "number") {
29934
+ return Number.isFinite(value) ? value : void 0;
29935
+ }
29936
+ if (value instanceof Date) {
29937
+ return Number.isFinite(value.getTime()) ? value.toISOString() : void 0;
29938
+ }
29939
+ if (typeof value !== "object" || depth >= 20) {
29940
+ return void 0;
29941
+ }
29942
+ if (seen.has(value)) {
29943
+ return "[Circular]";
29944
+ }
29945
+ seen.add(value);
29946
+ if (Array.isArray(value)) {
29947
+ return value.map((item) => sanitizeLoggedValue(item, seen, depth + 1));
29948
+ }
29949
+ const entries = [];
29950
+ for (const [key, descriptor] of Object.entries(
29951
+ Object.getOwnPropertyDescriptors(value)
29952
+ )) {
29953
+ if (!descriptor.enumerable || !("value" in descriptor) || BLOCKED_METADATA_KEYS.has(key)) {
29954
+ continue;
29955
+ }
29956
+ entries.push([key, sanitizeLoggedValue(descriptor.value, seen, depth + 1)]);
29957
+ }
29958
+ return Object.fromEntries(entries);
29959
+ }
29960
+
29458
29961
  // src/instrumentation/plugins/pi-coding-agent-channels.ts
29459
29962
  var piCodingAgentChannels = defineChannels(
29460
29963
  "@earendil-works/pi-coding-agent",
@@ -29834,11 +30337,11 @@ function patchAssistantMessageStream(stream, promptState, llmState) {
29834
30337
  function recordPiAssistantMessageEvent(promptState, llmState, event) {
29835
30338
  recordFirstTokenMetric(llmState, event);
29836
30339
  const message = "message" in event ? event.message : void 0;
29837
- const errorMessage = "error" in event ? event.error : void 0;
30340
+ const errorMessage2 = "error" in event ? event.error : void 0;
29838
30341
  if (event.type === "done" && isPiAssistantMessage(message)) {
29839
30342
  finishPiLlmSpan(promptState, llmState, message);
29840
- } else if (event.type === "error" && isPiAssistantMessage(errorMessage)) {
29841
- finishPiLlmSpan(promptState, llmState, errorMessage);
30343
+ } else if (event.type === "error" && isPiAssistantMessage(errorMessage2)) {
30344
+ finishPiLlmSpan(promptState, llmState, errorMessage2);
29842
30345
  }
29843
30346
  }
29844
30347
  function recordFirstTokenMetric(state, event) {
@@ -30356,6 +30859,7 @@ var strandsAgentSDKChannels = defineChannels("@strands-agents/sdk", {
30356
30859
  });
30357
30860
 
30358
30861
  // src/instrumentation/plugins/strands-agent-sdk-plugin.ts
30862
+ var MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES = 32;
30359
30863
  var StrandsAgentSDKPlugin = class extends BasePlugin {
30360
30864
  activeChildParents = /* @__PURE__ */ new WeakMap();
30361
30865
  onEnable() {
@@ -30500,11 +31004,16 @@ function startAgentStream(event, activeChildParents) {
30500
31004
  ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
30501
31005
  };
30502
31006
  const parentSpan = agent ? getOnlyChildParent(activeChildParents, agent) : void 0;
31007
+ const attachmentCache = createStrandsAttachmentCache();
31008
+ const input = processStrandsInputAttachments(
31009
+ event.arguments[0],
31010
+ attachmentCache
31011
+ );
30503
31012
  const span = parentSpan ? withCurrent(
30504
31013
  parentSpan,
30505
31014
  () => startSpan({
30506
31015
  event: {
30507
- input: event.arguments[0],
31016
+ input,
30508
31017
  metadata
30509
31018
  },
30510
31019
  name: formatAgentSpanName(agent),
@@ -30512,7 +31021,7 @@ function startAgentStream(event, activeChildParents) {
30512
31021
  })
30513
31022
  ) : startSpan({
30514
31023
  event: {
30515
- input: event.arguments[0],
31024
+ input,
30516
31025
  metadata
30517
31026
  },
30518
31027
  name: formatAgentSpanName(agent),
@@ -30520,6 +31029,7 @@ function startAgentStream(event, activeChildParents) {
30520
31029
  });
30521
31030
  return {
30522
31031
  activeTools: /* @__PURE__ */ new Map(),
31032
+ attachmentCache,
30523
31033
  finalized: false,
30524
31034
  metadata,
30525
31035
  span,
@@ -30535,11 +31045,12 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30535
31045
  ...event.moduleVersion ? { "strands_agent_sdk.version": event.moduleVersion } : {}
30536
31046
  };
30537
31047
  const parentSpan = orchestrator ? getOnlyChildParent(activeChildParents, orchestrator) : void 0;
31048
+ const input = processStrandsInputAttachments(event.arguments[0]);
30538
31049
  const span = parentSpan ? withCurrent(
30539
31050
  parentSpan,
30540
31051
  () => startSpan({
30541
31052
  event: {
30542
- input: event.arguments[0],
31053
+ input,
30543
31054
  metadata
30544
31055
  },
30545
31056
  name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
@@ -30547,7 +31058,7 @@ function startMultiAgentStream(event, operation, activeChildParents) {
30547
31058
  })
30548
31059
  ) : startSpan({
30549
31060
  event: {
30550
- input: event.arguments[0],
31061
+ input,
30551
31062
  metadata
30552
31063
  },
30553
31064
  name: operation === "Graph.stream" ? "Strands Graph" : "Strands Swarm",
@@ -30656,7 +31167,10 @@ function startModelSpan(state, event) {
30656
31167
  state.span,
30657
31168
  () => startSpan({
30658
31169
  event: {
30659
- input: Array.isArray(event.agent?.messages) ? event.agent.messages : void 0,
31170
+ input: Array.isArray(event.agent?.messages) ? processStrandsInputAttachments(
31171
+ event.agent.messages,
31172
+ state.attachmentCache
31173
+ ) : void 0,
30660
31174
  metadata
30661
31175
  },
30662
31176
  name: formatModelSpanName(model),
@@ -30870,6 +31384,7 @@ function finalizeAgentStream(state, error, output) {
30870
31384
  ...output !== void 0 ? { output } : {}
30871
31385
  });
30872
31386
  state.span.end();
31387
+ state.attachmentCache.strings.clear();
30873
31388
  }
30874
31389
  function finalizeMultiAgentStream(state, activeChildParents, error, output) {
30875
31390
  if (state.finalized) {
@@ -31016,6 +31531,166 @@ function extractNodeResultOutput(result) {
31016
31531
  }
31017
31532
  return result;
31018
31533
  }
31534
+ var STRANDS_MEDIA_TYPES = {
31535
+ png: "image/png",
31536
+ jpg: "image/jpeg",
31537
+ jpeg: "image/jpeg",
31538
+ gif: "image/gif",
31539
+ webp: "image/webp",
31540
+ mkv: "video/x-matroska",
31541
+ mov: "video/quicktime",
31542
+ mp4: "video/mp4",
31543
+ webm: "video/webm",
31544
+ flv: "video/x-flv",
31545
+ mpeg: "video/mpeg",
31546
+ mpg: "video/mpeg",
31547
+ wmv: "video/x-ms-wmv",
31548
+ "3gp": "video/3gpp",
31549
+ pdf: "application/pdf",
31550
+ csv: "text/csv",
31551
+ doc: "application/msword",
31552
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
31553
+ xls: "application/vnd.ms-excel",
31554
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
31555
+ html: "text/html",
31556
+ txt: "text/plain",
31557
+ md: "text/markdown",
31558
+ json: "application/json",
31559
+ xml: "application/xml"
31560
+ };
31561
+ function createStrandsAttachmentCache() {
31562
+ return {
31563
+ objects: /* @__PURE__ */ new WeakMap(),
31564
+ strings: new LRUCache({
31565
+ max: MAX_STRANDS_STRING_ATTACHMENT_CACHE_ENTRIES
31566
+ })
31567
+ };
31568
+ }
31569
+ function processStrandsInputAttachments(input, cache = createStrandsAttachmentCache()) {
31570
+ try {
31571
+ return processStrandsInputNode(input, cache);
31572
+ } catch (error) {
31573
+ logInstrumentationError5("Strands Agent SDK input attachments", error);
31574
+ return input;
31575
+ }
31576
+ }
31577
+ function processStrandsInputNode(value, cache) {
31578
+ if (value instanceof BaseAttachment) {
31579
+ return value;
31580
+ }
31581
+ if (Array.isArray(value)) {
31582
+ return value.map((child) => processStrandsInputNode(child, cache));
31583
+ }
31584
+ if (!isObject(value)) {
31585
+ return value;
31586
+ }
31587
+ const directMedia = processDirectStrandsMediaBlock(value, cache);
31588
+ if (directMedia !== void 0) {
31589
+ return directMedia;
31590
+ }
31591
+ const wrappedMedia = processWrappedStrandsMediaBlock(value, cache);
31592
+ if (wrappedMedia !== void 0) {
31593
+ return wrappedMedia;
31594
+ }
31595
+ if (value.type === "message" && Array.isArray(value.content)) {
31596
+ return {
31597
+ role: value.role,
31598
+ content: value.content.map(
31599
+ (child) => processStrandsInputNode(child, cache)
31600
+ ),
31601
+ ...value.metadata !== void 0 ? { metadata: value.metadata } : {}
31602
+ };
31603
+ }
31604
+ if (typeof value.toJSON === "function") {
31605
+ return processStrandsInputNode(value.toJSON(), cache);
31606
+ }
31607
+ return Object.fromEntries(
31608
+ Object.entries(value).map(([key, child]) => [
31609
+ key,
31610
+ processStrandsInputNode(child, cache)
31611
+ ])
31612
+ );
31613
+ }
31614
+ function processDirectStrandsMediaBlock(block, cache) {
31615
+ if (!isStrandsMediaBlock(block)) {
31616
+ return void 0;
31617
+ }
31618
+ const mediaKey = block.type === "imageBlock" ? "image" : block.type === "videoBlock" ? "video" : "document";
31619
+ return createStrandsMediaAttachment(mediaKey, block, cache);
31620
+ }
31621
+ function isStrandsMediaBlock(block) {
31622
+ return (block.type === "imageBlock" || block.type === "videoBlock" || block.type === "documentBlock") && typeof block.format === "string" && isObject(block.source);
31623
+ }
31624
+ function processWrappedStrandsMediaBlock(block, cache) {
31625
+ for (const mediaKey of ["image", "video", "document"]) {
31626
+ const media = block[mediaKey];
31627
+ if (!Object.hasOwn(block, mediaKey) || !isObject(media)) {
31628
+ continue;
31629
+ }
31630
+ const processed = createStrandsMediaAttachment(mediaKey, media, cache);
31631
+ if (processed !== void 0) {
31632
+ return processed;
31633
+ }
31634
+ }
31635
+ return void 0;
31636
+ }
31637
+ function createStrandsMediaAttachment(mediaKey, media, cache) {
31638
+ const format = media.format;
31639
+ const source = media.source;
31640
+ if (typeof format !== "string" || !isObject(source) || !Object.hasOwn(source, "bytes")) {
31641
+ return void 0;
31642
+ }
31643
+ const contentType = STRANDS_MEDIA_TYPES[format.toLowerCase()];
31644
+ if (!contentType) {
31645
+ return void 0;
31646
+ }
31647
+ const filename = mediaKey === "document" && typeof media.name === "string" && media.name.length > 0 ? media.name : `${mediaKey}.${format.toLowerCase()}`;
31648
+ const attachment = getOrCreateStrandsAttachment(
31649
+ source.bytes,
31650
+ filename,
31651
+ contentType,
31652
+ cache
31653
+ );
31654
+ if (!attachment) {
31655
+ return void 0;
31656
+ }
31657
+ const { type: _type, ...serializedMedia } = media;
31658
+ const { type: _sourceType, ...serializedSource } = source;
31659
+ return {
31660
+ [mediaKey]: {
31661
+ ...serializedMedia,
31662
+ source: {
31663
+ ...serializedSource,
31664
+ bytes: attachment
31665
+ }
31666
+ }
31667
+ };
31668
+ }
31669
+ function getOrCreateStrandsAttachment(data, filename, contentType, cache) {
31670
+ const key = `${contentType}\0${filename}`;
31671
+ const attachments = typeof data === "string" ? cache.strings.get(data) : isObject(data) ? cache.objects.get(data) : void 0;
31672
+ const cached = attachments?.get(key);
31673
+ if (cached) {
31674
+ return cached;
31675
+ }
31676
+ const blob = convertDataToBlob(data, contentType);
31677
+ if (!blob) {
31678
+ return void 0;
31679
+ }
31680
+ const attachment = new Attachment({
31681
+ data: blob,
31682
+ filename,
31683
+ contentType
31684
+ });
31685
+ const updatedAttachments = attachments ?? /* @__PURE__ */ new Map();
31686
+ updatedAttachments.set(key, attachment);
31687
+ if (typeof data === "string") {
31688
+ cache.strings.set(data, updatedAttachments);
31689
+ } else if (isObject(data)) {
31690
+ cache.objects.set(data, updatedAttachments);
31691
+ }
31692
+ return attachment;
31693
+ }
31019
31694
  function normalizeContentBlocks(blocks) {
31020
31695
  const text = blocks.map((block) => typeof block.text === "string" ? block.text : void 0).filter((part) => Boolean(part)).join("");
31021
31696
  return text.length > 0 ? text : blocks;
@@ -31145,6 +31820,7 @@ var BraintrustPlugin = class extends BasePlugin {
31145
31820
  gitHubCopilotPlugin = null;
31146
31821
  fluePlugin = null;
31147
31822
  langChainPlugin = null;
31823
+ langSmithPlugin = null;
31148
31824
  piCodingAgentPlugin = null;
31149
31825
  strandsAgentSDKPlugin = null;
31150
31826
  constructor(config = {}) {
@@ -31241,6 +31917,12 @@ var BraintrustPlugin = class extends BasePlugin {
31241
31917
  this.langChainPlugin = new LangChainPlugin();
31242
31918
  this.langChainPlugin.enable();
31243
31919
  }
31920
+ if (integrations.langsmith !== false) {
31921
+ this.langSmithPlugin = new LangSmithPlugin({
31922
+ skipLangChainRuns: integrations.langchain !== false
31923
+ });
31924
+ this.langSmithPlugin.enable();
31925
+ }
31244
31926
  }
31245
31927
  onDisable() {
31246
31928
  if (this.openaiPlugin) {
@@ -31331,6 +32013,10 @@ var BraintrustPlugin = class extends BasePlugin {
31331
32013
  this.langChainPlugin.disable();
31332
32014
  this.langChainPlugin = null;
31333
32015
  }
32016
+ if (this.langSmithPlugin) {
32017
+ this.langSmithPlugin.disable();
32018
+ this.langSmithPlugin = null;
32019
+ }
31334
32020
  }
31335
32021
  };
31336
32022
 
@@ -31395,7 +32081,8 @@ var envIntegrationAliases = {
31395
32081
  langchain: "langchain",
31396
32082
  "langchain-js": "langchain",
31397
32083
  "@langchain": "langchain",
31398
- langgraph: "langgraph"
32084
+ langgraph: "langgraph",
32085
+ langsmith: "langsmith"
31399
32086
  };
31400
32087
  function getDefaultInstrumentationIntegrations() {
31401
32088
  return {
@@ -31426,6 +32113,7 @@ function getDefaultInstrumentationIntegrations() {
31426
32113
  gitHubCopilot: true,
31427
32114
  langchain: true,
31428
32115
  langgraph: true,
32116
+ langsmith: true,
31429
32117
  piCodingAgent: true,
31430
32118
  strandsAgentSDK: true
31431
32119
  };
@@ -31737,6 +32425,9 @@ __export(exports_exports, {
31737
32425
  wrapGoogleGenAI: () => wrapGoogleGenAI,
31738
32426
  wrapGroq: () => wrapGroq,
31739
32427
  wrapHuggingFace: () => wrapHuggingFace,
32428
+ wrapLangSmithClient: () => wrapLangSmithClient,
32429
+ wrapLangSmithRunTrees: () => wrapLangSmithRunTrees,
32430
+ wrapLangSmithTraceable: () => wrapLangSmithTraceable,
31740
32431
  wrapMastraAgent: () => wrapMastraAgent,
31741
32432
  wrapMistral: () => wrapMistral,
31742
32433
  wrapOpenAI: () => wrapOpenAI,
@@ -33223,9 +33914,6 @@ var EveBridge = class {
33223
33914
  this.state = state;
33224
33915
  }
33225
33916
  eventQueuesBySession = /* @__PURE__ */ new Map();
33226
- sessionsById = new LRUCache({
33227
- max: MAX_EVE_CACHE_ENTRIES
33228
- });
33229
33917
  completedToolKeys = new LRUCache({
33230
33918
  max: MAX_EVE_CACHE_ENTRIES
33231
33919
  });
@@ -33392,7 +34080,7 @@ var EveBridge = class {
33392
34080
  async handleEvent(event, ctx, hookMetadata) {
33393
34081
  switch (event.type) {
33394
34082
  case "session.started":
33395
- await this.handleSessionStarted(event, ctx, hookMetadata);
34083
+ this.handleSessionStarted(event, ctx, hookMetadata);
33396
34084
  return true;
33397
34085
  case "turn.started":
33398
34086
  await this.handleTurnStarted(event, ctx, hookMetadata);
@@ -33428,22 +34116,22 @@ var EveBridge = class {
33428
34116
  this.handleStepFailed(event, ctx);
33429
34117
  return true;
33430
34118
  case "turn.completed":
33431
- await this.handleTurnCompleted(event, ctx);
34119
+ this.handleTurnCompleted(event, ctx);
33432
34120
  return true;
33433
34121
  case "turn.failed":
33434
- await this.handleTurnFailed(event, ctx);
34122
+ this.handleTurnFailed(event, ctx);
33435
34123
  return true;
33436
34124
  case "session.failed":
33437
- await this.handleSessionFailed(event, ctx);
34125
+ this.handleSessionFailed(event, ctx);
33438
34126
  return true;
33439
34127
  case "session.completed":
33440
- await this.handleSessionCompleted(event, ctx);
34128
+ this.handleSessionCompleted(event, ctx);
33441
34129
  return true;
33442
34130
  default:
33443
34131
  return false;
33444
34132
  }
33445
34133
  }
33446
- async handleSessionStarted(event, ctx, hookMetadata) {
34134
+ handleSessionStarted(event, ctx, hookMetadata) {
33447
34135
  const sessionId = sessionIdFromContext(ctx);
33448
34136
  if (!sessionId) {
33449
34137
  return;
@@ -33459,7 +34147,6 @@ var EveBridge = class {
33459
34147
  metadata: { ...normalized.metadata, ...metadata }
33460
34148
  };
33461
34149
  });
33462
- await this.ensureSession(sessionId, ctx, metadata, eventTime2(event));
33463
34150
  for (const [key, turn] of this.turnsByKey) {
33464
34151
  if (!key.startsWith(`${sessionId}:`)) {
33465
34152
  continue;
@@ -33477,21 +34164,19 @@ var EveBridge = class {
33477
34164
  if (!sessionId) {
33478
34165
  return;
33479
34166
  }
33480
- const session = await this.ensureSession(
33481
- sessionId,
33482
- ctx,
33483
- hookMetadata ?? {},
33484
- eventTime2(event)
33485
- );
33486
34167
  const key = turnKey2(sessionId, event.data.turnId);
33487
- const metadata = { ...session.metadata };
34168
+ const metadata = {
34169
+ ...readEveTraceState(this.state).metadata,
34170
+ ...hookMetadata ?? {},
34171
+ "eve.session_id": sessionId
34172
+ };
33488
34173
  const existing = this.turnsByKey.get(key);
33489
34174
  if (existing) {
33490
34175
  existing.metadata = { ...existing.metadata, ...metadata };
33491
34176
  existing.span.log({ metadata: existing.metadata });
33492
34177
  return;
33493
34178
  }
33494
- const span = await this.startTurnSpan(session, event, metadata);
34179
+ const span = await this.startTurnSpan(sessionId, event, ctx, metadata);
33495
34180
  span.log({ metadata });
33496
34181
  this.turnsByKey.set(key, {
33497
34182
  key,
@@ -33529,10 +34214,7 @@ var EveBridge = class {
33529
34214
  this.markStepEnded(event.data.turnId, event.data.stepIndex);
33530
34215
  }
33531
34216
  const stepOrdinal = this.stepOrdinal(event);
33532
- const metadata = {
33533
- ...turn.metadata,
33534
- ...this.sessionsById.get(sessionId)?.metadata ?? {}
33535
- };
34217
+ const metadata = { ...turn.metadata };
33536
34218
  const input = consumeCapturedEveModelInput(
33537
34219
  this.state,
33538
34220
  sessionId,
@@ -33627,6 +34309,28 @@ var EveBridge = class {
33627
34309
  if (!step) {
33628
34310
  return;
33629
34311
  }
34312
+ const toolCallsById = /* @__PURE__ */ new Map();
34313
+ if (Array.isArray(step.output) && isObject(step.output[0])) {
34314
+ const message = step.output[0]["message"];
34315
+ if (isObject(message) && Array.isArray(message["tool_calls"])) {
34316
+ for (const toolCall of message["tool_calls"]) {
34317
+ if (isObject(toolCall) && typeof toolCall["id"] === "string") {
34318
+ toolCallsById.set(toolCall["id"], toolCall);
34319
+ }
34320
+ }
34321
+ }
34322
+ }
34323
+ for (const action of traceActions) {
34324
+ const name = action.kind === "tool-call" ? action.toolName : action.subagentName ?? action.name ?? "agent";
34325
+ toolCallsById.set(action.callId, {
34326
+ function: {
34327
+ arguments: JSON.stringify(action.input),
34328
+ name
34329
+ },
34330
+ id: action.callId,
34331
+ type: "function"
34332
+ });
34333
+ }
33630
34334
  step.output = [
33631
34335
  {
33632
34336
  finish_reason: "tool_calls",
@@ -33634,17 +34338,7 @@ var EveBridge = class {
33634
34338
  message: {
33635
34339
  content: null,
33636
34340
  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
- })
34341
+ tool_calls: [...toolCallsById.values()]
33648
34342
  }
33649
34343
  }
33650
34344
  ];
@@ -33891,17 +34585,11 @@ var EveBridge = class {
33891
34585
  )
33892
34586
  });
33893
34587
  }
33894
- async handleSessionFailed(event, ctx) {
34588
+ handleSessionFailed(event, ctx) {
33895
34589
  const sessionId = event.data.sessionId || sessionIdFromContext(ctx);
33896
34590
  if (!sessionId) {
33897
34591
  return;
33898
34592
  }
33899
- const session = await this.ensureSession(
33900
- sessionId,
33901
- ctx,
33902
- {},
33903
- eventTime2(event)
33904
- );
33905
34593
  const error = errorFromMessage(
33906
34594
  event.data.message,
33907
34595
  event.data.code,
@@ -33918,29 +34606,20 @@ var EveBridge = class {
33918
34606
  }
33919
34607
  for (const [key, tool] of this.toolsByCallKey) {
33920
34608
  if (key.startsWith(`${sessionId}:`)) {
33921
- const endTime2 = eventTime2(event);
34609
+ const endTime = eventTime2(event);
33922
34610
  if (!tool.endedByTurn) {
33923
34611
  tool.span.log({ metadata: tool.metadata });
33924
- tool.span.end(endTime2 === void 0 ? void 0 : { endTime: endTime2 });
34612
+ tool.span.end(endTime === void 0 ? void 0 : { endTime });
33925
34613
  tool.endedByTurn = true;
33926
34614
  }
33927
34615
  }
33928
34616
  }
33929
- session.span.log({ error });
33930
- const endTime = eventTime2(event);
33931
- session.span.end(endTime === void 0 ? void 0 : { endTime });
33932
34617
  }
33933
- async handleSessionCompleted(event, ctx) {
34618
+ handleSessionCompleted(event, ctx) {
33934
34619
  const sessionId = sessionIdFromContext(ctx);
33935
34620
  if (!sessionId) {
33936
34621
  return;
33937
34622
  }
33938
- const session = await this.ensureSession(
33939
- sessionId,
33940
- ctx,
33941
- {},
33942
- eventTime2(event)
33943
- );
33944
34623
  for (const [key, turn] of this.turnsByKey) {
33945
34624
  if (!key.startsWith(`${sessionId}:`)) {
33946
34625
  continue;
@@ -33951,82 +34630,29 @@ var EveBridge = class {
33951
34630
  }
33952
34631
  for (const [key, tool] of this.toolsByCallKey) {
33953
34632
  if (key.startsWith(`${sessionId}:`) && !tool.endedByTurn) {
33954
- const endTime2 = eventTime2(event);
34633
+ const endTime = eventTime2(event);
33955
34634
  tool.span.log({ metadata: tool.metadata });
33956
- tool.span.end(endTime2 === void 0 ? void 0 : { endTime: endTime2 });
34635
+ tool.span.end(endTime === void 0 ? void 0 : { endTime });
33957
34636
  tool.endedByTurn = true;
33958
34637
  }
33959
34638
  }
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
34639
  }
34012
34640
  async ensureTurn(event, ctx, hookMetadata) {
34013
34641
  const sessionId = sessionIdFromContext(ctx);
34014
34642
  if (!sessionId) {
34015
34643
  return void 0;
34016
34644
  }
34017
- const session = await this.ensureSession(
34018
- sessionId,
34019
- ctx,
34020
- hookMetadata ?? {},
34021
- eventTime2(event)
34022
- );
34023
34645
  const key = turnKey2(sessionId, event.data.turnId);
34024
34646
  const existing = this.turnsByKey.get(key);
34025
34647
  if (existing) {
34026
34648
  return existing;
34027
34649
  }
34028
- const metadata = { ...session.metadata };
34029
- const span = await this.startTurnSpan(session, event, metadata);
34650
+ const metadata = {
34651
+ ...readEveTraceState(this.state).metadata,
34652
+ ...hookMetadata ?? {},
34653
+ "eve.session_id": sessionId
34654
+ };
34655
+ const span = await this.startTurnSpan(sessionId, event, ctx, metadata);
34030
34656
  span.log({ metadata });
34031
34657
  const state = {
34032
34658
  key,
@@ -34213,22 +34839,35 @@ var EveBridge = class {
34213
34839
  this.toolsByCallKey.set(toolKey3(sessionId, result.callId), state);
34214
34840
  return state;
34215
34841
  }
34216
- async startTurnSpan(session, event, metadata) {
34217
- const { rowId: eventId, spanId } = await generateEveIds(
34218
- "turn",
34219
- session.sessionId,
34220
- event.data.turnId
34221
- );
34842
+ async startTurnSpan(sessionId, event, ctx, metadata) {
34843
+ const session = isObject(ctx) ? ctx["session"] : void 0;
34844
+ const parent = isObject(session) ? session["parent"] : void 0;
34845
+ const parentTurn = isObject(parent) ? parent["turn"] : void 0;
34846
+ const parentLineage = isObject(parent) && typeof parent["callId"] === "string" && typeof parent["sessionId"] === "string" && isObject(parentTurn) && typeof parentTurn["id"] === "string" ? {
34847
+ callId: parent["callId"],
34848
+ sessionId: parent["sessionId"],
34849
+ turnId: parentTurn["id"]
34850
+ } : void 0;
34851
+ const [{ rowId: eventId, spanId }, rootSpanId, parentSpanId] = await Promise.all([
34852
+ generateEveIds("turn", sessionId, event.data.turnId),
34853
+ deterministicEveId(
34854
+ "eve:root",
34855
+ parentLineage?.sessionId ?? sessionId,
34856
+ parentLineage?.turnId ?? event.data.turnId
34857
+ ),
34858
+ parentLineage ? deterministicEveId(
34859
+ "eve:subagent",
34860
+ parentLineage.sessionId,
34861
+ parentLineage.callId
34862
+ ) : Promise.resolve(void 0)
34863
+ ]);
34222
34864
  return await this.startEveSpan({
34223
34865
  event: {
34224
34866
  id: eventId,
34225
34867
  metadata
34226
34868
  },
34227
34869
  name: "eve.turn",
34228
- parentSpanIds: {
34229
- rootSpanId: session.span.rootSpanId,
34230
- spanId: session.span.spanId
34231
- },
34870
+ parentSpanIds: parentSpanId ? { rootSpanId, spanId: parentSpanId } : { parentSpanIds: [], rootSpanId },
34232
34871
  spanAttributes: { type: "task" /* TASK */ },
34233
34872
  spanId,
34234
34873
  startTime: eventTime2(event)
@@ -34289,7 +34928,6 @@ var EveBridge = class {
34289
34928
  }
34290
34929
  cleanupSession(sessionId) {
34291
34930
  const keyPrefix = `${sessionId}:`;
34292
- this.sessionsById.delete(sessionId);
34293
34931
  for (const key of this.turnsByKey.keys()) {
34294
34932
  if (key.startsWith(keyPrefix)) {
34295
34933
  this.turnsByKey.delete(key);
@@ -34480,7 +35118,7 @@ function modelMetadataFromRuntime(runtime) {
34480
35118
  return {};
34481
35119
  }
34482
35120
  const modelId = runtime["modelId"];
34483
- return typeof modelId === "string" ? modelMetadataFromModelId(modelId) : {};
35121
+ return typeof modelId === "string" && !modelId.trim().startsWith("dynamic:") ? modelMetadataFromModelId(modelId) : {};
34484
35122
  }
34485
35123
  function modelMetadataFromModelId(modelId) {
34486
35124
  const normalized = modelId.trim();
@@ -34513,26 +35151,6 @@ function toolMetadataFromTurn(turn) {
34513
35151
  const { model: _model, provider: _provider, ...metadata } = turn.metadata;
34514
35152
  return metadata;
34515
35153
  }
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
35154
  function isToolCallAction(action) {
34537
35155
  return isObject(action) && action["kind"] === "tool-call" && typeof action["callId"] === "string" && typeof action["toolName"] === "string" && isObject(action["input"]);
34538
35156
  }
@@ -34588,9 +35206,6 @@ function turnKey2(sessionId, turnId) {
34588
35206
  function toolKey3(sessionId, callId) {
34589
35207
  return `${sessionId}:${callId}`;
34590
35208
  }
34591
- async function rootSpanIdForSession(sessionId) {
34592
- return deterministicEveId("eve:root", sessionId);
34593
- }
34594
35209
  async function generateEveIds(kind, ...parts) {
34595
35210
  const [rowId, spanId] = await Promise.all([
34596
35211
  deterministicEveId(`eve:row:${kind}`, ...parts),
@@ -34598,9 +35213,6 @@ async function generateEveIds(kind, ...parts) {
34598
35213
  ]);
34599
35214
  return { rowId, spanId };
34600
35215
  }
34601
- async function spanIdForSubagent(sessionId, callId) {
34602
- return deterministicEveId("eve:subagent", sessionId, callId);
34603
- }
34604
35216
  async function deterministicEveId(...parts) {
34605
35217
  const data = new TextEncoder().encode(
34606
35218
  parts.map((part) => `${part.length}:${part}`).join("\0")
@@ -34773,6 +35385,15 @@ function modelMetrics(attributes) {
34773
35385
  }
34774
35386
  return Object.keys(out).length > 0 ? out : void 0;
34775
35387
  }
35388
+ function timeToFirstTokenSeconds(attributes, spanStartSeconds) {
35389
+ if (!isObject(attributes)) return void 0;
35390
+ if (spanStartSeconds === void 0) return void 0;
35391
+ const raw = attributes.completionStartTime;
35392
+ const completionStart = raw instanceof Date || typeof raw === "string" || typeof raw === "number" ? epochSeconds(raw) : void 0;
35393
+ if (completionStart === void 0) return void 0;
35394
+ const ttft = completionStart - spanStartSeconds;
35395
+ return Number.isFinite(ttft) && ttft >= 0 ? ttft : void 0;
35396
+ }
34776
35397
  function buildMetadata(exported) {
34777
35398
  const out = {};
34778
35399
  if (exported.entityId !== void 0) out.entity_id = exported.entityId;
@@ -34897,8 +35518,15 @@ var BraintrustObservabilityExporter = class {
34897
35518
  event.metadata = metadata;
34898
35519
  }
34899
35520
  const metrics = modelMetrics(exported.attributes);
34900
- if (metrics) {
34901
- event.metrics = metrics;
35521
+ const ttft = timeToFirstTokenSeconds(
35522
+ exported.attributes,
35523
+ epochSeconds(exported.startTime)
35524
+ );
35525
+ if (metrics || ttft !== void 0) {
35526
+ event.metrics = {
35527
+ ...metrics ?? {},
35528
+ ...ttft !== void 0 ? { time_to_first_token: ttft } : {}
35529
+ };
34902
35530
  }
34903
35531
  if (Object.keys(event).length > 0) {
34904
35532
  record.span.log(event);
@@ -35777,17 +36405,17 @@ function wrapGenkit(genkit) {
35777
36405
  console.warn("Unsupported Genkit object. Not wrapping.");
35778
36406
  return genkit;
35779
36407
  }
35780
- function isRecord2(value) {
36408
+ function isRecord3(value) {
35781
36409
  return typeof value === "object" && value !== null;
35782
36410
  }
35783
36411
  function isPropertyBag(value) {
35784
- return isRecord2(value) || typeof value === "function";
36412
+ return isRecord3(value) || typeof value === "function";
35785
36413
  }
35786
36414
  function hasFunction(value, methodName) {
35787
36415
  return isPropertyBag(value) && methodName in value && typeof value[methodName] === "function";
35788
36416
  }
35789
36417
  function isGenkitInstance(value) {
35790
- return isRecord2(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
36418
+ return isRecord3(value) && (hasFunction(value, "generate") || hasFunction(value, "generateStream") || hasFunction(value, "defineFlow") || hasFunction(value, "defineTool"));
35791
36419
  }
35792
36420
  function isGenkitModule(value) {
35793
36421
  return hasFunction(value, "genkit");
@@ -35841,7 +36469,7 @@ function patchGenkitRegistry(instance) {
35841
36469
  patchGenkitRegistryConstructor(registry2);
35842
36470
  }
35843
36471
  function patchGenkitRegistryLookup(registry2) {
35844
- if (!isRecord2(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
36472
+ if (!isRecord3(registry2) || hasRegistryPatchedFlag(registry2) || !hasFunction(registry2, "lookupAction")) {
35845
36473
  return;
35846
36474
  }
35847
36475
  const originalLookupAction = registry2.lookupAction;
@@ -35867,7 +36495,7 @@ function patchGenkitRegistryLookup(registry2) {
35867
36495
  }
35868
36496
  }
35869
36497
  function patchGenkitRegistryConstructor(registry2) {
35870
- if (!isRecord2(registry2)) {
36498
+ if (!isRecord3(registry2)) {
35871
36499
  return;
35872
36500
  }
35873
36501
  const constructor = registry2.constructor;
@@ -35883,7 +36511,7 @@ function patchGenkitRegistryConstructor(registry2) {
35883
36511
  configurable: true,
35884
36512
  value: (...args) => {
35885
36513
  const childRegistry = originalWithParent.apply(constructor, args);
35886
- if (args.some((arg) => isRecord2(arg) && hasRegistryPatchedFlag(arg))) {
36514
+ if (args.some((arg) => isRecord3(arg) && hasRegistryPatchedFlag(arg))) {
35887
36515
  patchGenkitRegistryLookup(childRegistry);
35888
36516
  patchGenkitRegistryConstructor(childRegistry);
35889
36517
  }
@@ -35982,7 +36610,7 @@ function hasRegistryConstructorPatchedFlag(value) {
35982
36610
  );
35983
36611
  }
35984
36612
  function isPromiseLike2(value) {
35985
- return isRecord2(value) && "then" in value && typeof value.then === "function";
36613
+ return isRecord3(value) && "then" in value && typeof value.then === "function";
35986
36614
  }
35987
36615
 
35988
36616
  // src/wrappers/huggingface.ts
@@ -36345,14 +36973,14 @@ function wrapMistral(mistral) {
36345
36973
  console.warn("Unsupported Mistral library. Not wrapping.");
36346
36974
  return mistral;
36347
36975
  }
36348
- function isRecord3(value) {
36976
+ function isRecord4(value) {
36349
36977
  return typeof value === "object" && value !== null;
36350
36978
  }
36351
36979
  function hasFunction3(value, methodName) {
36352
- return isRecord3(value) && methodName in value && typeof value[methodName] === "function";
36980
+ return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
36353
36981
  }
36354
36982
  function isSupportedMistralClient(value) {
36355
- if (!isRecord3(value)) {
36983
+ if (!isRecord4(value)) {
36356
36984
  return false;
36357
36985
  }
36358
36986
  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 +37164,14 @@ function wrapCohere(cohere) {
36536
37164
  return cohere;
36537
37165
  }
36538
37166
  var cohereProxyCache = /* @__PURE__ */ new WeakMap();
36539
- function isRecord4(value) {
37167
+ function isRecord5(value) {
36540
37168
  return typeof value === "object" && value !== null;
36541
37169
  }
36542
37170
  function hasFunction4(value, methodName) {
36543
- return isRecord4(value) && methodName in value && typeof value[methodName] === "function";
37171
+ return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
36544
37172
  }
36545
37173
  function isSupportedCohereClient(value) {
36546
- if (!isRecord4(value)) {
37174
+ if (!isRecord5(value)) {
36547
37175
  return false;
36548
37176
  }
36549
37177
  return hasFunction4(value, "chat") || hasFunction4(value, "chatStream") || hasFunction4(value, "embed") || hasFunction4(value, "rerank");
@@ -36603,20 +37231,20 @@ function wrapGroq(groq) {
36603
37231
  console.warn("Unsupported Groq library. Not wrapping.");
36604
37232
  return groq;
36605
37233
  }
36606
- function isRecord5(value) {
37234
+ function isRecord6(value) {
36607
37235
  return typeof value === "object" && value !== null;
36608
37236
  }
36609
37237
  function hasFunction5(value, methodName) {
36610
- return isRecord5(value) && methodName in value && typeof value[methodName] === "function";
37238
+ return isRecord6(value) && methodName in value && typeof value[methodName] === "function";
36611
37239
  }
36612
37240
  function hasChat2(value) {
36613
- return isRecord5(value) && isRecord5(value.completions) && hasFunction5(value.completions, "create");
37241
+ return isRecord6(value) && isRecord6(value.completions) && hasFunction5(value.completions, "create");
36614
37242
  }
36615
37243
  function hasEmbeddings2(value) {
36616
37244
  return hasFunction5(value, "create");
36617
37245
  }
36618
37246
  function isSupportedGroqClient(value) {
36619
- return isRecord5(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
37247
+ return isRecord6(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
36620
37248
  }
36621
37249
  function groqProxy(groq) {
36622
37250
  const privateMethodWorkaroundCache = /* @__PURE__ */ new WeakMap();
@@ -36699,11 +37327,11 @@ var BEDROCK_RUNTIME_OPERATION_METHODS = /* @__PURE__ */ new Set([
36699
37327
  "invokeModelWithBidirectionalStream",
36700
37328
  "invokeModelWithResponseStream"
36701
37329
  ]);
36702
- function isRecord6(value) {
37330
+ function isRecord7(value) {
36703
37331
  return typeof value === "object" && value !== null;
36704
37332
  }
36705
37333
  function isSupportedBedrockRuntimeClient(value) {
36706
- return isRecord6(value) && typeof value.send === "function";
37334
+ return isRecord7(value) && typeof value.send === "function";
36707
37335
  }
36708
37336
  function bedrockRuntimeProxy(client) {
36709
37337
  const cached = bedrockRuntimeProxyCache.get(client);
@@ -36822,6 +37450,271 @@ function wrappedResumeSession(client) {
36822
37450
  );
36823
37451
  }
36824
37452
 
37453
+ // src/wrappers/langsmith.ts
37454
+ var WRAPPED_CLIENT_CLASS = /* @__PURE__ */ Symbol.for(
37455
+ "braintrust.langsmith.wrapped-client-class"
37456
+ );
37457
+ var WRAPPED_CLIENT_INSTANCE = /* @__PURE__ */ Symbol.for(
37458
+ "braintrust.langsmith.wrapped-client-instance"
37459
+ );
37460
+ var WRAPPED_CLIENT_NAMESPACE = /* @__PURE__ */ Symbol.for(
37461
+ "braintrust.langsmith.wrapped-client-namespace"
37462
+ );
37463
+ var WRAPPED_RUN_TREE_CLASS = /* @__PURE__ */ Symbol.for(
37464
+ "braintrust.langsmith.wrapped-run-tree-class"
37465
+ );
37466
+ var WRAPPED_RUN_TREE_INSTANCE = /* @__PURE__ */ Symbol.for(
37467
+ "braintrust.langsmith.wrapped-run-tree-instance"
37468
+ );
37469
+ var WRAPPED_RUN_TREES_NAMESPACE = /* @__PURE__ */ Symbol.for(
37470
+ "braintrust.langsmith.wrapped-run-trees-namespace"
37471
+ );
37472
+ var WRAPPED_TRACEABLE = /* @__PURE__ */ Symbol.for("braintrust.langsmith.wrapped-traceable");
37473
+ var WRAPPED_TRACEABLE_NAMESPACE = /* @__PURE__ */ Symbol.for(
37474
+ "braintrust.langsmith.wrapped-traceable-namespace"
37475
+ );
37476
+ function wrapLangSmithTraceable(namespace) {
37477
+ return wrapNamespaceExport(
37478
+ namespace,
37479
+ "traceable",
37480
+ WRAPPED_TRACEABLE_NAMESPACE,
37481
+ (value) => wrapTraceable(value)
37482
+ );
37483
+ }
37484
+ function wrapLangSmithRunTrees(namespace) {
37485
+ return wrapNamespaceExport(
37486
+ namespace,
37487
+ "RunTree",
37488
+ WRAPPED_RUN_TREES_NAMESPACE,
37489
+ (value) => wrapRunTreeClass(value)
37490
+ );
37491
+ }
37492
+ function wrapLangSmithClient(namespace) {
37493
+ return wrapNamespaceExport(
37494
+ namespace,
37495
+ "Client",
37496
+ WRAPPED_CLIENT_NAMESPACE,
37497
+ (value) => wrapClientClass(value)
37498
+ );
37499
+ }
37500
+ function wrapNamespaceExport(namespace, exportName, marker, wrap2) {
37501
+ if (!namespace || typeof namespace !== "object") {
37502
+ return namespace;
37503
+ }
37504
+ const candidate = namespace;
37505
+ if (candidate[marker] === true) {
37506
+ return namespace;
37507
+ }
37508
+ if (typeof candidate[exportName] !== "function") {
37509
+ console.warn(
37510
+ `Unsupported LangSmith ${exportName} namespace. Not wrapping.`
37511
+ );
37512
+ return namespace;
37513
+ }
37514
+ const target = isModuleNamespace5(namespace) ? Object.setPrototypeOf({}, namespace) : candidate;
37515
+ const moduleNamespace = target !== candidate;
37516
+ let wrappedExport;
37517
+ return new Proxy(target, {
37518
+ get(target2, prop, receiver) {
37519
+ if (prop === marker) {
37520
+ return true;
37521
+ }
37522
+ const value = Reflect.get(target2, prop, receiver);
37523
+ if (prop !== exportName || typeof value !== "function") {
37524
+ return value;
37525
+ }
37526
+ wrappedExport ??= wrap2(value);
37527
+ return wrappedExport;
37528
+ },
37529
+ getOwnPropertyDescriptor(target2, prop) {
37530
+ const descriptor = Reflect.getOwnPropertyDescriptor(target2, prop);
37531
+ if (descriptor || !moduleNamespace) {
37532
+ return descriptor;
37533
+ }
37534
+ const namespaceDescriptor = Reflect.getOwnPropertyDescriptor(
37535
+ candidate,
37536
+ prop
37537
+ );
37538
+ return namespaceDescriptor ? { ...namespaceDescriptor, configurable: true } : void 0;
37539
+ },
37540
+ has(target2, prop) {
37541
+ return Reflect.has(target2, prop) || moduleNamespace && prop in candidate;
37542
+ },
37543
+ ownKeys(target2) {
37544
+ return moduleNamespace ? Reflect.ownKeys(candidate) : Reflect.ownKeys(target2);
37545
+ }
37546
+ });
37547
+ }
37548
+ function isModuleNamespace5(value) {
37549
+ if (!value || typeof value !== "object") {
37550
+ return false;
37551
+ }
37552
+ if (value.constructor?.name === "Module") {
37553
+ return true;
37554
+ }
37555
+ const firstKey = Object.keys(value)[0];
37556
+ if (!firstKey) {
37557
+ return false;
37558
+ }
37559
+ const descriptor = Object.getOwnPropertyDescriptor(value, firstKey);
37560
+ return descriptor ? !descriptor.configurable && !descriptor.writable : false;
37561
+ }
37562
+ function wrapTraceable(traceable2) {
37563
+ if (traceable2[WRAPPED_TRACEABLE]) {
37564
+ return traceable2;
37565
+ }
37566
+ return new Proxy(traceable2, {
37567
+ get(target, prop, receiver) {
37568
+ if (prop === WRAPPED_TRACEABLE) {
37569
+ return true;
37570
+ }
37571
+ return Reflect.get(target, prop, receiver);
37572
+ },
37573
+ apply(target, thisArg, argArray) {
37574
+ const [fn, rawConfig] = argArray;
37575
+ const config = rawConfig && typeof rawConfig === "object" ? rawConfig : void 0;
37576
+ const originalOnEnd = config?.on_end;
37577
+ const wrappedConfig = {
37578
+ ...config,
37579
+ on_end(runTree) {
37580
+ publishRunUpdate(runTree);
37581
+ if (originalOnEnd) {
37582
+ Reflect.apply(originalOnEnd, config, [runTree]);
37583
+ }
37584
+ }
37585
+ };
37586
+ return Reflect.apply(target, thisArg, [fn, wrappedConfig]);
37587
+ }
37588
+ });
37589
+ }
37590
+ function wrapRunTreeClass(RunTree) {
37591
+ if (RunTree[WRAPPED_RUN_TREE_CLASS]) {
37592
+ return RunTree;
37593
+ }
37594
+ return new Proxy(RunTree, {
37595
+ get(target, prop, receiver) {
37596
+ if (prop === WRAPPED_RUN_TREE_CLASS) {
37597
+ return true;
37598
+ }
37599
+ const value = Reflect.get(target, prop, receiver);
37600
+ return typeof value === "function" ? value.bind(target) : value;
37601
+ },
37602
+ construct(target, args, newTarget) {
37603
+ return wrapRunTreeInstance(Reflect.construct(target, args, newTarget));
37604
+ }
37605
+ });
37606
+ }
37607
+ function wrapRunTreeInstance(runTree) {
37608
+ if (runTree[WRAPPED_RUN_TREE_INSTANCE]) {
37609
+ return runTree;
37610
+ }
37611
+ return new Proxy(runTree, {
37612
+ get(target, prop, receiver) {
37613
+ if (prop === WRAPPED_RUN_TREE_INSTANCE) {
37614
+ return true;
37615
+ }
37616
+ const value = Reflect.get(target, prop, receiver);
37617
+ if (typeof value !== "function") {
37618
+ return value;
37619
+ }
37620
+ let wrapped;
37621
+ if (prop === "createChild") {
37622
+ wrapped = (...args) => wrapRunTreeInstance(Reflect.apply(value, target, args));
37623
+ } else if (prop === "postRun") {
37624
+ const method = value;
37625
+ wrapped = (...args) => langSmithChannels.createRun.tracePromise(
37626
+ () => Reflect.apply(method, target, args),
37627
+ { arguments: [target] }
37628
+ );
37629
+ } else if (prop === "patchRun") {
37630
+ const method = value;
37631
+ wrapped = (...args) => langSmithChannels.updateRun.tracePromise(
37632
+ () => Reflect.apply(method, target, args),
37633
+ {
37634
+ arguments: [
37635
+ typeof target.id === "string" ? target.id : "",
37636
+ target
37637
+ ]
37638
+ }
37639
+ );
37640
+ } else {
37641
+ wrapped = value.bind(target);
37642
+ }
37643
+ return wrapped;
37644
+ }
37645
+ });
37646
+ }
37647
+ function wrapClientClass(Client) {
37648
+ if (Client[WRAPPED_CLIENT_CLASS]) {
37649
+ return Client;
37650
+ }
37651
+ return new Proxy(Client, {
37652
+ get(target, prop, receiver) {
37653
+ if (prop === WRAPPED_CLIENT_CLASS) {
37654
+ return true;
37655
+ }
37656
+ const value = Reflect.get(target, prop, receiver);
37657
+ return typeof value === "function" ? value.bind(target) : value;
37658
+ },
37659
+ construct(target, args, newTarget) {
37660
+ return wrapClientInstance(Reflect.construct(target, args, newTarget));
37661
+ }
37662
+ });
37663
+ }
37664
+ function wrapClientInstance(client) {
37665
+ if (client[WRAPPED_CLIENT_INSTANCE]) {
37666
+ return client;
37667
+ }
37668
+ return new Proxy(client, {
37669
+ get(target, prop, receiver) {
37670
+ if (prop === WRAPPED_CLIENT_INSTANCE) {
37671
+ return true;
37672
+ }
37673
+ const value = Reflect.get(target, prop, receiver);
37674
+ if (typeof value !== "function") {
37675
+ return value;
37676
+ }
37677
+ let wrapped;
37678
+ if (prop === "createRun") {
37679
+ const method = value;
37680
+ wrapped = (...args) => langSmithChannels.createRun.tracePromise(
37681
+ () => Reflect.apply(method, target, args),
37682
+ { arguments: args }
37683
+ );
37684
+ } else if (prop === "updateRun") {
37685
+ const method = value;
37686
+ wrapped = (...args) => langSmithChannels.updateRun.tracePromise(
37687
+ () => Reflect.apply(method, target, args),
37688
+ { arguments: args }
37689
+ );
37690
+ } else if (prop === "batchIngestRuns") {
37691
+ const method = value;
37692
+ wrapped = (...args) => langSmithChannels.batchIngestRuns.tracePromise(
37693
+ () => Reflect.apply(method, target, args),
37694
+ { arguments: args }
37695
+ );
37696
+ } else {
37697
+ wrapped = value.bind(target);
37698
+ }
37699
+ return wrapped;
37700
+ }
37701
+ });
37702
+ }
37703
+ function publishRunUpdate(runTree) {
37704
+ if (!runTree || typeof runTree.id !== "string" || !runTree.id) {
37705
+ return;
37706
+ }
37707
+ try {
37708
+ void langSmithChannels.updateRun.tracePromise(() => Promise.resolve(void 0), {
37709
+ arguments: [runTree.id, runTree]
37710
+ }).catch((error) => {
37711
+ debugLogger.error("LangSmith traceable instrumentation failed:", error);
37712
+ });
37713
+ } catch (error) {
37714
+ debugLogger.error("LangSmith traceable instrumentation failed:", error);
37715
+ }
37716
+ }
37717
+
36825
37718
  // src/wrappers/vitest/context-manager.ts
36826
37719
  var VitestContextManager = class {
36827
37720
  /**