@lmnr-ai/lmnr 0.8.44 → 0.8.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/cli.cjs +23 -25
  2. package/dist/cli.cjs.map +1 -1
  3. package/dist/cli.d.cts +1 -1
  4. package/dist/cli.d.mts +1 -1
  5. package/dist/cli.mjs +7 -8
  6. package/dist/cli.mjs.map +1 -1
  7. package/dist/{evaluations-RbBZb5yl.d.cts → evaluations-BHEE6fmA.d.cts} +17934 -8631
  8. package/dist/{evaluations-CVo0ms_r.d.mts → evaluations-BbIIQMLr.d.mts} +17934 -8631
  9. package/dist/{file-utils-1olUHMKC.mjs → file-utils-BtzEDUy6.mjs} +2 -2
  10. package/dist/file-utils-BtzEDUy6.mjs.map +1 -0
  11. package/dist/{file-utils-CMO5MuV9.cjs → file-utils-pZG20hHb.cjs} +6 -6
  12. package/dist/file-utils-pZG20hHb.cjs.map +1 -0
  13. package/dist/index.cjs +574 -435
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +1533 -437
  16. package/dist/index.d.mts +1533 -437
  17. package/dist/index.mjs +287 -148
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.cjs +159 -62
  20. package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.cjs.map +1 -1
  21. package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.d.cts +3388 -250
  22. package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.d.mts +3388 -250
  23. package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.mjs +159 -62
  24. package/dist/opentelemetry-lib/instrumentation/temporal/workflow-interceptors.mjs.map +1 -1
  25. package/dist/{dist-BtB31bk1.cjs → utils-CatgN6Pb.cjs} +558 -558
  26. package/dist/utils-CatgN6Pb.cjs.map +1 -0
  27. package/dist/{dist-Cjres0a5.mjs → utils-UmlDPMxe.mjs} +552 -552
  28. package/dist/utils-UmlDPMxe.mjs.map +1 -0
  29. package/package.json +30 -30
  30. package/dist/dist-BtB31bk1.cjs.map +0 -1
  31. package/dist/dist-Cjres0a5.mjs.map +0 -1
  32. package/dist/file-utils-1olUHMKC.mjs.map +0 -1
  33. package/dist/file-utils-CMO5MuV9.cjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  import { r as __require } from "./rolldown-runtime-2rV9d50f.mjs";
2
- import { A as SPAN_INSTRUMENTATION_SCOPE_VERSION, B as version, C as LaminarAttributes, D as SPAN_IDS_PATH, E as SESSION_ID, F as SPAN_SDK_VERSION, H as DEBUG_SESSION_FILE, I as SPAN_TYPE, L as TRACE_HAS_BROWSER_SESSION, M as SPAN_LANGUAGE_VERSION, N as SPAN_OUTPUT, O as SPAN_INPUT, P as SPAN_PATH, R as TRACE_TYPE, S as HUMAN_EVALUATOR_OPTIONS, T as PARENT_SPAN_PATH, U as TracingLevel, V as DEBUG_SESSION_DIR, W as errorMessage, _ as truncateSpanPayload, b as ASSOCIATION_PROPERTIES, c as initializeLogger, d as newUUID, f as normalizeOtelSpanId, g as parseOtelHeaders, h as otelTraceIdToUUID, i as deserializeLaminarSpanContext, j as SPAN_INSTRUMENTATION_SOURCE, k as SPAN_INSTRUMENTATION_SCOPE_NAME, l as loadEnv, m as otelSpanIdToUUID, n as NIL_UUID, o as getFrontendUrl, p as normalizeOtelTraceId, r as Semaphore, s as getOtelEnvVar, t as LaminarClient, u as metadataToAttributes, v as tryToOtelSpanContext, w as PARENT_SPAN_IDS_PATH, x as ASSOCIATION_PROPERTIES_OVERRIDES, y as validateTracingConfig, z as USER_ID } from "./dist-Cjres0a5.mjs";
2
+ import { A as SPAN_INSTRUMENTATION_SOURCE, B as LaminarClient, C as PARENT_SPAN_IDS_PATH, D as SPAN_INPUT, E as SPAN_IDS_PATH, F as SPAN_TYPE, H as DEBUG_SESSION_FILE, I as TRACE_HAS_BROWSER_SESSION, L as TRACE_TYPE, M as SPAN_OUTPUT, N as SPAN_PATH, O as SPAN_INSTRUMENTATION_SCOPE_NAME, P as SPAN_SDK_VERSION, R as USER_ID, S as LaminarAttributes, T as SESSION_ID, U as TracingLevel, V as DEBUG_SESSION_DIR, W as errorMessage, _ as tryToOtelSpanContext, a as getFrontendUrl, b as ASSOCIATION_PROPERTIES_OVERRIDES, c as loadEnv, d as normalizeOtelSpanId, f as normalizeOtelTraceId, g as truncateSpanPayload, h as parseOtelHeaders, j as SPAN_LANGUAGE_VERSION, k as SPAN_INSTRUMENTATION_SCOPE_VERSION, l as metadataToAttributes, m as otelTraceIdToUUID, n as Semaphore, o as getOtelEnvVar, p as otelSpanIdToUUID, r as deserializeLaminarSpanContext, s as initializeLogger, t as NIL_UUID, u as newUUID, v as validateTracingConfig, w as PARENT_SPAN_PATH, x as HUMAN_EVALUATOR_OPTIONS, y as ASSOCIATION_PROPERTIES, z as version } from "./utils-UmlDPMxe.mjs";
3
3
  import { n as TRACEPARENT_HEADER, t as LAMINAR_SPAN_CONTEXT_HEADER } from "./consts-CTTu3jhI.mjs";
4
+ import * as path from "path";
4
5
  import { DiagConsoleLogger, DiagLogLevel, ROOT_CONTEXT, SpanKind, SpanStatusCode, TraceFlags, context, createContextKey, diag, isSpanContextValid, trace } from "@opentelemetry/api";
5
6
  import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks";
6
7
  import { InstrumentationBase, InstrumentationNodeModuleDefinition, registerInstrumentations } from "@opentelemetry/instrumentation";
