@lmnr-ai/lmnr 0.8.52 → 0.8.53

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.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./rolldown-runtime-Ctb5zv51.cjs");
3
- const require_utils = require("./utils-vnm5E0kk.cjs");
3
+ const require_utils = require("./utils-DcdjJ-4n.cjs");
4
4
  const require_consts = require("./consts-9rSS0oeR.cjs");
5
5
  let path = require("path");
6
6
  path = require_rolldown_runtime.__toESM(path);
@@ -12,7 +12,6 @@ let _opentelemetry_sdk_trace_node = require("@opentelemetry/sdk-trace-node");
12
12
  let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conventions");
13
13
  let _traceloop_instrumentation_bedrock = require("@traceloop/instrumentation-bedrock");
14
14
  let _traceloop_instrumentation_chromadb = require("@traceloop/instrumentation-chromadb");
15
- let _traceloop_instrumentation_langchain = require("@traceloop/instrumentation-langchain");
16
15
  let _traceloop_instrumentation_pinecone = require("@traceloop/instrumentation-pinecone");
17
16
  let _traceloop_instrumentation_qdrant = require("@traceloop/instrumentation-qdrant");
18
17
  let _traceloop_instrumentation_together = require("@traceloop/instrumentation-together");
@@ -29,6 +28,7 @@ os = require_rolldown_runtime.__toESM(os);
29
28
  let async_hooks = require("async_hooks");
30
29
  let zod_to_json_schema = require("zod-to-json-schema");
31
30
  let _opentelemetry_core = require("@opentelemetry/core");
31
+ let node_async_hooks = require("node:async_hooks");
32
32
  let _grpc_grpc_js = require("@grpc/grpc-js");
33
33
  let _opentelemetry_exporter_trace_otlp_grpc = require("@opentelemetry/exporter-trace-otlp-grpc");
34
34
  let _opentelemetry_exporter_trace_otlp_proto = require("@opentelemetry/exporter-trace-otlp-proto");
@@ -195,7 +195,7 @@ var LaminarDataset = class extends EvaluationDataset {
195
195
  */
196
196
  async push(paths, recursive = false) {
197
197
  if (!this.client) throw new Error("Client not set");
198
- const { loadFromPaths } = await Promise.resolve().then(() => require("./file-utils-C_q3Dsf2.cjs")).then((n) => n.file_utils_exports);
198
+ const { loadFromPaths } = await Promise.resolve().then(() => require("./file-utils-CyBBBeeW.cjs")).then((n) => n.file_utils_exports);
199
199
  const data = await loadFromPaths(Array.isArray(paths) ? paths : [paths], recursive);
200
200
  if (data.length === 0) {
201
201
  console.warn("No data to push. Skipping");
@@ -211,7 +211,7 @@ var LaminarDataset = class extends EvaluationDataset {
211
211
  };
212
212
  //#endregion
213
213
  //#region src/opentelemetry-lib/tracing/compat.ts
214
- const logger$30 = require_utils.initializeLogger();
214
+ const logger$32 = require_utils.initializeLogger();
215
215
  const makeSpanOtelV2Compatible = (span) => {
216
216
  const spanAny = span;
217
217
  if (spanAny.instrumentationScope && !spanAny.instrumentationLibrary) Object.assign(span, { instrumentationLibrary: spanAny.instrumentationScope });
@@ -257,7 +257,7 @@ const createResource = (attributes) => {
257
257
  if (resources.Resource) return new resources.Resource(attributes);
258
258
  throw new Error("Unable to create Resource: neither v1 nor v2 API found");
259
259
  } catch {
260
- logger$30.debug("Laminar failed to @opentelemetry/resources, continuing without it");
260
+ logger$32.debug("Laminar failed to @opentelemetry/resources, continuing without it");
261
261
  return;
262
262
  }
263
263
  };
@@ -459,7 +459,7 @@ const consumeResponse = async (response) => {
459
459
  };
460
460
  //#endregion
461
461
  //#region src/opentelemetry-lib/tracing/stream-utils.ts
462
- const logger$29 = require_utils.initializeLogger();
462
+ const logger$31 = require_utils.initializeLogger();
463
463
  const pendingStreamProcessing = /* @__PURE__ */ new Set();
464
464
  /**
465
465
  * Wait for all pending stream processing to complete with a timeout
@@ -467,7 +467,7 @@ const pendingStreamProcessing = /* @__PURE__ */ new Set();
467
467
  */
468
468
  const waitForPendingStreams = async (timeoutMs = 5e3) => {
469
469
  if (pendingStreamProcessing.size === 0) return;
470
- logger$29.debug(`Waiting for ${pendingStreamProcessing.size} pending stream(s)`);
470
+ logger$31.debug(`Waiting for ${pendingStreamProcessing.size} pending stream(s)`);
471
471
  const initialCount = pendingStreamProcessing.size;
472
472
  const pendingPromises = Array.from(pendingStreamProcessing);
473
473
  let timedOut = false;
@@ -478,7 +478,7 @@ const waitForPendingStreams = async (timeoutMs = 5e3) => {
478
478
  }, timeoutMs);
479
479
  });
480
480
  await Promise.race([Promise.allSettled(pendingPromises), timeoutPromise]);
481
- if (timedOut && pendingStreamProcessing.size > 0) logger$29.warn(`Timeout waiting for ${pendingStreamProcessing.size} pending stream(s) after ${timeoutMs}ms (started with ${initialCount})`);
481
+ if (timedOut && pendingStreamProcessing.size > 0) logger$31.warn(`Timeout waiting for ${pendingStreamProcessing.size} pending stream(s) after ${timeoutMs}ms (started with ${initialCount})`);
482
482
  };
483
483
  /**
484
484
  * Track a background promise and ensure cleanup
@@ -494,34 +494,34 @@ const trackStreamProcessing = (task) => {
494
494
  * while passing through the original result to the caller
495
495
  */
496
496
  const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, serialize) => {
497
- logger$29.debug(`Handling stream result of type: ${streamInfo.type}`);
497
+ logger$31.debug(`Handling stream result of type: ${streamInfo.type}`);
498
498
  if (streamInfo.type === "aisdk-result") {
499
499
  trackStreamProcessing(async () => {
500
- logger$29.debug("Starting background processing for AI SDK result");
500
+ logger$31.debug("Starting background processing for AI SDK result");
501
501
  let partialOutput = {};
502
502
  try {
503
503
  partialOutput = await consumeAISDKResult(streamInfo.result);
504
504
  if (shouldSendTraces() && !ignoreOutput) try {
505
505
  span.setAttribute(require_utils.SPAN_OUTPUT, serialize(partialOutput));
506
506
  } catch (error) {
507
- logger$29.warn("Failed to serialize AI SDK stream output: " + require_utils.errorMessage(error));
507
+ logger$31.warn("Failed to serialize AI SDK stream output: " + require_utils.errorMessage(error));
508
508
  }
509
509
  } catch (error) {
510
510
  if (Object.keys(partialOutput).length > 0 && shouldSendTraces() && !ignoreOutput) try {
511
511
  span.setAttribute(require_utils.SPAN_OUTPUT, serialize(partialOutput));
512
512
  } catch (serError) {
513
- logger$29.warn("Failed to serialize partial AI SDK output: " + require_utils.errorMessage(serError));
513
+ logger$31.warn("Failed to serialize partial AI SDK output: " + require_utils.errorMessage(serError));
514
514
  }
515
515
  span.recordException(error);
516
516
  } finally {
517
- logger$29.debug("Ending span for AI SDK result");
517
+ logger$31.debug("Ending span for AI SDK result");
518
518
  span.end();
519
519
  }
520
520
  });
521
521
  return originalResult;
522
522
  }
523
523
  if (streamInfo.type === "readable-stream") {
524
- logger$29.debug("Setting up background processing for ReadableStream");
524
+ logger$31.debug("Setting up background processing for ReadableStream");
525
525
  const { stream, dataPromise } = consumeAndTeeReadableStream(streamInfo.stream);
526
526
  trackStreamProcessing(async () => {
527
527
  try {
@@ -533,18 +533,18 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
533
533
  };
534
534
  span.setAttribute(require_utils.SPAN_OUTPUT, serialize(output));
535
535
  } catch (serError) {
536
- logger$29.warn("Failed to serialize stream output: " + require_utils.errorMessage(serError));
536
+ logger$31.warn("Failed to serialize stream output: " + require_utils.errorMessage(serError));
537
537
  }
538
538
  if (error) span.recordException(error);
539
539
  } finally {
540
- logger$29.debug("Ending span for ReadableStream");
540
+ logger$31.debug("Ending span for ReadableStream");
541
541
  span.end();
542
542
  }
543
543
  });
544
544
  return stream;
545
545
  }
546
546
  if (streamInfo.type === "async-iterable") {
547
- logger$29.debug("Setting up background processing for AsyncIterable");
547
+ logger$31.debug("Setting up background processing for AsyncIterable");
548
548
  const { iterable, dataPromise } = consumeAndTeeAsyncIterable(streamInfo.iterable);
549
549
  trackStreamProcessing(async () => {
550
550
  try {
@@ -556,18 +556,18 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
556
556
  };
557
557
  span.setAttribute(require_utils.SPAN_OUTPUT, serialize(output));
558
558
  } catch (serError) {
559
- logger$29.warn("Failed to serialize async iterable output: " + require_utils.errorMessage(serError));
559
+ logger$31.warn("Failed to serialize async iterable output: " + require_utils.errorMessage(serError));
560
560
  }
561
561
  if (error) span.recordException(error);
562
562
  } finally {
563
- logger$29.debug("Ending span for AsyncIterable");
563
+ logger$31.debug("Ending span for AsyncIterable");
564
564
  span.end();
565
565
  }
566
566
  });
567
567
  return iterable;
568
568
  }
569
569
  if (streamInfo.type === "response") {
570
- logger$29.debug("Setting up background processing for Response");
570
+ logger$31.debug("Setting up background processing for Response");
571
571
  const originalResponse = streamInfo.response;
572
572
  if (!originalResponse.body) {
573
573
  span.end();
@@ -590,19 +590,19 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
590
590
  };
591
591
  span.setAttribute(require_utils.SPAN_OUTPUT, serialize(output));
592
592
  } catch (serError) {
593
- logger$29.warn("Failed to serialize response output: " + require_utils.errorMessage(serError));
593
+ logger$31.warn("Failed to serialize response output: " + require_utils.errorMessage(serError));
594
594
  }
595
595
  if (error) span.recordException(error);
596
596
  } catch (err) {
597
597
  span.recordException(err);
598
598
  } finally {
599
- logger$29.debug("Ending span for Response");
599
+ logger$31.debug("Ending span for Response");
600
600
  span.end();
601
601
  }
602
602
  });
603
603
  return newResponse;
604
604
  }
605
- logger$29.warn("Stream type not handled, ending span immediately");
605
+ logger$31.warn("Stream type not handled, ending span immediately");
606
606
  span.end();
607
607
  return originalResult;
608
608
  };
@@ -680,7 +680,7 @@ const writeDebugSessionFile = (file, dir = process.cwd()) => {
680
680
  * contract. This file is part of the cross-language parity surface — keep its
681
681
  * logic line-comparable with the Python `config.py`.
682
682
  */
683
- const logger$28 = require_utils.initializeLogger();
683
+ const logger$30 = require_utils.initializeLogger();
684
684
  const TRUTHY = /* @__PURE__ */ new Set([
685
685
  "true",
686
686
  "1",
@@ -716,7 +716,7 @@ const parseCacheUntil = (value) => {
716
716
  if (value === void 0 || value === "") return null;
717
717
  const spanId = normalizeSpanId(value);
718
718
  if (spanId !== null) return spanId;
719
- logger$28.warn(`LMNR_DEBUG_CACHE_UNTIL=${JSON.stringify(value)} is not a span id; ignoring`);
719
+ logger$30.warn(`LMNR_DEBUG_CACHE_UNTIL=${JSON.stringify(value)} is not a span id; ignoring`);
720
720
  return null;
721
721
  };
722
722
  /**
@@ -1070,7 +1070,7 @@ const resetDebugRuntime = () => {
1070
1070
  };
1071
1071
  //#endregion
1072
1072
  //#region src/opentelemetry-lib/tracing/span.ts
1073
- const logger$27 = require_utils.initializeLogger();
1073
+ const logger$29 = require_utils.initializeLogger();
1074
1074
  /**
1075
1075
  * Build the debug block to propagate, or undefined when debug mode is off.
1076
1076
  *
@@ -1220,7 +1220,7 @@ var LaminarSpan = class LaminarSpan {
1220
1220
  } catch {}
1221
1221
  metadata[key.replace(`${require_utils.ASSOCIATION_PROPERTIES}.metadata.`, "")] = value;
1222
1222
  }
1223
- } else logger$27.warn("Attributes object is not available. Most likely the span is not a LaminarSpan and not an OpenTelemetry default SDK Span. Span path and ids path will be empty.");
1223
+ } else logger$29.warn("Attributes object is not available. Most likely the span is not a LaminarSpan and not an OpenTelemetry default SDK Span. Span path and ids path will be empty.");
1224
1224
  return {
1225
1225
  spanId: require_utils.otelSpanIdToUUID(this._span.spanContext().spanId),
1226
1226
  traceId: require_utils.otelTraceIdToUUID(this._span.spanContext().traceId),
@@ -1247,14 +1247,14 @@ var LaminarSpan = class LaminarSpan {
1247
1247
  }
1248
1248
  get tags() {
1249
1249
  if (!this._span.attributes) {
1250
- logger$27.warn("[LaminarSpan.tags] WARNING. Current span does not have attributes object. Possibly, the span was created with a custom OTel SDK. Returning an empty list. Help: OpenTelemetry API does not guarantee reading attributes from a span, but OTel SDK allows it by default. Laminar SDK allows to read attributes too.");
1250
+ logger$29.warn("[LaminarSpan.tags] WARNING. Current span does not have attributes object. Possibly, the span was created with a custom OTel SDK. Returning an empty list. Help: OpenTelemetry API does not guarantee reading attributes from a span, but OTel SDK allows it by default. Laminar SDK allows to read attributes too.");
1251
1251
  return [];
1252
1252
  }
1253
1253
  return this._span.attributes[`lmnr.association.properties.tags`] ?? [];
1254
1254
  }
1255
1255
  get laminarAssociationProperties() {
1256
1256
  if (!this._span.attributes) {
1257
- logger$27.warn("[LaminarSpan.laminarAssociationProperties] WARNING. Current span does not have attributes object. Possibly, the span was created with a custom OTel SDK. Returning an empty object. Help: OpenTelemetry API does not guarantee reading attributes from a span, but OTel SDK allows it by default. Laminar SDK allows to read attributes too.");
1257
+ logger$29.warn("[LaminarSpan.laminarAssociationProperties] WARNING. Current span does not have attributes object. Possibly, the span was created with a custom OTel SDK. Returning an empty object. Help: OpenTelemetry API does not guarantee reading attributes from a span, but OTel SDK allows it by default. Laminar SDK allows to read attributes too.");
1258
1258
  return {};
1259
1259
  }
1260
1260
  try {
@@ -1450,7 +1450,7 @@ var LaminarContextManager = class {
1450
1450
  };
1451
1451
  //#endregion
1452
1452
  //#region src/opentelemetry-lib/instrumentation/claude-agent-sdk/proxy.ts
1453
- const logger$26 = require_utils.initializeLogger();
1453
+ const logger$28 = require_utils.initializeLogger();
1454
1454
  const DEFAULT_ANTHROPIC_BASE_URL = "https://api.anthropic.com";
1455
1455
  const DEFAULT_CC_PROXY_PORT = 45667;
1456
1456
  const CC_PROXY_PORT_ATTEMPTS = 50;
@@ -1704,7 +1704,7 @@ const resolveTargetUrlFromEnv = (envDict, fallback = DEFAULT_ANTHROPIC_BASE_URL,
1704
1704
  if (foundryBaseUrl) return foundryBaseUrl.replace(/\/$/, "");
1705
1705
  const foundryResource = getEnvValue(FOUNDRY_RESOURCE_ENV);
1706
1706
  if (foundryResource) return `https://${foundryResource}.services.ai.azure.com/anthropic`;
1707
- logger$26.error(`${FOUNDRY_USE_ENV} is set but neither ${FOUNDRY_BASE_URL_ENV} nor ${FOUNDRY_RESOURCE_ENV} is configured. Microsoft Foundry requires one of these values.`);
1707
+ logger$28.error(`${FOUNDRY_USE_ENV} is set but neither ${FOUNDRY_BASE_URL_ENV} nor ${FOUNDRY_RESOURCE_ENV} is configured. Microsoft Foundry requires one of these values.`);
1708
1708
  return null;
1709
1709
  }
1710
1710
  if (isTruthyEnv(getEnvValue(BEDROCK_USE_ENV))) {
@@ -1716,7 +1716,7 @@ const resolveTargetUrlFromEnv = (envDict, fallback = DEFAULT_ANTHROPIC_BASE_URL,
1716
1716
  region = getRegionFromAwsConfig(awsProfile) ?? void 0;
1717
1717
  }
1718
1718
  if (region) return `https://bedrock-runtime.${region}.amazonaws.com`;
1719
- logger$26.error(`${BEDROCK_USE_ENV} is set but could not determine AWS region. Set ${BEDROCK_AWS_REGION_ENV} or configure a region in ~/.aws/config for the active profile.`);
1719
+ logger$28.error(`${BEDROCK_USE_ENV} is set but could not determine AWS region. Set ${BEDROCK_AWS_REGION_ENV} or configure a region in ~/.aws/config for the active profile.`);
1720
1720
  return null;
1721
1721
  }
1722
1722
  if (isTruthyEnv(getEnvValue(VERTEX_USE_ENV))) {
@@ -1799,11 +1799,11 @@ const waitForPort = (port, timeoutMs = 5e3) => new Promise((resolve) => {
1799
1799
  const registerGlobalProxyShutdown = () => {
1800
1800
  if (!globalShutdownRegistered) {
1801
1801
  process.on("exit", () => {
1802
- logger$26.debug("process.on(\"exit\") called - stopping all active proxies");
1802
+ logger$28.debug("process.on(\"exit\") called - stopping all active proxies");
1803
1803
  for (const proxyServer of activeProxyServers) try {
1804
1804
  proxyServer.stopServer();
1805
1805
  } catch (e) {
1806
- logger$26.debug(`Failed to stop proxy: ${require_utils.errorMessage(e)}`);
1806
+ logger$28.debug(`Failed to stop proxy: ${require_utils.errorMessage(e)}`);
1807
1807
  }
1808
1808
  activeProxyServers.clear();
1809
1809
  });
@@ -1818,28 +1818,28 @@ const createProxyInstance = async ({ env, cwd, settingSources, settings, targetU
1818
1818
  try {
1819
1819
  const port = await findAvailablePort(DEFAULT_CC_PROXY_PORT, CC_PROXY_PORT_ATTEMPTS);
1820
1820
  if (port === null) {
1821
- logger$26.warn("Unable to allocate port for cc-proxy.");
1821
+ logger$28.warn("Unable to allocate port for cc-proxy.");
1822
1822
  return null;
1823
1823
  }
1824
1824
  const targetUrl = resolvedTargetUrl ?? resolveTargetUrlFromEnv(env, void 0, cwd, settingSources, settings);
1825
1825
  if (!targetUrl) {
1826
- logger$26.warn("Unable to resolve target URL for cc-proxy (provider misconfigured).");
1826
+ logger$28.warn("Unable to resolve target URL for cc-proxy (provider misconfigured).");
1827
1827
  return null;
1828
1828
  }
1829
- logger$26.debug(`Creating proxy instance on port ${port} targeting: ${targetUrl}`);
1829
+ logger$28.debug(`Creating proxy instance on port ${port} targeting: ${targetUrl}`);
1830
1830
  try {
1831
1831
  const { ProxyServer } = require("@lmnr-ai/claude-code-proxy");
1832
1832
  const proxyServer = new ProxyServer(port);
1833
1833
  proxyServer.runServer(targetUrl);
1834
1834
  if (!await waitForPort(port)) {
1835
- logger$26.warn(`cc-proxy failed to start on port ${port}`);
1835
+ logger$28.warn(`cc-proxy failed to start on port ${port}`);
1836
1836
  proxyServer.stopServer();
1837
1837
  return null;
1838
1838
  }
1839
1839
  const proxyBaseUrl = `http://127.0.0.1:${port}`;
1840
1840
  activeProxyServers.add(proxyServer);
1841
1841
  registerGlobalProxyShutdown();
1842
- logger$26.info(`Started claude proxy server on: ${proxyBaseUrl}`);
1842
+ logger$28.info(`Started claude proxy server on: ${proxyBaseUrl}`);
1843
1843
  return {
1844
1844
  server: proxyServer,
1845
1845
  baseUrl: proxyBaseUrl,
@@ -1847,11 +1847,11 @@ const createProxyInstance = async ({ env, cwd, settingSources, settings, targetU
1847
1847
  targetUrl
1848
1848
  };
1849
1849
  } catch (e) {
1850
- logger$26.warn(`Unable to start cc-proxy: ${require_utils.errorMessage(e)}`);
1850
+ logger$28.warn(`Unable to start cc-proxy: ${require_utils.errorMessage(e)}`);
1851
1851
  return null;
1852
1852
  }
1853
1853
  } catch (e) {
1854
- logger$26.warn(`Failed to create proxy instance: ${require_utils.errorMessage(e)}`);
1854
+ logger$28.warn(`Failed to create proxy instance: ${require_utils.errorMessage(e)}`);
1855
1855
  return null;
1856
1856
  }
1857
1857
  };
@@ -1861,11 +1861,11 @@ const createProxyInstance = async ({ env, cwd, settingSources, settings, targetU
1861
1861
  const stopProxyInstance = (instance) => {
1862
1862
  if (!instance) return;
1863
1863
  try {
1864
- logger$26.debug(`Stopping proxy instance on port ${instance.port}`);
1864
+ logger$28.debug(`Stopping proxy instance on port ${instance.port}`);
1865
1865
  instance.server.stopServer();
1866
1866
  activeProxyServers.delete(instance.server);
1867
1867
  } catch (e) {
1868
- logger$26.debug(`Failed to stop proxy instance: ${require_utils.errorMessage(e)}`);
1868
+ logger$28.debug(`Failed to stop proxy instance: ${require_utils.errorMessage(e)}`);
1869
1869
  }
1870
1870
  };
1871
1871
  /**
@@ -1873,11 +1873,11 @@ const stopProxyInstance = (instance) => {
1873
1873
  * Used during shutdown to ensure cleanup
1874
1874
  */
1875
1875
  const forceReleaseProxy = () => {
1876
- logger$26.debug(`Force stopping all ${activeProxyServers.size} active proxy servers`);
1876
+ logger$28.debug(`Force stopping all ${activeProxyServers.size} active proxy servers`);
1877
1877
  for (const proxyServer of activeProxyServers) try {
1878
1878
  proxyServer.stopServer();
1879
1879
  } catch (e) {
1880
- logger$26.debug(`Failed to stop proxy: ${require_utils.errorMessage(e)}`);
1880
+ logger$28.debug(`Failed to stop proxy: ${require_utils.errorMessage(e)}`);
1881
1881
  }
1882
1882
  activeProxyServers.clear();
1883
1883
  };
@@ -1927,14 +1927,14 @@ const setTraceToProxyInstance = async (instance) => {
1927
1927
  spanPath: payload.span_path,
1928
1928
  laminarUrl: payload.laminar_url
1929
1929
  });
1930
- logger$26.debug(`Set trace context to proxy on port ${instance.port}`);
1930
+ logger$28.debug(`Set trace context to proxy on port ${instance.port}`);
1931
1931
  } catch (e) {
1932
- logger$26.debug(`Unable to set trace context to proxy on port ${instance.port}: ` + require_utils.errorMessage(e));
1932
+ logger$28.debug(`Unable to set trace context to proxy on port ${instance.port}: ` + require_utils.errorMessage(e));
1933
1933
  }
1934
1934
  };
