@langfuse/tracing 4.0.0-beta.2 → 4.0.0-beta.4

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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _opentelemetry_api from '@opentelemetry/api';
2
- import { Span, TimeInput, Attributes, SpanContext } from '@opentelemetry/api';
2
+ import { Span, TimeInput, Attributes, TracerProvider, SpanContext } from '@opentelemetry/api';
3
3
  import { OpenAiUsage } from '@langfuse/core';
4
4
  export { LangfuseOtelSpanAttributes } from '@langfuse/core';
5
5
 
@@ -444,6 +444,90 @@ declare function createSpanAttributes({ metadata, input, output, level, statusMe
444
444
  */
445
445
  declare function createGenerationAttributes({ completionStartTime, metadata, level, statusMessage, version, model, modelParameters, input, output, usageDetails, costDetails, prompt, }: LangfuseGenerationAttributes): Attributes;
446
446
 
447
+ /**
448
+ * Sets an isolated TracerProvider for Langfuse tracing operations.
449
+ *
450
+ * This allows Langfuse to use its own TracerProvider instance, separate from
451
+ * the global OpenTelemetry TracerProvider. This is useful for avoiding conflicts
452
+ * with other OpenTelemetry instrumentation in the application.
453
+ *
454
+ * ⚠️ **Limitation: Span Context Sharing**
455
+ *
456
+ * While this function isolates span processing and export, it does NOT provide
457
+ * complete trace isolation. OpenTelemetry context (trace IDs, parent spans) is
458
+ * still shared between the global and isolated providers. This means:
459
+ *
460
+ * - Spans created with the isolated provider inherit trace IDs from global spans
461
+ * - Spans created with the isolated provider inherit parent relationships from global spans
462
+ * - This can result in spans from different providers being part of the same logical trace
463
+ *
464
+ * **Why this happens:**
465
+ * OpenTelemetry uses a global context propagation mechanism that operates at the
466
+ * JavaScript runtime level, independent of individual TracerProvider instances.
467
+ * The context (containing trace ID, span ID) flows through async boundaries and
468
+ * is inherited by all spans created within that context, regardless of which
469
+ * TracerProvider creates them.
470
+ *
471
+ * @example
472
+ * ```typescript
473
+ * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
474
+ * import { LangfuseSpanProcessor } from '@langfuse/otel';
475
+ * import { setLangfuseTracerProvider } from '@langfuse/tracing';
476
+ *
477
+ * // Create provider with span processors in constructor
478
+ * const provider = new NodeTracerProvider({
479
+ * spanProcessors: [new LangfuseSpanProcessor()]
480
+ * });
481
+ *
482
+ * setLangfuseTracerProvider(provider);
483
+ *
484
+ * // Note: Spans created with getLangfuseTracer() may still inherit
485
+ * // context from spans created with the global tracer
486
+ * ```
487
+ *
488
+ * @param provider - The TracerProvider instance to use, or null to clear the isolated provider
489
+ * @public
490
+ */
491
+ declare function setLangfuseTracerProvider(provider: TracerProvider | null): void;
492
+ /**
493
+ * Gets the TracerProvider for Langfuse tracing operations.
494
+ *
495
+ * Returns the isolated TracerProvider if one has been set via setLangfuseTracerProvider(),
496
+ * otherwise falls back to the global OpenTelemetry TracerProvider.
497
+ *
498
+ * @example
499
+ * ```typescript
500
+ * import { getLangfuseTracerProvider } from '@langfuse/tracing';
501
+ *
502
+ * const provider = getLangfuseTracerProvider();
503
+ * const tracer = provider.getTracer('my-tracer', '1.0.0');
504
+ * ```
505
+ *
506
+ * @returns The TracerProvider instance to use for Langfuse tracing
507
+ * @public
508
+ */
509
+ declare function getLangfuseTracerProvider(): TracerProvider;
510
+ /**
511
+ * Gets the OpenTelemetry tracer instance for Langfuse.
512
+ *
513
+ * This function returns a tracer specifically configured for Langfuse
514
+ * with the correct tracer name and version. Used internally by all
515
+ * Langfuse tracing functions to ensure consistent trace creation.
516
+ *
517
+ * @returns The Langfuse OpenTelemetry tracer instance
518
+ *
519
+ * @example
520
+ * ```typescript
521
+ * import { getLangfuseTracer } from '@langfuse/tracing';
522
+ *
523
+ * const tracer = getLangfuseTracer();
524
+ * const span = tracer.startSpan('my-operation');
525
+ * ```
526
+ *
527
+ * @public
528
+ */
529
+ declare function getLangfuseTracer(): _opentelemetry_api.Tracer;
530
+
447
531
  /**
448
532
  * Options for starting observations (spans, generations, events).
449
533
  *
@@ -455,6 +539,17 @@ type StartObservationOptions = {
455
539
  /** Parent span context to attach this observation to */
456
540
  parentSpanContext?: SpanContext;
457
541
  };
542
+ /**
543
+ * Options for starting an observations set to active in context
544
+ *
545
+ * Extends StartObservationOptions with additional context-specific configuration.
546
+ *
547
+ * @public
548
+ */
549
+ type StartActiveObservationContext = StartObservationOptions & {
550
+ /** Whether to automatically end the observation when exiting the context. Default is true */
551
+ endOnExit?: boolean;
552
+ };
458
553
  /**
459
554
  * Creates and starts a new Langfuse span for general-purpose tracing.
460
555
  *
@@ -614,7 +709,7 @@ declare function createEvent(name: string, attributes?: LangfuseEventAttributes,
614
709
  *
615
710
  * @public
616
711
  */
617
- declare function startActiveSpan<F extends (span: LangfuseSpan) => unknown>(name: string, fn: F, options?: StartObservationOptions): ReturnType<F>;
712
+ declare function startActiveSpan<F extends (span: LangfuseSpan) => unknown>(name: string, fn: F, options?: StartActiveObservationContext): ReturnType<F>;
618
713
  /**
619
714
  * Starts an active generation and executes a function within its context.
620
715
  *
@@ -650,7 +745,7 @@ declare function startActiveSpan<F extends (span: LangfuseSpan) => unknown>(name
650
745
  *
651
746
  * @public
652
747
  */
653
- declare function startActiveGeneration<F extends (span: LangfuseGeneration) => unknown>(name: string, fn: F, options?: StartObservationOptions): ReturnType<F>;
748
+ declare function startActiveGeneration<F extends (span: LangfuseGeneration) => unknown>(name: string, fn: F, options?: StartActiveObservationContext): ReturnType<F>;
654
749
  /**
655
750
  * Updates the currently active trace with new attributes.
656
751
  *
@@ -739,6 +834,10 @@ interface ObserveOptions {
739
834
  captureInput?: boolean;
740
835
  /** Whether to capture function output as observation output */
741
836
  captureOutput?: boolean;
837
+ /** Parent span context to attach this observation to */
838
+ parentSpanContext?: SpanContext;
839
+ /** Whether to automatically end the observation when exiting the context. Default is true */
840
+ endOnExit?: boolean;
742
841
  }