7
8
  import { AlwaysOnSampler, BatchSpanProcessor, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
8
9
  import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
9
10
  import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from "@opentelemetry/semantic-conventions";
10
- import * as path from "path";
11
11
  import { AnthropicInstrumentation } from "@traceloop/instrumentation-anthropic";
12
12
  import { BedrockInstrumentation } from "@traceloop/instrumentation-bedrock";
13
13
  import { ChromaDBInstrumentation } from "@traceloop/instrumentation-chromadb";
@@ -176,7 +176,7 @@ var LaminarDataset = class extends EvaluationDataset {
176
176
  */
177
177
  async push(paths, recursive = false) {
178
178
  if (!this.client) throw new Error("Client not set");
179
- const { loadFromPaths } = await import("./file-utils-1olUHMKC.mjs").then((n) => n.t);
179
+ const { loadFromPaths } = await import("./file-utils-BtzEDUy6.mjs").then((n) => n.t);
180
180
  const data = await loadFromPaths(Array.isArray(paths) ? paths : [paths], recursive);
181
181
  if (data.length === 0) {
182
182
  console.warn("No data to push. Skipping");
@@ -192,7 +192,7 @@ var LaminarDataset = class extends EvaluationDataset {
192
192
  };
193
193
  //#endregion
194
194
  //#region src/opentelemetry-lib/tracing/compat.ts
195
- const logger$25 = initializeLogger();
195
+ const logger$26 = initializeLogger();
196
196
  const makeSpanOtelV2Compatible = (span) => {
197
197
  const spanAny = span;
198
198
  if (spanAny.instrumentationScope && !spanAny.instrumentationLibrary) Object.assign(span, { instrumentationLibrary: spanAny.instrumentationScope });
@@ -238,7 +238,7 @@ const createResource = (attributes) => {
238
238
  if (resources.Resource) return new resources.Resource(attributes);
239
239
  throw new Error("Unable to create Resource: neither v1 nor v2 API found");
240
240
  } catch {
241
- logger$25.debug("Laminar failed to @opentelemetry/resources, continuing without it");
241
+ logger$26.debug("Laminar failed to @opentelemetry/resources, continuing without it");
242
242
  return;
243
243
  }
244
244
  };
@@ -271,6 +271,23 @@ function convertUint8ArrayToBase64(array) {
271
271
  return btoa(latin1string);
272
272
  }
273
273
  /**
274
+ * Checks whether `key` looks like an AI SDK stream property WITHOUT reading it.
275
+ *
276
+ * Reading is not safe here: AI SDK exposes `textStream` / `fullStream` as getters that build a
277
+ * fresh stream on every access. On `streamText` that tees (and mutates) the internal base stream,
278
+ * leaving an abandoned branch that buffers the whole response; on `streamObject` it `pipeThrough`s
279
+ * the base stream directly, permanently LOCKING it so the caller's own access throws. So we only
280
+ * inspect the property descriptor: AI SDK's are accessors, whereas a same-named host API (e.g.
281
+ * Node 26's `Response.prototype.textStream`) is a data property holding a method.
282
+ */
283
+ const hasStreamAccessor = (obj, key) => {
284
+ for (let o = obj; o !== null; o = Object.getPrototypeOf(o)) {
285
+ const descriptor = Object.getOwnPropertyDescriptor(o, key);
286
+ if (descriptor) return typeof descriptor.value !== "function";
287
+ }
288
+ return false;
289
+ };
290
+ /**
274
291
  * This function checks if an object is stream or stream-like, and returns information
275
292
  * about the stream type and how to handle it.
276
293
  * @param response - The result of a function, either an AI SDK result, a raw stream, or any other
@@ -279,10 +296,6 @@ function convertUint8ArrayToBase64(array) {
279
296
  */
280
297
  const getStream = (response) => {
281
298
  if (!response || typeof response !== "object") return { type: null };
282
- if ("textStream" in response || "fullStream" in response) return {
283
- type: "aisdk-result",
284
- result: response
285
- };
286
299
  if (response instanceof Response) return {
287
300
  type: "response",
288
301
  response
@@ -291,6 +304,10 @@ const getStream = (response) => {
291
304
  type: "readable-stream",
292
305
  stream: response
293
306
  };
307
+ if (hasStreamAccessor(response, "textStream") || hasStreamAccessor(response, "fullStream")) return {
308
+ type: "aisdk-result",
309
+ result: response
310
+ };
294
311
  if (Symbol.asyncIterator in response && !(response instanceof ReadableStream)) return {
295
312
  type: "async-iterable",
296
313
  iterable: response
@@ -423,7 +440,7 @@ const consumeResponse = async (response) => {
423
440
  };
424
441
  //#endregion
425
442
  //#region src/opentelemetry-lib/tracing/stream-utils.ts
426
- const logger$24 = initializeLogger();
443
+ const logger$25 = initializeLogger();
427
444
  const pendingStreamProcessing = /* @__PURE__ */ new Set();
428
445
  /**
429
446
  * Wait for all pending stream processing to complete with a timeout
@@ -431,7 +448,7 @@ const pendingStreamProcessing = /* @__PURE__ */ new Set();
431
448
  */
432
449
  const waitForPendingStreams = async (timeoutMs = 5e3) => {
433
450
  if (pendingStreamProcessing.size === 0) return;
434
- logger$24.debug(`Waiting for ${pendingStreamProcessing.size} pending stream(s)`);
451
+ logger$25.debug(`Waiting for ${pendingStreamProcessing.size} pending stream(s)`);
435
452
  const initialCount = pendingStreamProcessing.size;
436
453
  const pendingPromises = Array.from(pendingStreamProcessing);
437
454
  let timedOut = false;
@@ -442,7 +459,7 @@ const waitForPendingStreams = async (timeoutMs = 5e3) => {
442
459
  }, timeoutMs);
443
460
  });
444
461
  await Promise.race([Promise.allSettled(pendingPromises), timeoutPromise]);
445
- if (timedOut && pendingStreamProcessing.size > 0) logger$24.warn(`Timeout waiting for ${pendingStreamProcessing.size} pending stream(s) after ${timeoutMs}ms (started with ${initialCount})`);
462
+ if (timedOut && pendingStreamProcessing.size > 0) logger$25.warn(`Timeout waiting for ${pendingStreamProcessing.size} pending stream(s) after ${timeoutMs}ms (started with ${initialCount})`);
446
463
  };
447
464
  /**
448
465
  * Track a background promise and ensure cleanup
@@ -458,34 +475,34 @@ const trackStreamProcessing = (task) => {
458
475
  * while passing through the original result to the caller
459
476
  */
460
477
  const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, serialize) => {
461
- logger$24.debug(`Handling stream result of type: ${streamInfo.type}`);
478
+ logger$25.debug(`Handling stream result of type: ${streamInfo.type}`);
462
479
  if (streamInfo.type === "aisdk-result") {
463
480
  trackStreamProcessing(async () => {
464
- logger$24.debug("Starting background processing for AI SDK result");
481
+ logger$25.debug("Starting background processing for AI SDK result");
465
482
  let partialOutput = {};
466
483
  try {
467
484
  partialOutput = await consumeAISDKResult(streamInfo.result);
468
485
  if (shouldSendTraces() && !ignoreOutput) try {
469
486
  span.setAttribute(SPAN_OUTPUT, serialize(partialOutput));
470
487
  } catch (error) {
471
- logger$24.warn("Failed to serialize AI SDK stream output: " + errorMessage(error));
488
+ logger$25.warn("Failed to serialize AI SDK stream output: " + errorMessage(error));
472
489
  }
473
490
  } catch (error) {
474
491
  if (Object.keys(partialOutput).length > 0 && shouldSendTraces() && !ignoreOutput) try {
475
492
  span.setAttribute(SPAN_OUTPUT, serialize(partialOutput));
476
493
  } catch (serError) {
477
- logger$24.warn("Failed to serialize partial AI SDK output: " + errorMessage(serError));
494
+ logger$25.warn("Failed to serialize partial AI SDK output: " + errorMessage(serError));
478
495
  }
479
496
  span.recordException(error);
480
497
  } finally {
481
- logger$24.debug("Ending span for AI SDK result");
498
+ logger$25.debug("Ending span for AI SDK result");
482
499
  span.end();
483
500
  }
484
501
  });
485
502
  return originalResult;
486
503
  }
487
504
  if (streamInfo.type === "readable-stream") {
488
- logger$24.debug("Setting up background processing for ReadableStream");
505
+ logger$25.debug("Setting up background processing for ReadableStream");
489
506
  const { stream, dataPromise } = consumeAndTeeReadableStream(streamInfo.stream);
490
507
  trackStreamProcessing(async () => {
491
508
  try {
@@ -497,18 +514,18 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
497
514
  };
498
515
  span.setAttribute(SPAN_OUTPUT, serialize(output));
499
516
  } catch (serError) {
500
- logger$24.warn("Failed to serialize stream output: " + errorMessage(serError));
517
+ logger$25.warn("Failed to serialize stream output: " + errorMessage(serError));
501
518
  }
502
519
  if (error) span.recordException(error);
503
520
  } finally {
504
- logger$24.debug("Ending span for ReadableStream");
521
+ logger$25.debug("Ending span for ReadableStream");
505
522
  span.end();
506
523
  }
507
524
  });
508
525
  return stream;
509
526
  }
510
527
  if (streamInfo.type === "async-iterable") {
511
- logger$24.debug("Setting up background processing for AsyncIterable");
528
+ logger$25.debug("Setting up background processing for AsyncIterable");
512
529
  const { iterable, dataPromise } = consumeAndTeeAsyncIterable(streamInfo.iterable);
513
530
  trackStreamProcessing(async () => {
514
531
  try {
@@ -520,18 +537,18 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
520
537
  };
521
538
  span.setAttribute(SPAN_OUTPUT, serialize(output));
522
539
  } catch (serError) {
523
- logger$24.warn("Failed to serialize async iterable output: " + errorMessage(serError));
540
+ logger$25.warn("Failed to serialize async iterable output: " + errorMessage(serError));
524
541
  }
525
542
  if (error) span.recordException(error);
526
543
  } finally {
527
- logger$24.debug("Ending span for AsyncIterable");
544
+ logger$25.debug("Ending span for AsyncIterable");
528
545
  span.end();
529
546
  }
530
547
  });
531
548
  return iterable;
532
549
  }
533
550
  if (streamInfo.type === "response") {
534
- logger$24.debug("Setting up background processing for Response");
551
+ logger$25.debug("Setting up background processing for Response");
535
552
  const originalResponse = streamInfo.response;
536
553
  if (!originalResponse.body) {
537
554
  span.end();
@@ -553,19 +570,19 @@ const handleStreamResult = (originalResult, streamInfo, span, ignoreOutput, seri
553
570
  };
554
571
  span.setAttribute(SPAN_OUTPUT, serialize(output));
555
572
  } catch (serError) {
556
- logger$24.warn("Failed to serialize response output: " + errorMessage(serError));
573
+ logger$25.warn("Failed to serialize response output: " + errorMessage(serError));
557
574
  }
558
575
  if (error) span.recordException(error);
559
576
  } catch (err) {
560
577
  span.recordException(err);
561
578
  } finally {
562
- logger$24.debug("Ending span for Response");
579
+ logger$25.debug("Ending span for Response");
563
580
  span.end();
564
581
  }
565
582
  });
566
583
  return newResponse;
567
584
  }
568
- logger$24.warn("Stream type not handled, ending span immediately");
585
+ logger$25.warn("Stream type not handled, ending span immediately");
569
586
  span.end();
570
587
  return originalResult;
571
588
  };
