@lmnr-ai/lmnr 0.7.13-alpha.1 → 0.8.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  const require_utils = require('./utils-BmfIfQcB.cjs');
2
- const require_client = require('./client-CPYdIP16.cjs');
2
+ const require_client = require('./client-VmPk12gK.cjs');
3
3
  let dotenv = require("dotenv");
4
4
  let _opentelemetry_api = require("@opentelemetry/api");
5
5
  let _opentelemetry_context_async_hooks = require("@opentelemetry/context-async-hooks");
@@ -343,7 +343,7 @@ function instrumentClaudeAgentQuery(originalQuery) {
343
343
  const collected = [];
344
344
  try {
345
345
  await startProxy();
346
- if (getProxyBaseUrl()) await Laminar.withSpan(span, () => {
346
+ if (getProxyBaseUrl()) Laminar.withSpan(span, () => {
347
347
  setTraceToProxy();
348
348
  });
349
349
  else logger$10.debug("No claude proxy server found. Skipping span context publication.");
@@ -353,7 +353,7 @@ function instrumentClaudeAgentQuery(originalQuery) {
353
353
  yield message;
354
354
  }
355
355
  } catch (error) {
356
- await Laminar.withSpan(span, () => {
356
+ Laminar.withSpan(span, () => {
357
357
  span.recordException(error);
358
358
  });
359
359
  throw error;
@@ -445,6 +445,8 @@ var Laminar = class Laminar {
445
445
  * @param {boolean} props.inheritGlobalContext - Whether to inherit the global OpenTelemetry
446
446
  * context. Defaults to false. This is useful if your library is instrumented with OpenTelemetry
447
447
  * and you want Laminar spans to be children of the existing spans.
448
+ * @param {SpanProcessor} props.spanProcessor - The span processor to use. If passed, some of
449
+ * the other options will be ignored.
448
450
  *
449
451
  * @example
450
452
  * import { Laminar } from '@lmnr-ai/lmnr';
@@ -464,7 +466,7 @@ var Laminar = class Laminar {
464
466
  *
465
467
  * @throws {Error} - If project API key is not set
466
468
  */
467
- static initialize({ projectApiKey, baseUrl, baseHttpUrl, httpPort, grpcPort, instrumentModules, disableBatch, traceExportTimeoutMillis, logLevel, maxExportBatchSize, forceHttp, sessionRecordingOptions, metadata, inheritGlobalContext } = {}) {
469
+ static initialize({ projectApiKey, baseUrl, baseHttpUrl, httpPort, grpcPort, instrumentModules, disableBatch, traceExportTimeoutMillis, logLevel, maxExportBatchSize, forceHttp, sessionRecordingOptions, metadata, inheritGlobalContext, spanProcessor: spanProcessor$1 } = {}) {
468
470
  if (this.isInitialized) {
469
471
  logger$9.warn("Laminar has already been initialized. Skipping initialization.");
470
472
  return;
@@ -486,6 +488,7 @@ var Laminar = class Laminar {
486
488
  this.globalMetadata = metadata ?? {};
487
489
  require_client.LaminarContextManager.setGlobalMetadata(this.globalMetadata);
488
490
  if (inheritGlobalContext) require_client.LaminarContextManager.inheritGlobalContext = true;
491
+ if (spanProcessor$1 && !(spanProcessor$1 instanceof LaminarSpanProcessor)) logger$9.warn("Span processor is not a LaminarSpanProcessor. Some functionality may be impaired.");
489
492
  this.isInitialized = true;
490
493
  const urlWithoutSlash = url?.replace(/\/$/, "").replace(/:\d{1,5}$/g, "");
491
494
  const httpUrlWithoutSlash = httpUrl?.replace(/\/$/, "").replace(/:\d{1,5}$/g, "");
@@ -502,7 +505,8 @@ var Laminar = class Laminar {
502
505
  disableBatch,
503
506
  maxExportBatchSize,
504
507
  traceExportTimeoutMillis,
505
- sessionRecordingOptions
508
+ sessionRecordingOptions,
509
+ spanProcessor: spanProcessor$1
506
510
  });
507
511
  this._initializeContextFromEnv();
508
512
  }
@@ -851,7 +855,10 @@ var Laminar = class Laminar {
851
855
  return _opentelemetry_api.context.with(context$4, () => require_client.LaminarContextManager.runWithIsolatedContext([context$4], () => {
852
856
  try {
853
857
  const result = fn();
854
- if (result instanceof Promise) return result.finally(() => {
858
+ if (result instanceof Promise) return result.catch((err) => {
859
+ span.recordException(err);
860
+ throw err;
861
+ }).finally(() => {
855
862
  if (endOnExit !== void 0 && endOnExit) span.end();
856
863
  });
857
864
  if (endOnExit !== void 0 && endOnExit) span.end();
@@ -3347,7 +3354,7 @@ var LaminarSpanExporter = class {
3347
3354
 
3348
3355
  //#endregion
3349
3356
  //#region src/opentelemetry-lib/tracing/processor.ts
3350
- var LaminarSpanProcessor = class {
3357
+ var LaminarSpanProcessor = class LaminarSpanProcessor {
3351
3358
  /**
3352
3359
  * @param {object} options - The options for the Laminar span processor.
3353
3360
  * @param {string} options.baseUrl - The base URL of the Laminar API.
@@ -3366,11 +3373,18 @@ var LaminarSpanProcessor = class {
3366
3373
  constructor(options = {}) {
3367
3374
  this._spanIdToPath = /* @__PURE__ */ new Map();
3368
3375
  this._spanIdLists = /* @__PURE__ */ new Map();
3369
- const exporter = options.exporter ?? new LaminarSpanExporter(options);
3370
- this.instance = options.disableBatch ? new _opentelemetry_sdk_trace_base.SimpleSpanProcessor(exporter) : new _opentelemetry_sdk_trace_base.BatchSpanProcessor(exporter, {
3371
- maxExportBatchSize: options.maxExportBatchSize ?? 512,
3372
- exportTimeoutMillis: options.traceExportTimeoutMillis ?? 3e4
3373
- });
3376
+ if (options.spanProcessor && options.spanProcessor instanceof LaminarSpanProcessor) {
3377
+ this.instance = options.spanProcessor.instance;
3378
+ this._spanIdToPath = options.spanProcessor._spanIdToPath;
3379
+ this._spanIdLists = options.spanProcessor._spanIdLists;
3380
+ } else if (options.spanProcessor) this.instance = options.spanProcessor;
3381
+ else {
3382
+ const exporter = options.exporter ?? new LaminarSpanExporter(options);
3383
+ this.instance = options.disableBatch ? new _opentelemetry_sdk_trace_base.SimpleSpanProcessor(exporter) : new _opentelemetry_sdk_trace_base.BatchSpanProcessor(exporter, {
3384
+ maxExportBatchSize: options.maxExportBatchSize ?? 512,
3385
+ exportTimeoutMillis: options.traceExportTimeoutMillis ?? 3e4
3386
+ });
3387
+ }
3374
3388
  }
3375
3389
  forceFlush() {
3376
3390
  return this.instance.forceFlush();
@@ -3490,6 +3504,7 @@ const startTracing = (options) => {
3490
3504
  });
3491
3505
  const port = options.forceHttp ? options.httpPort : options.port;
3492
3506
  spanProcessor = new LaminarSpanProcessor({
3507
+ spanProcessor: options.spanProcessor,
3493
3508
  baseUrl: options.baseUrl,
3494
3509
  port,
3495
3510
  apiKey: options.apiKey,
@@ -3637,7 +3652,7 @@ function observeBase({ name, associationProperties, input, ignoreInput, ignoreOu
3637
3652
  } catch (e) {
3638
3653
  logger$2.warn("Failed to parse parent span context: " + (e instanceof Error ? e.message : String(e)));
3639
3654
  }
3640
- return _opentelemetry_api.context.with(entityContext, () => getTracer().startActiveSpan(name, { attributes: associationProperties }, entityContext, async (span) => {
3655
+ return _opentelemetry_api.context.with(entityContext, () => getTracer().startActiveSpan(name, { attributes: associationProperties }, entityContext, (span) => {
3641
3656
  if (shouldSendTraces() && !ignoreInput) try {
3642
3657
  const spanInput = inputParameters ?? args;
3643
3658
  if (input !== void 0) span.setAttribute(require_utils.SPAN_INPUT, typeof input === "string" ? input : serialize(input));
@@ -3731,7 +3746,7 @@ const logger$1 = require_utils.initializeLogger();
3731
3746
  * // Your code here
3732
3747
  * });
3733
3748
  */
3734
- async function observe({ name, sessionId, userId, traceType, spanType, input, ignoreInput, ignoreOutput, parentSpanContext, metadata, tags }, fn, ...args) {
3749
+ function observe({ name, sessionId, userId, traceType, spanType, input, ignoreInput, ignoreOutput, parentSpanContext, metadata, tags }, fn, ...args) {
3735
3750
  if (fn === void 0 || typeof fn !== "function") throw new Error("Invalid `observe` usage. Second argument `fn` must be a function.");
3736
3751
  const associationProperties = buildAssociationProperties({
3737
3752
  sessionId,
@@ -3742,7 +3757,7 @@ async function observe({ name, sessionId, userId, traceType, spanType, input, ig
3742
3757
  metadata,
3743
3758
  parentSpanContext
3744
3759
  });
3745
- return await observeBase({
3760
+ return observeBase({
3746
3761
  name: name ?? fn.name,
3747
3762
  associationProperties,
3748
3763
  input,
@@ -3836,6 +3851,12 @@ const buildAssociationProperties = (options) => {
3836
3851
  };
3837
3852
  /**
3838
3853
  * Decorator that wraps a method to automatically observe it with Laminar tracing.
3854
+ * This decorator uses the TypeScript 5.0+ standard decorator syntax.
3855
+ *
3856
+ * **Important**: Use this decorator only if your `tsconfig.json` does NOT have
3857
+ * `experimentalDecorators: true`. If you're using experimental decorators, use
3858
+ * {@link observeExperimentalDecorator} instead.
3859
+ *
3839
3860
  * This decorator can be used on class methods to automatically create spans.
3840
3861
  *
3841
3862
  * @param config - Configuration for the observe decorator, can be static or a function
@@ -3843,6 +3864,13 @@ const buildAssociationProperties = (options) => {
3843
3864
  *
3844
3865
  * @example
3845
3866
  * ```typescript
3867
+ * // In your tsconfig.json, ensure experimentalDecorators is NOT enabled:
3868
+ * // {
3869
+ * // "compilerOptions": {
3870
+ * // "experimentalDecorators": false // or omit this line
3871
+ * // }
3872
+ * // }
3873
+ *
3846
3874
  * import { observeDecorator } from '@lmnr-ai/lmnr';
3847
3875
  *
3848
3876
  * class MyService {
@@ -3863,8 +3891,72 @@ const buildAssociationProperties = (options) => {
3863
3891
  * ```
3864
3892
  */
3865
3893
  function observeDecorator(config$2) {
3894
+ return function(originalMethod, context$4) {
3895
+ if (context$4.kind !== "method") throw new Error(`observeDecorator can only be applied to methods. Applied to: ${String(context$4.name)}`);
3896
+ const methodName = String(context$4.name);
3897
+ return function(...args) {
3898
+ let actualConfig;
3899
+ if (typeof config$2 === "function") actualConfig = config$2(this, ...args);
3900
+ else actualConfig = config$2;
3901
+ return observeBase({
3902
+ name: actualConfig.name ?? methodName,
3903
+ associationProperties: buildAssociationProperties(actualConfig),
3904
+ input: actualConfig.input,
3905
+ ignoreInput: actualConfig.ignoreInput,
3906
+ ignoreOutput: actualConfig.ignoreOutput,
3907
+ parentSpanContext: actualConfig.parentSpanContext
3908
+ }, originalMethod, this, ...args);
3909
+ };
3910
+ };
3911
+ }
3912
+ /**
3913
+ * Decorator that wraps a method to automatically observe it with Laminar tracing.
3914
+ * This decorator uses the legacy experimental decorator syntax
3915
+ * (requires `--experimentalDecorators` flag).
3916
+ *
3917
+ * **Important**: Use this decorator only if your `tsconfig.json` has
3918
+ * `experimentalDecorators: true` in the `compilerOptions` section
3919
+ * (or if you compile with the `--experimentalDecorators` flag).
3920
+ * For TypeScript 5.0+ projects without experimental decorators, use
3921
+ * {@link observeDecorator} instead.
3922
+ *
3923
+ * This decorator can be used on class methods to automatically create spans.
3924
+ *
3925
+ * Use this only if you need the legacy experimental decorator syntax.
3926
+ * @param config - Configuration for the observe decorator, can be static or a function
3927
+ * @returns A method decorator
3928
+ *
3929
+ * @example
3930
+ * ```typescript
3931
+ * // In your tsconfig.json, ensure experimentalDecorators is enabled:
3932
+ * // {
3933
+ * // "compilerOptions": {
3934
+ * // "experimentalDecorators": true
3935
+ * // }
3936
+ * // }
3937
+ *
3938
+ * import { observeExperimentalDecorator } from '@lmnr-ai/lmnr';
3939
+ *
3940
+ * class MyService {
3941
+ * @observeExperimentalDecorator({ name: 'processData', spanType: 'DEFAULT' })
3942
+ * async processData(input: string) {
3943
+ * // Your code here
3944
+ * return `processed: ${input}`;
3945
+ * }
3946
+ *
3947
+ * @observeExperimentalDecorator((thisArg, ...args) => ({
3948
+ * name: `dynamicMethod_${args[0]}`,
3949
+ * sessionId: thisArg.sessionId
3950
+ * }))
3951
+ * async dynamicMethod(id: string) {
3952
+ * // Your code here
3953
+ * }
3954
+ * }
3955
+ * ```
3956
+ */
3957
+ function observeExperimentalDecorator(config$2) {
3866
3958
  return function(_target, propertyKey, descriptor) {
3867
- if (!descriptor || typeof descriptor.value !== "function") throw new Error(`observeDecorator can only be applied to methods. Applied to: ${String(propertyKey)}`);
3959
+ if (!descriptor || typeof descriptor.value !== "function") throw new Error(`observeExperimentalDecorator can only be applied to methods. Applied to: ${String(propertyKey)}`);
3868
3960
  const originalMethod = descriptor.value;
3869
3961
  descriptor.value = function(...args) {
3870
3962
  let actualConfig;
@@ -4245,6 +4337,7 @@ exports.initializeLaminarInstrumentations = initializeLaminarInstrumentations;
4245
4337
  exports.instrumentClaudeAgentQuery = instrumentClaudeAgentQuery;
4246
4338
  exports.observe = observe;
4247
4339
  exports.observeDecorator = observeDecorator;
4340
+ exports.observeExperimentalDecorator = observeExperimentalDecorator;
4248
4341
  exports.withTracingLevel = withTracingLevel;
4249
4342
  exports.wrapAISDK = wrapAISDK;
4250
4343
  //# sourceMappingURL=index.cjs.map