1935
1935
  //#endregion
1936
1936
  //#region src/opentelemetry-lib/instrumentation/claude-agent-sdk/index.ts
1937
- const logger$25 = require_utils.initializeLogger();
1937
+ const logger$27 = require_utils.initializeLogger();
1938
1938
  /**
1939
1939
  * Create an instrumented version of the claude-agent-sdk query function.
1940
1940
  * This can be used when importing the query function before Laminar initialization.
@@ -1970,9 +1970,9 @@ function instrumentClaudeAgentQuery(originalQuery) {
1970
1970
  targetUrl
1971
1971
  });
1972
1972
  if (proxyInstance && targetUrl) {
1973
- logger$25.debug(`Using proxy on port ${proxyInstance.port}`);
1973
+ logger$27.debug(`Using proxy on port ${proxyInstance.port}`);
1974
1974
  await Laminar.withSpan(span, async () => {
1975
- logger$25.debug("Setting trace to proxy instance...");
1975
+ logger$27.debug("Setting trace to proxy instance...");
1976
1976
  await setTraceToProxyInstance(proxyInstance);
1977
1977
  });
1978
1978
  const varsToRemove = getEnvVarsToRemove(mergedEnv, sessionCwd, settingSources);
@@ -1987,13 +1987,13 @@ function instrumentClaudeAgentQuery(originalQuery) {
1987
1987
  if (isProviderEnabledInEnv(subprocessEnv, "CLAUDE_CODE_USE_BEDROCK")) subprocessEnv.ANTHROPIC_BEDROCK_BASE_URL = proxyInstance.baseUrl;
1988
1988
  if (isProviderEnabledInEnv(subprocessEnv, "CLAUDE_CODE_USE_VERTEX")) subprocessEnv.ANTHROPIC_VERTEX_BASE_URL = proxyInstance.baseUrl;
1989
1989
  const flagSettings = buildProxyFlagSettings(callerSettings, proxyInstance.baseUrl, sessionCwd, settingSources);
1990
- if (flagSettings === null) logger$25.warn(`Could not read options.settings ${JSON.stringify(callerSettings)}; Claude Code settings that define a base URL will bypass the Laminar proxy and produce no LLM spans.`);
1990
+ if (flagSettings === null) logger$27.warn(`Could not read options.settings ${JSON.stringify(callerSettings)}; Claude Code settings that define a base URL will bypass the Laminar proxy and produce no LLM spans.`);
1991
1991
  else {
1992
1992
  params.options.settings = flagSettings;
1993
1993
  const conflicting = Object.entries(readClaudeSettingsEnv(sessionCwd, settingSources)).filter(([key, value]) => PROXY_BASE_URL_ENV_KEYS.includes(key) && value !== "" && value !== proxyInstance?.baseUrl).map(([key]) => key);
1994
- if (conflicting.length > 0) logger$25.info(`Claude Code settings define ${conflicting.sort().join(", ")}, which outranks the subprocess environment. Injected settings so the Laminar proxy at ${proxyInstance.baseUrl} still intercepts API traffic; your settings files were not modified.`);
1994
+ if (conflicting.length > 0) logger$27.info(`Claude Code settings define ${conflicting.sort().join(", ")}, which outranks the subprocess environment. Injected settings so the Laminar proxy at ${proxyInstance.baseUrl} still intercepts API traffic; your settings files were not modified.`);
1995
1995
  }
1996
- } else logger$25.debug("No claude proxy server available. Proceeding without proxy.");
1996
+ } else logger$27.debug("No claude proxy server available. Proceeding without proxy.");
1997
1997
  const originalGenerator = originalQuery(params);
1998
1998
  for await (const message of originalGenerator) {
1999
1999
  collected.push(message);
@@ -2022,7 +2022,7 @@ var ClaudeAgentSDKInstrumentation = class extends _opentelemetry_instrumentation
2022
2022
  }
2023
2023
  manuallyInstrument(claudeAgentModule) {
2024
2024
  if (claudeAgentModule.query && typeof claudeAgentModule.query === "function") this._wrap(claudeAgentModule, "query", this.patchQuery());
2025
- else logger$25.debug("query function not found in claudeAgentSDK module, skipping instrumentation");
2025
+ else logger$27.debug("query function not found in claudeAgentSDK module, skipping instrumentation");
2026
2026
  }
2027
2027
  patchQuery() {
2028
2028
  return (original) => instrumentClaudeAgentQuery(original);
@@ -2038,9 +2038,19 @@ var ClaudeAgentSDKInstrumentation = class extends _opentelemetry_instrumentation
2038
2038
  }
2039
2039
  };
2040
2040
  //#endregion
2041
+ //#region src/opentelemetry-lib/instrumentation/langchain/llm-call.ts
2042
+ /**
2043
+ * Context key carrying the LangChain LLM call currently in progress. Set by the
2044
+ * `BaseChatModel` / `BaseLLM` wrappers for the duration of the model call.
2045
+ *
2046
+ * Kept free of other imports: `Laminar._startSpan` reads it to tell a handed
2047
+ * off call that the provider SDK instrumentation did record its span.
2048
+ */
2049
+ const LLM_CALL_KEY = (0, _opentelemetry_api.createContextKey)("lmnr.langchain.llm_call");
2050
+ //#endregion
2041
2051
  //#region src/laminar.ts
2042
2052
  require_utils.loadEnv();
2043
- const logger$24 = require_utils.initializeLogger();
2053
+ const logger$26 = require_utils.initializeLogger();
2044
2054
  var Laminar = class Laminar {
2045
2055
  static {
2046
2056
  this.isInitialized = false;
@@ -2112,28 +2122,32 @@ var Laminar = class Laminar {
2112
2122
  * and you want Laminar spans to be children of the existing spans.
2113
2123
  * @param {SpanProcessor} props.spanProcessor - The span processor to use. If passed, some of
2114
2124
  * the other options will be ignored.
2125
+ * @param {string} props.release - The release of the running code, usually its git commit
2126
+ * SHA. Laminar groups an agent's traces into versions by release. If not specified, read
2127
+ * from the LMNR_RELEASE environment variable, common deploy platform variables (Vercel,
2128
+ * Render, Railway, Heroku, Cloud Run, ...), or the checked-out git commit.
2115
2129
  *
2116
2130
  * @example
2117
2131
  * import { Laminar } from '@lmnr-ai/lmnr';
2118
2132
  * import { OpenAI } from 'openai';
2119
- * import * as ChainsModule from "langchain/chains";
2133
+ * import * as CallbackManagerModule from "@langchain/core/callbacks/manager";
2120
2134
  *
2121
- * // Initialize Laminar while auto-instrumenting Langchain and OpenAI modules.
2135
+ * // Initialize Laminar while instrumenting LangChain and OpenAI modules.
2122
2136
  * Laminar.initialize({
2123
2137
  * projectApiKey: "<LMNR_PROJECT_API_KEY>",
2124
2138
  * instrumentModules: {
2125
2139
  * langchain: {
2126
- * chainsModule: ChainsModule
2140
+ * callbackManagerModule: CallbackManagerModule
2127
2141
  * },
2128
- * openAI: OpenAI
2142
+ * OpenAI: OpenAI
2129
2143
  * }
2130
2144
  * });
2131
2145
  *
2132
2146
  * @throws {Error} - If project API key is not set
2133
2147
  */
2134
- static initialize({ projectApiKey, baseUrl, baseHttpUrl, httpPort, grpcPort, instrumentModules, disableBatch, traceExportTimeoutMillis, logLevel, maxExportBatchSize, maxExportBatchSizeBytes, flushBySize, forceHttp, sessionRecordingOptions, metadata, inheritGlobalContext, spanProcessor } = {}) {
2148
+ static initialize({ projectApiKey, baseUrl, baseHttpUrl, httpPort, grpcPort, instrumentModules, disableBatch, traceExportTimeoutMillis, logLevel, maxExportBatchSize, maxExportBatchSizeBytes, flushBySize, forceHttp, sessionRecordingOptions, metadata, inheritGlobalContext, spanProcessor, release } = {}) {
2135
2149
  if (this.isInitialized) {
2136
- logger$24.warn("Laminar has already been initialized. Skipping initialization.");
2150
+ logger$26.warn("Laminar has already been initialized. Skipping initialization.");
2137
2151
  return;
2138
2152
  }
2139
2153
  const key = projectApiKey ?? process?.env?.LMNR_PROJECT_API_KEY;
@@ -2157,7 +2171,7 @@ var Laminar = class Laminar {
2157
2171
  ...metadata ?? {}
2158
2172
  };
2159
2173
  if (inheritGlobalContext) LaminarContextManager.inheritGlobalContext = true;
2160
- if (spanProcessor && !(spanProcessor instanceof LaminarSpanProcessor)) logger$24.warn("Span processor is not a LaminarSpanProcessor. Some functionality may be impaired.");
2174
+ if (spanProcessor && !(spanProcessor instanceof LaminarSpanProcessor)) logger$26.warn("Span processor is not a LaminarSpanProcessor. Some functionality may be impaired.");
2161
2175
  this.isInitialized = true;
2162
2176
  const urlWithoutSlash = url?.replace(/\/$/, "").replace(/:\d{1,5}$/g, "");
2163
2177
  const httpUrlWithoutSlash = httpUrl?.replace(/\/$/, "").replace(/:\d{1,5}$/g, "");
@@ -2177,7 +2191,8 @@ var Laminar = class Laminar {
2177
2191
  flushBySize,
2178
2192
  traceExportTimeoutMillis,
2179
2193
  sessionRecordingOptions,
2180
- spanProcessor
2194
+ spanProcessor,
2195
+ release
2181
2196
  });
2182
2197
  this._initDebugRuntime(url, port);
2183
2198
  LaminarContextManager.setGlobalMetadata(this.globalMetadata);
@@ -2204,11 +2219,11 @@ var Laminar = class Laminar {
2204
2219
  try {
2205
2220
  getRuntime()?.recordTraceId(require_utils.otelTraceIdToUUID(otelSpanContext.traceId));
2206
2221
  } catch (e) {
2207
- logger$24.debug("Failed to record debug trace id from env: " + require_utils.errorMessage(e));
2222
+ logger$26.debug("Failed to record debug trace id from env: " + require_utils.errorMessage(e));
2208
2223
  }
2209
- logger$24.debug("Initialized Laminar parent context from LMNR_SPAN_CONTEXT.");
2224
+ logger$26.debug("Initialized Laminar parent context from LMNR_SPAN_CONTEXT.");
2210
2225
  } catch (e) {
2211
- logger$24.warn("LMNR_SPAN_CONTEXT is set but could not be used: " + require_utils.errorMessage(e));
2226
+ logger$26.warn("LMNR_SPAN_CONTEXT is set but could not be used: " + require_utils.errorMessage(e));
2212
2227
  }
2213
2228
  }
2214
2229
  /**
@@ -2252,7 +2267,7 @@ var Laminar = class Laminar {
2252
2267
  if (projectId) {
2253
2268
  runtime.recordProjectId(projectId);
2254
2269
  const sessionUrl = runtime.debuggerSessionUrl();
2255
- logger$24.info(`Laminar debugger session: ${sessionUrl}`);
2270
+ logger$26.info(`Laminar debugger session: ${sessionUrl}`);
2256
2271
  if (runtime.shouldOpenBrowser) {
2257
2272
  const opener = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
2258
2273
  (0, node_child_process.spawn)(opener, [sessionUrl], {
@@ -2262,7 +2277,7 @@ var Laminar = class Laminar {
2262
2277
  }
2263
2278
  }
2264
2279
  }).catch((e) => {
2265
- logger$24.warn("Failed to register debug session: " + require_utils.errorMessage(e));
2280
+ logger$26.warn("Failed to register debug session: " + require_utils.errorMessage(e));
2266
2281
  });
2267
2282
  this.globalMetadata = {
2268
2283
  ...this.globalMetadata,
@@ -2272,7 +2287,7 @@ var Laminar = class Laminar {
2272
2287
  this.debugExitHook = () => runtime.emitPointer();
2273
2288
  process.once("exit", this.debugExitHook);
2274
2289
  } catch (e) {
2275
- logger$24.warn("Failed to initialize debug runtime: " + require_utils.errorMessage(e));
2290
+ logger$26.warn("Failed to initialize debug runtime: " + require_utils.errorMessage(e));
2276
2291
  }
2277
2292
  }
2278
2293
  /**
@@ -2319,7 +2334,7 @@ var Laminar = class Laminar {
2319
2334
  runtime.rolloutSessions.register({ sessionId: runtime.sessionId }).then((projectId) => {
2320
2335
  if (projectId) runtime.recordProjectId(projectId);
2321
2336
  }).catch((e) => {
2322
- logger$24.debug("Failed to register downstream debug session: " + require_utils.errorMessage(e));
2337
+ logger$26.debug("Failed to register downstream debug session: " + require_utils.errorMessage(e));
2323
2338
  });
2324
2339
  this.globalMetadata = {
2325
2340
  ...this.globalMetadata,
@@ -2328,7 +2343,7 @@ var Laminar = class Laminar {
2328
2343
  LaminarContextManager.setGlobalMetadata(this.globalMetadata);
2329
2344
  }
2330
2345
  } catch (e) {
2331
- logger$24.debug("Failed to arm debug runtime from context: " + require_utils.errorMessage(e));
2346
+ logger$26.debug("Failed to arm debug runtime from context: " + require_utils.errorMessage(e));
2332
2347
  }
2333
2348
  }
2334
2349
  /**
@@ -2343,7 +2358,7 @@ var Laminar = class Laminar {
2343
2358
  */
2344
2359
  static patch(modules) {
2345
2360
  if (!this.isInitialized) {
2346
- logger$24.warn("Laminar must be initialized before patching modules. Skipping patch.");
2361
+ logger$26.warn("Laminar must be initialized before patching modules. Skipping patch.");
2347
2362
  return;
2348
2363
  }
2349
2364
  if (!modules || Object.keys(modules).length === 0) throw new Error("Pass at least one module to patch");
@@ -2603,7 +2618,7 @@ var Laminar = class Laminar {
2603
2618
  const spanContext = require_utils.tryToOtelSpanContext(laminarContext);
2604
2619
  entityContext = _opentelemetry_api.trace.setSpan(entityContext, _opentelemetry_api.trace.wrapSpanContext(spanContext));
2605
2620
  } catch (e) {
2606
- logger$24.warn("Failed to parse parent span context: " + require_utils.errorMessage(e));
2621
+ logger$26.warn("Failed to parse parent span context: " + require_utils.errorMessage(e));
2607
2622
  }
2608
2623
  const tagProperties = tags ? { [`${require_utils.ASSOCIATION_PROPERTIES}.tags`]: Array.from(new Set(tags)) } : {};
2609
2624
  const ctxAssociationProperties = LaminarContextManager.getAssociationProperties();
@@ -2639,6 +2654,10 @@ var Laminar = class Laminar {
2639
2654
  startTime
2640
2655
  }, entityContext));
2641
2656
  span.activated = activated ?? false;
2657
+ if (spanType === "LLM") {
2658
+ const llmCall = entityContext.getValue(LLM_CALL_KEY);
2659
+ if (llmCall?.mode === "handoff" && span.isRecording()) llmCall.recorded = true;
2660
+ }
2642
2661
  if (input) span.setInput(input);
2643
2662
  if (activated) {
2644
2663
  entityContext = LaminarContextManager.setAssociationProperties(span, entityContext);
@@ -2707,13 +2726,13 @@ var Laminar = class Laminar {
2707
2726
  }
2708
2727
  static async flush() {
2709
2728
  if (this.isInitialized) {
2710
- logger$24.debug("Flushing spans");
2729
+ logger$26.debug("Flushing spans");
2711
2730
  await forceFlush();
2712
2731
  }
2713
2732
  }
2714
2733
  static async shutdown() {
2715
2734
  if (this.isInitialized) {
2716
- logger$24.debug("Shutting down Laminar");
2735
+ logger$26.debug("Shutting down Laminar");
2717
2736
  getRuntime()?.emitPointer();
2718
2737
  await forceFlush();
2719
2738
  this.isInitialized = false;
@@ -2848,7 +2867,7 @@ return module.exports;
2848
2867
  //#endregion
2849
2868
  //#region src/browser/utils.ts
2850
2869
  const LMNR_SEND_EVENTS_FUNCTION_NAME = "lmnrSendEvents";
2851
- const logger$23 = require_utils.initializeLogger();
2870
+ const logger$25 = require_utils.initializeLogger();
2852
2871
  /**
2853
2872
  * If the first argument is a string, return an object with the name of the method
2854
2873
  * and the argument as the value.
@@ -2871,7 +2890,7 @@ const takeFullSnapshot = async (page) => await page.evaluate(() => {
2871
2890
  window.lmnrRrweb.record.takeFullSnapshot();
2872
2891
  return true;
2873
2892
  } catch (error) {
2874
- logger$23.error("Error taking full snapshot: " + require_utils.errorMessage(error));
2893
+ logger$25.error("Error taking full snapshot: " + require_utils.errorMessage(error));
2875
2894
  return false;
2876
2895
  }
2877
2896
  return false;
@@ -2882,7 +2901,7 @@ const injectSessionRecorder = async (page, sessionRecordingOptions) => {
2882
2901
  try {
2883
2902
  return await script();
2884
2903
  } catch (error) {
2885
- logger$23.error("Operation " + script.name + " failed: " + require_utils.errorMessage(error));
2904
+ logger$25.error("Operation " + script.name + " failed: " + require_utils.errorMessage(error));
2886
2905
  }
2887
2906
  await new Promise((resolve) => setTimeout(resolve, 500));
2888
2907
  }
@@ -2892,20 +2911,20 @@ const injectSessionRecorder = async (page, sessionRecordingOptions) => {
2892
2911
  try {
2893
2912
  isRrwebPresent = await castedPage.evaluate(() => typeof window.lmnrRrweb !== "undefined");
2894
2913
  } catch (error) {
2895
- logger$23.debug("Failed to check if session recorder is loaded: " + require_utils.errorMessage(error));
2914
+ logger$25.debug("Failed to check if session recorder is loaded: " + require_utils.errorMessage(error));
2896
2915
  }
2897
2916
  if (!isRrwebPresent) {
2898
2917
  if (!await tryRunScript(async function injectSessionRecorder() {
2899
2918
  await castedPage.evaluate(RECORDER);
2900
2919
  return true;
2901
2920
  })) {
2902
- logger$23.error("Failed to load session recorder");
2921
+ logger$25.error("Failed to load session recorder");
2903
2922
  return;
2904
2923
  }
2905
2924
  try {
2906
2925
  await castedPage.evaluate(injectScript, sessionRecordingOptions);
2907
2926
  } catch (error) {
2908
- logger$23.debug("Failed to inject session recorder: " + require_utils.errorMessage(error));
2927
+ logger$25.debug("Failed to inject session recorder: " + require_utils.errorMessage(error));
2909
2928
  }
2910
2929
  }
2911
2930
  };
@@ -3171,7 +3190,7 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
3171
3190
  try {
3172
3191
  const { batchId, chunkIndex, totalChunks, data } = chunk;
3173
3192
  if (!sessionId || !traceId) {
3174
- logger$23.debug("Missing sessionId or traceId in chunk");
3193
+ logger$25.debug("Missing sessionId or traceId in chunk");
3175
3194
  return;
3176
3195
  }
3177
3196
  if (!chunkBuffers.has(batchId)) chunkBuffers.set(batchId, {
@@ -3190,7 +3209,7 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
3190
3209
  traceId,
3191
3210
  events
3192
3211
  }).catch((error) => {
3193
- logger$23.debug("Failed to send events: " + require_utils.errorMessage(error));
3212
+ logger$25.debug("Failed to send events: " + require_utils.errorMessage(error));
3194
3213
  });
3195
3214
  chunkBuffers.delete(batchId);
3196
3215
  }
@@ -3198,16 +3217,16 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
3198
3217
  const toDelete = [];
3199
3218
  for (const [bid, buffer] of chunkBuffers.entries()) if (currentTime - buffer.timestamp > OLD_BUFFER_TIMEOUT) toDelete.push(bid);
3200
3219
  for (const bid of toDelete) {
3201
- logger$23.debug(`Cleaning up incomplete chunk buffer: ${bid}`);
3220
+ logger$25.debug(`Cleaning up incomplete chunk buffer: ${bid}`);
3202
3221
  chunkBuffers.delete(bid);
3203
3222
  }
3204
3223
  } catch (error) {
3205
- logger$23.debug("Could not send events: " + require_utils.errorMessage(error));
3224
+ logger$25.debug("Could not send events: " + require_utils.errorMessage(error));
3206
3225
  }
3207
3226
  }
3208
3227
  //#endregion
3209
3228
  //#region src/browser/playwright.ts
3210
- const logger$22 = require_utils.initializeLogger();
3229
+ const logger$24 = require_utils.initializeLogger();
3211
3230
  var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
3212
3231
  constructor(client, sessionRecordingOptions) {
3213
3232
  super("@lmnr/playwright-instrumentation", require_utils.version, { enabled: true });
@@ -3315,7 +3334,7 @@ var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.Ins
3315
3334
  try {
3316
3335
  await injectSessionRecorder(page, this._sessionRecordingOptions);
3317
3336
  } catch (error) {
3318
- logger$22.error("Error in onLoad handler: " + require_utils.errorMessage(error));
3337
+ logger$24.error("Error in onLoad handler: " + require_utils.errorMessage(error));
3319
3338
  }
3320
3339
  });
3321
3340
  const chunkBuffers = /* @__PURE__ */ new Map();
@@ -3325,7 +3344,7 @@ var PlaywrightInstrumentation = class extends _opentelemetry_instrumentation.Ins
3325
3344
  await sendEvents(chunk, this._client, chunkBuffers, sessionId, traceId);
3326
3345
  });
3327
3346
  } catch (error) {
3328
- logger$22.debug("Could not expose function lmnrSendEvents: " + require_utils.errorMessage(error));
3347
+ logger$24.debug("Could not expose function lmnrSendEvents: " + require_utils.errorMessage(error));
3329
3348
  }
3330
3349
  }
3331
3350
  };