743
842
  /**
744
843
  * Decorator function that automatically wraps a function with Langfuse tracing.
@@ -843,5 +942,25 @@ declare function observe<T extends (...args: unknown[]) => unknown>(fn: T, optio
843
942
  * @public
844
943
  */
845
944
  declare function createTraceId(seed?: string): Promise<string>;
945
+ /**
946
+ * Gets the current active trace ID.
947
+ *
948
+ * If there is no span in the current context, returns undefined.
949
+ *
950
+ * @returns The trace ID of the currently active span, or undefined if no span is active
951
+ *
952
+ * @public
953
+ */
954
+ declare function getActiveTraceId(): string | undefined;
955
+ /**
956
+ * Gets the current active observation ID.
957
+ *
958
+ * If there is no OTEL span in the current context, returns undefined.
959
+ *
960
+ * @returns The ID of the currently active OTEL span, or undefined if no OTEL span is active
961
+ *
962
+ * @public
963
+ */
964
+ declare function getActiveSpanId(): string | undefined;
846
965
 
847
- export { type LangfuseAttributes, LangfuseEvent, type LangfuseEventAttributes, LangfuseGeneration, type LangfuseGenerationAttributes, type LangfuseObservation, type LangfuseObservationType, LangfuseSpan, type LangfuseSpanAttributes, type LangfuseTraceAttributes, type ObservationLevel, type ObserveOptions, type StartObservationOptions, createEvent, createGenerationAttributes, createSpanAttributes, createTraceAttributes, createTraceId, observe, startActiveGeneration, startActiveSpan, startGeneration, startSpan, updateActiveGeneration, updateActiveSpan, updateActiveTrace };
966
+ export { type LangfuseAttributes, LangfuseEvent, type LangfuseEventAttributes, LangfuseGeneration, type LangfuseGenerationAttributes, type LangfuseObservation, type LangfuseObservationType, LangfuseSpan, type LangfuseSpanAttributes, type LangfuseTraceAttributes, type ObservationLevel, type ObserveOptions, type StartActiveObservationContext, type StartObservationOptions, createEvent, createGenerationAttributes, createSpanAttributes, createTraceAttributes, createTraceId, getActiveSpanId, getActiveTraceId, getLangfuseTracer, getLangfuseTracerProvider, observe, setLangfuseTracerProvider, startActiveGeneration, startActiveSpan, startGeneration, startSpan, updateActiveGeneration, updateActiveSpan, updateActiveTrace };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _opentelemetry_api from '@opentelemetry/api';
2
- import { Span, TimeInput, Attributes, SpanContext } from '@opentelemetry/api';
2
+ import { Span, TimeInput, Attributes, TracerProvider, SpanContext } from '@opentelemetry/api';
3
3
  import { OpenAiUsage } from '@langfuse/core';