@@ -643,7 +660,7 @@ const writeDebugSessionFile = (file, dir = process.cwd()) => {
643
660
  * contract. This file is part of the cross-language parity surface — keep its
644
661
  * logic line-comparable with the Python `config.py`.
645
662
  */
646
- const logger$23 = initializeLogger();
663
+ const logger$24 = initializeLogger();
647
664
  const TRUTHY = new Set([
648
665
  "true",
649
666
  "1",
@@ -679,7 +696,7 @@ const parseCacheUntil = (value) => {
679
696
  if (value === void 0 || value === "") return null;
680
697
  const spanId = normalizeSpanId(value);
681
698
  if (spanId !== null) return spanId;
682
- logger$23.warn(`LMNR_DEBUG_CACHE_UNTIL=${JSON.stringify(value)} is not a span id; ignoring`);
699
+ logger$24.warn(`LMNR_DEBUG_CACHE_UNTIL=${JSON.stringify(value)} is not a span id; ignoring`);
683
700
  return null;
684
701
  };
685
702
  /**
@@ -1030,7 +1047,7 @@ const resetDebugRuntime = () => {
1030
1047
  };
1031
1048
  //#endregion
1032
1049
  //#region src/opentelemetry-lib/tracing/span.ts
1033
- const logger$22 = initializeLogger();
1050
+ const logger$23 = initializeLogger();
1034
1051
  /**
1035
1052
  * Build the debug block to propagate, or undefined when debug mode is off.
1036
1053
  *
@@ -1180,7 +1197,7 @@ var LaminarSpan = class LaminarSpan {
1180
1197
  } catch {}
1181
1198
  metadata[key.replace(`${ASSOCIATION_PROPERTIES}.metadata.`, "")] = value;
1182
1199
  }
1183
- } else logger$22.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.");
1200
+ } else logger$23.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.");
1184
1201
  return {
1185
1202
  spanId: otelSpanIdToUUID(this._span.spanContext().spanId),
1186
1203
  traceId: otelTraceIdToUUID(this._span.spanContext().traceId),
@@ -1207,14 +1224,14 @@ var LaminarSpan = class LaminarSpan {
1207
1224
  }
1208
1225
  get tags() {
1209
1226
  if (!this._span.attributes) {
1210
- logger$22.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.");
1227
+ logger$23.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.");
1211
1228
  return [];
1212
1229
  }
1213
1230
  return this._span.attributes[`lmnr.association.properties.tags`] ?? [];
1214
1231
  }
1215
1232
  get laminarAssociationProperties() {
1216
1233
  if (!this._span.attributes) {
1217
- logger$22.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.");
1234
+ logger$23.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.");
1218
1235
  return {};
1219
1236
  }
1220
1237
  try {
@@ -1410,7 +1427,7 @@ var LaminarContextManager = class {
1410
1427
  };
1411
1428
  //#endregion
1412
1429
  //#region src/opentelemetry-lib/instrumentation/claude-agent-sdk/proxy.ts
1413
- const logger$21 = initializeLogger();
1430
+ const logger$22 = initializeLogger();
1414
1431
  const DEFAULT_ANTHROPIC_BASE_URL = "https://api.anthropic.com";
1415
1432
  const DEFAULT_CC_PROXY_PORT = 45667;
1416
1433
  const CC_PROXY_PORT_ATTEMPTS = 50;
@@ -1662,7 +1679,7 @@ const resolveTargetUrlFromEnv = (envDict, fallback = DEFAULT_ANTHROPIC_BASE_URL,
1662
1679
  if (foundryBaseUrl) return foundryBaseUrl.replace(/\/$/, "");
1663
1680
  const foundryResource = getEnvValue(FOUNDRY_RESOURCE_ENV);
1664
1681
  if (foundryResource) return `https://${foundryResource}.services.ai.azure.com/anthropic`;
1665
- logger$21.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.`);
1682
+ logger$22.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.`);
1666
1683
  return null;
1667
1684
  }
1668
1685
  if (isTruthyEnv(getEnvValue(BEDROCK_USE_ENV))) {
@@ -1671,7 +1688,7 @@ const resolveTargetUrlFromEnv = (envDict, fallback = DEFAULT_ANTHROPIC_BASE_URL,
1671
1688
  let region = getEnvValue(BEDROCK_AWS_REGION_ENV);
1672
1689
  if (!region) region = getRegionFromAwsConfig(getEnvValue("AWS_PROFILE") || "default") ?? void 0;
1673
1690
  if (region) return `https://bedrock-runtime.${region}.amazonaws.com`;
1674
- logger$21.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.`);
1691
+ logger$22.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.`);
1675
1692
  return null;
1676
1693
  }
1677
1694
  if (isTruthyEnv(getEnvValue(VERTEX_USE_ENV))) {
@@ -1754,11 +1771,11 @@ const waitForPort = (port, timeoutMs = 5e3) => new Promise((resolve) => {
1754
1771
  const registerGlobalProxyShutdown = () => {
1755
1772
  if (!globalShutdownRegistered) {
1756
1773
  process.on("exit", () => {
1757
- logger$21.debug("process.on(\"exit\") called - stopping all active proxies");
1774
+ logger$22.debug("process.on(\"exit\") called - stopping all active proxies");
1758
1775
  for (const proxyServer of activeProxyServers) try {
1759
1776
  proxyServer.stopServer();
1760
1777
  } catch (e) {
1761
- logger$21.debug(`Failed to stop proxy: ${errorMessage(e)}`);
1778
+ logger$22.debug(`Failed to stop proxy: ${errorMessage(e)}`);
1762
1779
  }
1763
1780
  activeProxyServers.clear();
1764
1781
  });
@@ -1773,28 +1790,28 @@ const createProxyInstance = async ({ env, cwd, settingSources, settings, targetU
1773
1790
  try {
1774
1791
  const port = await findAvailablePort(DEFAULT_CC_PROXY_PORT, CC_PROXY_PORT_ATTEMPTS);
1775
1792
  if (port === null) {
1776
- logger$21.warn("Unable to allocate port for cc-proxy.");
1793
+ logger$22.warn("Unable to allocate port for cc-proxy.");
1777
1794
  return null;
1778
1795
  }
1779
1796
  const targetUrl = resolvedTargetUrl ?? resolveTargetUrlFromEnv(env, void 0, cwd, settingSources, settings);
1780
1797
  if (!targetUrl) {
1781
- logger$21.warn("Unable to resolve target URL for cc-proxy (provider misconfigured).");
1798
+ logger$22.warn("Unable to resolve target URL for cc-proxy (provider misconfigured).");
1782
1799
  return null;
1783
1800
  }
1784
- logger$21.debug(`Creating proxy instance on port ${port} targeting: ${targetUrl}`);
1801
+ logger$22.debug(`Creating proxy instance on port ${port} targeting: ${targetUrl}`);
1785
1802
  try {
1786
1803
  const { ProxyServer } = __require("@lmnr-ai/claude-code-proxy");
1787
1804
  const proxyServer = new ProxyServer(port);
1788
1805
  proxyServer.runServer(targetUrl);
1789
1806
  if (!await waitForPort(port)) {
1790
- logger$21.warn(`cc-proxy failed to start on port ${port}`);
1807
+ logger$22.warn(`cc-proxy failed to start on port ${port}`);
1791
1808
  proxyServer.stopServer();
1792
1809
  return null;
1793
1810
  }
1794
1811
  const proxyBaseUrl = `http://127.0.0.1:${port}`;
1795
1812
  activeProxyServers.add(proxyServer);
1796
1813
  registerGlobalProxyShutdown();
1797
- logger$21.info(`Started claude proxy server on: ${proxyBaseUrl}`);
1814
+ logger$22.info(`Started claude proxy server on: ${proxyBaseUrl}`);
1798
1815
  return {
1799
1816
  server: proxyServer,
1800
1817
  baseUrl: proxyBaseUrl,
@@ -1802,11 +1819,11 @@ const createProxyInstance = async ({ env, cwd, settingSources, settings, targetU
1802
1819
  targetUrl
1803
1820
  };
1804
1821
  } catch (e) {
1805
- logger$21.warn(`Unable to start cc-proxy: ${errorMessage(e)}`);
1822
+ logger$22.warn(`Unable to start cc-proxy: ${errorMessage(e)}`);
1806
1823
  return null;
1807
1824
  }
1808
1825
  } catch (e) {
1809
- logger$21.warn(`Failed to create proxy instance: ${errorMessage(e)}`);
1826
+ logger$22.warn(`Failed to create proxy instance: ${errorMessage(e)}`);
1810
1827
  return null;
1811
1828
  }
1812
1829
  };
@@ -1816,11 +1833,11 @@ const createProxyInstance = async ({ env, cwd, settingSources, settings, targetU
1816
1833
  const stopProxyInstance = (instance) => {
1817
1834
  if (!instance) return;
1818
1835
  try {
1819
- logger$21.debug(`Stopping proxy instance on port ${instance.port}`);
1836
+ logger$22.debug(`Stopping proxy instance on port ${instance.port}`);
1820
1837
  instance.server.stopServer();
1821
1838
  activeProxyServers.delete(instance.server);
1822
1839
  } catch (e) {
1823
- logger$21.debug(`Failed to stop proxy instance: ${errorMessage(e)}`);
1840
+ logger$22.debug(`Failed to stop proxy instance: ${errorMessage(e)}`);
1824
1841
  }
1825
1842
  };
1826
1843
  /**
@@ -1828,11 +1845,11 @@ const stopProxyInstance = (instance) => {
1828
1845
  * Used during shutdown to ensure cleanup
1829
1846
  */
1830
1847
  const forceReleaseProxy = () => {
1831
- logger$21.debug(`Force stopping all ${activeProxyServers.size} active proxy servers`);
1848
+ logger$22.debug(`Force stopping all ${activeProxyServers.size} active proxy servers`);
1832
1849
  for (const proxyServer of activeProxyServers) try {
1833
1850
  proxyServer.stopServer();
1834
1851
  } catch (e) {
1835
- logger$21.debug(`Failed to stop proxy: ${errorMessage(e)}`);
1852
+ logger$22.debug(`Failed to stop proxy: ${errorMessage(e)}`);
1836
1853
  }
1837
1854
  activeProxyServers.clear();
1838
1855
  };
@@ -1882,14 +1899,14 @@ const setTraceToProxyInstance = async (instance) => {
1882
1899
  spanPath: payload.span_path,
1883
1900
  laminarUrl: payload.laminar_url
1884
1901
  });
1885
- logger$21.debug(`Set trace context to proxy on port ${instance.port}`);
1902
+ logger$22.debug(`Set trace context to proxy on port ${instance.port}`);
1886
1903
  } catch (e) {
1887
- logger$21.debug(`Unable to set trace context to proxy on port ${instance.port}: ` + errorMessage(e));
1904
+ logger$22.debug(`Unable to set trace context to proxy on port ${instance.port}: ` + errorMessage(e));
1888
1905
  }
1889
1906
  };
1890
1907
  //#endregion
1891
1908
  //#region src/opentelemetry-lib/instrumentation/claude-agent-sdk/index.ts
