braintrust 3.22.0 → 3.23.0

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