@@ -3750,7 +3769,7 @@ var StagehandV2Instrumentation = class extends _opentelemetry_instrumentation.In
3750
3769
  };
3751
3770
  //#endregion
3752
3771
  //#region src/browser/puppeteer.ts
3753
- const logger$21 = require_utils.initializeLogger();
3772
+ const logger$23 = require_utils.initializeLogger();
3754
3773
  var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
3755
3774
  constructor(client, sessionRecordingOptions) {
3756
3775
  super("@lmnr/puppeteer-instrumentation", require_utils.version, { enabled: true });
@@ -3795,10 +3814,10 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
3795
3814
  context.on("targetcreated", (target) => {
3796
3815
  target.page().then((page) => {
3797
3816
  if (page) plugin.patchPage(page, sessionId).catch((error) => {
3798
- logger$21.error("Failed to patch page: " + require_utils.errorMessage(error));
3817
+ logger$23.error("Failed to patch page: " + require_utils.errorMessage(error));
3799
3818
  });
3800
3819
  }).catch((error) => {
3801
- logger$21.error("Failed to patch page: " + require_utils.errorMessage(error));
3820
+ logger$23.error("Failed to patch page: " + require_utils.errorMessage(error));
3802
3821
  });
3803
3822
  });
3804
3823
  await Promise.all((await context.pages()).map((page) => plugin.patchPage(page, sessionId)));
@@ -3816,19 +3835,19 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
3816
3835
  context.on("targetcreated", (target) => {
3817
3836
  target.page().then((page) => {
3818
3837
  if (page) plugin.patchPage(page, sessionId).catch((error) => {
3819
- logger$21.error("Failed to patch page: " + require_utils.errorMessage(error));
3838
+ logger$23.error("Failed to patch page: " + require_utils.errorMessage(error));
3820
3839
  });
3821
3840
  }).catch((error) => {
3822
- logger$21.error("Failed to patch page: " + require_utils.errorMessage(error));
3841
+ logger$23.error("Failed to patch page: " + require_utils.errorMessage(error));
3823
3842
  });
3824
3843
  });
3825
3844
  context.on("targetchanged", (target) => {
3826
3845
  target.page().then((page) => {
3827
3846
  if (page) plugin.patchPage(page, sessionId).catch((error) => {
3828
- logger$21.error("Failed to patch page: " + require_utils.errorMessage(error));
3847
+ logger$23.error("Failed to patch page: " + require_utils.errorMessage(error));
3829
3848
  });
3830
3849
  }).catch((error) => {
3831
- logger$21.error("Failed to patch page: " + require_utils.errorMessage(error));
3850
+ logger$23.error("Failed to patch page: " + require_utils.errorMessage(error));
3832
3851
  });
3833
3852
  });
3834
3853
  for (const page of await context.pages()) await plugin.patchPage(page, sessionId);
@@ -3852,7 +3871,7 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
3852
3871
  const traceId = otelTraceId ? require_utils.otelTraceIdToUUID(otelTraceId) : require_utils.NIL_UUID;
3853
3872
  page.on("domcontentloaded", () => {
3854
3873
  injectSessionRecorder(page, this._sessionRecordingOptions).catch((error) => {
3855
- logger$21.error("Error in onLoad handler: " + require_utils.errorMessage(error));
3874
+ logger$23.error("Error in onLoad handler: " + require_utils.errorMessage(error));
3856
3875
  });
3857
3876
  });
3858
3877
  await injectSessionRecorder(page, this._sessionRecordingOptions);
@@ -3862,13 +3881,13 @@ var PuppeteerInstrumentation = class extends _opentelemetry_instrumentation.Inst
3862
3881
  await sendEvents(chunk, this._client, chunkBuffers, sessionId, traceId);
3863
3882
  });
3864
3883
  } catch (error) {
3865
- logger$21.debug("Could not expose function lmnrSendEvents: " + require_utils.errorMessage(error));
3884
+ logger$23.debug("Could not expose function lmnrSendEvents: " + require_utils.errorMessage(error));
3866
3885
  }
3867
3886
  }
3868
3887
  };
3869
3888
  //#endregion
3870
3889
  //#region src/browser/stagehand/v3/constants.ts
3871
- const logger$20 = require_utils.initializeLogger();
3890
+ const logger$22 = require_utils.initializeLogger();
3872
3891
  const CDP_OPERATION_TIMEOUT_MS = 1e4;
3873
3892
  const SKIP_URL_PATTERNS = [
3874
3893
  "about:blank",
@@ -3919,7 +3938,7 @@ async function getOrCreateIsolatedWorld(page) {
3919
3938
  frameId
3920
3939
  };
3921
3940
  } catch (error) {
3922
- logger$20.debug("Failed to create isolated world: " + require_utils.errorMessage(error));
3941
+ logger$22.debug("Failed to create isolated world: " + require_utils.errorMessage(error));
3923
3942
  return null;
3924
3943
  }
3925
3944
  }
@@ -3936,7 +3955,7 @@ async function isRecorderPresent(page, contextId) {
3936
3955
  if (!result) return true;
3937
3956
  return result.result?.value === true;
3938
3957
  } catch (error) {
3939
- logger$20.debug("Failed to check if recorder is present: " + require_utils.errorMessage(error));
3958
+ logger$22.debug("Failed to check if recorder is present: " + require_utils.errorMessage(error));
3940
3959
  return true;
3941
3960
  }
3942
3961
  }
@@ -3949,21 +3968,21 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
3949
3968
  try {
3950
3969
  url = page.url();
3951
3970
  } catch (error) {
3952
- logger$20.debug("Failed to get page URL, page might be closed: " + require_utils.errorMessage(error));
3971
+ logger$22.debug("Failed to get page URL, page might be closed: " + require_utils.errorMessage(error));
3953
3972
  return null;
3954
3973
  }
3955
3974
  if (shouldSkipUrl(url)) {
3956
- logger$20.debug(`Skipping recorder injection for URL: ${url}`);
3975
+ logger$22.debug(`Skipping recorder injection for URL: ${url}`);
3957
3976
  return null;
3958
3977
  }
3959
3978
  const worldResult = await getOrCreateIsolatedWorld(page);
3960
3979
  if (!worldResult) {
3961
- logger$20.debug("Failed to get isolated world for page");
3980
+ logger$22.debug("Failed to get isolated world for page");
3962
3981
  return null;
3963
3982
  }
3964
3983
  const { contextId, frameId } = worldResult;
3965
3984
  if (await isRecorderPresent(page, contextId)) {
3966
- logger$20.debug("Recorder already present, skipping injection");
3985
+ logger$22.debug("Recorder already present, skipping injection");
3967
3986
  state.contextIdToSession.set(contextId, {
3968
3987
  sessionId: state.sessionId,
3969
3988
  traceId: state.traceId
@@ -3976,7 +3995,7 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
3976
3995
  contextId
3977
3996
  });
3978
3997
  } catch (error) {
3979
- logger$20.debug("Failed to inject rrweb: " + require_utils.errorMessage(error));
3998
+ logger$22.debug("Failed to inject rrweb: " + require_utils.errorMessage(error));
3980
3999
  return null;
3981
4000
  }
3982
4001
  const optionsJson = JSON.stringify(sessionRecordingOptions ?? {});
@@ -3987,14 +4006,14 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
3987
4006
  contextId
3988
4007
  });
3989
4008
  } catch (error) {
3990
- logger$20.debug("Failed to inject recording setup: " + require_utils.errorMessage(error));
4009
+ logger$22.debug("Failed to inject recording setup: " + require_utils.errorMessage(error));
3991
4010
  return null;
3992
4011
  }
3993
4012
  try {
3994
4013
  await sendCDP(page, "Runtime.addBinding", { name: "lmnrSendEvents" });
3995
- logger$20.debug(`Added binding 'lmnrSendEvents' for page ${frameId}, context ${contextId}`);
4014
+ logger$22.debug(`Added binding 'lmnrSendEvents' for page ${frameId}, context ${contextId}`);
3996
4015
  } catch (error) {
3997
- logger$20.debug("Binding may already exist: " + require_utils.errorMessage(error));
4016
+ logger$22.debug("Binding may already exist: " + require_utils.errorMessage(error));
3998
4017
  }
3999
4018
  if (bindingHandler) try {
4000
4019
  const pageTargetId = page.targetId();
@@ -4004,26 +4023,26 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
4004
4023
  const sessionTyped = session;
4005
4024
  if (sessionTyped.on) {
4006
4025
  sessionTyped.on("Runtime.bindingCalled", bindingHandler);
4007
- logger$20.debug(`Set up binding handler on session ${sessionId}`);
4026
+ logger$22.debug(`Set up binding handler on session ${sessionId}`);
4008
4027
  }
4009
4028
  } catch (error) {
4010
- logger$20.debug(`Failed to set up binding handler on session ${sessionId}: ` + require_utils.errorMessage(error));
4029
+ logger$22.debug(`Failed to set up binding handler on session ${sessionId}: ` + require_utils.errorMessage(error));
4011
4030
  }
4012
4031
  state.pageSessionHandlers.set(pageTargetId, bindingHandler);
4013
4032
  }
4014
4033
  } catch (error) {
4015
- logger$20.debug("Failed to set up binding handler: " + require_utils.errorMessage(error));
4034
+ logger$22.debug("Failed to set up binding handler: " + require_utils.errorMessage(error));
4016
4035
  }
4017
4036
  state.contextIdToSession.set(contextId, {
4018
4037
  sessionId: state.sessionId,
4019
4038
  traceId: state.traceId
4020
4039
  });
4021
- logger$20.debug(`Registered context mapping: contextId=${contextId}, sessionId=${state.sessionId}`);
4040
+ logger$22.debug(`Registered context mapping: contextId=${contextId}, sessionId=${state.sessionId}`);
4022
4041
  state.instrumentedPageIds.add(frameId);
4023
- logger$20.debug(`Successfully injected recorder into page ${frameId}`);
4042
+ logger$22.debug(`Successfully injected recorder into page ${frameId}`);
4024
4043
  return contextId;
4025
4044
  } catch (error) {
4026
- logger$20.debug("Error injecting recorder: " + require_utils.errorMessage(error));
4045
+ logger$22.debug("Error injecting recorder: " + require_utils.errorMessage(error));
4027
4046
  return null;
4028
4047
  }
4029
4048
  }
@@ -4037,13 +4056,13 @@ function createBindingHandler(state) {
4037
4056
  if (event.name !== "lmnrSendEvents") return;
4038
4057
  const sessionInfo = state.contextIdToSession.get(event.executionContextId);
4039
4058
  if (!sessionInfo) {
4040
- logger$20.debug("No session info found for context ID: " + event.executionContextId);
4059
+ logger$22.debug("No session info found for context ID: " + event.executionContextId);
4041
4060
  if (state.contextIdToSession.size > 0) {
4042
4061
  const [, fallbackInfo] = state.contextIdToSession.entries().next().value;
4043
4062
  if (fallbackInfo) try {
4044
4063
  sendEvents(JSON.parse(event.payload), state.client, state.chunkBuffers, fallbackInfo.sessionId, fallbackInfo.traceId);
4045
4064
  } catch (error) {
4046
- logger$20.debug("Failed to parse binding payload: " + require_utils.errorMessage(error));
4065
+ logger$22.debug("Failed to parse binding payload: " + require_utils.errorMessage(error));
4047
4066
  }
4048
4067
  }
4049
4068
  return;
@@ -4051,7 +4070,7 @@ function createBindingHandler(state) {
4051
4070
  try {
4052
4071
  sendEvents(JSON.parse(event.payload), state.client, state.chunkBuffers, sessionInfo.sessionId, sessionInfo.traceId);
4053
4072
  } catch (error) {
4054
- logger$20.debug("Failed to handle binding event: " + require_utils.errorMessage(error));
4073
+ logger$22.debug("Failed to handle binding event: " + require_utils.errorMessage(error));
4055
4074
  }
4056
4075
  };
4057
4076
  }
@@ -4067,10 +4086,10 @@ function createTargetCreatedHandler(context, state, sessionRecordingOptions) {
4067
4086
  const pageId = page.mainFrameId();
4068
4087
  if (!state.instrumentedPageIds.has(pageId)) await injectRecorderViaCDP(page, state, context.conn, sessionRecordingOptions, state.bindingHandler ?? void 0);
4069
4088
  } catch (error) {
4070
- logger$20.debug("Error injecting recorder into new page: " + require_utils.errorMessage(error));
4089
+ logger$22.debug("Error injecting recorder into new page: " + require_utils.errorMessage(error));
4071
4090
  }
4072
4091
  } catch (error) {
4073
- logger$20.debug("Error handling target created event: " + require_utils.errorMessage(error));
4092
+ logger$22.debug("Error handling target created event: " + require_utils.errorMessage(error));
4074
4093
  }
4075
4094
  };
4076
4095
  }
@@ -4082,7 +4101,7 @@ function createTargetInfoChangedHandler(context, state, sessionRecordingOptions)
4082
4101
  if (event.targetInfo.type !== "page") return;
4083
4102
  const url = event.targetInfo.url;
4084
4103
  if (shouldSkipUrl(url)) return;