1892
- const logger$20 = initializeLogger();
1909
+ const logger$21 = initializeLogger();
1893
1910
  /**
1894
1911
  * Create an instrumented version of the claude-agent-sdk query function.
1895
1912
  * This can be used when importing the query function before Laminar initialization.
@@ -1925,9 +1942,9 @@ function instrumentClaudeAgentQuery(originalQuery) {
1925
1942
  targetUrl
1926
1943
  });
1927
1944
  if (proxyInstance && targetUrl) {
1928
- logger$20.debug(`Using proxy on port ${proxyInstance.port}`);
1945
+ logger$21.debug(`Using proxy on port ${proxyInstance.port}`);
1929
1946
  await Laminar.withSpan(span, async () => {
1930
- logger$20.debug("Setting trace to proxy instance...");
1947
+ logger$21.debug("Setting trace to proxy instance...");
1931
1948
  await setTraceToProxyInstance(proxyInstance);
1932
1949
  });
1933
1950
  const varsToRemove = getEnvVarsToRemove(mergedEnv, sessionCwd, settingSources);
@@ -1942,13 +1959,13 @@ function instrumentClaudeAgentQuery(originalQuery) {
1942
1959
  if (isProviderEnabledInEnv(subprocessEnv, "CLAUDE_CODE_USE_BEDROCK")) subprocessEnv.ANTHROPIC_BEDROCK_BASE_URL = proxyInstance.baseUrl;
1943
1960
  if (isProviderEnabledInEnv(subprocessEnv, "CLAUDE_CODE_USE_VERTEX")) subprocessEnv.ANTHROPIC_VERTEX_BASE_URL = proxyInstance.baseUrl;
1944
1961
  const flagSettings = buildProxyFlagSettings(callerSettings, proxyInstance.baseUrl, sessionCwd, settingSources);
1945
- if (flagSettings === null) logger$20.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.`);
1962
+ if (flagSettings === null) logger$21.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.`);
1946
1963
  else {
1947
1964
  params.options.settings = flagSettings;
1948
- const conflicting = Object.entries(readClaudeSettingsEnv(sessionCwd, settingSources)).filter(([key, value]) => PROXY_BASE_URL_ENV_KEYS.includes(key) && value !== "" && value !== proxyInstance.baseUrl).map(([key]) => key);
1949
- if (conflicting.length > 0) logger$20.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.`);
1965
+ const conflicting = Object.entries(readClaudeSettingsEnv(sessionCwd, settingSources)).filter(([key, value]) => PROXY_BASE_URL_ENV_KEYS.includes(key) && value !== "" && value !== proxyInstance?.baseUrl).map(([key]) => key);
1966
+ if (conflicting.length > 0) logger$21.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.`);
1950
1967
  }
1951
- } else logger$20.debug("No claude proxy server available. Proceeding without proxy.");
1968
+ } else logger$21.debug("No claude proxy server available. Proceeding without proxy.");
1952
1969
  const originalGenerator = originalQuery(params);
1953
1970
  for await (const message of originalGenerator) {
1954
1971
  collected.push(message);
@@ -1977,7 +1994,7 @@ var ClaudeAgentSDKInstrumentation = class extends InstrumentationBase {
1977
1994
  }
1978
1995
  manuallyInstrument(claudeAgentModule) {
1979
1996
  if (claudeAgentModule.query && typeof claudeAgentModule.query === "function") this._wrap(claudeAgentModule, "query", this.patchQuery());
1980
- else logger$20.debug("query function not found in claudeAgentSDK module, skipping instrumentation");
1997
+ else logger$21.debug("query function not found in claudeAgentSDK module, skipping instrumentation");
1981
1998
  }
1982
1999
  patchQuery() {
1983
2000
  return (original) => instrumentClaudeAgentQuery(original);
@@ -1995,7 +2012,7 @@ var ClaudeAgentSDKInstrumentation = class extends InstrumentationBase {
1995
2012
  //#endregion
1996
2013
  //#region src/laminar.ts
1997
2014
  loadEnv();
1998
- const logger$19 = initializeLogger();
2015
+ const logger$20 = initializeLogger();
1999
2016
  var Laminar = class Laminar {
2000
2017
  static {
2001
2018
  this.isInitialized = false;
@@ -2047,6 +2064,13 @@ var Laminar = class Laminar {
2047
2064
  * @param {string} props.logLevel - OTel log level. Defaults to "error".
2048
2065
  * @param {number} props.maxExportBatchSize - Maximum number of spans to export in a single batch.
2049
2066
  * Ignored when `disableBatch` is true.
2067
+ * @param {boolean} props.flushBySize - Whether to also flush batches by approximate payload
2068
+ * size, not just by span count and schedule delay. The batch is flushed when the next span
2069
+ * would push it past `maxExportBatchSizeBytes`, so a few large spans are exported without
2070
+ * waiting for `maxExportBatchSize` spans to accumulate. Useful when spans carry large prompts
2071
+ * or completions and exports get rejected for being too big. Defaults to false.
2072
+ * @param {number} props.maxExportBatchSizeBytes - Approximate maximum size, in bytes, of the
2073
+ * spans buffered in one batch. Only used when `flushBySize` is true. Defaults to 32 MiB.
2050
2074
  * @param {boolean} props.forceHttp - Whether to force HTTP export. Not recommended.
2051
2075
  * @param {SessionRecordingOptions} props.sessionRecordingOptions - Options for browser
2052
2076
  * session recording.
@@ -2079,9 +2103,9 @@ var Laminar = class Laminar {
2079
2103
  *
2080
2104
  * @throws {Error} - If project API key is not set
2081
2105
  */