4
4
  export { LangfuseOtelSpanAttributes } from '@langfuse/core';
5
5
 
@@ -444,6 +444,90 @@ declare function createSpanAttributes({ metadata, input, output, level, statusMe
444
444
  */
445
445
  declare function createGenerationAttributes({ completionStartTime, metadata, level, statusMessage, version, model, modelParameters, input, output, usageDetails, costDetails, prompt, }: LangfuseGenerationAttributes): Attributes;
446
446
 
447
+ /**
448
+ * Sets an isolated TracerProvider for Langfuse tracing operations.
449
+ *
450
+ * This allows Langfuse to use its own TracerProvider instance, separate from
451
+ * the global OpenTelemetry TracerProvider. This is useful for avoiding conflicts
452
+ * with other OpenTelemetry instrumentation in the application.
453
+ *
454
+ * ⚠️ **Limitation: Span Context Sharing**
455
+ *
456
+ * While this function isolates span processing and export, it does NOT provide
457
+ * complete trace isolation. OpenTelemetry context (trace IDs, parent spans) is
458
+ * still shared between the global and isolated providers. This means:
459
+ *
460
+ * - Spans created with the isolated provider inherit trace IDs from global spans
461
+ * - Spans created with the isolated provider inherit parent relationships from global spans
462
+ * - This can result in spans from different providers being part of the same logical trace
463
+ *
464
+ * **Why this happens:**
465
+ * OpenTelemetry uses a global context propagation mechanism that operates at the
466
+ * JavaScript runtime level, independent of individual TracerProvider instances.
467
+ * The context (containing trace ID, span ID) flows through async boundaries and
468
+ * is inherited by all spans created within that context, regardless of which
469
+ * TracerProvider creates them.
470
+ *
471
+ * @example
472
+ * ```typescript
473
+ * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
474
+ * import { LangfuseSpanProcessor } from '@langfuse/otel';
475
+ * import { setLangfuseTracerProvider } from '@langfuse/tracing';
476
+ *
477
+ * // Create provider with span processors in constructor
478
+ * const provider = new NodeTracerProvider({
479
+ * spanProcessors: [new LangfuseSpanProcessor()]
480
+ * });
481
+ *
482
+ * setLangfuseTracerProvider(provider);
483
+ *
484
+ * // Note: Spans created with getLangfuseTracer() may still inherit
485
+ * // context from spans created with the global tracer
486
+ * ```
487
+ *
488
+ * @param provider - The TracerProvider instance to use, or null to clear the isolated provider
489
+ * @public
490
+ */
491
+ declare function setLangfuseTracerProvider(provider: TracerProvider | null): void;
492
+ /**
493
+ * Gets the TracerProvider for Langfuse tracing operations.
494
+ *
495
+ * Returns the isolated TracerProvider if one has been set via setLangfuseTracerProvider(),
496
+ * otherwise falls back to the global OpenTelemetry TracerProvider.
497
+ *
498
+ * @example
499
+ * ```typescript
500
+ * import { getLangfuseTracerProvider } from '@langfuse/tracing';
501
+ *
502
+ * const provider = getLangfuseTracerProvider();
503
+ * const tracer = provider.getTracer('my-tracer', '1.0.0');
504
+ * ```
505
+ *
506
+ * @returns The TracerProvider instance to use for Langfuse tracing
507
+ * @public
508
+ */
509
+ declare function getLangfuseTracerProvider(): TracerProvider;
510
+ /**
511
+ * Gets the OpenTelemetry tracer instance for Langfuse.
512
+ *
513
+ * This function returns a tracer specifically configured for Langfuse
514
+ * with the correct tracer name and version. Used internally by all
515
+ * Langfuse tracing functions to ensure consistent trace creation.
516
+ *
517
+ * @returns The Langfuse OpenTelemetry tracer instance
518
+ *
519
+ * @example
520
+ * ```typescript
521
+ * import { getLangfuseTracer } from '@langfuse/tracing';
522
+ *
523
+ * const tracer = getLangfuseTracer();
524
+ * const span = tracer.startSpan('my-operation');
525
+ * ```
526
+ *
527
+ * @public
528
+ */
529
+ declare function getLangfuseTracer(): _opentelemetry_api.Tracer;
530
+
447
531
  /**
448
532
  * Options for starting observations (spans, generations, events).
449
533
  *
@@ -455,6 +539,17 @@ type StartObservationOptions = {
455
539
  /** Parent span context to attach this observation to */
456
540
  parentSpanContext?: SpanContext;
457
541
  };
542
+ /**
543
+ * Options for starting an observations set to active in context
544
+ *
545
+ * Extends StartObservationOptions with additional context-specific configuration.
546
+ *
547
+ * @public
548
+ */
549
+ type StartActiveObservationContext = StartObservationOptions & {
550
+ /** Whether to automatically end the observation when exiting the context. Default is true */
551
+ endOnExit?: boolean;
552
+ };
458
553
  /**
459
554
  * Creates and starts a new Langfuse span for general-purpose tracing.
460
555
  *
@@ -614,7 +709,7 @@ declare function createEvent(name: string, attributes?: LangfuseEventAttributes,
614
709
  *
615
710
  * @public
616
711
  */
617
- declare function startActiveSpan<F extends (span: LangfuseSpan) => unknown>(name: string, fn: F, options?: StartObservationOptions): ReturnType<F>;
712
+ declare function startActiveSpan<F extends (span: LangfuseSpan) => unknown>(name: string, fn: F, options?: StartActiveObservationContext): ReturnType<F>;
618
713
  /**
619
714
  * Starts an active generation and executes a function within its context.
620
715
  *
@@ -650,7 +745,7 @@ declare function startActiveSpan<F extends (span: LangfuseSpan) => unknown>(name
650
745
  *
651
746
  * @public
652
747
  */
653
- declare function startActiveGeneration<F extends (span: LangfuseGeneration) => unknown>(name: string, fn: F, options?: StartObservationOptions): ReturnType<F>;
748
+ declare function startActiveGeneration<F extends (span: LangfuseGeneration) => unknown>(name: string, fn: F, options?: StartActiveObservationContext): ReturnType<F>;
654
749
  /**
655
750
  * Updates the currently active trace with new attributes.
656
751
  *
@@ -739,6 +834,10 @@ interface ObserveOptions {
739
834
  captureInput?: boolean;
740
835
  /** Whether to capture function output as observation output */
741
836
  captureOutput?: boolean;
837
+ /** Parent span context to attach this observation to */
838
+ parentSpanContext?: SpanContext;
839
+ /** Whether to automatically end the observation when exiting the context. Default is true */
840
+ endOnExit?: boolean;
742
841
  }