4085
- logger$20.debug(`Target URL changed to ${url}, checking if recorder injection needed`);
4104
+ logger$22.debug(`Target URL changed to ${url}, checking if recorder injection needed`);
4086
4105
  await new Promise((resolve) => setTimeout(resolve, 150));
4087
4106
  try {
4088
4107
  for (const page of context.pages()) if (page.targetId() === event.targetInfo.targetId) {
@@ -4090,7 +4109,7 @@ function createTargetInfoChangedHandler(context, state, sessionRecordingOptions)
4090
4109
  break;
4091
4110
  }
4092
4111
  } catch (error) {
4093
- logger$20.debug("Error handling target info change: " + require_utils.errorMessage(error));
4112
+ logger$22.debug("Error handling target info change: " + require_utils.errorMessage(error));
4094
4113
  }
4095
4114
  };
4096
4115
  }
@@ -4251,12 +4270,12 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
4251
4270
  */
4252
4271
  async setupSessionRecording(stagehandInstance, sessionId, traceId) {
4253
4272
  if (!this._client) {
4254
- logger$20.debug("No Laminar client available, skipping session recording setup");
4273
+ logger$22.debug("No Laminar client available, skipping session recording setup");
4255
4274
  return;
4256
4275
  }
4257
4276
  const context = stagehandInstance.context;
4258
4277
  if (!context || !context.conn) {
4259
- logger$20.debug("No context or connection available, skipping session recording setup");
4278
+ logger$22.debug("No context or connection available, skipping session recording setup");
4260
4279
  return;
4261
4280
  }
4262
4281
  const recorderState = {
@@ -4286,11 +4305,11 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
4286
4305
  for (const page of pages) try {
4287
4306
  if (await injectRecorderViaCDP(page, recorderState, context.conn, this._sessionRecordingOptions, bindingHandler) !== null) injectedCount++;
4288
4307
  } catch (error) {
4289
- logger$20.debug("Error injecting recorder into page: " + require_utils.errorMessage(error));
4308
+ logger$22.debug("Error injecting recorder into page: " + require_utils.errorMessage(error));
4290
4309
  }
4291
- logger$20.debug(`Injected session recorder into ${injectedCount} of ${pages.length} existing page(s)`);
4310
+ logger$22.debug(`Injected session recorder into ${injectedCount} of ${pages.length} existing page(s)`);
4292
4311
  } catch (error) {
4293
- logger$20.debug("Error accessing pages for recorder injection: " + require_utils.errorMessage(error));
4312
+ logger$22.debug("Error accessing pages for recorder injection: " + require_utils.errorMessage(error));
4294
4313
  }
4295
4314
  }
4296
4315
  patchStagehandClose() {
@@ -4320,12 +4339,12 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
4320
4339
  if (recorderState.targetCreatedHandler) try {
4321
4340
  context.conn.off("Target.targetCreated", recorderState.targetCreatedHandler);
4322
4341
  } catch (error) {
4323
- logger$20.debug("Error removing target created handler: " + require_utils.errorMessage(error));
4342
+ logger$22.debug("Error removing target created handler: " + require_utils.errorMessage(error));
4324
4343
  }
4325
4344
  if (recorderState.targetInfoChangedHandler) try {
4326
4345
  context.conn.off("Target.targetInfoChanged", recorderState.targetInfoChangedHandler);
4327
4346
  } catch (error) {
4328
- logger$20.debug("Error removing target info changed handler: " + require_utils.errorMessage(error));
4347
+ logger$22.debug("Error removing target info changed handler: " + require_utils.errorMessage(error));
4329
4348
  }
4330
4349
  }
4331
4350
  recorderState.contextIdToSession.clear();
@@ -4336,7 +4355,7 @@ var StagehandInstrumentation = class extends _opentelemetry_instrumentation.Inst
4336
4355
  recorderState.targetCreatedHandler = null;
4337
4356
  recorderState.targetInfoChangedHandler = null;
4338
4357
  this.stagehandInstanceToRecorderState.delete(stagehandInstance);
4339
- logger$20.debug("Cleaned up session recording for Stagehand instance");
4358
+ logger$22.debug("Cleaned up session recording for Stagehand instance");
4340
4359
  }