2082
- static initialize({ projectApiKey, baseUrl, baseHttpUrl, httpPort, grpcPort, instrumentModules, disableBatch, traceExportTimeoutMillis, logLevel, maxExportBatchSize, forceHttp, sessionRecordingOptions, metadata, inheritGlobalContext, spanProcessor } = {}) {
2106
+ static initialize({ projectApiKey, baseUrl, baseHttpUrl, httpPort, grpcPort, instrumentModules, disableBatch, traceExportTimeoutMillis, logLevel, maxExportBatchSize, maxExportBatchSizeBytes, flushBySize, forceHttp, sessionRecordingOptions, metadata, inheritGlobalContext, spanProcessor } = {}) {
2083
2107
  if (this.isInitialized) {
2084
- logger$19.warn("Laminar has already been initialized. Skipping initialization.");
2108
+ logger$20.warn("Laminar has already been initialized. Skipping initialization.");
2085
2109
  return;
2086
2110
  }
2087
2111
  const key = projectApiKey ?? process?.env?.LMNR_PROJECT_API_KEY;
@@ -2105,7 +2129,7 @@ var Laminar = class Laminar {
2105
2129
  ...metadata ?? {}
2106
2130
  };
2107
2131
  if (inheritGlobalContext) LaminarContextManager.inheritGlobalContext = true;
2108
- if (spanProcessor && !(spanProcessor instanceof LaminarSpanProcessor)) logger$19.warn("Span processor is not a LaminarSpanProcessor. Some functionality may be impaired.");
2132
+ if (spanProcessor && !(spanProcessor instanceof LaminarSpanProcessor)) logger$20.warn("Span processor is not a LaminarSpanProcessor. Some functionality may be impaired.");
2109
2133
  this.isInitialized = true;
2110
2134
  const urlWithoutSlash = url?.replace(/\/$/, "").replace(/:\d{1,5}$/g, "");
2111
2135
  const httpUrlWithoutSlash = httpUrl?.replace(/\/$/, "").replace(/:\d{1,5}$/g, "");
@@ -2121,6 +2145,8 @@ var Laminar = class Laminar {
2121
2145
  logLevel: logLevel ?? "error",
2122
2146
  disableBatch,
2123
2147
  maxExportBatchSize,
2148
+ maxExportBatchSizeBytes,
2149
+ flushBySize,
2124
2150
  traceExportTimeoutMillis,
2125
2151
  sessionRecordingOptions,
2126
2152
  spanProcessor
@@ -2150,11 +2176,11 @@ var Laminar = class Laminar {
2150
2176
  try {
2151
2177
  getRuntime()?.recordTraceId(otelTraceIdToUUID(otelSpanContext.traceId));
2152
2178
  } catch (e) {
2153
- logger$19.debug("Failed to record debug trace id from env: " + errorMessage(e));
2179
+ logger$20.debug("Failed to record debug trace id from env: " + errorMessage(e));
2154
2180
  }
2155
- logger$19.debug("Initialized Laminar parent context from LMNR_SPAN_CONTEXT.");
2181
+ logger$20.debug("Initialized Laminar parent context from LMNR_SPAN_CONTEXT.");
2156
2182
  } catch (e) {
2157
- logger$19.warn("LMNR_SPAN_CONTEXT is set but could not be used: " + errorMessage(e));
2183
+ logger$20.warn("LMNR_SPAN_CONTEXT is set but could not be used: " + errorMessage(e));
2158
2184
  }
2159
2185
  }
2160
2186
  /**
@@ -2198,14 +2224,14 @@ var Laminar = class Laminar {
2198
2224
  if (projectId) {
2199
2225
  runtime.recordProjectId(projectId);
2200
2226
  const sessionUrl = runtime.debuggerSessionUrl();
2201
- logger$19.info(`Laminar debugger session: ${sessionUrl}`);
2227
+ logger$20.info(`Laminar debugger session: ${sessionUrl}`);
2202
2228
  if (runtime.shouldOpenBrowser) spawn(process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open", [sessionUrl], {
2203
2229
  detached: true,
2204
2230
  stdio: "ignore"
2205
2231
  }).unref();
2206
2232
  }
2207
2233
  }).catch((e) => {
2208
- logger$19.warn("Failed to register debug session: " + errorMessage(e));
2234
+ logger$20.warn("Failed to register debug session: " + errorMessage(e));
2209
2235
  });
2210
2236
  this.globalMetadata = {
2211
2237
  ...this.globalMetadata,
@@ -2215,7 +2241,7 @@ var Laminar = class Laminar {
2215
2241
  this.debugExitHook = () => runtime.emitPointer();
2216
2242
  process.once("exit", this.debugExitHook);
2217
2243
  } catch (e) {
2218
- logger$19.warn("Failed to initialize debug runtime: " + errorMessage(e));
2244
+ logger$20.warn("Failed to initialize debug runtime: " + errorMessage(e));
2219
2245
  }
2220
2246
  }
2221
2247
  /**
@@ -2260,7 +2286,7 @@ var Laminar = class Laminar {
2260
2286
  runtime.rolloutSessions.register({ sessionId: runtime.sessionId }).then((projectId) => {
2261
2287
  if (projectId) runtime.recordProjectId(projectId);
2262
2288
  }).catch((e) => {
2263
- logger$19.debug("Failed to register downstream debug session: " + errorMessage(e));
2289
+ logger$20.debug("Failed to register downstream debug session: " + errorMessage(e));
2264
2290
  });
2265
2291
  this.globalMetadata = {
2266
2292
  ...this.globalMetadata,
@@ -2269,7 +2295,7 @@ var Laminar = class Laminar {
2269
2295
  LaminarContextManager.setGlobalMetadata(this.globalMetadata);
2270
2296
  }
2271
2297
  } catch (e) {
2272
- logger$19.debug("Failed to arm debug runtime from context: " + errorMessage(e));
2298
+ logger$20.debug("Failed to arm debug runtime from context: " + errorMessage(e));
2273
2299
  }
2274
2300
  }
2275
2301
  /**
@@ -2284,7 +2310,7 @@ var Laminar = class Laminar {
2284
2310
  */
2285
2311
  static patch(modules) {
2286
2312
  if (!this.isInitialized) {
2287
- logger$19.warn("Laminar must be initialized before patching modules. Skipping patch.");
2313
+ logger$20.warn("Laminar must be initialized before patching modules. Skipping patch.");
2288
2314
  return;
2289
2315
  }
2290
2316
  if (!modules || Object.keys(modules).length === 0) throw new Error("Pass at least one module to patch");
@@ -2544,7 +2570,7 @@ var Laminar = class Laminar {
2544
2570
  const spanContext = tryToOtelSpanContext(laminarContext);
2545
2571
  entityContext = trace.setSpan(entityContext, trace.wrapSpanContext(spanContext));
2546
2572
  } catch (e) {
2547
- logger$19.warn("Failed to parse parent span context: " + errorMessage(e));
2573
+ logger$20.warn("Failed to parse parent span context: " + errorMessage(e));
2548
2574
  }
2549
2575
  const tagProperties = tags ? { [`${ASSOCIATION_PROPERTIES}.tags`]: Array.from(new Set(tags)) } : {};
2550
2576
  const ctxAssociationProperties = LaminarContextManager.getAssociationProperties();
@@ -2647,13 +2673,13 @@ var Laminar = class Laminar {
2647
2673
  }
2648
2674
  static async flush() {
2649
2675
  if (this.isInitialized) {
2650
- logger$19.debug("Flushing spans");
2676
+ logger$20.debug("Flushing spans");
2651
2677
  await forceFlush();
2652
2678
  }
2653
2679
  }
2654
2680
  static async shutdown() {
2655
2681
  if (this.isInitialized) {
2656
- logger$19.debug("Shutting down Laminar");
2682
+ logger$20.debug("Shutting down Laminar");
2657
2683
  getRuntime()?.emitPointer();
2658
2684
  await forceFlush();
2659
2685
  this.isInitialized = false;
@@ -2788,7 +2814,7 @@ return module.exports;
2788
2814
  //#endregion
2789
2815
  //#region src/browser/utils.ts
2790
2816
  const LMNR_SEND_EVENTS_FUNCTION_NAME = "lmnrSendEvents";
2791
- const logger$18 = initializeLogger();
2817
+ const logger$19 = initializeLogger();
2792
2818
  /**
2793
2819
  * If the first argument is a string, return an object with the name of the method
2794
2820
  * and the argument as the value.
@@ -2811,7 +2837,7 @@ const takeFullSnapshot = async (page) => await page.evaluate(() => {
2811
2837
  window.lmnrRrweb.record.takeFullSnapshot();
2812
2838
  return true;
2813
2839
  } catch (error) {
2814
- logger$18.error("Error taking full snapshot: " + errorMessage(error));
2840
+ logger$19.error("Error taking full snapshot: " + errorMessage(error));
2815
2841
  return false;
2816
2842
  }
2817
2843
  return false;
@@ -2822,7 +2848,7 @@ const injectSessionRecorder = async (page, sessionRecordingOptions) => {
2822
2848
  try {
2823
2849
  return await script();
2824
2850
  } catch (error) {
2825
- logger$18.error("Operation " + script.name + " failed: " + errorMessage(error));
2851
+ logger$19.error("Operation " + script.name + " failed: " + errorMessage(error));
2826
2852
  }
2827
2853
  await new Promise((resolve) => setTimeout(resolve, 500));
2828
2854
  }
@@ -2832,20 +2858,20 @@ const injectSessionRecorder = async (page, sessionRecordingOptions) => {
2832
2858
  try {
2833
2859
  isRrwebPresent = await castedPage.evaluate(() => typeof window.lmnrRrweb !== "undefined");
2834
2860
  } catch (error) {
2835
- logger$18.debug("Failed to check if session recorder is loaded: " + errorMessage(error));
2861
+ logger$19.debug("Failed to check if session recorder is loaded: " + errorMessage(error));
2836
2862
  }
2837
2863
  if (!isRrwebPresent) {
2838
2864
  if (!await tryRunScript(async function injectSessionRecorder() {
2839
2865
  await castedPage.evaluate(RECORDER);
2840
2866
  return true;
2841
2867
  })) {
2842
- logger$18.error("Failed to load session recorder");
2868
+ logger$19.error("Failed to load session recorder");
2843
2869
  return;
2844
2870
  }
2845
2871
  try {
2846
2872
  await castedPage.evaluate(injectScript, sessionRecordingOptions);
2847
2873
  } catch (error) {
2848
- logger$18.debug("Failed to inject session recorder: " + errorMessage(error));
2874
+ logger$19.debug("Failed to inject session recorder: " + errorMessage(error));
2849
2875
  }
2850
2876
  }
2851
2877
  };
@@ -2934,9 +2960,9 @@ const modelToProviderMap = {
2934
2960
  "gpt-4.1-mini": "openai",
2935
2961
  "gpt-4.1-nano": "openai",
2936
2962
  "o4-mini": "openai",
2937
- "o3": "openai",
2963
+ o3: "openai",
2938
2964
  "o3-mini": "openai",
2939
- "o1": "openai",
2965
+ o1: "openai",
2940
2966
  "o1-mini": "openai",
2941
2967
  "gpt-4o": "openai",
2942
2968
  "gpt-4o-mini": "openai",
@@ -3108,7 +3134,7 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
3108
3134
  try {
3109
3135
  const { batchId, chunkIndex, totalChunks, data } = chunk;
3110
3136
  if (!sessionId || !traceId) {
3111
- logger$18.debug("Missing sessionId or traceId in chunk");
3137
+ logger$19.debug("Missing sessionId or traceId in chunk");
3112
3138
  return;
3113
3139
  }
3114
3140
  if (!chunkBuffers.has(batchId)) chunkBuffers.set(batchId, {
@@ -3127,7 +3153,7 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
3127
3153
  traceId,
3128
3154
  events
3129
3155
  }).catch((error) => {
3130
- logger$18.debug("Failed to send events: " + errorMessage(error));
3156
+ logger$19.debug("Failed to send events: " + errorMessage(error));
3131
3157
  });
3132
3158
  chunkBuffers.delete(batchId);
3133
3159
  }
@@ -3135,16 +3161,16 @@ async function sendEvents(chunk, client, chunkBuffers, sessionId, traceId) {
3135
3161
  const toDelete = [];
3136
3162
  for (const [bid, buffer] of chunkBuffers.entries()) if (currentTime - buffer.timestamp > OLD_BUFFER_TIMEOUT) toDelete.push(bid);
3137
3163
  for (const bid of toDelete) {
3138
- logger$18.debug(`Cleaning up incomplete chunk buffer: ${bid}`);
3164
+ logger$19.debug(`Cleaning up incomplete chunk buffer: ${bid}`);
3139
3165
  chunkBuffers.delete(bid);
3140
3166
  }
3141
3167
  } catch (error) {
3142
- logger$18.debug("Could not send events: " + errorMessage(error));
3168
+ logger$19.debug("Could not send events: " + errorMessage(error));
3143
3169
  }
3144
3170
  }
3145
3171
  //#endregion
3146
3172
  //#region src/browser/playwright.ts
3147
- const logger$17 = initializeLogger();
3173
+ const logger$18 = initializeLogger();
3148
3174
  var PlaywrightInstrumentation = class extends InstrumentationBase {
3149
3175
  constructor(client, sessionRecordingOptions) {
3150
3176
  super("@lmnr/playwright-instrumentation", version, { enabled: true });
@@ -3252,7 +3278,7 @@ var PlaywrightInstrumentation = class extends InstrumentationBase {
3252
3278
  try {
3253
3279
  await injectSessionRecorder(page, this._sessionRecordingOptions);
3254
3280
  } catch (error) {
3255
- logger$17.error("Error in onLoad handler: " + errorMessage(error));
3281
+ logger$18.error("Error in onLoad handler: " + errorMessage(error));
3256
3282
  }
3257
3283
  });
3258
3284
  const chunkBuffers = /* @__PURE__ */ new Map();
@@ -3262,7 +3288,7 @@ var PlaywrightInstrumentation = class extends InstrumentationBase {
3262
3288
  await sendEvents(chunk, this._client, chunkBuffers, sessionId, traceId);
3263
3289
  });
3264
3290
  } catch (error) {
3265
- logger$17.debug("Could not expose function lmnrSendEvents: " + errorMessage(error));
3291
+ logger$18.debug("Could not expose function lmnrSendEvents: " + errorMessage(error));
3266
3292
  }
3267
3293
  }
3268
3294
  };
@@ -3687,7 +3713,7 @@ var StagehandV2Instrumentation = class extends InstrumentationBase {
3687
3713
  };
3688
3714
  //#endregion
3689
3715
  //#region src/browser/puppeteer.ts
3690
- const logger$16 = initializeLogger();
3716
+ const logger$17 = initializeLogger();
3691
3717
  var PuppeteerInstrumentation = class extends InstrumentationBase {
3692
3718
  constructor(client, sessionRecordingOptions) {
3693
3719
  super("@lmnr/puppeteer-instrumentation", version, { enabled: true });
@@ -3732,10 +3758,10 @@ var PuppeteerInstrumentation = class extends InstrumentationBase {
3732
3758
  context.on("targetcreated", (target) => {
3733
3759
  target.page().then((page) => {
3734
3760
  if (page) plugin.patchPage(page, sessionId).catch((error) => {
3735
- logger$16.error("Failed to patch page: " + errorMessage(error));
3761
+ logger$17.error("Failed to patch page: " + errorMessage(error));
3736
3762
  });
3737
3763
  }).catch((error) => {
3738
- logger$16.error("Failed to patch page: " + errorMessage(error));
3764
+ logger$17.error("Failed to patch page: " + errorMessage(error));
3739
3765
  });
3740
3766
  });
3741
3767
  await Promise.all((await context.pages()).map((page) => plugin.patchPage(page, sessionId)));
@@ -3753,19 +3779,19 @@ var PuppeteerInstrumentation = class extends InstrumentationBase {
3753
3779
  context.on("targetcreated", (target) => {
3754
3780
  target.page().then((page) => {
3755
3781
  if (page) plugin.patchPage(page, sessionId).catch((error) => {
3756
- logger$16.error("Failed to patch page: " + errorMessage(error));
3782
+ logger$17.error("Failed to patch page: " + errorMessage(error));
3757
3783
  });
3758
3784
  }).catch((error) => {
3759
- logger$16.error("Failed to patch page: " + errorMessage(error));
3785
+ logger$17.error("Failed to patch page: " + errorMessage(error));
3760
3786
  });
3761
3787
  });
3762
3788
  context.on("targetchanged", (target) => {
3763
3789
  target.page().then((page) => {
3764
3790
  if (page) plugin.patchPage(page, sessionId).catch((error) => {
3765
- logger$16.error("Failed to patch page: " + errorMessage(error));
3791
+ logger$17.error("Failed to patch page: " + errorMessage(error));
3766
3792
  });
3767
3793
  }).catch((error) => {
3768
- logger$16.error("Failed to patch page: " + errorMessage(error));
3794
+ logger$17.error("Failed to patch page: " + errorMessage(error));
3769
3795
  });
3770
3796
  });
3771
3797
  for (const page of await context.pages()) await plugin.patchPage(page, sessionId);
@@ -3789,7 +3815,7 @@ var PuppeteerInstrumentation = class extends InstrumentationBase {
3789
3815
  const traceId = otelTraceId ? otelTraceIdToUUID(otelTraceId) : NIL_UUID;
3790
3816
  page.on("domcontentloaded", () => {
3791
3817
  injectSessionRecorder(page, this._sessionRecordingOptions).catch((error) => {
3792
- logger$16.error("Error in onLoad handler: " + errorMessage(error));
3818
+ logger$17.error("Error in onLoad handler: " + errorMessage(error));
3793
3819
  });
3794
3820
  });
3795
3821
  await injectSessionRecorder(page, this._sessionRecordingOptions);
@@ -3799,13 +3825,13 @@ var PuppeteerInstrumentation = class extends InstrumentationBase {
3799
3825
  await sendEvents(chunk, this._client, chunkBuffers, sessionId, traceId);
3800
3826
  });
3801
3827
  } catch (error) {
3802
- logger$16.debug("Could not expose function lmnrSendEvents: " + errorMessage(error));
3828
+ logger$17.debug("Could not expose function lmnrSendEvents: " + errorMessage(error));
3803
3829
  }
3804
3830
  }
3805
3831
  };
3806
3832
  //#endregion
3807
3833
  //#region src/browser/stagehand/v3/constants.ts
3808
- const logger$15 = initializeLogger();
3834
+ const logger$16 = initializeLogger();
3809
3835
  const CDP_OPERATION_TIMEOUT_MS = 1e4;
3810
3836
  const SKIP_URL_PATTERNS = [
3811
3837
  "about:blank",
@@ -3856,7 +3882,7 @@ async function getOrCreateIsolatedWorld(page) {
3856
3882
  frameId
3857
3883
  };
3858
3884
  } catch (error) {
3859
- logger$15.debug("Failed to create isolated world: " + errorMessage(error));
3885
+ logger$16.debug("Failed to create isolated world: " + errorMessage(error));
3860
3886
  return null;
3861
3887
  }
3862
3888
  }
@@ -3873,7 +3899,7 @@ async function isRecorderPresent(page, contextId) {
3873
3899
  if (!result) return true;
3874
3900
  return result.result?.value === true;
3875
3901
  } catch (error) {
3876
- logger$15.debug("Failed to check if recorder is present: " + errorMessage(error));
3902
+ logger$16.debug("Failed to check if recorder is present: " + errorMessage(error));
3877
3903
  return true;
3878
3904
  }
3879
3905
  }