743
842
  /**
744
843
  * Decorator function that automatically wraps a function with Langfuse tracing.
@@ -843,5 +942,25 @@ declare function observe<T extends (...args: unknown[]) => unknown>(fn: T, optio
843
942
  * @public
844
943
  */
845
944
  declare function createTraceId(seed?: string): Promise<string>;
945
+ /**
946
+ * Gets the current active trace ID.
947
+ *
948
+ * If there is no span in the current context, returns undefined.
949
+ *
950
+ * @returns The trace ID of the currently active span, or undefined if no span is active
951
+ *
952
+ * @public
953
+ */
954
+ declare function getActiveTraceId(): string | undefined;
955
+ /**
956
+ * Gets the current active observation ID.
957
+ *
958
+ * If there is no OTEL span in the current context, returns undefined.
959
+ *
960
+ * @returns The ID of the currently active OTEL span, or undefined if no OTEL span is active
961
+ *
962
+ * @public
963
+ */
964
+ declare function getActiveSpanId(): string | undefined;
846
965
 
847
- export { type LangfuseAttributes, LangfuseEvent, type LangfuseEventAttributes, LangfuseGeneration, type LangfuseGenerationAttributes, type LangfuseObservation, type LangfuseObservationType, LangfuseSpan, type LangfuseSpanAttributes, type LangfuseTraceAttributes, type ObservationLevel, type ObserveOptions, type StartObservationOptions, createEvent, createGenerationAttributes, createSpanAttributes, createTraceAttributes, createTraceId, observe, startActiveGeneration, startActiveSpan, startGeneration, startSpan, updateActiveGeneration, updateActiveSpan, updateActiveTrace };
966
+ export { type LangfuseAttributes, LangfuseEvent, type LangfuseEventAttributes, LangfuseGeneration, type LangfuseGenerationAttributes, type LangfuseObservation, type LangfuseObservationType, LangfuseSpan, type LangfuseSpanAttributes, type LangfuseTraceAttributes, type ObservationLevel, type ObserveOptions, type StartActiveObservationContext, type StartObservationOptions, createEvent, createGenerationAttributes, createSpanAttributes, createTraceAttributes, createTraceId, getActiveSpanId, getActiveTraceId, getLangfuseTracer, getLangfuseTracerProvider, observe, setLangfuseTracerProvider, startActiveGeneration, startActiveSpan, startGeneration, startSpan, updateActiveGeneration, updateActiveSpan, updateActiveTrace };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- import { getGlobalLogger } from "@langfuse/core";
2
+ import { getGlobalLogger as getGlobalLogger2 } from "@langfuse/core";
3
3
  import {
4
4
  trace as trace2,
5
5
  context,
@@ -145,11 +145,61 @@ function _flattenAndSerializeMetadata(metadata, type) {
145
145
  return metadataAttributes;
146
146
  }
147
147
 
148
- // src/utils.ts
149
- import { LANGFUSE_SDK_VERSION, LANGFUSE_TRACER_NAME } from "@langfuse/core";
148
+ // src/tracerProvider.ts
149
+ import {
150
+ getGlobalLogger,
151
+ LANGFUSE_SDK_VERSION,
152
+ LANGFUSE_TRACER_NAME
153
+ } from "@langfuse/core";
150
154
  import { trace } from "@opentelemetry/api";
155
+ var LANGFUSE_GLOBAL_SYMBOL = Symbol.for("langfuse");
156
+ function createState() {
157
+ return {
158
+ isolatedTracerProvider: null
159
+ };
160
+ }
161
+ function getGlobalState() {
162
+ const initialState = createState();
163
+ try {
164
+ const g = globalThis;
165
+ if (typeof g !== "object" || g === null) {
166
+ getGlobalLogger().warn(
167
+ "globalThis is not available, using fallback state"
168
+ );
169
+ return initialState;
170
+ }
171
+ if (!g[LANGFUSE_GLOBAL_SYMBOL]) {
172
+ Object.defineProperty(g, LANGFUSE_GLOBAL_SYMBOL, {
173
+ value: initialState,
174
+ writable: false,
175
+ // lock the slot (not the contents)
176
+ configurable: false,
177
+ enumerable: false
178
+ });
179
+ }
180
+ return g[LANGFUSE_GLOBAL_SYMBOL];
181
+ } catch (err) {
182
+ if (err instanceof Error) {
183
+ getGlobalLogger().error(`Failed to access global state: ${err.message}`);
184
+ } else {
185
+ getGlobalLogger().error(`Failed to access global state: ${String(err)}`);
186
+ }
187
+ return initialState;
188
+ }
189
+ }
190
+ function setLangfuseTracerProvider(provider) {
191
+ getGlobalState().isolatedTracerProvider = provider;
192
+ }
193
+ function getLangfuseTracerProvider() {
194
+ const { isolatedTracerProvider } = getGlobalState();
195
+ if (isolatedTracerProvider) return isolatedTracerProvider;
196
+ return trace.getTracerProvider();
197
+ }
151
198
  function getLangfuseTracer() {
152
- return trace.getTracer(LANGFUSE_TRACER_NAME, LANGFUSE_SDK_VERSION);
199
+ return getLangfuseTracerProvider().getTracer(
200
+ LANGFUSE_TRACER_NAME,
201
+ LANGFUSE_SDK_VERSION
202
+ );
153
203
  }
154
204
 
155
205
  // src/spanWrapper.ts
@@ -353,17 +403,22 @@ function createParentContext(parentSpanContext) {
353
403
  if (!parentSpanContext) return;
354
404
  return trace2.setSpanContext(context.active(), parentSpanContext);
355
405
  }
356
- function wrapPromise(promise, span) {
406
+ function wrapPromise(promise, span, endOnExit) {
357
407
  return promise.then(
358
408
  (value) => {
359
- span.end();
409
+ if (endOnExit !== false) {
410
+ span.end();
411
+ }
360
412
  return value;
361
413
  },
362
414
  (err) => {
363
415
  span.setStatus({
364
416
  code: SpanStatusCode.ERROR,
365
417
  message: err instanceof Error ? err.message : "Unknown error"
366
- }).end();
418
+ });
419
+ if (endOnExit !== false) {
420
+ span.end();
421
+ }
367
422
  throw err;
368
423
  }
369
424
  );
@@ -402,16 +457,21 @@ function startActiveSpan(name, fn, options) {
402
457
  try {
403
458
  const result = fn(new LangfuseSpan({ otelSpan: span }));
404
459
  if (result instanceof Promise) {
405
- return wrapPromise(result, span);
460
+ return wrapPromise(result, span, options == null ? void 0 : options.endOnExit);
406
461
  } else {
407
- span.end();
462
+ if ((options == null ? void 0 : options.endOnExit) !== false) {
463
+ span.end();
464
+ }
408
465
  return result;
409
466
  }
410
467
  } catch (err) {
411
468
  span.setStatus({
412
469
  code: SpanStatusCode.ERROR,
413
470
  message: err instanceof Error ? err.message : "Unknown error"
414
- }).end();
471
+ });
472
+ if ((options == null ? void 0 : options.endOnExit) !== false) {
473
+ span.end();
474
+ }
415
475
  throw err;
416
476
  }