4341
4360
  patchStagehandGlobalMethod(methodName, sessionId, parentSpan) {
4342
4361
  return (original) => async function method(...args) {
@@ -4687,7 +4706,7 @@ function extractToolDefinitions(config) {
4687
4706
  * Also used by the google-aiplatform (Vertex AI) instrumentation, which
4688
4707
  * reshapes its requests into the same `{model, contents, config}` form.
4689
4708
  */
4690
- function setRequestAttributes$5(span, params, traceContent, system = "gemini") {
4709
+ function setRequestAttributes$6(span, params, traceContent, system = "gemini") {
4691
4710
  safeSetAttribute$2(span, LLM_SYSTEM, system);
4692
4711
  safeSetAttribute$2(span, LLM_REQUEST_MODEL, params?.model);
4693
4712
  const config = params?.config;
@@ -4714,7 +4733,7 @@ function setRequestAttributes$5(span, params, traceContent, system = "gemini") {
4714
4733
  /**
4715
4734
  * Set response attributes on a span from a GenerateContentResponse.
4716
4735
  */
4717
- function setResponseAttributes$5(span, response, traceContent) {
4736
+ function setResponseAttributes$6(span, response, traceContent) {
4718
4737
  if (!response) return;
4719
4738
  safeSetAttribute$2(span, LLM_RESPONSE_MODEL, response.modelVersion);
4720
4739
  const usage = response.usageMetadata;
@@ -4816,7 +4835,7 @@ function wrapStreamingResponse(span, asyncGen, traceContent) {
4816
4835
  try {
4817
4836
  if (modelVersion !== void 0 || role !== void 0 || accumulatedParts.length > 0 || sawUsageMetadata) {
4818
4837
  const mergedParts = mergeTextParts(accumulatedParts);
4819
- setResponseAttributes$5(span, {
4838
+ setResponseAttributes$6(span, {
4820
4839
  modelVersion,
4821
4840
  candidates: [{ content: {
4822
4841
  role: role ?? "model",
@@ -4847,22 +4866,22 @@ function wrapStreamingResponse(span, asyncGen, traceContent) {
4847
4866
  //#endregion
4848
4867
  //#region src/opentelemetry-lib/instrumentation/anthropic/utils.ts
4849
4868
  const ANTHROPIC_SYSTEM = "anthropic";
4850
- const INPUT_MESSAGES$2 = "gen_ai.input.messages";
4851
- const OUTPUT_MESSAGES$2 = "gen_ai.output.messages";
4869
+ const INPUT_MESSAGES$3 = "gen_ai.input.messages";
4870
+ const OUTPUT_MESSAGES$3 = "gen_ai.output.messages";
4852
4871
  const createStreamState$1 = () => ({
4853
4872
  usage: {},
4854
4873
  blocks: [],
4855
4874
  completion: ""
4856
4875
  });
4857
- const toJson$1 = (value) => {
4876
+ const toJson$2 = (value) => {
4858
4877
  if (value === void 0 || value === null) return void 0;
4859
4878
  return JSON.stringify(value);
4860
4879
  };
4861
4880
  const extractStructuredOutputSchema$1 = (params) => {
4862
4881
  const outputFormat = params?.output_format;
4863
- if (outputFormat && typeof outputFormat === "object") return toJson$1(outputFormat.schema ?? outputFormat);
4882
+ if (outputFormat && typeof outputFormat === "object") return toJson$2(outputFormat.schema ?? outputFormat);
4864
4883
  const schema = params?.output_config?.format?.schema;
4865
- if (schema && typeof schema === "object") return toJson$1(schema);
4884
+ if (schema && typeof schema === "object") return toJson$2(schema);
4866
4885
  };
4867
4886
  const buildInputMessages$1 = (params) => {
4868
4887
  if (params?.prompt !== void 0 && params?.prompt !== null) return [{
@@ -4878,7 +4897,7 @@ const buildInputMessages$1 = (params) => {
4878
4897
  messages.push(...params.messages);
4879
4898
  return messages;
4880
4899
  };
4881
- const setRequestAttributes$4 = (span, params, traceContent) => {
4900
+ const setRequestAttributes$5 = (span, params, traceContent) => {
4882
4901
  safeSetAttribute$2(span, "gen_ai.system", ANTHROPIC_SYSTEM);
4883
4902
  safeSetAttribute$2(span, "gen_ai.request.model", params?.model);
4884
4903
  safeSetAttribute$2(span, "gen_ai.request.max_tokens", params?.max_tokens ?? params?.max_tokens_to_sample);
@@ -4889,8 +4908,8 @@ const setRequestAttributes$4 = (span, params, traceContent) => {
4889
4908
  safeSetAttribute$2(span, "llm.is_streaming", params?.stream);
4890
4909
  safeSetAttribute$2(span, "anthropic.request.service_tier", params?.service_tier);
4891
4910
  if (traceContent) {
4892
- safeSetAttribute$2(span, INPUT_MESSAGES$2, toJson$1(buildInputMessages$1(params)));
4893
- safeSetAttribute$2(span, "gen_ai.tool.definitions", toJson$1(params?.tools));
4911
+ safeSetAttribute$2(span, INPUT_MESSAGES$3, toJson$2(buildInputMessages$1(params)));
4912
+ safeSetAttribute$2(span, "gen_ai.tool.definitions", toJson$2(params?.tools));
4894
4913
  }
4895
4914
  safeSetAttribute$2(span, "gen_ai.request.structured_output_schema", extractStructuredOutputSchema$1(params));
4896
4915
  };
@@ -4910,7 +4929,7 @@ const setUsageAttributes$1 = (span, usage, includeTotal) => {
4910
4929
  /**
4911
4930
  * Response attributes for a non-streaming `Message` (or legacy `Completion`).
4912
4931
  */
4913
- const setResponseAttributes$4 = (span, response, traceContent) => {
4932
+ const setResponseAttributes$5 = (span, response, traceContent) => {
4914
4933
  if (!response || typeof response !== "object") return;
4915
4934
  safeSetAttribute$2(span, "gen_ai.response.model", response.model);
4916
4935
  safeSetAttribute$2(span, "gen_ai.response.id", response.id);
@@ -4927,7 +4946,7 @@ const setResponseAttributes$4 = (span, response, traceContent) => {
4927
4946
  text: response.completion
4928
4947
  });
4929
4948
  else if (Array.isArray(response.content)) output.content.push(...response.content);
4930
- safeSetAttribute$2(span, OUTPUT_MESSAGES$2, toJson$1([output]));
4949
+ safeSetAttribute$2(span, OUTPUT_MESSAGES$3, toJson$2([output]));
4931
4950
  }
4932
4951
  span.setStatus({ code: _opentelemetry_api.SpanStatusCode.OK });
4933
4952
  };
@@ -5020,14 +5039,14 @@ const setStreamingResponseAttributes = (span, state, traceContent) => {
5020
5039
  content: buildStreamedContent(state)
5021
5040
  };
5022
5041
  if (state.stopReason) output.stop_reason = state.stopReason;
5023
- safeSetAttribute$2(span, OUTPUT_MESSAGES$2, toJson$1([output]));
5042
+ safeSetAttribute$2(span, OUTPUT_MESSAGES$3, toJson$2([output]));
5024
5043
  }
5025
5044
  };
5026
5045
  //#endregion
5027
5046
  //#region src/opentelemetry-lib/instrumentation/anthropic/index.ts
5028
- const logger$19 = require_utils.initializeLogger();
5029
- const PATCH_DATA_SYMBOL$3 = Symbol("lmnr.anthropic.patchData");
5030
- const hasOwnPatchData$2 = (proto) => Object.getOwnPropertyDescriptor(proto, PATCH_DATA_SYMBOL$3) !== void 0;
5047
+ const logger$21 = require_utils.initializeLogger();
5048
+ const PATCH_DATA_SYMBOL$4 = Symbol("lmnr.anthropic.patchData");
5049
+ const hasOwnPatchData$3 = (proto) => Object.getOwnPropertyDescriptor(proto, PATCH_DATA_SYMBOL$4) !== void 0;
5031
5050
  const markSpanError$3 = (span, error) => {
5032
5051
  span.recordException(error);
5033
5052
  span.setAttribute("error.type", error?.constructor?.name ?? "Error");
@@ -5040,7 +5059,7 @@ const safely$3 = (fn) => {
5040
5059
  try {
5041
5060
  fn();
5042
5061
  } catch (error) {
5043
- logger$19.debug(`Failed to set anthropic span attributes: ${String(error)}`);
5062
+ logger$21.debug(`Failed to set anthropic span attributes: ${String(error)}`);
5044
5063
  }
5045
5064
  };
5046
5065
  const isAsyncIterable$3 = (value) => value !== null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function";
@@ -5091,9 +5110,9 @@ var AnthropicInstrumentation = class extends _opentelemetry_instrumentation.Inst
5091
5110
  unpatch(moduleExports) {
5092
5111
  _opentelemetry_api.diag.debug("Unpatching @anthropic-ai/sdk");
5093
5112
  for (const proto of this.resourcePrototypes(moduleExports)) {
5094
- if (!proto || !hasOwnPatchData$2(proto)) continue;
5095
- proto.create = proto[PATCH_DATA_SYMBOL$3].original;
5096
- delete proto[PATCH_DATA_SYMBOL$3];
5113
+ if (!proto || !hasOwnPatchData$3(proto)) continue;
5114
+ proto.create = proto[PATCH_DATA_SYMBOL$4].original;
5115
+ delete proto[PATCH_DATA_SYMBOL$4];
5097
5116
  }
5098
5117
  }
5099
5118
  /**
@@ -5115,15 +5134,15 @@ var AnthropicInstrumentation = class extends _opentelemetry_instrumentation.Inst
5115
5134
  */
5116
5135
  patchCreate(proto, spanName) {
5117
5136
  if (!proto || typeof proto.create !== "function") return;
5118
- if (hasOwnPatchData$2(proto)) {
5119
- proto[PATCH_DATA_SYMBOL$3].traceContent = this.traceContent;
5137
+ if (hasOwnPatchData$3(proto)) {
5138
+ proto[PATCH_DATA_SYMBOL$4].traceContent = this.traceContent;
5120
5139
  return;
5121
5140
  }
5122
5141
  const patchData = {
5123
5142
  traceContent: this.traceContent,
5124
5143
  original: proto.create
5125
5144
  };
5126
- Object.defineProperty(proto, PATCH_DATA_SYMBOL$3, {
5145
+ Object.defineProperty(proto, PATCH_DATA_SYMBOL$4, {
5127
5146
  value: patchData,
5128
5147
  writable: true,
5129
5148
  configurable: true,
@@ -5140,7 +5159,7 @@ const wrapCreate = (patchData, spanName) => function(params, ...rest) {
5140
5159
  name: spanName,
5141
5160
  spanType: "LLM"
5142
5161
  });
5143
- safely$3(() => setRequestAttributes$4(span, params, traceContent));
5162
+ safely$3(() => setRequestAttributes$5(span, params, traceContent));
5144
5163
  let result;
5145
5164
  try {
5146
5165
  result = Laminar.withSpan(span, () => ({ value: original.call(this, params, ...rest) })).value;
@@ -5164,7 +5183,7 @@ const wrapCreate = (patchData, spanName) => function(params, ...rest) {
5164
5183
  return data;
5165
5184
  }
5166
5185
  ended = true;
5167
- safely$3(() => setResponseAttributes$4(span, data, traceContent));
5186
+ safely$3(() => setResponseAttributes$5(span, data, traceContent));
5168
5187
  span.end();
5169
5188
  return data;
5170
5189
  };
@@ -5214,8 +5233,8 @@ const instrumentStream$2 = (stream, span, traceContent) => {
5214
5233
  //#endregion
5215
5234
  //#region src/opentelemetry-lib/instrumentation/cohere/utils.ts
5216
5235
  const COHERE_SYSTEM = "cohere";
5217
- const INPUT_MESSAGES$1 = "gen_ai.input.messages";
5218
- const OUTPUT_MESSAGES$1 = "gen_ai.output.messages";
5236
+ const INPUT_MESSAGES$2 = "gen_ai.input.messages";
5237
+ const OUTPUT_MESSAGES$2 = "gen_ai.output.messages";
5219
5238
  const OPERATION_NAMES = {
5220
5239
  chat: "chat",
5221
5240
  completion: "text_completion",
@@ -5230,7 +5249,7 @@ const V1_ROLES = {
5230
5249
  };
5231
5250
  const asList = (value) => Array.isArray(value) ? value : [];
5232
5251
  const asInt = (value) => typeof value === "number" && Number.isFinite(value) ? Math.trunc(value) : void 0;
5233
- const maybeJson = (value) => {
5252
+ const maybeJson$1 = (value) => {
5234
5253
  if (typeof value !== "string") return value;
5235
5254
  try {
5236
5255
  return JSON.parse(value);
@@ -5298,7 +5317,7 @@ const v2ToolCallParts = (toolCalls) => asList(toolCalls).map((toolCall) => {
5298
5317
  name: toolCall?.function?.name ?? ""
5299
5318
  };
5300
5319
  const args = toolCall?.function?.arguments;
5301
- if (args !== void 0 && args !== null) part.arguments = maybeJson(args);
5320
+ if (args !== void 0 && args !== null) part.arguments = maybeJson$1(args);
5302
5321
  return part;
5303
5322
  });
5304
5323
  const v1ToolCallParts = (toolCalls) => asList(toolCalls).map((toolCall) => ({
@@ -5388,7 +5407,7 @@ const toolDefinitions = (tools) => asList(tools).map((tool) => {
5388
5407
  if (parameters) definition.parameters = parameters;
5389
5408
  return definition;
5390
5409
  });
5391
- const setRequestAttributes$3 = (span, params, requestType, isV2, isStreaming, traceContent) => {
5410
+ const setRequestAttributes$4 = (span, params, requestType, isV2, isStreaming, traceContent) => {
5392
5411
  safeSetAttribute$2(span, "gen_ai.system", COHERE_SYSTEM);
5393
5412
  safeSetAttribute$2(span, "gen_ai.operation.name", OPERATION_NAMES[requestType]);
5394
5413
  safeSetAttribute$2(span, "gen_ai.request.model", params?.model);
@@ -5413,12 +5432,12 @@ const setRequestAttributes$3 = (span, params, requestType, isV2, isStreaming, tr
5413
5432
  }] : [];
5414
5433
  else if (requestType === "rerank") messages = rerankInput(params);
5415
5434
  else messages = embedInput(params);
5416
- if (messages.length > 0) span.setAttribute(INPUT_MESSAGES$1, JSON.stringify(messages));
5435
+ if (messages.length > 0) span.setAttribute(INPUT_MESSAGES$2, JSON.stringify(messages));
5417
5436
  };
5418
5437
  /**
5419
5438
  * `usage` (v2) / `meta` (v1): actual `tokens`, falling back to `billedUnits`.
5420
5439
  */
5421
- const setUsage = (span, usage) => {
5440
+ const setUsage$1 = (span, usage) => {
5422
5441
  const inputTokens = asInt(usage?.tokens?.inputTokens) ?? asInt(usage?.billedUnits?.inputTokens);
5423
5442
  const outputTokens = asInt(usage?.tokens?.outputTokens) ?? asInt(usage?.billedUnits?.outputTokens);
5424
5443
  safeSetAttribute$2(span, "gen_ai.usage.input_tokens", inputTokens);
@@ -5454,9 +5473,9 @@ const rerankOutput = (response) => {
5454
5473
  parts
5455
5474
  }] : [];
5456
5475
  };
5457
- const setResponseAttributes$3 = (span, response, requestType, isV2, traceContent) => {
5476
+ const setResponseAttributes$4 = (span, response, requestType, isV2, traceContent) => {
5458
5477
  safeSetAttribute$2(span, "gen_ai.response.id", response?.responseId ?? response?.id);
5459
- setUsage(span, response?.usage ?? response?.meta);
5478
+ setUsage$1(span, response?.usage ?? response?.meta);
5460
5479
  let output = [];
5461
5480
  if (requestType === "chat") {
5462
5481
  const message = isV2 ? v2ChatOutput(response) : v1ChatOutput(response);
@@ -5468,7 +5487,7 @@ const setResponseAttributes$3 = (span, response, requestType, isV2, traceContent
5468
5487
  output = [message];
5469
5488
  } else if (requestType === "completion") output = completionOutput(response);
5470
5489
  else if (requestType === "rerank") output = rerankOutput(response);
5471
- if (output.length > 0 && traceContent) span.setAttribute(OUTPUT_MESSAGES$1, JSON.stringify(output));
5490
+ if (output.length > 0 && traceContent) span.setAttribute(OUTPUT_MESSAGES$2, JSON.stringify(output));
5472
5491
  };
5473
5492
  /**
5474
5493
  * v1 `chatStream`: the `stream-end` event carries the full response.
@@ -5585,8 +5604,8 @@ const createV2ChatStreamAccumulator = () => {
5585
5604
  };
5586
5605
  //#endregion
5587
5606
  //#region src/opentelemetry-lib/instrumentation/cohere/index.ts
5588
- const logger$18 = require_utils.initializeLogger();
5589
- const PATCH_DATA_SYMBOL$2 = Symbol("lmnr.cohere.patchData");
5607
+ const logger$20 = require_utils.initializeLogger();
5608
+ const PATCH_DATA_SYMBOL$3 = Symbol("lmnr.cohere.patchData");
5590
5609
  const SPAN_NAMES = {
5591
5610
  chat: "cohere.chat",
5592
5611
  completion: "cohere.completion",
@@ -5642,7 +5661,7 @@ const V2_METHODS = [
5642
5661
  streaming: false
5643
5662
  }
5644
5663
  ];
5645
- const ownPatchData = (proto) => Object.getOwnPropertyDescriptor(proto, PATCH_DATA_SYMBOL$2)?.value;
5664
+ const ownPatchData = (proto) => Object.getOwnPropertyDescriptor(proto, PATCH_DATA_SYMBOL$3)?.value;
5646
5665
  const markSpanError$2 = (span, error) => {
5647
5666
  span.recordException(error);
5648
5667
  span.setAttribute("error.type", error?.constructor?.name ?? "Error");
@@ -5658,7 +5677,7 @@ const safely$2 = (fn) => {
5658
5677
  try {
5659
5678
  fn();
5660
5679
  } catch (error) {
5661
- logger$18.debug(`Failed to set cohere span attributes: ${String(error)}`);
5680
+ logger$20.debug(`Failed to set cohere span attributes: ${String(error)}`);
5662
5681
  }
5663
5682
  };
5664
5683
  const isAsyncIterable$2 = (value) => value !== null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function";
@@ -5765,7 +5784,7 @@ var CohereInstrumentation = class extends _opentelemetry_instrumentation.Instrum
5765
5784
  }
5766
5785
  if (!patched) {
5767
5786
  patched = {};
5768
- Object.defineProperty(proto, PATCH_DATA_SYMBOL$2, {
5787
+ Object.defineProperty(proto, PATCH_DATA_SYMBOL$3, {
5769
5788
  value: patched,
5770
5789
  writable: true,
5771
5790
  configurable: true,
@@ -5790,7 +5809,7 @@ const wrapMethod$1 = (patchData) => function(request, ...rest) {
5790
5809
  name: SPAN_NAMES[requestType],
5791
5810
  spanType: "LLM"
5792
5811
  });
5793
- safely$2(() => setRequestAttributes$3(span, request, requestType, isV2, streaming, traceContent));
5812
+ safely$2(() => setRequestAttributes$4(span, request, requestType, isV2, streaming, traceContent));
5794
5813
  let result;
5795
5814
  try {
5796
5815
  result = Laminar.withSpan(span, () => ({ value: original.call(this, request, ...rest) })).value;
@@ -5814,7 +5833,7 @@ const wrapMethod$1 = (patchData) => function(request, ...rest) {
5814
5833
  instrumentStream$1(data, span, accumulator, isV2, traceContent);
5815
5834
  return data;
5816
5835
  }
5817
- safely$2(() => setResponseAttributes$3(span, data, requestType, isV2, traceContent));
5836
+ safely$2(() => setResponseAttributes$4(span, data, requestType, isV2, traceContent));
5818
5837
  span.end();
5819
5838
  return data;
5820
5839
  };
@@ -5839,7 +5858,7 @@ const instrumentStream$1 = (stream, span, accumulator, isV2, traceContent) => {
5839
5858
  const end = (error) => {
5840
5859
  if (ended) return;
5841
5860
  ended = true;
5842
- safely$2(() => setResponseAttributes$3(span, accumulator.response(), "chat", isV2, traceContent));
5861
+ safely$2(() => setResponseAttributes$4(span, accumulator.response(), "chat", isV2, traceContent));
5843
5862
  if (error !== void 0) markSpanError$2(span, error);
5844
5863
  else span.setStatus({ code: _opentelemetry_api.SpanStatusCode.OK });
5845
5864
  span.end();
@@ -5889,7 +5908,7 @@ const fromValue = (value) => {
5889
5908
  default: return;
5890
5909
  }
5891
5910
  };
5892
- const asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
5911
+ const asRecord$1 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
5893
5912
  const asNumber = (value) => typeof value === "number" && !Number.isNaN(value) ? value : void 0;
5894
5913
  /**
5895
5914
  * Strip resource prefixes, e.g.
@@ -5910,7 +5929,7 @@ const toInputMessages = (instance) => {
5910
5929
  content: instance.prompt
5911
5930
  });
5912
5931
  if (Array.isArray(instance.messages)) for (const message of instance.messages) {
5913
- const record = asRecord(message);
5932
+ const record = asRecord$1(message);
5914
5933
  if (!record) continue;
5915
5934
  const author = typeof record.author === "string" ? record.author : "user";
5916
5935
  messages.push({
@@ -5927,7 +5946,7 @@ const toInputMessages = (instance) => {
5927
5946
  const setPredictRequestAttributes = (span, request, traceContent) => {
5928
5947
  safeSetAttribute$2(span, "gen_ai.system", VERTEX_AI_SYSTEM);
5929
5948
  safeSetAttribute$2(span, "gen_ai.request.model", lastPathSegment(request?.endpoint));
5930
- const parameters = asRecord(fromValue(request?.parameters));
5949
+ const parameters = asRecord$1(fromValue(request?.parameters));
5931
5950
  if (parameters) {
5932
5951
  safeSetAttribute$2(span, "gen_ai.request.max_tokens", asNumber(parameters.maxOutputTokens));
5933
5952
  safeSetAttribute$2(span, "gen_ai.request.temperature", asNumber(parameters.temperature));
@@ -5936,16 +5955,16 @@ const setPredictRequestAttributes = (span, request, traceContent) => {
5936
5955
  }
5937
5956
  if (!traceContent || !Array.isArray(request?.instances)) return;
5938
5957
  const messages = request.instances.flatMap((instance) => {
5939
- const record = asRecord(fromValue(instance));
5958
+ const record = asRecord$1(fromValue(instance));
5940
5959
  return record ? toInputMessages(record) : [];
5941
5960
  });
5942
5961
  if (messages.length > 0) safeSetAttribute$2(span, "gen_ai.input.messages", JSON.stringify(messages));
5943
5962
  };
5944
5963
  const predictionContent = (prediction) => {
5945
- const record = asRecord(fromValue(prediction));
5964
+ const record = asRecord$1(fromValue(prediction));
5946
5965
  if (!record) return void 0;
5947
5966
  if (typeof record.content === "string") return record.content;
5948
- const firstCandidate = Array.isArray(record.candidates) ? asRecord(record.candidates[0]) : void 0;
5967
+ const firstCandidate = Array.isArray(record.candidates) ? asRecord$1(record.candidates[0]) : void 0;
5949
5968
  if (typeof firstCandidate?.content === "string") return firstCandidate.content;
5950
5969
  };
5951
5970
  /**
@@ -5954,10 +5973,10 @@ const predictionContent = (prediction) => {
5954
5973
  const setPredictResponseAttributes = (span, response, traceContent) => {
5955
5974
  if (!response) return;
5956
5975
  safeSetAttribute$2(span, "gen_ai.response.model", lastPathSegment(response.model));
5957
- const metadata = asRecord(fromValue(response.metadata));
5958
- const tokenMetadata = asRecord(metadata?.tokenMetadata);
5959
- const inputTokens = asNumber(asRecord(tokenMetadata?.inputTokenCount)?.totalTokens);
5960
- const outputTokens = asNumber(asRecord(tokenMetadata?.outputTokenCount)?.totalTokens);
5976
+ const metadata = asRecord$1(fromValue(response.metadata));
5977
+ const tokenMetadata = asRecord$1(metadata?.tokenMetadata);
5978
+ const inputTokens = asNumber(asRecord$1(tokenMetadata?.inputTokenCount)?.totalTokens);
5979
+ const outputTokens = asNumber(asRecord$1(tokenMetadata?.outputTokenCount)?.totalTokens);
5961
5980
  safeSetAttribute$2(span, "gen_ai.usage.input_tokens", inputTokens);
5962
5981
  safeSetAttribute$2(span, "gen_ai.usage.output_tokens", outputTokens);
5963
5982
  if (inputTokens !== void 0 && outputTokens !== void 0) safeSetAttribute$2(span, "llm.usage.total_tokens", inputTokens + outputTokens);
@@ -5989,9 +6008,9 @@ const toGenAiParams = (model, request) => {
5989
6008
  };
5990
6009
  //#endregion
5991
6010
  //#region src/opentelemetry-lib/instrumentation/google-aiplatform/index.ts
5992
- const logger$17 = require_utils.initializeLogger();
5993
- const PATCH_DATA_SYMBOL$1 = Symbol("lmnr.google-aiplatform.patchData");
5994
- const hasOwnPatchData$1 = (proto) => Object.getOwnPropertyDescriptor(proto, PATCH_DATA_SYMBOL$1) !== void 0;
6011
+ const logger$19 = require_utils.initializeLogger();
6012
+ const PATCH_DATA_SYMBOL$2 = Symbol("lmnr.google-aiplatform.patchData");
6013
+ const hasOwnPatchData$2 = (proto) => Object.getOwnPropertyDescriptor(proto, PATCH_DATA_SYMBOL$2) !== void 0;
5995
6014
  const GENERATIVE_MODEL_CLASSES = ["GenerativeModel", "GenerativeModelPreview"];
5996
6015
  const markSpanError$1 = (span, error) => {
5997
6016
  span.setAttribute("error.type", error?.constructor?.name ?? "Error");
@@ -6004,7 +6023,7 @@ const safely$1 = (fn) => {
6004
6023
  try {
6005
6024
  fn();
6006
6025
  } catch (error) {
6007
- logger$17.debug(`Failed to set google-aiplatform span attributes: ${String(error)}`);
6026
+ logger$19.debug(`Failed to set google-aiplatform span attributes: ${String(error)}`);
6008
6027
  }
6009
6028
  };
6010
6029
  /**
@@ -6094,13 +6113,13 @@ var GoogleAIPlatformInstrumentation = class extends _opentelemetry_instrumentati
6094
6113
  */
6095
6114
  patchMethod(proto, method, makeWrapper) {
6096
6115
  if (!proto || typeof proto[method] !== "function") return;
6097
- if (!hasOwnPatchData$1(proto)) Object.defineProperty(proto, PATCH_DATA_SYMBOL$1, {
6116
+ if (!hasOwnPatchData$2(proto)) Object.defineProperty(proto, PATCH_DATA_SYMBOL$2, {
6098
6117
  value: {},
6099
6118
  writable: true,
6100
6119
  configurable: true,
6101
6120
  enumerable: false
6102
6121
  });
6103
- const patches = proto[PATCH_DATA_SYMBOL$1];
6122
+ const patches = proto[PATCH_DATA_SYMBOL$2];
6104
6123
  const existing = patches[method];
6105
6124
  if (existing) {
6106
6125
  existing.traceContent = this.traceContent;
@@ -6114,10 +6133,10 @@ var GoogleAIPlatformInstrumentation = class extends _opentelemetry_instrumentati
6114
6133
  proto[method] = makeWrapper(patchData.original, patchData);
6115
6134
  }
6116
6135
  unpatchMethods(proto) {
6117
- if (!proto || !hasOwnPatchData$1(proto)) return;
6118
- const patches = proto[PATCH_DATA_SYMBOL$1];
6136
+ if (!proto || !hasOwnPatchData$2(proto)) return;
6137
+ const patches = proto[PATCH_DATA_SYMBOL$2];
6119
6138
  for (const [method, patchData] of Object.entries(patches)) proto[method] = patchData.original;
6120
- delete proto[PATCH_DATA_SYMBOL$1];
6139
+ delete proto[PATCH_DATA_SYMBOL$2];
6121
6140
  }
6122
6141
  wrapGenerateContent(original, patchData) {
6123
6142
  return function(request, ...rest) {
@@ -6127,7 +6146,7 @@ var GoogleAIPlatformInstrumentation = class extends _opentelemetry_instrumentati
6127
6146
  spanType: "LLM"
6128
6147
  });
6129
6148
  const params = toGenAiParams(this, request);
6130
- safely$1(() => setRequestAttributes$5(span, params, patchData.traceContent, VERTEX_AI_SYSTEM));
6149
+ safely$1(() => setRequestAttributes$6(span, params, patchData.traceContent, VERTEX_AI_SYSTEM));
6131
6150
  return Laminar.withSpan(span, async () => {
6132
6151
  try {
6133
6152
  const result = await original.call(this, request, ...rest);
@@ -6148,7 +6167,7 @@ var GoogleAIPlatformInstrumentation = class extends _opentelemetry_instrumentati
6148
6167
  spanType: "LLM"
6149
6168
  });
6150
6169
  const params = toGenAiParams(this, request);
6151
- safely$1(() => setRequestAttributes$5(span, params, patchData.traceContent, VERTEX_AI_SYSTEM));
6170
+ safely$1(() => setRequestAttributes$6(span, params, patchData.traceContent, VERTEX_AI_SYSTEM));
6152
6171
  let result;
6153
6172
  try {
6154
6173
  result = await Laminar.withSpan(span, () => original.call(this, request, ...rest));
@@ -6212,7 +6231,7 @@ var GoogleAIPlatformInstrumentation = class extends _opentelemetry_instrumentati
6212
6231
  }
6213
6232
  };
6214
6233
  const setGenerateContentResponseAttributes = (span, response, requestModel, traceContent) => {
6215
- setResponseAttributes$5(span, response, traceContent);
6234
+ setResponseAttributes$6(span, response, traceContent);
6216
6235
  if (!response?.modelVersion) safeSetAttribute$2(span, "gen_ai.response.model", requestModel);
6217
6236
  };
6218
6237
  //#endregion
@@ -6312,11 +6331,11 @@ var GoogleGenAiInstrumentation = class extends _opentelemetry_instrumentation.In
6312
6331
  name: "gemini.generate_content",
6313
6332
  spanType: "LLM"
6314
6333
  });
6315
- setRequestAttributes$5(span, params, classPatchData.traceContent);
6334
+ setRequestAttributes$6(span, params, classPatchData.traceContent);
6316
6335
  return Laminar.withSpan(span, async () => {
6317
6336
  try {
6318
6337
  const response = await originalGenerateContent(params);
6319
- setResponseAttributes$5(span, response, classPatchData.traceContent);
6338
+ setResponseAttributes$6(span, response, classPatchData.traceContent);
6320
6339
  return response;
6321
6340
  } catch (error) {
6322
6341
  span.setAttribute("error.type", error.constructor?.name ?? "Error");
@@ -6331,7 +6350,7 @@ var GoogleGenAiInstrumentation = class extends _opentelemetry_instrumentation.In
6331
6350
  name: "gemini.generate_content_stream",
6332
6351
  spanType: "LLM"
6333
6352
  });
6334
- setRequestAttributes$5(span, params, classPatchData.traceContent);
6353
+ setRequestAttributes$6(span, params, classPatchData.traceContent);
6335
6354
  try {
6336
6355
  return wrapStreamingResponse(span, await originalGenerateContentStream(params), classPatchData.traceContent);
6337
6356
  } catch (error) {
@@ -6489,6 +6508,1053 @@ var KernelInstrumentation = class extends _opentelemetry_instrumentation.Instrum
6489
6508
  this._unwrap(moduleExports.Kernel.prototype, "app");
6490
6509
  }
6491
6510
  };
6511
+ //#endregion
6512
+ //#region src/opentelemetry-lib/instrumentation/langchain/span-utils.ts
6513
+ const INPUT_MESSAGES$1 = "gen_ai.input.messages";
6514
+ const OUTPUT_MESSAGES$1 = "gen_ai.output.messages";
6515
+ const ROLE_BY_MESSAGE_TYPE = {
6516
+ human: "user",
6517
+ system: "system",
6518
+ ai: "assistant",
6519
+ tool: "tool",
6520
+ function: "tool"
6521
+ };
6522
+ const FINISH_REASON_MAP = {
6523
+ stop: "stop",
6524
+ length: "length",
6525
+ tool_calls: "tool_call",
6526
+ function_call: "tool_call",
6527
+ content_filter: "content_filter",
6528
+ end_turn: "stop",
6529
+ stop_sequence: "stop",
6530
+ tool_use: "tool_call",
6531
+ max_tokens: "length"
6532
+ };
6533
+ const MODEL_KEYS = [
6534
+ "model",
6535
+ "model_name",
6536
+ "model_id",
6537
+ "modelName"
6538
+ ];
6539
+ const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
6540
+ const asRecord = (value) => isRecord(value) ? value : {};
6541
+ const isInt = (value) => typeof value === "number" && Number.isInteger(value);
6542
+ /**
6543
+ * `JSON.stringify` that never throws: cycles become `"[Circular]"` and bigints
6544
+ * strings.
6545
+ */
6546
+ const toJson$1 = (value) => {
6547
+ const seen = /* @__PURE__ */ new WeakSet();
6548
+ try {
6549
+ return JSON.stringify(value, (_key, item) => {
6550
+ if (typeof item === "bigint") return item.toString();
6551
+ if (item !== null && typeof item === "object") {
6552
+ if (seen.has(item)) return "[Circular]";
6553
+ seen.add(item);
6554
+ }
6555
+ return item;
6556
+ }) ?? "null";
6557
+ } catch {
6558
+ return String(value);
6559
+ }
6560
+ };
6561
+ const maybeJson = (value) => {
6562
+ if (typeof value !== "string") return value;
6563
+ try {
6564
+ return JSON.parse(value);
6565
+ } catch {
6566
+ return value;
6567
+ }
6568
+ };
6569
+ const setIfPresent = (span, key, value) => {
6570
+ if (value === void 0 || value === null) return;
6571
+ if (typeof value === "string" && value.length === 0) return;
6572
+ span.setAttribute(key, value);
6573
+ };
6574
+ const messageType = (message) => {
6575
+ const type = message?.type ?? message?._getType?.() ?? message?.getType?.();
6576
+ return typeof type === "string" ? type : "";
6577
+ };
6578
+ const messageRole = (type) => ROLE_BY_MESSAGE_TYPE[type] ?? (type || "unknown");
6579
+ /**
6580
+ * Convert LangChain message content (string or list of blocks) into GenAI
6581
+ * parts.
6582
+ */
6583
+ const contentToParts = (content) => {
6584
+ if (typeof content === "string") return content ? [{
6585
+ type: "text",
6586
+ content
6587
+ }] : [];
6588
+ if (!Array.isArray(content)) return content ? [{
6589
+ type: "text",
6590
+ content: String(content)
6591
+ }] : [];
6592
+ const parts = [];
6593
+ for (const block of content) {
6594
+ if (typeof block === "string") {
6595
+ if (block) parts.push({
6596
+ type: "text",
6597
+ content: block
6598
+ });
6599
+ continue;
6600
+ }
6601
+ if (!isRecord(block)) {
6602
+ parts.push({
6603
+ type: "text",
6604
+ content: String(block)
6605
+ });
6606
+ continue;
6607
+ }
6608
+ if (block.type === "text") {
6609
+ if (block.text) parts.push({
6610
+ type: "text",
6611
+ content: block.text
6612
+ });
6613
+ } else if (block.type === "image_url") {
6614
+ const url = isRecord(block.image_url) ? block.image_url.url : block.image_url;
6615
+ if (url) parts.push({
6616
+ type: "uri",
6617
+ modality: "image",
6618
+ uri: url
6619
+ });
6620
+ } else if (block.type === "image" && block.url) parts.push({
6621
+ type: "uri",
6622
+ modality: "image",
6623
+ uri: block.url
6624
+ });
6625
+ else if (block.type === "image") parts.push({
6626
+ type: "blob",
6627
+ modality: "image",
6628
+ mime_type: block.mime_type || block.mimeType || block.media_type || "",
6629
+ content: block.data || block.base64 || ""
6630
+ });
6631
+ else parts.push(block);
6632
+ }
6633
+ return parts;
6634
+ };
6635
+ const toolCallsToParts = (toolCalls) => {
6636
+ if (!Array.isArray(toolCalls)) return [];
6637
+ const parts = [];
6638
+ for (const toolCall of toolCalls) {
6639
+ if (!isRecord(toolCall)) continue;
6640
+ const fn = asRecord(toolCall.function);
6641
+ const part = {
6642
+ type: "tool_call",
6643
+ id: toolCall.id || "",
6644
+ name: toolCall.name || fn.name || ""
6645
+ };
6646
+ const args = toolCall.args ?? fn.arguments;
6647
+ if (args !== void 0 && args !== null) part.arguments = maybeJson(args);
6648
+ parts.push(part);
6649
+ }
6650
+ return parts;
6651
+ };
6652
+ const messageToolCalls = (message) => {
6653
+ if (Array.isArray(message?.tool_calls) && message.tool_calls.length > 0) return message.tool_calls;
6654
+ return message?.additional_kwargs?.tool_calls;
6655
+ };
6656
+ const messageToDict = (message) => {
6657
+ const role = messageRole(messageType(message));
6658
+ const toolCallId = message?.tool_call_id;
6659
+ if (role === "tool" && toolCallId) return {
6660
+ role,
6661
+ parts: [{
6662
+ type: "tool_call_response",
6663
+ id: toolCallId,
6664
+ response: message.content
6665
+ }]
6666
+ };
6667
+ const parts = [...contentToParts(message?.content), ...toolCallsToParts(messageToolCalls(message))];
6668
+ const functionCall = message?.additional_kwargs?.function_call;
6669
+ if (isRecord(functionCall)) parts.push({
6670
+ type: "tool_call",
6671
+ id: "",
6672
+ name: functionCall.name || "",
6673
+ arguments: maybeJson(functionCall.arguments)
6674
+ });
6675
+ return {
6676
+ role,
6677
+ parts
6678
+ };
6679
+ };
6680
+ const firstModel = (...sources) => {
6681
+ for (const source of sources) for (const key of MODEL_KEYS) {
6682
+ const model = source[key];
6683
+ if (typeof model === "string" && model) return model;
6684
+ }
6685
+ };
6686
+ /**
6687
+ * Record the request model and sampling params. Returns the request model.
6688
+ */
6689
+ const setRequestAttributes$3 = (span, serialized, metadata, extraParams, traceContent) => {
6690
+ const invocationParams = asRecord(extraParams?.invocation_params);
6691
+ const nested = asRecord(invocationParams.params);
6692
+ const params = Object.keys(nested).length > 0 ? nested : invocationParams;
6693
+ const serializedKwargs = asRecord(serialized?.kwargs);
6694
+ let model = firstModel(params, invocationParams, serializedKwargs);
6695
+ if (model === void 0) {
6696
+ const lsModelName = metadata?.ls_model_name;
6697
+ model = typeof lsModelName === "string" && lsModelName ? lsModelName : void 0;
6698
+ }
6699
+ setIfPresent(span, "gen_ai.request.model", model);
6700
+ const param = (...keys) => {
6701
+ for (const source of [params, serializedKwargs]) for (const key of keys) if (source[key] !== void 0 && source[key] !== null) return source[key];
6702
+ };
6703
+ const maxTokens = param("max_tokens", "max_completion_tokens", "max_new_tokens", "maxTokens");
6704
+ const temperature = param("temperature");
6705
+ const topP = param("top_p", "topP");
6706
+ if (isInt(maxTokens)) span.setAttribute("gen_ai.request.max_tokens", maxTokens);
6707
+ if (typeof temperature === "number") span.setAttribute("gen_ai.request.temperature", temperature);
6708
+ if (typeof topP === "number") span.setAttribute("gen_ai.request.top_p", topP);
6709
+ const tools = params.tools || params.functions;
6710
+ if (traceContent && Array.isArray(tools) && tools.length > 0) {
6711
+ const definitions = tools.map((tool) => {
6712
+ const record = asRecord(tool);
6713
+ const fn = isRecord(record.function) ? record.function : record;
6714
+ const definition = { name: fn.name };
6715
+ if (fn.description) definition.description = fn.description;
6716
+ const parameters = fn.parameters || record.input_schema;
6717
+ if (parameters) definition.parameters = parameters;
6718
+ return definition;
6719
+ });
6720
+ span.setAttribute("gen_ai.tool.definitions", toJson$1(definitions));
6721
+ }
6722
+ return model;
6723
+ };
6724
+ const setChatRequest$1 = (span, messages, traceContent) => {
6725
+ if (!traceContent) return;
6726
+ const inputMessages = (messages ?? []).flatMap((batch) => (batch ?? []).map(messageToDict));
6727
+ if (inputMessages.length > 0) span.setAttribute(INPUT_MESSAGES$1, toJson$1(inputMessages));
6728
+ };
6729
+ const setCompletionRequest$1 = (span, prompts, traceContent) => {
6730
+ if (!traceContent) return;
6731
+ const inputMessages = (prompts ?? []).map((prompt) => ({
6732
+ role: "user",
6733
+ parts: [{
6734
+ type: "text",
6735
+ content: prompt
6736
+ }]
6737
+ }));
6738
+ if (inputMessages.length > 0) span.setAttribute(INPUT_MESSAGES$1, toJson$1(inputMessages));
6739
+ };
6740
+ const allGenerations = (response) => Array.isArray(response?.generations) ? response.generations.flatMap((batch) => Array.isArray(batch) ? batch : []) : [];
6741
+ const setUsage = (span, response) => {
6742
+ let inputTokens = 0;
6743
+ let outputTokens = 0;
6744
+ let cacheReadTokens;
6745
+ let cacheCreationTokens;
6746
+ let found = false;
6747
+ for (const generation of allGenerations(response)) {
6748
+ const usage = asRecord(generation?.message?.usage_metadata);
6749
+ if (Object.keys(usage).length === 0) continue;
6750
+ found = true;
6751
+ inputTokens += isInt(usage.input_tokens) ? usage.input_tokens : 0;
6752
+ outputTokens += isInt(usage.output_tokens) ? usage.output_tokens : 0;
6753
+ const details = asRecord(usage.input_token_details);
6754
+ if (isInt(details.cache_read)) cacheReadTokens = (cacheReadTokens ?? 0) + details.cache_read;
6755
+ if (isInt(details.cache_creation)) cacheCreationTokens = (cacheCreationTokens ?? 0) + details.cache_creation;
6756
+ }
6757
+ if (!found) {
6758
+ const llmOutput = asRecord(response?.llmOutput);
6759
+ const tokenUsage = asRecord(llmOutput.tokenUsage ?? llmOutput.token_usage ?? llmOutput.usage);
6760
+ if (Object.keys(tokenUsage).length === 0) return;
6761
+ const pick = (...keys) => {
6762
+ for (const key of keys) if (isInt(tokenUsage[key]) && tokenUsage[key] !== 0) return tokenUsage[key];
6763
+ return 0;
6764
+ };
6765
+ inputTokens = pick("promptTokens", "prompt_tokens", "input_tokens", "input_token_count");
6766
+ outputTokens = pick("completionTokens", "completion_tokens", "output_tokens", "generated_token_count");
6767
+ }
6768
+ span.setAttribute("gen_ai.usage.input_tokens", inputTokens);
6769
+ span.setAttribute("gen_ai.usage.output_tokens", outputTokens);
6770
+ span.setAttribute("llm.usage.total_tokens", inputTokens + outputTokens);
6771
+ setIfPresent(span, "gen_ai.usage.cache_read_input_tokens", cacheReadTokens);
6772
+ setIfPresent(span, "gen_ai.usage.cache_creation_input_tokens", cacheCreationTokens);
6773
+ };
6774
+ const responseModelAndId = (response) => {
6775
+ const llmOutput = asRecord(response?.llmOutput);
6776
+ let model = firstModel(llmOutput);
6777
+ let id = llmOutput.id;
6778
+ for (const generation of allGenerations(response)) {
6779
+ const message = generation?.message;
6780
+ if (model === void 0) model = firstModel(asRecord(message?.response_metadata));
6781
+ if (id === void 0 || id === null) id = message?.id;
6782
+ }
6783
+ return {
6784
+ model,
6785
+ id: typeof id === "string" && id ? id : void 0
6786
+ };
6787
+ };
6788
+ const finishReasonOf = (generation) => {
6789
+ const info = asRecord(generation?.generationInfo);
6790
+ const metadata = asRecord(generation?.message?.response_metadata);
6791
+ const raw = info.finish_reason || info.stop_reason || metadata.finish_reason || metadata.stop_reason;
6792
+ return typeof raw === "string" ? FINISH_REASON_MAP[raw] ?? raw : void 0;
6793
+ };
6794
+ const setResponseAttributes$3 = (span, response, requestModel, traceContent) => {
6795
+ const { model, id } = responseModelAndId(response);
6796
+ setIfPresent(span, "gen_ai.response.model", model ?? requestModel);
6797
+ if (requestModel === void 0) setIfPresent(span, "gen_ai.request.model", model);
6798
+ setIfPresent(span, "gen_ai.response.id", id);
6799
+ setUsage(span, response);
6800
+ const outputMessages = [];
6801
+ const finishReasons = [];
6802
+ for (const generation of allGenerations(response)) {
6803
+ const finishReason = finishReasonOf(generation);
6804
+ if (finishReason && !finishReasons.includes(finishReason)) finishReasons.push(finishReason);
6805
+ if (!traceContent) continue;
6806
+ const message = generation?.message;
6807
+ const outputMessage = message && typeof message === "object" ? messageToDict(message) : {
6808
+ role: "assistant",
6809
+ parts: contentToParts(generation?.text)
6810
+ };
6811
+ outputMessage.finish_reason = finishReason ?? "";
6812
+ outputMessages.push(outputMessage);
6813
+ }
6814
+ if (finishReasons.length > 0) span.setAttribute("gen_ai.response.finish_reasons", finishReasons);
6815
+ if (outputMessages.length > 0) span.setAttribute(OUTPUT_MESSAGES$1, toJson$1(outputMessages));
6816
+ };
6817
+ /**
6818
+ * Return plain-data metadata as is, or undefined for anything else.
6819
+ *
6820
+ * Class instances are dropped rather than stringified: a model, client or
6821
+ * config object routinely carries credentials the caller never meant to
6822
+ * export.
6823
+ */
6824
+ const metadataValue = (value) => {
6825
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
6826
+ if (value instanceof Date) return Number.isNaN(value.getTime()) ? void 0 : value.toISOString();
6827
+ if (Array.isArray(value)) return value.map(metadataValue).filter((item) => item !== void 0);
6828
+ if (isRecord(value)) {
6829
+ const proto = Object.getPrototypeOf(value);
6830
+ if (proto !== Object.prototype && proto !== null) return void 0;
6831
+ const kept = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, metadataValue(item)]).filter(([, item]) => item !== void 0));
6832
+ return Object.keys(kept).length > 0 ? kept : void 0;
6833
+ }
6834
+ };
6835
+ const sanitizeMetadata = (metadata) => {
6836
+ if (!isRecord(metadata)) return {};
6837
+ return Object.fromEntries(Object.entries(metadata).map(([key, value]) => [key, metadataValue(value)]).filter(([, value]) => value !== void 0));
6838
+ };
6839
+ const retrieverOutput = (documents) => {
6840
+ if (!Array.isArray(documents)) return [];
6841
+ return documents.map((document) => {
6842
+ const pageContent = document?.pageContent ?? document?.page_content;
6843
+ if (pageContent === void 0 || pageContent === null) return document;
6844
+ return {
6845
+ page_content: pageContent,
6846
+ metadata: document?.metadata ?? {}
6847
+ };
6848
+ });
6849
+ };
6850
+ //#endregion
6851
+ //#region src/opentelemetry-lib/instrumentation/langchain/vendor-detection.ts
6852
+ const DEFAULT_VENDOR = "langchain";
6853
+ /**
6854
+ * Lower-cased class-name substrings → `gen_ai.system` vendor, in priority
6855
+ * order (`AzureChatOpenAI` must match azure before openai).
6856
+ */
6857
+ const VENDOR_RULES = [
6858
+ [["azure"], "azure.ai.openai"],
6859
+ [["openai"], "openai"],
6860
+ [["bedrock", "aws"], "aws.bedrock"],
6861
+ [["anthropic"], "anthropic"],
6862
+ [["vertex"], "gcp.vertex_ai"],
6863
+ [["google", "gemini"], "gcp.gen_ai"],
6864
+ [["cohere"], "cohere"],
6865
+ [["huggingface"], "hugging_face"],
6866
+ [["ollama"], "ollama"],
6867
+ [["together"], "together_ai"],
6868
+ [["replicate"], "replicate"],
6869
+ [["fireworks"], "fireworks"],
6870
+ [["groq"], "groq"],
6871
+ [["mistral"], "mistral_ai"]
6872
+ ];
6873
+ /**
6874
+ * Map a LangChain model class name (e.g. `ChatOpenAI`) onto the
6875
+ * `gen_ai.system` vendor string, or `"langchain"` when unknown.
6876
+ */
6877
+ const detectVendorFromClass = (className) => {
6878
+ if (!className) return DEFAULT_VENDOR;
6879
+ const lower = className.toLowerCase();
6880
+ for (const [patterns, vendor] of VENDOR_RULES) if (patterns.some((pattern) => lower.includes(pattern))) return vendor;
6881
+ return DEFAULT_VENDOR;
6882
+ };
6883
+ //#endregion
6884
+ //#region src/opentelemetry-lib/instrumentation/langchain/callback-handler.ts
6885
+ const logger$18 = require_utils.initializeLogger();
6886
+ const HANDLER_NAME = "laminar_callback_handler";
6887
+ /**
6888
+ * Callback handlers must never break the user's chain.
6889
+ */
6890
+ const dontThrow = (fn) => {
6891
+ try {
6892
+ fn();
6893
+ } catch (error) {
6894
+ logger$18.debug(`Failed to record LangChain run: ${String(error)}`);
6895
+ }
6896
+ };
6897
+ const className = (serialized) => {
6898
+ const id = serialized?.id;
6899
+ if (Array.isArray(id) && id.length > 0) return String(id[id.length - 1]);
6900
+ return typeof id === "string" ? id : "";
6901
+ };
6902
+ const runNameOf = (serialized, runName) => {
6903
+ for (const name of [
6904
+ runName,
6905
+ serialized?.kwargs?.name,
6906
+ serialized?.name
6907
+ ]) if (typeof name === "string" && name) return name;
6908
+ return className(serialized) || "unknown";
6909
+ };
6910
+ /**
6911
+ * LangGraph's `configurable.thread_id`, the conversation id.
6912
+ */
6913
+ const threadIdOf = (metadata, extra) => {
6914
+ const threadId = metadata?.thread_id ?? extra?.config?.configurable?.thread_id;
6915
+ return threadId === void 0 || threadId === null ? void 0 : String(threadId);
6916
+ };
6917
+ /**
6918
+ * Drop what only applies to the context a callback fired in (an open LLM
6919
+ * call's marker and its suppression) before parenting a new run from it.
6920
+ */
6921
+ const cleanContext = (ctx) => (0, _opentelemetry_core.unsuppressTracing)(ctx).deleteValue(LLM_CALL_KEY);
6922
+ /**
6923
+ * Records LangChain runs as Laminar spans.
6924
+ *
6925
+ * A single instance is injected into every LangChain `CallbackManager`, so all
6926
+ * state is keyed by LangChain's `runId`. Callbacks only start and end spans:
6927
+ * JavaScript callbacks cannot change the context of the code they observe, so
6928
+ * the instrumentation wrappers read `contextFor(runId)` to run user code (a
6929
+ * lambda, a tool, a graph node) and provider SDK calls under the right span.
6930
+ *
6931
+ * Duck-types LangChain's `BaseCallbackHandler` (`name`, `awaitHandlers`,
6932
+ * `copy`), as `@langchain/core` is not a runtime dependency of this package.
6933
+ */
6934
+ var LaminarCallbackHandler = class {
6935
+ constructor(traceContent) {
6936
+ this.name = HANDLER_NAME;
6937
+ this.awaitHandlers = true;
6938
+ this.raiseError = false;
6939
+ this.ignoreLLM = false;
6940
+ this.ignoreChain = false;
6941
+ this.ignoreAgent = false;
6942
+ this.ignoreRetriever = false;
6943
+ this.ignoreCustomEvent = true;
6944
+ this.lc_serializable = false;
6945
+ this.takeTopology = () => void 0;
6946
+ this.runs = /* @__PURE__ */ new Map();
6947
+ this.handedOff = /* @__PURE__ */ new Map();
6948
+ this.traceContent = traceContent;
6949
+ }
6950
+ copy() {
6951
+ return this;
6952
+ }
6953
+ /**
6954
+ * Context of an open run (or of a handed-off LLM run's parent), for code
6955
+ * that runs under it.
6956
+ */
6957
+ contextFor(runId) {
6958
+ if (!runId) return void 0;
6959
+ return this.runs.get(runId)?.context ?? this.handedOff.get(runId)?.context;
6960
+ }
6961
+ handleChainStart(chain, inputs, runId, parentRunId, tags, metadata, _runType, runName, extra) {
6962
+ dontThrow(() => {
6963
+ const name = runNameOf(chain, runName);
6964
+ const isRoot = !parentRunId || !this.runs.has(parentRunId) && !this.handedOff.has(parentRunId);
6965
+ const attributes = {};
6966
+ let spanName;
6967
+ if (isRoot) {
6968
+ spanName = `${name}.workflow`;
6969
+ attributes["gen_ai.operation.name"] = "invoke_agent";
6970
+ attributes["gen_ai.agent.name"] = name;
6971
+ attributes["gen_ai.agent.id"] = String(runId);
6972
+ } else {
6973
+ spanName = `execute_task ${name}`;
6974
+ attributes["gen_ai.operation.name"] = "execute_task";
6975
+ }
6976
+ const threadId = threadIdOf(metadata, extra);
6977
+ if (threadId) attributes["gen_ai.conversation.id"] = threadId;
6978
+ const topology = this.takeTopology();
6979
+ if (topology && isRoot) for (const [key, value] of Object.entries(topology)) attributes[`lmnr.association.properties.${key}`] = value;
6980
+ const span = this.startRun(runId, parentRunId, spanName, {
6981
+ attributes,
6982
+ tags,
6983
+ metadata
6984
+ });
6985
+ if (span && this.traceContent) span.setInput(toJson$1(inputs));
6986
+ });
6987
+ }
6988
+ handleChainEnd(outputs, runId) {
6989
+ dontThrow(() => {
6990
+ try {
6991
+ this.setOutput(runId, outputs);
6992
+ } finally {
6993
+ this.endRun(runId);
6994
+ }
6995
+ });
6996
+ }
6997
+ handleChainError(error, runId) {
6998
+ dontThrow(() => this.handleError(error, runId));
6999
+ }
7000
+ handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, runName) {
7001
+ dontThrow(() => this.startLlm(llm, messages, "chat", runId, parentRunId, {
7002
+ extraParams,
7003
+ tags,
7004
+ metadata,
7005
+ runName
7006
+ }));
7007
+ }
7008
+ handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata, runName) {
7009
+ dontThrow(() => this.startLlm(llm, prompts, "text_completion", runId, parentRunId, {
7010
+ extraParams,
7011
+ tags,
7012
+ metadata,
7013
+ runName
7014
+ }));
7015
+ }
7016
+ handleLLMEnd(output, runId) {
7017
+ dontThrow(() => {
7018
+ try {
7019
+ const run = this.runs.get(runId);
7020
+ if (run) setResponseAttributes$3(run.span, output, run.requestModel, this.traceContent);
7021
+ else this.recordUnrecordedHandoff(runId, (span, requestModel) => setResponseAttributes$3(span, output, requestModel, this.traceContent));
7022
+ } finally {
7023
+ this.endRun(runId);
7024
+ }
7025
+ });
7026
+ }
7027
+ handleLLMError(error, runId) {
7028
+ dontThrow(() => this.handleError(error, runId));
7029
+ }
7030
+ handleToolStart(tool, input, runId, parentRunId, tags, metadata, runName, toolCallId) {
7031
+ dontThrow(() => {
7032
+ const name = runNameOf(tool, runName);
7033
+ const attributes = {
7034
+ "gen_ai.operation.name": "execute_tool",
7035
+ "gen_ai.tool.name": name,
7036
+ "gen_ai.tool.type": "function"
7037
+ };
7038
+ const description = tool?.description ?? tool?.kwargs?.description;
7039
+ if (typeof description === "string" && description) attributes["gen_ai.tool.description"] = description;
7040
+ if (typeof toolCallId === "string" && toolCallId) attributes["gen_ai.tool.call.id"] = toolCallId;
7041
+ const span = this.startRun(runId, parentRunId, `execute_tool ${name}`, {
7042
+ spanType: "TOOL",
7043
+ attributes,
7044
+ tags,
7045
+ metadata
7046
+ });
7047
+ if (span && this.traceContent) span.setInput(toJson$1(parseJsonObject(input)));
7048
+ });
7049
+ }
7050
+ handleToolEnd(output, runId) {
7051
+ dontThrow(() => {
7052
+ try {
7053
+ this.setOutput(runId, output);
7054
+ } finally {
7055
+ this.endRun(runId);
7056
+ }
7057
+ });
7058
+ }
7059
+ handleToolError(error, runId) {
7060
+ dontThrow(() => this.handleError(error, runId));
7061
+ }
7062
+ handleRetrieverStart(retriever, query, runId, parentRunId, tags, metadata, runName) {
7063
+ dontThrow(() => {
7064
+ const name = runNameOf(retriever, runName);
7065
+ const span = this.startRun(runId, parentRunId, `vector_db_retrieve ${name}`, {
7066
+ attributes: { "gen_ai.operation.name": "vector_db_retrieve" },
7067
+ tags,
7068
+ metadata
7069
+ });
7070
+ if (span && this.traceContent) span.setInput(toJson$1(query));
7071
+ });
7072
+ }
7073
+ handleRetrieverEnd(documents, runId) {
7074
+ dontThrow(() => {
7075
+ try {
7076
+ this.setOutput(runId, retrieverOutput(documents));
7077
+ } finally {
7078
+ this.endRun(runId);
7079
+ }
7080
+ });
7081
+ }
7082
+ handleRetrieverError(error, runId) {
7083
+ dontThrow(() => this.handleError(error, runId));
7084
+ }
7085
+ parentContext(parentRunId) {
7086
+ return cleanContext(this.contextFor(parentRunId) ?? LaminarContextManager.getContext());
7087
+ }
7088
+ startRun(runId, parentRunId, name, { spanType = "DEFAULT", attributes, tags, metadata, startTime }) {
7089
+ const active = _opentelemetry_api.context.active();
7090
+ if ((0, _opentelemetry_core.isTracingSuppressed)(active) && active.getValue(LLM_CALL_KEY)?.mode !== "own") return;
7091
+ const parentContext = this.parentContext(parentRunId);
7092
+ const span = this.startSpan(name, spanType, parentContext, {
7093
+ attributes,
7094
+ tags,
7095
+ metadata,
7096
+ startTime
7097
+ });
7098
+ const run = {
7099
+ span,
7100
+ context: _opentelemetry_api.trace.setSpan(LaminarContextManager.setAssociationProperties(span, parentContext), span),
7101
+ children: []
7102
+ };
7103
+ if (parentRunId) this.runs.get(parentRunId)?.children.push(runId);
7104
+ const stale = this.runs.get(runId);
7105
+ if (stale) {
7106
+ this.runs.delete(runId);
7107
+ stale.span.end();
7108
+ }
7109
+ this.runs.set(runId, run);
7110
+ return span;
7111
+ }
7112
+ startSpan(name, spanType, parentContext, { attributes, tags, metadata, startTime }) {
7113
+ const span = Laminar.startSpan({
7114
+ name,
7115
+ spanType,
7116
+ context: parentContext,
7117
+ startTime
7118
+ });
7119
+ if (attributes) span.setAttributes(attributes);
7120
+ if (tags && tags.length > 0) span.setAttribute("langchain.tags", tags);
7121
+ const sanitized = sanitizeMetadata(metadata);
7122
+ if (Object.keys(sanitized).length > 0) span.setAttribute("langchain.metadata", toJson$1(sanitized));
7123
+ return span;
7124
+ }
7125
+ startLlm(llm, input, operation, runId, parentRunId, { extraParams, tags, metadata, runName }) {
7126
+ const name = runNameOf(llm, runName);
7127
+ const call = _opentelemetry_api.context.active().getValue(LLM_CALL_KEY);
7128
+ if (call?.mode === "handoff") {
7129
+ this.handedOff.set(runId, {
7130
+ context: this.parentContext(parentRunId),
7131
+ call,
7132
+ name,
7133
+ operation,
7134
+ serialized: llm,
7135
+ input,
7136
+ extraParams,
7137
+ tags,
7138
+ metadata,
7139
+ startTime: (0, _opentelemetry_core.hrTime)()
7140
+ });
7141
+ if (parentRunId) this.runs.get(parentRunId)?.children.push(runId);
7142
+ return;
7143
+ }
7144
+ const span = this.startRun(runId, parentRunId, llmSpanName(name, operation), {
7145
+ spanType: "LLM",
7146
+ attributes: llmAttributes(llm, operation),
7147
+ tags,
7148
+ metadata
7149
+ });
7150
+ if (!span) return;
7151
+ const run = this.runs.get(runId);
7152
+ run.requestModel = this.setLlmRequest(span, {
7153
+ serialized: llm,
7154
+ input,
7155
+ operation,
7156
+ extraParams,
7157
+ metadata
7158
+ });
7159
+ }
7160
+ setLlmRequest(span, { serialized, input, operation, extraParams, metadata }) {
7161
+ const requestModel = setRequestAttributes$3(span, serialized, metadata, extraParams, this.traceContent);
7162
+ if (operation === "chat") setChatRequest$1(span, input, this.traceContent);
7163
+ else setCompletionRequest$1(span, input, this.traceContent);
7164
+ return requestModel;
7165
+ }
7166
+ /**
7167
+ * A handed-off LLM run whose provider instrumentation did not record the
7168
+ * call (it is disabled, or the integration bundles its own copy of the
7169
+ * provider SDK) gets its LangChain span after all, spanning the run.
7170
+ */
7171
+ recordUnrecordedHandoff(runId, finish) {
7172
+ const pending = this.handedOff.get(runId);
7173
+ if (!pending || pending.call.recorded) return;
7174
+ const span = this.startSpan(llmSpanName(pending.name, pending.operation), "LLM", pending.context, {
7175
+ attributes: llmAttributes(pending.serialized, pending.operation),
7176
+ tags: pending.tags,
7177
+ metadata: pending.metadata,
7178
+ startTime: pending.startTime
7179
+ });
7180
+ try {
7181
+ finish(span, this.setLlmRequest(span, pending));
7182
+ } finally {
7183
+ span.end();
7184
+ }
7185
+ }
7186
+ setOutput(runId, output) {
7187
+ const run = this.runs.get(runId);
7188
+ if (run && this.traceContent) run.span.setOutput(toJson$1(output));
7189
+ }
7190
+ handleError(error, runId) {
7191
+ const run = this.runs.get(runId);
7192
+ if (!run) {
7193
+ try {
7194
+ this.recordUnrecordedHandoff(runId, (span) => markError(span, error));
7195
+ } finally {
7196
+ this.handedOff.delete(runId);
7197
+ }
7198
+ return;
7199
+ }
7200
+ try {
7201
+ markError(run.span, error);
7202
+ } finally {
7203
+ this.endRun(runId);
7204
+ }
7205
+ }
7206
+ endRun(runId) {
7207
+ this.handedOff.delete(runId);
7208
+ const run = this.runs.get(runId);
7209
+ if (!run) return;
7210
+ this.runs.delete(runId);
7211
+ for (const childId of run.children) this.endRun(childId);
7212
+ run.span.end();
7213
+ }
7214
+ };
7215
+ const llmSpanName = (name, operation) => `${name}.${operation === "chat" ? "chat" : "completion"}`;
7216
+ const llmAttributes = (serialized, operation) => {
7217
+ const vendor = detectVendorFromClass(className(serialized));
7218
+ return {
7219
+ "gen_ai.operation.name": operation,
7220
+ "gen_ai.system": vendor,
7221
+ "gen_ai.provider.name": vendor
7222
+ };
7223
+ };
7224
+ const markError = (span, error) => {
7225
+ span.setAttribute("error.type", error?.constructor?.name ?? "Error");
7226
+ span.recordException(error);
7227
+ span.setStatus({
7228
+ code: _opentelemetry_api.SpanStatusCode.ERROR,
7229
+ message: error?.message ?? String(error)
7230
+ });
7231
+ };
7232
+ const parseJsonObject = (input) => {
7233
+ if (typeof input !== "string") return input;
7234
+ try {
7235
+ const parsed = JSON.parse(input);
7236
+ return parsed !== null && typeof parsed === "object" ? parsed : input;
7237
+ } catch {
7238
+ return input;
7239
+ }
7240
+ };
7241
+ //#endregion
7242
+ //#region src/opentelemetry-lib/instrumentation/langchain/index.ts
7243
+ const logger$17 = require_utils.initializeLogger();
7244
+ const PATCH_DATA_SYMBOL$1 = Symbol("lmnr.langchain.patchData");
7245
+ const hasOwnPatchData$1 = (target) => Object.getOwnPropertyDescriptor(target, PATCH_DATA_SYMBOL$1) !== void 0;
7246
+ /**
7247
+ * Model classes whose provider SDK Laminar instruments itself (`_llmType()`).
7248
+ * Their LLM calls are handed off: the provider span is the LLM span, with the
7249
+ * provider-specific attributes, and LangChain opens none of its own.
7250
+ */
7251
+ const HANDOFF_LLM_TYPES = /* @__PURE__ */ new Set([
7252
+ "openai",
7253
+ "azure_openai",
7254
+ "anthropic"
7255
+ ]);
7256
+ /**
7257
+ * The single handler injected into every LangChain `CallbackManager`. All its
7258
+ * state is keyed by LangChain run id, so it is shared by every instrumentation
7259
+ * instance (auto and manual) and patched module copy.
7260
+ */
7261
+ const handler = new LaminarCallbackHandler(true);
7262
+ const topologyStorage = new node_async_hooks.AsyncLocalStorage();
7263
+ handler.takeTopology = () => {
7264
+ const holder = topologyStorage.getStore();
7265
+ const topology = holder?.topology;
7266
+ if (holder) holder.topology = void 0;
7267
+ return topology;
7268
+ };
7269
+ /**
7270
+ * Run `fn` with `ctx` current in both the OTel context (read by OTel-aware
7271
+ * code) and Laminar's context stack (read by `Laminar.startSpan` and
7272
+ * Laminar's own provider instrumentations).
7273
+ */
7274
+ const runUnder = (ctx, fn) => _opentelemetry_api.context.with(ctx, () => LaminarContextManager.runWithIsolatedContext([...LaminarContextManager.getContextStack(), ctx], fn));
7275
+ /**
7276
+ * Wrap an async iterator so each step runs through `run`.
7277
+ * `AsyncLocalStorage.run` and `context.with` only cover the synchronous part
7278
+ * of the call, so every `next` / `return` / `throw` needs its own.
7279
+ */
7280
+ const wrapIterator = (iterator, run) => ({
7281
+ next: (...args) => run(() => iterator.next(...args)),
7282
+ return: (value) => run(() => typeof iterator.return === "function" ? iterator.return(value) : Promise.resolve({
7283
+ done: true,
7284
+ value
7285
+ })),
7286
+ throw: (error) => run(() => typeof iterator.throw === "function" ? iterator.throw(error) : Promise.reject(error)),
7287
+ [Symbol.asyncIterator]() {
7288
+ return this;
7289
+ }
7290
+ });
7291
+ /**
7292
+ * Replace the own method `target[method]` with `wrap(original)`. Already
7293
+ * patched methods are left alone, so repeated initialization never
7294
+ * double-wraps.
7295
+ */
7296
+ const patchMethod = (target, method, wrap) => {
7297
+ if (!target || !Object.getOwnPropertyDescriptor(target, method) || typeof target[method] !== "function") return;
7298
+ if (!hasOwnPatchData$1(target)) Object.defineProperty(target, PATCH_DATA_SYMBOL$1, {
7299
+ value: {},
7300
+ enumerable: false,
7301
+ writable: true,
7302
+ configurable: true
7303
+ });
7304
+ const patchData = target[PATCH_DATA_SYMBOL$1];
7305
+ if (patchData[method]) return;
7306
+ const original = target[method];
7307
+ patchData[method] = original;
7308
+ target[method] = wrap(original);
7309
+ };
7310
+ const unpatchMethod = (target, method) => {
7311
+ if (!target || !hasOwnPatchData$1(target)) return;
7312
+ const patchData = target[PATCH_DATA_SYMBOL$1];
7313
+ const original = patchData[method];
7314
+ if (!original) return;
7315
+ target[method] = original;
7316
+ delete patchData[method];
7317
+ if (Object.keys(patchData).length === 0) delete target[PATCH_DATA_SYMBOL$1];
7318
+ };
7319
+ /**
7320
+ * Inject the handler into every `CallbackManager` LangChain configures.
7321
+ * `configure` delegates to the static `_configureSync`, and LangGraph calls
7322
+ * `_configureSync` directly, so this one method covers both.
7323
+ */
7324
+ const wrapConfigureSync = (original) => function(inheritableHandlers, ...rest) {
7325
+ const manager = original.call(this, inheritableHandlers, ...rest);
7326
+ if (!manager) return original.call(this, [handler], ...rest);
7327
+ try {
7328
+ if (!manager.handlers?.some((h) => h?.name === "laminar_callback_handler") && typeof manager.addHandler === "function") manager.addHandler(handler, true);
7329
+ } catch (error) {
7330
+ logger$17.debug(`Failed to add the Laminar LangChain handler: ${error}`);
7331
+ }
7332
+ return manager;
7333
+ };
7334
+ /**
7335
+ * Run user code that LangChain runs for a run (a lambda, a tool, a graph
7336
+ * node) under that run's span. LangChain passes it the run's child config,
7337
+ * whose callback manager's parent run id is that run.
7338
+ */
7339
+ const wrapRunWithConfig = (original) => function(config, ...rest) {
7340
+ let ctx;
7341
+ try {
7342
+ ctx = handler.contextFor(config?.callbacks?.getParentRunId?.());
7343
+ } catch {
7344
+ ctx = void 0;
7345
+ }
7346
+ if (!ctx) return original.call(this, config, ...rest);
7347
+ return runUnder(ctx, () => original.call(this, config, ...rest));
7348
+ };
7349
+ /**
7350
+ * The context an LLM call runs under, or undefined to run it untouched (it is
7351
+ * nested in another LLM call, or tracing is suppressed).
7352
+ *
7353
+ * The call is handed off to Laminar's provider instrumentation when the model
7354
+ * wraps a provider SDK it instruments. Otherwise the handler records the LLM
7355
+ * span and provider instrumentations underneath are suppressed, so a call is
7356
+ * never recorded twice.
7357
+ */
7358
+ const llmCallContext = (model, callbacks, startedRunManagers) => {
7359
+ const active = _opentelemetry_api.context.active();
7360
+ if (active.getValue(LLM_CALL_KEY) || (0, _opentelemetry_core.isTracingSuppressed)(active)) return;
7361
+ let parentRunId;
7362
+ let llmType;
7363
+ try {
7364
+ parentRunId = callbacks?.getParentRunId?.();
7365
+ llmType = model?._llmType?.();
7366
+ } catch {}
7367
+ const base = handler.contextFor(parentRunId) ?? LaminarContextManager.getContext();
7368
+ const mode = llmType && HANDOFF_LLM_TYPES.has(llmType) && !startedRunManagers ? "handoff" : "own";
7369
+ const call = {
7370
+ mode,
7371
+ recorded: false
7372
+ };
7373
+ const ctx = base.setValue(LLM_CALL_KEY, call);
7374
+ return mode === "own" ? (0, _opentelemetry_core.suppressTracing)(ctx) : ctx;
7375
+ };
7376
+ const wrapGenerateUncached = (original) => function(input, parsedOptions, handledOptions, startedRunManagers, ...rest) {
7377
+ const call = () => original.call(this, input, parsedOptions, handledOptions, startedRunManagers, ...rest);
7378
+ const ctx = llmCallContext(this, handledOptions?.callbacks, startedRunManagers);
7379
+ return ctx ? runUnder(ctx, call) : call();
7380
+ };
7381
+ const wrapModelStreamIterator = (original) => function(input, options, ...rest) {
7382
+ const ctx = llmCallContext(this, options?.callbacks);
7383
+ if (!ctx) return original.call(this, input, options, ...rest);
7384
+ const iterator = runUnder(ctx, () => original.call(this, input, options, ...rest));
7385
+ return wrapIterator(iterator, (fn) => runUnder(ctx, fn));
7386
+ };
7387
+ /**
7388
+ * The graph topology, recorded on the graph's root span the way the Python
7389
+ * SDK does. Only the synchronous `getGraph` is used: it runs before the
7390
+ * graph does, and an async drawing would hold the run back.
7391
+ */
7392
+ const topologyCache = /* @__PURE__ */ new WeakMap();
7393
+ const graphTopology = (pregel, config) => {
7394
+ const cached = topologyCache.get(pregel);
7395
+ if (cached) return cached;
7396
+ if (typeof pregel?.getGraph !== "function") return void 0;
7397
+ const graph = pregel.getGraph(config);
7398
+ if (!graph || graph instanceof Promise) return void 0;
7399
+ const nodes = Object.values(graph.nodes ?? {}).map((node) => ({
7400
+ id: node.id,
7401
+ name: node.name,
7402
+ metadata: node.metadata ?? null
7403
+ }));
7404
+ const edges = (graph.edges ?? []).map((edge) => ({
7405
+ source: edge.source,
7406
+ target: edge.target,
7407
+ conditional: Boolean(edge.conditional)
7408
+ }));
7409
+ const topology = {
7410
+ "langgraph.nodes": JSON.stringify(nodes),
7411
+ "langgraph.edges": JSON.stringify(edges)
7412
+ };
7413
+ topologyCache.set(pregel, topology);
7414
+ return topology;
7415
+ };
7416
+ /**
7417
+ * Publish the graph topology for the graph's own run, which the handler
7418
+ * starts in the iterator's first step. Each iterator gets its own holder, so
7419
+ * concurrent graph runs never read each other's topology.
7420
+ */
7421
+ const wrapPregelStreamIterator = (original) => function(input, options, ...rest) {
7422
+ let topology;
7423
+ try {
7424
+ topology = graphTopology(this, options);
7425
+ } catch (error) {
7426
+ logger$17.debug(`Failed to read the LangGraph topology: ${error}`);
7427
+ }
7428
+ const iterator = original.call(this, input, options, ...rest);
7429
+ if (!topology) return iterator;
7430
+ const holder = { topology };
7431
+ return wrapIterator(iterator, (fn) => topologyStorage.run(holder, fn));
7432
+ };
7433
+ /**
7434
+ * `Pregel.prototype` from `@langchain/langgraph/pregel`, or the first
7435
+ * prototype that owns `_streamIterator` above a compiled graph class.
7436
+ */
7437
+ const pregelPrototype = (module) => {
7438
+ if (typeof module?.Pregel === "function") return module.Pregel.prototype;
7439
+ const graphClass = module?.CompiledStateGraph ?? module?.CompiledGraph ?? module;
7440
+ let proto = typeof graphClass === "function" ? graphClass.prototype : null;
7441
+ while (proto && proto !== Object.prototype) {
7442
+ if (Object.getOwnPropertyDescriptor(proto, "_streamIterator")) return proto;
7443
+ proto = Object.getPrototypeOf(proto);
7444
+ }
7445
+ };
7446
+ const singletonPrototype = (module) => {
7447
+ const singleton = module?.AsyncLocalStorageProviderSingleton;
7448
+ return singleton ? Object.getPrototypeOf(singleton) : void 0;
7449
+ };
7450
+ const CORE_FILES = {
7451
+ callbackManager: ["@langchain/core/dist/callbacks/manager"],
7452
+ singletons: ["@langchain/core/dist/singletons/async_local_storage/index", "@langchain/core/dist/singletons/index"],
7453
+ chatModels: ["@langchain/core/dist/language_models/chat_models"],
7454
+ llms: ["@langchain/core/dist/language_models/llms"]
7455
+ };
7456
+ /**
7457
+ * Instruments LangChain (`@langchain/core`) and LangGraph
7458
+ * (`@langchain/langgraph`) through a callback handler injected into every
7459
+ * callback manager, with wrappers that run user code and provider SDK calls
7460
+ * under the right span.
7461
+ *
7462
+ * Calls made through LangChain's OpenAI and Anthropic integrations are left to
7463
+ * Laminar's OpenAI and Anthropic instrumentations, which record them as the
7464
+ * LLM span. Other model calls are recorded by the handler, with provider
7465
+ * instrumentations underneath suppressed.
7466
+ */
7467
+ var LangChainInstrumentation = class extends _opentelemetry_instrumentation.InstrumentationBase {
7468
+ constructor(config) {
7469
+ super("@lmnr/langchain-instrumentation", require_utils.version, { enabled: true });
7470
+ this.traceContent = config?.traceContent ?? true;
7471
+ }
7472
+ init() {
7473
+ const coreFiles = (names, patch, unpatch) => names.flatMap((name) => [".cjs", ".js"].map((extension) => new _opentelemetry_instrumentation.InstrumentationNodeModuleFile(`${name}${extension}`, [">=0.3.0"], (exports) => {
7474
+ patch.call(this, exports);
7475
+ return exports;
7476
+ }, (exports) => {
7477
+ if (exports) unpatch.call(this, exports);
7478
+ })));
7479
+ return [new _opentelemetry_instrumentation.InstrumentationNodeModuleDefinition("@langchain/core", [">=0.3.0"], void 0, void 0, [
7480
+ ...coreFiles(CORE_FILES.callbackManager, this.patchCallbackManager, this.unpatchCallbackManager),
7481
+ ...coreFiles(CORE_FILES.singletons, this.patchSingletons, this.unpatchSingletons),
7482
+ ...coreFiles(CORE_FILES.chatModels, this.patchChatModels, this.unpatchChatModels),
7483
+ ...coreFiles(CORE_FILES.llms, this.patchLlms, this.unpatchLlms)
7484
+ ]), new _opentelemetry_instrumentation.InstrumentationNodeModuleDefinition("@langchain/langgraph", [">=0.2.0"], void 0, void 0, [".cjs", ".js"].map((extension) => new _opentelemetry_instrumentation.InstrumentationNodeModuleFile(`@langchain/langgraph/dist/pregel/index${extension}`, [">=0.2.0"], (exports) => {
7485
+ this.patchLanggraph(exports);
7486
+ return exports;
7487
+ }, (exports) => {
7488
+ if (exports) this.unpatchLanggraph(exports);
7489
+ })))];
7490
+ }
7491
+ /**
7492
+ * Pass every module you use; a module left out is not traced. The model
7493
+ * modules are what lets OpenAI and Anthropic calls be recorded once, by the
7494
+ * provider instrumentation, instead of twice.
7495
+ */
7496
+ manuallyInstrument(modules) {
7497
+ const { callbackManagerModule, singletonsModule, chatModelsModule, llmsModule, langgraphModule } = modules ?? {};
7498
+ if (!callbackManagerModule && !singletonsModule && !chatModelsModule && !llmsModule && !langgraphModule) {
7499
+ _opentelemetry_api.diag.warn("No modules in langchain manual instrumentation input. Pass at least @langchain/core/callbacks/manager as callbackManagerModule.");
7500
+ return;
7501
+ }
7502
+ _opentelemetry_api.diag.debug("Manually instrumenting LangChain");
7503
+ if (callbackManagerModule && !chatModelsModule) _opentelemetry_api.diag.warn("LangChain chatModelsModule is missing from manual instrumentation input. Chat model calls may be recorded twice. Pass @langchain/core/language_models/chat_models as chatModelsModule.");
7504
+ if (callbackManagerModule) this.patchCallbackManager(callbackManagerModule);
7505
+ if (singletonsModule) this.patchSingletons(singletonsModule);
7506
+ if (chatModelsModule) this.patchChatModels(chatModelsModule);
7507
+ if (llmsModule) this.patchLlms(llmsModule);
7508
+ if (langgraphModule) {
7509
+ if (!pregelPrototype(langgraphModule)) _opentelemetry_api.diag.warn("Could not find Pregel in langchain manual instrumentation input. Pass the @langchain/langgraph module as langgraphModule.");
7510
+ else this.patchLanggraph(langgraphModule);
7511
+ }
7512
+ }
7513
+ patchCallbackManager(moduleExports) {
7514
+ _opentelemetry_api.diag.debug("Patching @langchain/core CallbackManager");
7515
+ handler.traceContent = this.traceContent;
7516
+ patchMethod(moduleExports?.CallbackManager, "_configureSync", wrapConfigureSync);
7517
+ }
7518
+ unpatchCallbackManager(moduleExports) {
7519
+ unpatchMethod(moduleExports?.CallbackManager, "_configureSync");
7520
+ }
7521
+ patchSingletons(moduleExports) {
7522
+ _opentelemetry_api.diag.debug("Patching @langchain/core AsyncLocalStorageProvider");
7523
+ patchMethod(singletonPrototype(moduleExports), "runWithConfig", wrapRunWithConfig);
7524
+ }
7525
+ unpatchSingletons(moduleExports) {
7526
+ unpatchMethod(singletonPrototype(moduleExports), "runWithConfig");
7527
+ }
7528
+ patchChatModels(moduleExports) {
7529
+ _opentelemetry_api.diag.debug("Patching @langchain/core BaseChatModel");
7530
+ this.patchModel(moduleExports?.BaseChatModel?.prototype);
7531
+ }
7532
+ unpatchChatModels(moduleExports) {
7533
+ this.unpatchModel(moduleExports?.BaseChatModel?.prototype);
7534
+ }
7535
+ patchLlms(moduleExports) {
7536
+ _opentelemetry_api.diag.debug("Patching @langchain/core BaseLLM");
7537
+ this.patchModel(moduleExports?.BaseLLM?.prototype);
7538
+ }
7539
+ unpatchLlms(moduleExports) {
7540
+ this.unpatchModel(moduleExports?.BaseLLM?.prototype);
7541
+ }
7542
+ patchModel(proto) {
7543
+ patchMethod(proto, "_generateUncached", wrapGenerateUncached);
7544
+ patchMethod(proto, "_streamIterator", wrapModelStreamIterator);
7545
+ }
7546
+ unpatchModel(proto) {
7547
+ unpatchMethod(proto, "_generateUncached");
7548
+ unpatchMethod(proto, "_streamIterator");
7549
+ }
7550
+ patchLanggraph(moduleExports) {
7551
+ _opentelemetry_api.diag.debug("Patching @langchain/langgraph Pregel");
7552
+ patchMethod(pregelPrototype(moduleExports), "_streamIterator", wrapPregelStreamIterator);
7553
+ }
7554
+ unpatchLanggraph(moduleExports) {
7555
+ unpatchMethod(pregelPrototype(moduleExports), "_streamIterator");
7556
+ }
7557
+ };
6492
7558
  const DISABLE_OPENAI_RESPONSES_INSTRUMENTATION_CONTEXT_KEY = (0, _opentelemetry_api.createContextKey)("LMNR_DISABLE_OPENAI_RESPONSES_INSTRUMENTATION");
6493
7559
  const systemInstructionsStorage = new async_hooks.AsyncLocalStorage();
6494
7560
  const getCurrentSystemInstructions = () => systemInstructionsStorage.getStore();
@@ -8585,6 +9651,107 @@ var LaminarSpanExporter = class {
8585
9651
  return this.exporter.forceFlush?.();
8586
9652
  }
8587
9653
  };
9654
+ const RELEASE_ENV_VARS = [
9655
+ "GITHUB_SHA",
9656
+ "SENTRY_RELEASE",
9657
+ "VERCEL_GIT_COMMIT_SHA",
9658
+ "RENDER_GIT_COMMIT",
9659
+ "RAILWAY_GIT_COMMIT_SHA",
9660
+ "HEROKU_BUILD_COMMIT",
9661
+ "SOURCE_VERSION",
9662
+ "CODEBUILD_RESOLVED_SOURCE_VERSION",
9663
+ "CIRCLE_SHA1",
9664
+ "K_REVISION",
9665
+ "GAE_DEPLOYMENT_ID",
9666
+ "FLY_IMAGE_REF"
9667
+ ];
9668
+ /**
9669
+ * The first available of: `explicit`, `LMNR_RELEASE`, a known platform
9670
+ * variable, a numeric AWS Lambda version, the checked-out git commit.
9671
+ */
9672
+ const detectRelease = (explicit) => {
9673
+ const candidates = [
9674
+ () => explicit,
9675
+ () => env("LMNR_RELEASE"),
9676
+ ...RELEASE_ENV_VARS.map((name) => () => env(name)),
9677
+ lambdaVersion,
9678
+ gitHead
9679
+ ];
9680
+ for (const candidate of candidates) {
9681
+ const release = clean(candidate());
9682
+ if (release) return release;
9683
+ }
9684
+ };
9685
+ const env = (name) => {
9686
+ try {
9687
+ return process.env[name];
9688
+ } catch {
9689
+ return;
9690
+ }
9691
+ };
9692
+ const clean = (value) => {
9693
+ const trimmed = value?.trim();
9694
+ if (!trimmed) return;
9695
+ const chars = Array.from(trimmed);
9696
+ return chars.length > 128 ? chars.slice(0, 128).join("") : trimmed;
9697
+ };
9698
+ const lambdaVersion = () => {
9699
+ const version = env("AWS_LAMBDA_FUNCTION_VERSION");
9700
+ const fn = env("AWS_LAMBDA_FUNCTION_NAME");
9701
+ if (!version || !/^\d+$/.test(version) || !fn) return;
9702
+ return `${fn}:${version}`;
9703
+ };
9704
+ const isFile = (path) => {
9705
+ try {
9706
+ return (0, node_fs.statSync)(path).isFile();
9707
+ } catch {
9708
+ return false;
9709
+ }
9710
+ };
9711
+ const isDirectory = (path) => {
9712
+ try {
9713
+ return (0, node_fs.statSync)(path).isDirectory();
9714
+ } catch {
9715
+ return false;
9716
+ }
9717
+ };
9718
+ /** The commit `.git/HEAD` points at, read from disk without running git. */
9719
+ const gitHead = () => {
9720
+ try {
9721
+ const gitDir = findGitDir(process.cwd());
9722
+ if (gitDir === void 0) return;
9723
+ const head = (0, node_fs.readFileSync)((0, node_path.join)(gitDir, "HEAD"), "utf8").trim();
9724
+ if (!head.startsWith("ref:")) return head;
9725
+ const ref = head.slice(4).trim();
9726
+ const commonFile = (0, node_path.join)(gitDir, "commondir");
9727
+ const commonDir = isFile(commonFile) ? (0, node_path.resolve)(gitDir, (0, node_fs.readFileSync)(commonFile, "utf8").trim()) : gitDir;
9728
+ for (const refsDir of /* @__PURE__ */ new Set([gitDir, commonDir])) {
9729
+ const refFile = (0, node_path.join)(refsDir, ref);
9730
+ if (isFile(refFile)) return (0, node_fs.readFileSync)(refFile, "utf8").trim();
9731
+ }
9732
+ const packedRefs = (0, node_path.join)(commonDir, "packed-refs");
9733
+ if (isFile(packedRefs)) for (const line of (0, node_fs.readFileSync)(packedRefs, "utf8").split("\n")) {
9734
+ const space = line.indexOf(" ");
9735
+ if (space !== -1 && line.slice(space + 1).trim() === ref) return line.slice(0, space);
9736
+ }
9737
+ } catch {
9738
+ return;
9739
+ }
9740
+ };
9741
+ const findGitDir = (start) => {
9742
+ let directory = (0, node_path.resolve)(start);
9743
+ for (;;) {
9744
+ const dotGit = (0, node_path.join)(directory, ".git");
9745
+ if (isDirectory(dotGit)) return dotGit;
9746
+ if (isFile(dotGit)) {
9747
+ const content = (0, node_fs.readFileSync)(dotGit, "utf8").trim();
9748
+ if (content.startsWith("gitdir:")) return (0, node_path.resolve)(directory, content.slice(7).trim());
9749
+ }
9750
+ const parent = (0, node_path.dirname)(directory);
9751
+ if (parent === directory) return;
9752
+ directory = parent;
9753
+ }
9754
+ };
8588
9755
  //#endregion
8589
9756
  //#region src/opentelemetry-lib/tracing/processor.ts
8590
9757
  var LaminarSpanProcessor = class LaminarSpanProcessor {
@@ -8602,11 +9769,15 @@ var LaminarSpanProcessor = class LaminarSpanProcessor {
8602
9769
  * @param {boolean} options.forceHttp - Whether to force HTTP and use OpenTelemetry
8603
9770
  * HTTP/protobuf exporter.
8604
9771
  * Not recommended with Laminar backends.
9772
+ * @param {string} options.release - The release of the running code, usually
9773
+ * its git commit SHA. Detected from the environment if not provided.
8605
9774
  */
8606
9775
  constructor(options = {}) {
8607
9776
  this._spanIdToPath = /* @__PURE__ */ new Map();
8608
9777
  this._spanIdLists = /* @__PURE__ */ new Map();
8609
9778
  this.logger = require_utils.initializeLogger();
9779
+ const wrapped = options.spanProcessor instanceof LaminarSpanProcessor ? options.spanProcessor.release : void 0;
9780
+ this.release = detectRelease(options.release ?? wrapped);
8610
9781
  if (options.spanProcessor && options.spanProcessor instanceof LaminarSpanProcessor) {
8611
9782
  this.instance = options.spanProcessor.instance;
8612
9783
  this._spanIdToPath = options.spanProcessor._spanIdToPath;
@@ -8652,6 +9823,7 @@ var LaminarSpanProcessor = class LaminarSpanProcessor {
8652
9823
  span.setAttribute(require_utils.SPAN_SDK_VERSION, require_utils.version);
8653
9824
  const langVersion = getLangVersion();
8654
9825
  if (langVersion) span.setAttribute(require_utils.SPAN_LANGUAGE_VERSION, langVersion);
9826
+ if (this.release) span.setAttribute(require_utils.SPAN_RELEASE, this.release);
8655
9827
  const globalMetadata = LaminarContextManager.getGlobalMetadata();
8656
9828
  if (globalMetadata && Object.keys(globalMetadata).length > 0) span.setAttributes(require_utils.metadataToAttributes(globalMetadata));
8657
9829
  const associationProperties = _opentelemetry_api.context.active().getValue(ASSOCIATION_PROPERTIES_KEY);
@@ -9464,7 +10636,7 @@ const initInstrumentations = (client, suppressContentTracing, sessionRecordingOp
9464
10636
  instrumentations.push(new CohereInstrumentation({ traceContent: !suppressContentTracing }));
9465
10637
  instrumentations.push(new _traceloop_instrumentation_bedrock.BedrockInstrumentation({ traceContent: !suppressContentTracing }));
9466
10638
  instrumentations.push(new _traceloop_instrumentation_pinecone.PineconeInstrumentation());
9467
- instrumentations.push(new _traceloop_instrumentation_langchain.LangChainInstrumentation({ traceContent: !suppressContentTracing }));
10639
+ instrumentations.push(new LangChainInstrumentation({ traceContent: !suppressContentTracing }));
9468
10640
  instrumentations.push(new _traceloop_instrumentation_together.TogetherInstrumentation({ traceContent: !suppressContentTracing }));
9469
10641
  instrumentations.push(new _traceloop_instrumentation_chromadb.ChromaDBInstrumentation({ traceContent: !suppressContentTracing }));
9470
10642
  instrumentations.push(new _traceloop_instrumentation_qdrant.QdrantInstrumentation({ traceContent: !suppressContentTracing }));
@@ -9520,7 +10692,7 @@ const manuallyInitInstrumentations = (client, instrumentModules, suppressContent
9520
10692
  instrumentation.manuallyInstrument(instrumentModules.pinecone);
9521
10693
  }
9522
10694
  if (instrumentModules?.langchain) {
9523
- const langchainInstrumentation = new _traceloop_instrumentation_langchain.LangChainInstrumentation({ traceContent: !suppressContentTracing });
10695
+ const langchainInstrumentation = new LangChainInstrumentation({ traceContent: !suppressContentTracing });
9524
10696
  instrumentations.push(langchainInstrumentation);
9525
10697
  langchainInstrumentation.manuallyInstrument(instrumentModules.langchain);
9526
10698
  }
@@ -9684,7 +10856,8 @@ const startTracing = (options) => {
9684
10856
  maxExportBatchSizeBytes: options.maxExportBatchSizeBytes,
9685
10857
  flushBySize: options.flushBySize,
9686
10858
  exporter: options.exporter,
9687
- disableBatch: options.disableBatch
10859
+ disableBatch: options.disableBatch,
10860
+ release: options.release
9688
10861
  });
9689
10862
  const newProvider = new _opentelemetry_sdk_trace_node.NodeTracerProvider({
9690
10863
  spanProcessors: [spanProcessor],