@@ -3886,21 +3912,21 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
3886
3912
  try {
3887
3913
  url = page.url();
3888
3914
  } catch (error) {
3889
- logger$15.debug("Failed to get page URL, page might be closed: " + errorMessage(error));
3915
+ logger$16.debug("Failed to get page URL, page might be closed: " + errorMessage(error));
3890
3916
  return null;
3891
3917
  }
3892
3918
  if (shouldSkipUrl(url)) {
3893
- logger$15.debug(`Skipping recorder injection for URL: ${url}`);
3919
+ logger$16.debug(`Skipping recorder injection for URL: ${url}`);
3894
3920
  return null;
3895
3921
  }
3896
3922
  const worldResult = await getOrCreateIsolatedWorld(page);
3897
3923
  if (!worldResult) {
3898
- logger$15.debug("Failed to get isolated world for page");
3924
+ logger$16.debug("Failed to get isolated world for page");
3899
3925
  return null;
3900
3926
  }
3901
3927
  const { contextId, frameId } = worldResult;
3902
3928
  if (await isRecorderPresent(page, contextId)) {
3903
- logger$15.debug("Recorder already present, skipping injection");
3929
+ logger$16.debug("Recorder already present, skipping injection");
3904
3930
  state.contextIdToSession.set(contextId, {
3905
3931
  sessionId: state.sessionId,
3906
3932
  traceId: state.traceId
@@ -3913,7 +3939,7 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
3913
3939
  contextId
3914
3940
  });
3915
3941
  } catch (error) {
3916
- logger$15.debug("Failed to inject rrweb: " + errorMessage(error));
3942
+ logger$16.debug("Failed to inject rrweb: " + errorMessage(error));
3917
3943
  return null;
3918
3944
  }
3919
3945
  const optionsJson = JSON.stringify(sessionRecordingOptions ?? {});
@@ -3924,14 +3950,14 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
3924
3950
  contextId
3925
3951
  });
3926
3952
  } catch (error) {
3927
- logger$15.debug("Failed to inject recording setup: " + errorMessage(error));
3953
+ logger$16.debug("Failed to inject recording setup: " + errorMessage(error));
3928
3954
  return null;
3929
3955
  }
3930
3956
  try {
3931
3957
  await sendCDP(page, "Runtime.addBinding", { name: "lmnrSendEvents" });
3932
- logger$15.debug(`Added binding 'lmnrSendEvents' for page ${frameId}, context ${contextId}`);
3958
+ logger$16.debug(`Added binding 'lmnrSendEvents' for page ${frameId}, context ${contextId}`);
3933
3959
  } catch (error) {
3934
- logger$15.debug("Binding may already exist: " + errorMessage(error));
3960
+ logger$16.debug("Binding may already exist: " + errorMessage(error));
3935
3961
  }
3936
3962
  if (bindingHandler) try {
3937
3963
  const pageTargetId = page.targetId();
@@ -3941,26 +3967,26 @@ async function injectRecorderViaCDP(page, state, conn, sessionRecordingOptions,
3941
3967
  const sessionTyped = session;
3942
3968
  if (sessionTyped.on) {
3943
3969
  sessionTyped.on("Runtime.bindingCalled", bindingHandler);
3944
- logger$15.debug(`Set up binding handler on session ${sessionId}`);
3970
+ logger$16.debug(`Set up binding handler on session ${sessionId}`);
3945
3971
  }
3946
3972
  } catch (error) {
3947
- logger$15.debug(`Failed to set up binding handler on session ${sessionId}: ` + errorMessage(error));
3973
+ logger$16.debug(`Failed to set up binding handler on session ${sessionId}: ` + errorMessage(error));
3948
3974
  }
3949
3975
  state.pageSessionHandlers.set(pageTargetId, bindingHandler);
3950
3976
  }
3951
3977
  } catch (error) {
3952
- logger$15.debug("Failed to set up binding handler: " + errorMessage(error));
3978
+ logger$16.debug("Failed to set up binding handler: " + errorMessage(error));
3953
3979
  }
3954
3980
  state.contextIdToSession.set(contextId, {
3955
3981
  sessionId: state.sessionId,
3956
3982
  traceId: state.traceId
3957
3983
  });
3958
- logger$15.debug(`Registered context mapping: contextId=${contextId}, sessionId=${state.sessionId}`);
3984
+ logger$16.debug(`Registered context mapping: contextId=${contextId}, sessionId=${state.sessionId}`);
3959
3985
  state.instrumentedPageIds.add(frameId);
3960
- logger$15.debug(`Successfully injected recorder into page ${frameId}`);
3986
+ logger$16.debug(`Successfully injected recorder into page ${frameId}`);
3961
3987
  return contextId;
3962
3988
  } catch (error) {
3963
- logger$15.debug("Error injecting recorder: " + errorMessage(error));
3989
+ logger$16.debug("Error injecting recorder: " + errorMessage(error));
3964
3990
  return null;
3965
3991
  }
3966
3992
  }
@@ -3974,13 +4000,13 @@ function createBindingHandler(state) {
3974
4000
  if (event.name !== "lmnrSendEvents") return;
3975
4001
  const sessionInfo = state.contextIdToSession.get(event.executionContextId);
3976
4002
  if (!sessionInfo) {
3977
- logger$15.debug("No session info found for context ID: " + event.executionContextId);
4003
+ logger$16.debug("No session info found for context ID: " + event.executionContextId);
3978
4004
  if (state.contextIdToSession.size > 0) {
3979
4005
  const [, fallbackInfo] = state.contextIdToSession.entries().next().value;
3980
4006
  if (fallbackInfo) try {
3981
4007
  sendEvents(JSON.parse(event.payload), state.client, state.chunkBuffers, fallbackInfo.sessionId, fallbackInfo.traceId);
3982
4008
  } catch (error) {
3983
- logger$15.debug("Failed to parse binding payload: " + errorMessage(error));
4009
+ logger$16.debug("Failed to parse binding payload: " + errorMessage(error));
3984
4010
  }
3985
4011
  }
3986
4012
  return;
@@ -3988,7 +4014,7 @@ function createBindingHandler(state) {
3988
4014
  try {
3989
4015
  sendEvents(JSON.parse(event.payload), state.client, state.chunkBuffers, sessionInfo.sessionId, sessionInfo.traceId);
3990
4016
  } catch (error) {
3991
- logger$15.debug("Failed to handle binding event: " + errorMessage(error));
4017
+ logger$16.debug("Failed to handle binding event: " + errorMessage(error));
3992
4018
  }
3993
4019
  };
3994
4020
  }
@@ -4004,10 +4030,10 @@ function createTargetCreatedHandler(context, state, sessionRecordingOptions) {
4004
4030
  const pageId = page.mainFrameId();
4005
4031
  if (!state.instrumentedPageIds.has(pageId)) await injectRecorderViaCDP(page, state, context.conn, sessionRecordingOptions, state.bindingHandler ?? void 0);
4006
4032
  } catch (error) {
4007
- logger$15.debug("Error injecting recorder into new page: " + errorMessage(error));
4033
+ logger$16.debug("Error injecting recorder into new page: " + errorMessage(error));
4008
4034
  }
4009
4035
  } catch (error) {
4010
- logger$15.debug("Error handling target created event: " + errorMessage(error));
4036
+ logger$16.debug("Error handling target created event: " + errorMessage(error));
4011
4037
  }
4012
4038
  };
4013
4039
  }
@@ -4019,7 +4045,7 @@ function createTargetInfoChangedHandler(context, state, sessionRecordingOptions)
4019
4045
  if (event.targetInfo.type !== "page") return;
4020
4046
  const url = event.targetInfo.url;
4021
4047
  if (shouldSkipUrl(url)) return;
4022
- logger$15.debug(`Target URL changed to ${url}, checking if recorder injection needed`);
4048
+ logger$16.debug(`Target URL changed to ${url}, checking if recorder injection needed`);
4023
4049
  await new Promise((resolve) => setTimeout(resolve, 150));
4024
4050
  try {
4025
4051
  for (const page of context.pages()) if (page.targetId() === event.targetInfo.targetId) {
@@ -4027,7 +4053,7 @@ function createTargetInfoChangedHandler(context, state, sessionRecordingOptions)
4027
4053
  break;
4028
4054
  }
4029
4055
  } catch (error) {
4030
- logger$15.debug("Error handling target info change: " + errorMessage(error));
4056
+ logger$16.debug("Error handling target info change: " + errorMessage(error));
4031
4057
  }