417
477
  }
@@ -427,16 +487,21 @@ function startActiveGeneration(name, fn, options) {
427
487
  try {
428
488
  const result = fn(new LangfuseGeneration({ otelSpan: span }));
429
489
  if (result instanceof Promise) {
430
- return wrapPromise(result, span);
490
+ return wrapPromise(result, span, options == null ? void 0 : options.endOnExit);
431
491
  } else {
432
- span.end();
492
+ if ((options == null ? void 0 : options.endOnExit) !== false) {
493
+ span.end();
494
+ }
433
495
  return result;
434
496
  }
435
497
  } catch (err) {
436
498
  span.setStatus({
437
499
  code: SpanStatusCode.ERROR,
438
500
  message: err instanceof Error ? err.message : "Unknown error"
439
- }).end();
501
+ });
502
+ if ((options == null ? void 0 : options.endOnExit) !== false) {
503
+ span.end();
504
+ }
440
505
  throw err;
441
506
  }
442
507
  }
@@ -445,7 +510,7 @@ function startActiveGeneration(name, fn, options) {
445
510
  function updateActiveTrace(attributes) {
446
511
  const span = trace2.getActiveSpan();
447
512
  if (!span) {
448
- getGlobalLogger().warn(
513
+ getGlobalLogger2().warn(
449
514
  "No active OTEL span in context. Skipping trace update."
450
515
  );
451
516
  return;
@@ -455,7 +520,7 @@ function updateActiveTrace(attributes) {
455
520
  function updateActiveSpan(attributes) {
456
521
  const span = trace2.getActiveSpan();
457
522
  if (!span) {
458
- getGlobalLogger().warn(
523
+ getGlobalLogger2().warn(
459
524
  "No active OTEL span in context. Skipping span update."
460
525
  );
461
526
  return;
@@ -465,7 +530,7 @@ function updateActiveSpan(attributes) {
465
530
  function updateActiveGeneration(attributes) {
466
531
  const span = trace2.getActiveSpan();
467
532
  if (!span) {
468
- getGlobalLogger().warn(
533
+ getGlobalLogger2().warn(
469
534
  "No active OTEL span in context. Skipping generation update."
470
535
  );
471
536
  return;
@@ -477,21 +542,28 @@ function observe(fn, options = {}) {
477
542
  name = fn.name || "anonymous-function",
478
543
  asType = "span",
479
544
  captureInput = true,
480
- captureOutput = true
545
+ captureOutput = true,
546
+ parentSpanContext = void 0
481
547
  } = options;
482
- const wrappedFunction = (...args) => {
548
+ const wrappedFunction = function(...args) {
483
549
  const inputData = captureInput ? _captureArguments(args) : void 0;
484
- const observation = asType === "generation" ? startGeneration(name, inputData ? { input: inputData } : {}) : startSpan(name, inputData ? { input: inputData } : {});
550
+ const observation = asType === "generation" ? startGeneration(name, inputData ? { input: inputData } : {}, {
551
+ parentSpanContext
552
+ }) : startSpan(name, inputData ? { input: inputData } : {}, {
553
+ parentSpanContext
554
+ });
485
555
  const activeContext = trace2.setSpan(context.active(), observation.otelSpan);
486
556
  try {
487
- const result = context.with(activeContext, () => fn(...args));
557
+ const result = context.with(activeContext, () => fn.apply(this, args));
488
558
  if (result instanceof Promise) {
489
559
  return result.then(
490
560
  (value) => {
491
561
  if (captureOutput) {
492
562
  observation.update({ output: _captureOutput(value) });
493
563
  }
494
- observation.end();
564
+ if ((options == null ? void 0 : options.endOnExit) !== false) {
565
+ observation.end();
566
+ }
495
567
  return value;
496
568
  },
497
569
  (error) => {
@@ -499,7 +571,10 @@ function observe(fn, options = {}) {
499
571
  level: "ERROR",
500
572
  statusMessage: (error instanceof Error ? error.message : String(error)) || "Function threw an error",
501
573
  output: captureOutput ? { error: String(error) } : void 0
502
- }).end();
574
+ });
575
+ if ((options == null ? void 0 : options.endOnExit) !== false) {
576
+ observation.end();
577
+ }
503
578
  throw error;
504
579
  }
505
580
  );
@@ -507,7 +582,9 @@ function observe(fn, options = {}) {
507
582
  if (captureOutput) {
508
583
  observation.update({ output: _captureOutput(result) });
509
584
  }
510
- observation.end();
585
+ if ((options == null ? void 0 : options.endOnExit) !== false) {
586
+ observation.end();
587
+ }
511
588
  return result;
512
589
  }
513
590
  } catch (error) {
@@ -515,7 +592,10 @@ function observe(fn, options = {}) {
515
592
  level: "ERROR",
516
593
  statusMessage: (error instanceof Error ? error.message : String(error)) || "Function threw an error",
517
594
  output: captureOutput ? { error: String(error) } : void 0
518
- }).end();
595
+ });
596
+ if ((options == null ? void 0 : options.endOnExit) !== false) {
597
+ observation.end();
598
+ }
519
599
  throw error;
520
600
  }
521
601
  };
@@ -552,6 +632,14 @@ async function createTraceId(seed) {
552
632
  function uint8ArrayToHex(array) {
553
633
  return Array.from(array).map((b) => b.toString(16).padStart(2, "0")).join("");
554
634
  }
635
+ function getActiveTraceId() {
636
+ var _a;
637
+ return (_a = trace2.getActiveSpan()) == null ? void 0 : _a.spanContext().traceId;
638
+ }
639
+ function getActiveSpanId() {
640
+ var _a;
641
+ return (_a = trace2.getActiveSpan()) == null ? void 0 : _a.spanContext().spanId;
642
+ }
555
643
  export {
556
644
  LangfuseEvent,
557
645
  LangfuseGeneration,
@@ -562,7 +650,12 @@ export {
562
650
  createSpanAttributes,
563
651
  createTraceAttributes,
564
652
  createTraceId,
653
+ getActiveSpanId,
654
+ getActiveTraceId,
655
+ getLangfuseTracer,
656
+ getLangfuseTracerProvider,
565
657
  observe,
658
+ setLangfuseTracerProvider,
566
659
  startActiveGeneration,
567
660
  startActiveSpan,
568
661
  startGeneration,