4032
4058
  };
4033
4059
  }
@@ -4188,12 +4214,12 @@ var StagehandInstrumentation = class extends InstrumentationBase {
4188
4214
  */
4189
4215
  async setupSessionRecording(stagehandInstance, sessionId, traceId) {
4190
4216
  if (!this._client) {
4191
- logger$15.debug("No Laminar client available, skipping session recording setup");
4217
+ logger$16.debug("No Laminar client available, skipping session recording setup");
4192
4218
  return;
4193
4219
  }
4194
4220
  const context = stagehandInstance.context;
4195
4221
  if (!context || !context.conn) {
4196
- logger$15.debug("No context or connection available, skipping session recording setup");
4222
+ logger$16.debug("No context or connection available, skipping session recording setup");
4197
4223
  return;
4198
4224
  }
4199
4225
  const recorderState = {
@@ -4223,11 +4249,11 @@ var StagehandInstrumentation = class extends InstrumentationBase {
4223
4249
  for (const page of pages) try {
4224
4250
  if (await injectRecorderViaCDP(page, recorderState, context.conn, this._sessionRecordingOptions, bindingHandler) !== null) injectedCount++;
4225
4251
  } catch (error) {
4226
- logger$15.debug("Error injecting recorder into page: " + errorMessage(error));
4252
+ logger$16.debug("Error injecting recorder into page: " + errorMessage(error));
4227
4253
  }
4228
- logger$15.debug(`Injected session recorder into ${injectedCount} of ${pages.length} existing page(s)`);
4254
+ logger$16.debug(`Injected session recorder into ${injectedCount} of ${pages.length} existing page(s)`);
4229
4255
  } catch (error) {
4230
- logger$15.debug("Error accessing pages for recorder injection: " + errorMessage(error));
4256
+ logger$16.debug("Error accessing pages for recorder injection: " + errorMessage(error));
4231
4257
  }
4232
4258
  }
4233
4259
  patchStagehandClose() {
@@ -4257,12 +4283,12 @@ var StagehandInstrumentation = class extends InstrumentationBase {
4257
4283
  if (recorderState.targetCreatedHandler) try {
4258
4284
  context.conn.off("Target.targetCreated", recorderState.targetCreatedHandler);
4259
4285
  } catch (error) {
4260
- logger$15.debug("Error removing target created handler: " + errorMessage(error));
4286
+ logger$16.debug("Error removing target created handler: " + errorMessage(error));
4261
4287
  }
4262
4288
  if (recorderState.targetInfoChangedHandler) try {
4263
4289
  context.conn.off("Target.targetInfoChanged", recorderState.targetInfoChangedHandler);
4264
4290
  } catch (error) {
4265
- logger$15.debug("Error removing target info changed handler: " + errorMessage(error));
4291
+ logger$16.debug("Error removing target info changed handler: " + errorMessage(error));
4266
4292
  }
4267
4293
  }
4268
4294
  recorderState.contextIdToSession.clear();
@@ -4273,7 +4299,7 @@ var StagehandInstrumentation = class extends InstrumentationBase {
4273
4299
  recorderState.targetCreatedHandler = null;
4274
4300
  recorderState.targetInfoChangedHandler = null;
4275
4301
  this.stagehandInstanceToRecorderState.delete(stagehandInstance);
4276
- logger$15.debug("Cleaned up session recording for Stagehand instance");
4302
+ logger$16.debug("Cleaned up session recording for Stagehand instance");
4277
4303
  }
4278
4304
  patchStagehandGlobalMethod(methodName, sessionId, parentSpan) {
4279
4305
  return (original) => async function method(...args) {
@@ -4498,12 +4524,11 @@ var StagehandInstrumentation = class extends InstrumentationBase {
4498
4524
  * LLM-backed calls and surface token usage from the response where available.
4499
4525
  */
4500
4526
  patchStagehandApiClient(apiClient, parentSpan, stagehandInstance) {
4501
- const instrumentation = this;
4502
4527
  let baseProvider = stagehandInstance?.llmClient?.type;
4503
4528
  const baseModel = stagehandInstance?.llmClient?.modelName;
4504
4529
  if (baseModel && !baseProvider) baseProvider = modelToProvider(baseModel) ?? "aisdk";
4505
4530
  const wrapApiMethod = (methodName) => {
4506
- safeWrap(instrumentation, apiClient, methodName, (original) => async function method(...args) {
4531
+ safeWrap(this, apiClient, methodName, (original) => async function method(...args) {
4507
4532
  const currentSpan = trace.getSpan(LaminarContextManager.getContext()) ?? trace.getActiveSpan();
4508
4533
  const input = nameArgsOrCopy(args);
4509
4534
  const spanName = `stagehand.apiClient.${methodName}`;
@@ -4916,7 +4941,6 @@ const WRAPPED_BROWSER_METHODS = [
4916
4941
  "create",
4917
4942
  "retrieve",
4918
4943
  "list",
4919
- "delete",
4920
4944
  "deleteByID",
4921
4945
  "loadExtensions"
4922
4946
  ];
@@ -5144,7 +5168,7 @@ const normalizeMessages = (data, role = "user") => {
5144
5168
  };
5145
5169
  //#endregion
5146
5170
  //#region src/opentelemetry-lib/instrumentation/openai-agents/messages.ts
5147
- const logger$14 = initializeLogger();
5171
+ const logger$15 = initializeLogger();
5148
5172
  const setLmnrSpanIo = (lmnrSpan, inputData, outputData) => {
5149
5173
  if (inputData !== void 0 && inputData !== null) lmnrSpan.setAttribute(SPAN_INPUT, JSON.stringify(inputData));
5150
5174
  if (outputData !== void 0 && outputData !== null) lmnrSpan.setAttribute(SPAN_OUTPUT, JSON.stringify(outputData));
@@ -5173,7 +5197,7 @@ const setGenAiOutputMessagesFromResponse = (lmnrSpan, response) => {
5173
5197
  if (!outputItems) return;
5174
5198
  const id = response.id;
5175
5199
  if (!Array.isArray(outputItems)) {
5176
- logger$14.debug("Laminar OpenAI agents instrumentation, failed to parse output items. Expected array");
5200
+ logger$15.debug("Laminar OpenAI agents instrumentation, failed to parse output items. Expected array");
5177
5201
  outputItems = [];
5178
5202
  }
5179
5203
  const result = {
@@ -5368,7 +5392,7 @@ const applySpeechGroupSpanData = (lmnrSpan, spanData) => {
5368
5392
  };
5369
5393
  //#endregion
5370
5394
  //#region src/opentelemetry-lib/instrumentation/openai-agents/processor.ts
5371
- const logger$13 = initializeLogger();
5395
+ const logger$14 = initializeLogger();
5372
5396
  var LaminarAgentsTraceProcessor = class {
5373
5397
  constructor() {
5374
5398
  this.traces = /* @__PURE__ */ new Map();
@@ -5386,7 +5410,7 @@ var LaminarAgentsTraceProcessor = class {
5386
5410
  } catch {}
5387
5411
  this.applyTraceMetadata(state.rootSpan, agentsTrace);
5388
5412
  } catch (e) {
5389
- logger$13.debug(`Error in onTraceStart: ${String(e)}`);
5413
+ logger$14.debug(`Error in onTraceStart: ${String(e)}`);
5390
5414
  }
5391
5415
  }
5392
5416
  async onTraceEnd(agentsTrace) {
@@ -5435,7 +5459,7 @@ var LaminarAgentsTraceProcessor = class {
5435
5459
  });
5436
5460
  const key = span.spanId;
5437
5461
  if (!key) {
5438
- logger$13.debug("Span missing spanId, cannot track");
5462
+ logger$14.debug("Span missing spanId, cannot track");
5439
5463
  try {
5440
5464
  lmnrSpan.end();
5441
5465
  } catch {}
@@ -5454,7 +5478,7 @@ var LaminarAgentsTraceProcessor = class {
5454
5478
  activationContext
5455
5479
  });
5456
5480
  } catch (e) {
5457
- logger$13.debug(`Error in onSpanStart: ${String(e)}`);
5481
+ logger$14.debug(`Error in onSpanStart: ${String(e)}`);
5458
5482
  if (lmnrSpan !== void 0) try {
5459
5483
  lmnrSpan.end();
5460
5484
  } catch {}
@@ -5572,7 +5596,7 @@ var LaminarAgentsTraceProcessor = class {
5572
5596
  };
5573
5597
  //#endregion
5574
5598
  //#region src/opentelemetry-lib/instrumentation/openai-agents/index.ts
5575
- const logger$12 = initializeLogger();
5599
+ const logger$13 = initializeLogger();
5576
5600
  const wrapGetResponse = (original) => function(request, ...rest) {
5577
5601
  const systemInstructions = request?.systemInstructions;
5578
5602
  return runWithSystemInstructions(systemInstructions, () => original.call(this, request, ...rest));
@@ -5592,7 +5616,7 @@ var OpenAIAgentsInstrumentation = class extends InstrumentationBase {
5592
5616
  }
5593
5617
  manuallyInstrument(agentsModule) {
5594
5618
  if (!agentsModule) {
5595
- logger$12.debug("@openai/agents module not provided, skipping");
5619
+ logger$13.debug("@openai/agents module not provided, skipping");
5596
5620
  return;
5597
5621
  }
5598
5622
  this.registerProcessor(agentsModule);
@@ -5602,7 +5626,7 @@ var OpenAIAgentsInstrumentation = class extends InstrumentationBase {
5602
5626
  if (this._processor !== void 0) return;
5603
5627
  const addTraceProcessor = module.addTraceProcessor;
5604
5628
  if (typeof addTraceProcessor !== "function") {
5605
- logger$12.debug("addTraceProcessor not found in @openai/agents module");
5629
+ logger$13.debug("addTraceProcessor not found in @openai/agents module");
5606
5630
  return;
5607
5631
  }
5608
5632
  try {
@@ -5610,7 +5634,7 @@ var OpenAIAgentsInstrumentation = class extends InstrumentationBase {
5610
5634
  addTraceProcessor(processor);
5611
5635
  this._processor = processor;
5612
5636
  } catch (e) {
5613
- logger$12.debug(`Failed to register Laminar Agents processor: ${String(e)}`);
5637
+ logger$13.debug(`Failed to register Laminar Agents processor: ${String(e)}`);
5614
5638
  }
5615
5639
  }
5616
5640
  patchModel(module) {
@@ -5623,7 +5647,7 @@ var OpenAIAgentsInstrumentation = class extends InstrumentationBase {
5623
5647
  try {
5624
5648
  this._wrap(cls.prototype, method, wrapper);
5625
5649
  } catch (e) {
5626
- logger$12.debug(`Failed to wrap ${method}: ${String(e)}`);
5650
+ logger$13.debug(`Failed to wrap ${method}: ${String(e)}`);
5627
5651
  }
5628
5652
  }
5629
5653
  this._wrappedPrototypes.add(cls.prototype);
@@ -5728,6 +5752,113 @@ const getLangVersion = () => {
5728
5752
  if (process?.versions?.node) return `node@${process.versions.node}`;
5729
5753
  };
5730
5754
  //#endregion
5755
+ //#region src/opentelemetry-lib/tracing/batch-processor.ts
5756
+ const logger$12 = initializeLogger();
5757
+ /**
5758
+ * Non-string attribute values (numbers, booleans) are counted as a flat 8 bytes
5759
+ * instead of being measured — they never dominate a GenAI payload.
5760
+ */
5761
+ const FIXED_ATTRIBUTE_VALUE_SIZE = 8;
5762
+ const valueSize = (value) => {
5763
+ if (typeof value === "string") return utf8Size(value);
5764
+ if (Array.isArray(value)) return value.reduce((total, item) => total + valueSize(item), 0);
5765
+ return FIXED_ATTRIBUTE_VALUE_SIZE;
5766
+ };
5767
+ const attributesSize = (attributes) => {
5768
+ if (!attributes) return 0;
5769
+ return Object.entries(attributes).reduce((total, [key, value]) => total + utf8Size(key) + valueSize(value), 0);
5770
+ };
5771
+ /**
5772
+ * Byte length of `value` encoded as UTF-8.
5773
+ *
5774
+ * `.length` counts UTF-16 code units, which undercounts CJK by ~3x and
5775
+ * Cyrillic/Arabic/emoji by ~2x — on GenAI payloads that made a batch several
5776
+ * times the configured limit, the exact oversized-export case this limit exists
5777
+ * to prevent.
5778
+ *
5779
+ * Unlike the Python SDK, which samples a strided subset of long strings, this
5780
+ * measures exactly. `Buffer.byteLength` walks the string in native code without
5781
+ * allocating the encoded bytes, so it is both cheaper and more accurate than
5782
+ * sampling here: measured ~27us on a 20k-character CJK string, against ~16us for
5783
+ * a sampled estimate that was also *wrong* for emoji (+11.7%, because indexing a
5784
+ * string splits surrogate pairs and each half encodes as U+FFFD). Python has no
5785
+ * equivalent primitive — `len(s.encode())` allocates the whole encoded copy —
5786
+ * which is the only reason it samples.
5787
+ */
5788
+ const utf8Size = (value) => Buffer.byteLength(value, "utf8");
5789
+ /**
5790
+ * Approximate the exported size of a span, in bytes.
5791
+ *
5792
+ * Deliberately an underestimate: protobuf framing, ids and timestamps are
5793
+ * ignored, and non-string values are counted flat. Underestimating small spans
5794
+ * is fine — the count and schedule-delay limits fire first for those. What
5795
+ * matters is that a span carrying a large prompt or completion is measured close
5796
+ * to its real weight.
5797
+ */
5798
+ const approximateSpanSize = (span) => {
5799
+ let total = utf8Size(span.name ?? "");
5800
+ total += attributesSize(span.attributes);
5801
+ for (const event of span.events ?? []) total += utf8Size(event.name ?? "") + attributesSize(event.attributes);
5802
+ for (const link of span.links ?? []) total += attributesSize(link.attributes);
5803
+ if (span.status?.message) total += utf8Size(span.status.message);
5804
+ return total;
5805
+ };
5806
+ /**
5807
+ * `BatchSpanProcessor` with a third, size-based flush trigger.
5808
+ *
5809
+ * Opt-in via `Laminar.initialize({ flushBySize: true })`; the default transport
5810
+ * is the plain upstream `BatchSpanProcessor`.
5811
+ *
5812
+ * Upstream flushes on whichever comes first: `maxExportBatchSize` spans
5813
+ * buffered, or `scheduledDelayMillis` elapsed. Neither bounds the *payload*, so
5814
+ * a handful of large GenAI spans can produce an export big enough for the
5815
+ * backend to reject. This adds `maxExportBatchSizeBytes`: when the span being
5816
+ * ended would push the buffer past the limit, the buffer is flushed first and
5817
+ * the span then starts a fresh batch.
5818
+ *
5819
+ * The Python SDK needs considerably more machinery for this — a dedicated flush
5820
+ * thread, a lock around the running total, a fork handler, and an inline
5821
+ * fallback for backpressure — none of which is needed here, because the two
5822
+ * runtimes behave differently in three ways:
5823
+ *
5824
+ * 1. `forceFlush()` moves the buffered spans out synchronously and only *awaits*
5825
+ * the network, so calling it from `onEnd` never blocks the caller (measured:
5826
+ * 0.34ms worst case against a 300ms export). Python's `force_flush` performs
5827
+ * the export itself on the calling thread, which load testing measured at a
5828
+ * p99 of ~664ms and is why it needs a background thread.
5829
+ * 2. Because the flush is synchronous with respect to the buffer, the batch stays
5830
+ * bounded even when a producer emits in a tight loop, so no inline-fallback
5831
+ * backpressure path is needed. Python's asynchronous handoff can be outrun.
5832
+ * 3. `onEnd` calls `super.onEnd(span)` *after* flushing, so the triggering span
5833
+ * is genuinely excluded from the batch it caused. Python cannot do this — its
5834
+ * flush is asynchronous, so the triggering span rides along, which is why it
5835
+ * needs a separate "span is at least half the limit" rule to bound overshoot.
5836
+ * Here a batch never exceeds the limit by more than the last span under it.
5837
+ *
5838
+ * Single-threaded event loop, so no lock guards the running total, and there is
5839
+ * no `fork` story to handle.
5840
+ */
5841
+ var SizeLimitedBatchSpanProcessor = class extends BatchSpanProcessor {
5842
+ constructor(exporter, config) {
5843
+ super(exporter, config);
5844
+ this.pendingSizeBytes = 0;
5845
+ this.maxExportBatchSizeBytes = config?.maxExportBatchSizeBytes ?? 33554432;
5846
+ }
5847
+ onEnd(span) {
5848
+ if ((span.spanContext().traceFlags & TraceFlags.SAMPLED) === 0) {
5849
+ super.onEnd(span);
5850
+ return;
5851
+ }
5852
+ const size = approximateSpanSize(span);
5853
+ const shouldFlush = this.pendingSizeBytes > 0 && this.pendingSizeBytes + size > this.maxExportBatchSizeBytes;
5854
+ this.pendingSizeBytes = shouldFlush ? size : this.pendingSizeBytes + size;
5855
+ if (shouldFlush) this.forceFlush().catch((error) => {
5856
+ logger$12.debug(`Size-triggered span flush failed: ${String(error)}`);
5857
+ });
5858
+ super.onEnd(span);
5859
+ }
5860
+ };
5861
+ //#endregion
5731
5862
  //#region src/opentelemetry-lib/tracing/exporter.ts
5732
5863
  const logger$11 = initializeLogger();
5733
5864
  var LaminarSpanExporter = class {
@@ -5738,7 +5869,7 @@ var LaminarSpanExporter = class {
5738
5869
  const key = options.apiKey ?? process?.env?.LMNR_PROJECT_API_KEY;
5739
5870
  let headers = {};
5740
5871
  if (key) {
5741
- headers = forceHttp ? { "Authorization": `Bearer ${key}` } : { "authorization": `Bearer ${key}` };
5872
+ headers = forceHttp ? { Authorization: `Bearer ${key}` } : { authorization: `Bearer ${key}` };
5742
5873
  if (!url) url = "https://api.lmnr.ai";
5743
5874
  } else {
5744
5875
  const otelHeaders = getOtelEnvVar("HEADERS");
@@ -5811,10 +5942,16 @@ var LaminarSpanProcessor = class LaminarSpanProcessor {
5811
5942
  } else if (options.spanProcessor) this.instance = options.spanProcessor;
5812
5943
  else {
5813
5944
  const exporter = options.exporter ?? new LaminarSpanExporter(options);
5814
- this.instance = options.disableBatch ? new SimpleSpanProcessor(exporter) : new BatchSpanProcessor(exporter, {
5945
+ const batchConfig = {
5815
5946
  maxExportBatchSize: options.maxExportBatchSize ?? 512,
5816
5947
  exportTimeoutMillis: options.traceExportTimeoutMillis ?? 3e4
5948
+ };
5949
+ if (options.disableBatch) this.instance = new SimpleSpanProcessor(exporter);
5950
+ else if (options.flushBySize) this.instance = new SizeLimitedBatchSpanProcessor(exporter, {
5951
+ ...batchConfig,
5952
+ maxExportBatchSizeBytes: options.maxExportBatchSizeBytes
5817
5953
  });
5954
+ else this.instance = new BatchSpanProcessor(exporter, batchConfig);
5818
5955
  }
5819
5956
  }
5820
5957
  forceFlush() {
@@ -6727,6 +6864,8 @@ const startTracing = (options) => {
6727
6864
  forceHttp: options.forceHttp,
6728
6865
  traceExportTimeoutMillis: options.traceExportTimeoutMillis,
6729
6866
  maxExportBatchSize: options.maxExportBatchSize,
6867
+ maxExportBatchSizeBytes: options.maxExportBatchSizeBytes,
6868
+ flushBySize: options.flushBySize,
6730
6869
  exporter: options.exporter,
6731
6870
  disableBatch: options.disableBatch
6732
6871
  });
@@ -7059,7 +7198,7 @@ function withTracingLevel(tracingLevel, fn, ...args) {
7059
7198
  const currentAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY) ?? {};
7060
7199
  entityContext = entityContext.setValue(ASSOCIATION_PROPERTIES_KEY, {
7061
7200
  ...currentAssociationProperties,
7062
- "tracing_level": tracingLevel
7201
+ tracing_level: tracingLevel
7063
7202
  });
7064
7203
  const result = LaminarContextManager.runWithIsolatedContext([entityContext], () => fn(...args));
7065
7204
  const newAssociationProperties = entityContext.getValue(ASSOCIATION_PROPERTIES_KEY) ?? {};