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

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
@@ -29,7 +29,12 @@ __export(index_exports, {
29
29
  createSpanAttributes: () => createSpanAttributes,
30
30
  createTraceAttributes: () => createTraceAttributes,
31
31
  createTraceId: () => createTraceId,
32
+ getActiveSpanId: () => getActiveSpanId,
33
+ getActiveTraceId: () => getActiveTraceId,
34
+ getLangfuseTracer: () => getLangfuseTracer,
35
+ getLangfuseTracerProvider: () => getLangfuseTracerProvider,
32
36
  observe: () => observe,
37
+ setLangfuseTracerProvider: () => setLangfuseTracerProvider,
33
38
  startActiveGeneration: () => startActiveGeneration,
34
39
  startActiveSpan: () => startActiveSpan,
35
40
  startGeneration: () => startGeneration,
@@ -181,11 +186,57 @@ function _flattenAndSerializeMetadata(metadata, type) {
181
186
  return metadataAttributes;
182
187
  }
183
188
 
184
- // src/utils.ts
189
+ // src/tracerProvider.ts
185
190
  var import_core2 = require("@langfuse/core");
186
191
  var import_api = require("@opentelemetry/api");
192
+ var LANGFUSE_GLOBAL_SYMBOL = Symbol.for("langfuse");
193
+ function createState() {
194
+ return {
195
+ isolatedTracerProvider: null
196
+ };
197
+ }
198
+ function getGlobalState() {
199
+ const initialState = createState();
200
+ try {
201
+ const g = globalThis;
202
+ if (typeof g !== "object" || g === null) {
203
+ (0, import_core2.getGlobalLogger)().warn(
204
+ "globalThis is not available, using fallback state"
205
+ );
206
+ return initialState;
207
+ }
208
+ if (!g[LANGFUSE_GLOBAL_SYMBOL]) {
209
+ Object.defineProperty(g, LANGFUSE_GLOBAL_SYMBOL, {
210
+ value: initialState,
211
+ writable: false,
212
+ // lock the slot (not the contents)
213
+ configurable: false,
214
+ enumerable: false
215
+ });
216
+ }
217
+ return g[LANGFUSE_GLOBAL_SYMBOL];
218
+ } catch (err) {
219
+ if (err instanceof Error) {
220
+ (0, import_core2.getGlobalLogger)().error(`Failed to access global state: ${err.message}`);
221
+ } else {
222
+ (0, import_core2.getGlobalLogger)().error(`Failed to access global state: ${String(err)}`);
223
+ }
224
+ return initialState;
225
+ }
226
+ }
227
+ function setLangfuseTracerProvider(provider) {
228
+ getGlobalState().isolatedTracerProvider = provider;
229
+ }
230
+ function getLangfuseTracerProvider() {
231
+ const { isolatedTracerProvider } = getGlobalState();
232
+ if (isolatedTracerProvider) return isolatedTracerProvider;
233
+ return import_api.trace.getTracerProvider();
234
+ }
187
235
  function getLangfuseTracer() {
188
- return import_api.trace.getTracer(import_core2.LANGFUSE_TRACER_NAME, import_core2.LANGFUSE_SDK_VERSION);
236
+ return getLangfuseTracerProvider().getTracer(
237
+ import_core2.LANGFUSE_TRACER_NAME,
238
+ import_core2.LANGFUSE_SDK_VERSION
239
+ );
189
240
  }
190
241
 
191
242
  // src/spanWrapper.ts
@@ -513,14 +564,19 @@ function observe(fn, options = {}) {
513
564
  name = fn.name || "anonymous-function",
514
565
  asType = "span",
515
566
  captureInput = true,
516
- captureOutput = true
567
+ captureOutput = true,
568
+ parentSpanContext = void 0
517
569
  } = options;
518
- const wrappedFunction = (...args) => {
570
+ const wrappedFunction = function(...args) {
519
571
  const inputData = captureInput ? _captureArguments(args) : void 0;
520
- const observation = asType === "generation" ? startGeneration(name, inputData ? { input: inputData } : {}) : startSpan(name, inputData ? { input: inputData } : {});
572
+ const observation = asType === "generation" ? startGeneration(name, inputData ? { input: inputData } : {}, {
573
+ parentSpanContext
574
+ }) : startSpan(name, inputData ? { input: inputData } : {}, {
575
+ parentSpanContext
576
+ });
521
577
  const activeContext = import_api2.trace.setSpan(import_api2.context.active(), observation.otelSpan);
522
578
  try {
523
- const result = import_api2.context.with(activeContext, () => fn(...args));
579
+ const result = import_api2.context.with(activeContext, () => fn.apply(this, args));
524
580
  if (result instanceof Promise) {
525
581
  return result.then(
526
582
  (value) => {
@@ -588,6 +644,14 @@ async function createTraceId(seed) {
588
644
  function uint8ArrayToHex(array) {
589
645
  return Array.from(array).map((b) => b.toString(16).padStart(2, "0")).join("");
590
646
  }
647
+ function getActiveTraceId() {
648
+ var _a;
649
+ return (_a = import_api2.trace.getActiveSpan()) == null ? void 0 : _a.spanContext().traceId;
650
+ }
651
+ function getActiveSpanId() {
652
+ var _a;
653
+ return (_a = import_api2.trace.getActiveSpan()) == null ? void 0 : _a.spanContext().spanId;
654
+ }
591
655
  // Annotate the CommonJS export names for ESM import in node:
592
656
  0 && (module.exports = {
593
657
  LangfuseEvent,
@@ -599,7 +663,12 @@ function uint8ArrayToHex(array) {
599
663
  createSpanAttributes,
600
664
  createTraceAttributes,
601
665
  createTraceId,
666
+ getActiveSpanId,
667
+ getActiveTraceId,
668
+ getLangfuseTracer,
669
+ getLangfuseTracerProvider,
602
670
  observe,
671
+ setLangfuseTracerProvider,
603
672
  startActiveGeneration,
604
673
  startActiveSpan,
605
674
  startGeneration,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/attributes.ts","../src/utils.ts","../src/spanWrapper.ts"],"sourcesContent":["import { getGlobalLogger } from \"@langfuse/core\";\nimport {\n trace,\n context,\n TimeInput,\n SpanStatusCode,\n Span,\n Context,\n SpanContext,\n} from \"@opentelemetry/api\";\n\nimport {\n createGenerationAttributes,\n createSpanAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport {\n LangfuseEvent,\n LangfuseGeneration,\n LangfuseSpan,\n} from \"./spanWrapper.js\";\nimport {\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\nimport { getLangfuseTracer } from \"./utils.js\";\n\nexport type {\n LangfuseObservationType,\n ObservationLevel,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\nexport * from \"./spanWrapper.js\";\nexport {\n createTraceAttributes,\n createSpanAttributes,\n createGenerationAttributes,\n} from \"./attributes.js\";\n\nexport { LangfuseOtelSpanAttributes } from \"@langfuse/core\";\n\n/**\n * Options for starting observations (spans, generations, events).\n *\n * @public\n */\nexport type StartObservationOptions = {\n /** Custom start time for the observation */\n startTime?: Date;\n /** Parent span context to attach this observation to */\n parentSpanContext?: SpanContext;\n};\n\n/**\n * Creates an OpenTelemetry span with the Langfuse tracer.\n *\n * @param params - Parameters for span creation\n * @returns The created OpenTelemetry span\n * @internal\n */\nfunction createOtelSpan(params: {\n name: string;\n startTime?: TimeInput;\n parentSpanContext?: SpanContext;\n}): Span {\n return getLangfuseTracer().startSpan(\n params.name,\n { startTime: params.startTime },\n createParentContext(params.parentSpanContext),\n );\n}\n\n/**\n * Creates a parent context from a span context.\n *\n * @param parentSpanContext - The span context to use as parent\n * @returns The created context or undefined if no parent provided\n * @internal\n */\nfunction createParentContext(\n parentSpanContext?: SpanContext,\n): Context | undefined {\n if (!parentSpanContext) return;\n\n return trace.setSpanContext(context.active(), parentSpanContext);\n}\n\n/**\n * Wraps a promise to automatically end the span when the promise resolves or rejects.\n *\n * @param promise - The promise to wrap\n * @param span - The span to end when promise completes\n * @returns The wrapped promise\n * @internal\n */\nfunction wrapPromise<T>(promise: Promise<T>, span: Span): Promise<T> {\n return promise.then(\n (value) => {\n span.end(); // End span AFTER Promise resolves\n\n return value;\n },\n (err: unknown) => {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end(); // End span AFTER Promise rejects\n\n throw err;\n },\n );\n}\n\n/**\n * Creates and starts a new Langfuse span for general-purpose tracing.\n *\n * Spans are used to track operations, functions, or logical units of work.\n * They can contain other spans or generations as children.\n *\n * @param name - Name of the span\n * @param attributes - Optional attributes to set on the span\n * @param options - Optional configuration for the span\n * @returns A LangfuseSpan instance\n *\n * @example\n * ```typescript\n * import { startSpan } from '@langfuse/tracing';\n *\n * const span = startSpan('data-processing', {\n * input: { userId: '123', data: {...} },\n * metadata: { version: '1.0' },\n * level: 'DEFAULT'\n * });\n *\n * try {\n * // Do some work\n * const result = await processData();\n *\n * span.update({ output: result });\n * } catch (error) {\n * span.update({\n * level: 'ERROR',\n * statusMessage: error.message\n * });\n * } finally {\n * span.end();\n * }\n * ```\n *\n * @public\n */\nexport function startSpan(\n name: string,\n attributes?: LangfuseSpanAttributes,\n options?: {\n startTime?: TimeInput;\n parentSpanContext?: SpanContext;\n },\n): LangfuseSpan {\n const otelSpan = createOtelSpan({\n name,\n ...options,\n });\n\n return new LangfuseSpan({ otelSpan, attributes });\n}\n\n/**\n * Creates and starts a new Langfuse generation for tracking LLM calls.\n *\n * Generations are specialized observations for tracking language model\n * interactions, including model parameters, usage metrics, and costs.\n *\n * @param name - Name of the generation (typically the model or operation)\n * @param attributes - Optional generation-specific attributes\n * @param options - Optional configuration for the generation\n * @returns A LangfuseGeneration instance\n *\n * @example\n * ```typescript\n * import { startGeneration } from '@langfuse/tracing';\n *\n * const generation = startGeneration('openai-gpt-4', {\n * input: [{ role: 'user', content: 'Hello, world!' }],\n * model: 'gpt-4',\n * modelParameters: {\n * temperature: 0.7,\n * max_tokens: 150\n * },\n * metadata: { feature: 'chat' }\n * });\n *\n * try {\n * const response = await callOpenAI(messages);\n *\n * generation.update({\n * output: response.choices[0].message,\n * usageDetails: {\n * promptTokens: response.usage.prompt_tokens,\n * completionTokens: response.usage.completion_tokens,\n * totalTokens: response.usage.total_tokens\n * }\n * });\n * } finally {\n * generation.end();\n * }\n * ```\n *\n * @public\n */\nexport function startGeneration(\n name: string,\n attributes?: LangfuseGenerationAttributes,\n options?: StartObservationOptions,\n): LangfuseGeneration {\n const otelSpan = createOtelSpan({\n name,\n ...options,\n });\n\n return new LangfuseGeneration({ otelSpan, attributes });\n}\n\n/**\n * Creates a Langfuse event for point-in-time occurrences.\n *\n * Events are used to capture instantaneous occurrences or log entries\n * within a trace. Unlike spans, they represent a single point in time.\n *\n * @param name - Name of the event\n * @param attributes - Optional attributes for the event\n * @param options - Optional configuration for the event\n * @returns A LangfuseEvent instance (automatically ended)\n *\n * @example\n * ```typescript\n * import { createEvent } from '@langfuse/tracing';\n *\n * // Log a user action\n * createEvent('user-click', {\n * input: { buttonId: 'submit', userId: '123' },\n * metadata: { page: '/checkout' },\n * level: 'DEFAULT'\n * });\n *\n * // Log an error\n * createEvent('api-error', {\n * level: 'ERROR',\n * statusMessage: 'Failed to fetch user data',\n * metadata: { endpoint: '/api/users/123', statusCode: 500 }\n * });\n * ```\n *\n * @public\n */\nexport function createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n options?: StartObservationOptions,\n) {\n const timestamp = options?.startTime ?? new Date();\n\n const otelSpan = createOtelSpan({\n name,\n ...options,\n startTime: timestamp,\n });\n\n return new LangfuseEvent({ otelSpan, attributes, timestamp });\n}\n\n/**\n * Starts an active span and executes a function within its context.\n *\n * This function creates a span, sets it as the active span in the OpenTelemetry\n * context, executes the provided function, and automatically ends the span.\n * Perfect for wrapping operations where you want child spans to be automatically\n * linked.\n *\n * @param name - Name of the span\n * @param fn - Function to execute within the span context\n * @param options - Optional configuration for the span\n * @returns The return value of the executed function\n *\n * @example\n * ```typescript\n * import { startActiveSpan } from '@langfuse/tracing';\n *\n * // Synchronous function\n * const result = startActiveSpan('calculate-metrics', (span) => {\n * span.update({ input: { data: rawData } });\n *\n * const metrics = calculateMetrics(rawData);\n * span.update({ output: metrics });\n *\n * return metrics;\n * });\n *\n * // Asynchronous function\n * const data = await startActiveSpan('fetch-user-data', async (span) => {\n * span.update({ input: { userId: '123' } });\n *\n * const userData = await api.getUser('123');\n * span.update({ output: userData });\n *\n * return userData;\n * });\n * ```\n *\n * @public\n */\nexport function startActiveSpan<F extends (span: LangfuseSpan) => unknown>(\n name: string,\n fn: F,\n options?: StartObservationOptions,\n): ReturnType<F> {\n return getLangfuseTracer().startActiveSpan(\n name,\n { startTime: options?.startTime },\n createParentContext(options?.parentSpanContext) ?? context.active(),\n (span) => {\n try {\n const result = fn(new LangfuseSpan({ otelSpan: span }));\n\n if (result instanceof Promise) {\n return wrapPromise(result, span) as ReturnType<F>;\n } else {\n span.end();\n\n return result as ReturnType<F>;\n }\n } catch (err) {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end();\n\n throw err;\n }\n },\n );\n}\n\n/**\n * Starts an active generation and executes a function within its context.\n *\n * Similar to startActiveSpan but creates a generation for tracking LLM calls.\n * The generation is automatically ended when the function completes.\n *\n * @param name - Name of the generation\n * @param fn - Function to execute within the generation context\n * @param options - Optional configuration for the generation\n * @returns The return value of the executed function\n *\n * @example\n * ```typescript\n * import { startActiveGeneration } from '@langfuse/tracing';\n *\n * const response = await startActiveGeneration('openai-completion', async (generation) => {\n * generation.update({\n * input: { messages: [...] },\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 }\n * });\n *\n * const result = await openai.chat.completions.create({...});\n *\n * generation.update({\n * output: result.choices[0].message,\n * usageDetails: result.usage\n * });\n *\n * return result;\n * });\n * ```\n *\n * @public\n */\nexport function startActiveGeneration<\n F extends (span: LangfuseGeneration) => unknown,\n>(name: string, fn: F, options?: StartObservationOptions): ReturnType<F> {\n return getLangfuseTracer().startActiveSpan(\n name,\n { startTime: options?.startTime },\n createParentContext(options?.parentSpanContext) ?? context.active(),\n (span) => {\n try {\n const result = fn(new LangfuseGeneration({ otelSpan: span }));\n\n if (result instanceof Promise) {\n return wrapPromise(result, span) as ReturnType<F>;\n } else {\n span.end();\n\n return result as ReturnType<F>;\n }\n } catch (err) {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end();\n\n throw err;\n }\n },\n );\n}\n\n/**\n * Updates the currently active trace with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with trace-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Trace attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveTrace } from '@langfuse/tracing';\n *\n * // Inside an active span context\n * updateActiveTrace({\n * name: 'user-workflow',\n * userId: '123',\n * sessionId: 'session-456',\n * tags: ['production', 'critical'],\n * public: true\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveTrace(attributes: LangfuseTraceAttributes) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping trace update.\",\n );\n\n return;\n }\n\n span.setAttributes(createTraceAttributes(attributes));\n}\n\n/**\n * Updates the currently active span with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with span-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Span attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveSpan } from '@langfuse/tracing';\n *\n * // Inside an active span context\n * updateActiveSpan({\n * level: 'WARNING',\n * statusMessage: 'Operation completed with warnings',\n * metadata: { warningCount: 3 }\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveSpan(attributes: LangfuseSpanAttributes) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping span update.\",\n );\n\n return;\n }\n\n span.setAttributes(createSpanAttributes(attributes));\n}\n\n/**\n * Updates the currently active generation with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with generation-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Generation attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveGeneration } from '@langfuse/tracing';\n *\n * // Inside an active generation context\n * updateActiveGeneration({\n * usageDetails: {\n * promptTokens: 50,\n * completionTokens: 100,\n * totalTokens: 150\n * },\n * costDetails: { totalCost: 0.003 }\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveGeneration(\n attributes: LangfuseGenerationAttributes,\n) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping generation update.\",\n );\n\n return;\n }\n\n span.setAttributes(createGenerationAttributes(attributes));\n}\n\n/**\n * Options for the observe decorator function.\n *\n * @public\n */\nexport interface ObserveOptions {\n /** Name for the observation (defaults to function name) */\n name?: string;\n /** Type of observation to create */\n asType?: \"span\" | \"generation\";\n /** Whether to capture function input as observation input */\n captureInput?: boolean;\n /** Whether to capture function output as observation output */\n captureOutput?: boolean;\n}\n\n/**\n * Decorator function that automatically wraps a function with Langfuse tracing.\n *\n * This function creates a wrapper around the provided function that automatically:\n * - Creates a span or generation when the function is called\n * - Captures input arguments (if enabled)\n * - Captures return value/output (if enabled)\n * - Handles errors and sets appropriate status\n * - Ends the observation when the function completes\n *\n * @param fn - The function to wrap with tracing\n * @param options - Configuration options for the observation\n * @returns A wrapped version of the function that includes tracing\n *\n * @example\n * ```typescript\n * import { observe } from '@langfuse/tracing';\n *\n * // Wrap a regular function\n * const processData = observe(\n * async (userId: string, data: any) => {\n * // Function implementation\n * return await processUserData(userId, data);\n * },\n * {\n * name: 'process-user-data',\n * asType: 'span',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Wrap an LLM call\n * const generateText = observe(\n * async (prompt: string) => {\n * return await openai.chat.completions.create({\n * model: 'gpt-4',\n * messages: [{ role: 'user', content: prompt }]\n * });\n * },\n * {\n * name: 'openai-generation',\n * asType: 'generation',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Usage\n * const result = await processData('123', { key: 'value' });\n * const text = await generateText('Hello, world!');\n * ```\n *\n * @public\n */\nexport function observe<T extends (...args: unknown[]) => unknown>(\n fn: T,\n options: ObserveOptions = {},\n): T {\n const {\n name = fn.name || \"anonymous-function\",\n asType = \"span\",\n captureInput = true,\n captureOutput = true,\n } = options;\n\n const wrappedFunction = (...args: Parameters<T>): ReturnType<T> => {\n // Prepare input data\n const inputData = captureInput ? _captureArguments(args) : undefined;\n\n // Create the appropriate observation type\n const observation =\n asType === \"generation\"\n ? startGeneration(name, inputData ? { input: inputData } : {})\n : startSpan(name, inputData ? { input: inputData } : {});\n\n // Set the observation span as active in the context\n const activeContext = trace.setSpan(context.active(), observation.otelSpan);\n\n try {\n const result = context.with(activeContext, () => fn(...args));\n\n // Handle async functions - check if result is a Promise\n // TODO: handle returned generators for streamed responses\n if (result instanceof Promise) {\n return result.then(\n (value) => {\n if (captureOutput) {\n observation.update({ output: _captureOutput(value) });\n }\n observation.end();\n\n return value;\n },\n (error: unknown) => {\n observation\n .update({\n level: \"ERROR\",\n statusMessage:\n (error instanceof Error ? error.message : String(error)) ||\n \"Function threw an error\",\n output: captureOutput ? { error: String(error) } : undefined,\n })\n .end();\n\n throw error;\n },\n ) as ReturnType<T>;\n } else {\n // Handle sync functions\n if (captureOutput) {\n observation.update({ output: _captureOutput(result) });\n }\n observation.end();\n\n return result as ReturnType<T>;\n }\n } catch (error: unknown) {\n observation\n .update({\n level: \"ERROR\",\n statusMessage:\n (error instanceof Error ? error.message : String(error)) ||\n \"Function threw an error\",\n output: captureOutput ? { error: String(error) } : undefined,\n })\n .end();\n\n throw error;\n }\n };\n\n return wrappedFunction as T;\n}\n\n/**\n * Helper function to safely capture function arguments.\n *\n * @param args - Function arguments array\n * @returns Captured arguments or error message\n * @internal\n */\nfunction _captureArguments(args: unknown[]): unknown {\n try {\n if (args.length === 0) return undefined;\n if (args.length === 1) return args[0];\n return args;\n } catch {\n return \"<failed to capture arguments>\";\n }\n}\n\n/**\n * Helper function to safely capture function output.\n *\n * @param value - Function return value\n * @returns Captured output or error message\n * @internal\n */\nfunction _captureOutput(value: unknown): unknown {\n try {\n // Handle undefined/null\n if (value === undefined || value === null) return value;\n\n // For primitive types, return as-is\n if (typeof value !== \"object\") return value;\n\n // For objects, return them directly (serialization happens in span processor)\n return value;\n } catch {\n return \"<failed to capture output>\";\n }\n}\n\n/**\n * Creates a trace ID for OpenTelemetry spans.\n *\n * @param seed - A seed string for deterministic trace ID generation.\n * If provided (non-empty), the same seed will always generate the same trace ID.\n * If empty or falsy, generates a random trace ID.\n *\n * Using a seed is especially useful when trying to correlate external,\n * non-W3C compliant IDs with Langfuse trace IDs. This allows you to later\n * have a method available for scoring the Langfuse trace given only the\n * external ID by regenerating the same trace ID from the external ID.\n *\n * @returns A Promise that resolves to a 32-character lowercase hexadecimal string suitable for use as an OpenTelemetry trace ID.\n *\n * @example\n * ```typescript\n * // Deterministic trace ID from seed\n * const traceId1 = await createTraceId(\"my-session-123\");\n * const traceId2 = await createTraceId(\"my-session-123\");\n * console.log(traceId1 === traceId2); // true\n *\n * // Random trace ID\n * const randomId1 = await createTraceId(\"\");\n * const randomId2 = await createTraceId(\"\");\n * console.log(randomId1 === randomId2); // false\n *\n * // Use with spans\n * const span = startSpan(\"my-span\", {}, {\n * parentSpanContext: {\n * traceId: await createTraceId(\"session-456\"),\n * spanId: \"0123456789abcdef\",\n * traceFlags: 1\n * }\n * });\n *\n * // Correlating external IDs with Langfuse traces\n * const externalId = \"ext-12345-67890\";\n * const traceId = await createTraceId(externalId);\n *\n * // Later, when you need to score this trace, regenerate the same ID\n * const scoringTraceId = await createTraceId(externalId);\n * console.log(traceId === scoringTraceId); // true - can now find and score the trace\n * ```\n *\n * @public\n */\nexport async function createTraceId(seed?: string): Promise<string> {\n if (seed) {\n const data = new TextEncoder().encode(seed);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n\n const hashArray = new Uint8Array(hashBuffer);\n\n return uint8ArrayToHex(hashArray).slice(0, 32);\n }\n\n const randomValues = crypto.getRandomValues(new Uint8Array(16));\n\n return uint8ArrayToHex(randomValues);\n}\n\n/**\n * Converts a Uint8Array to a hexadecimal string.\n *\n * @param array - The byte array to convert\n * @returns Hexadecimal string representation\n * @internal\n */\nfunction uint8ArrayToHex(array: Uint8Array): string {\n return Array.from(array)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n","import { LangfuseOtelSpanAttributes } from \"@langfuse/core\";\nimport { type Attributes } from \"@opentelemetry/api\";\n\nimport {\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\n/**\n * Creates OpenTelemetry attributes from Langfuse trace attributes.\n *\n * Converts user-friendly trace attributes into the internal OpenTelemetry\n * attribute format required by the span processor.\n *\n * @param attributes - Langfuse trace attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createTraceAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createTraceAttributes({\n * name: 'user-checkout-flow',\n * userId: 'user-123',\n * sessionId: 'session-456',\n * tags: ['checkout', 'payment'],\n * metadata: { version: '2.1.0' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createTraceAttributes({\n name,\n userId,\n sessionId,\n version,\n release,\n input,\n output,\n metadata,\n tags,\n environment,\n public: isPublic,\n}: LangfuseTraceAttributes = {}): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.TRACE_NAME]: name,\n [LangfuseOtelSpanAttributes.TRACE_USER_ID]: userId,\n [LangfuseOtelSpanAttributes.TRACE_SESSION_ID]: sessionId,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.RELEASE]: release,\n [LangfuseOtelSpanAttributes.TRACE_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.TRACE_OUTPUT]: _serialize(output),\n [LangfuseOtelSpanAttributes.TRACE_TAGS]: tags,\n [LangfuseOtelSpanAttributes.ENVIRONMENT]: environment,\n [LangfuseOtelSpanAttributes.TRACE_PUBLIC]: isPublic,\n ..._flattenAndSerializeMetadata(metadata, \"trace\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse span attributes.\n *\n * Converts user-friendly span attributes into the internal OpenTelemetry\n * attribute format required by the span processor.\n *\n * @param attributes - Langfuse span attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createSpanAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createSpanAttributes({\n * input: { query: 'SELECT * FROM users' },\n * output: { rowCount: 42 },\n * level: 'DEFAULT',\n * metadata: { database: 'prod' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createSpanAttributes({\n metadata,\n input,\n output,\n level,\n statusMessage,\n version,\n}: LangfuseSpanAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"span\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse generation attributes.\n *\n * Converts user-friendly generation attributes into the internal OpenTelemetry\n * attribute format required by the span processor. Includes special handling\n * for LLM-specific fields like model parameters, usage, and costs.\n *\n * @param attributes - Langfuse generation attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createGenerationAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createGenerationAttributes({\n * input: [{ role: 'user', content: 'Hello!' }],\n * output: { role: 'assistant', content: 'Hi there!' },\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 },\n * usageDetails: {\n * promptTokens: 10,\n * completionTokens: 15,\n * totalTokens: 25\n * },\n * costDetails: { totalCost: 0.001 }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createGenerationAttributes({\n completionStartTime,\n metadata,\n level,\n statusMessage,\n version,\n model,\n modelParameters,\n input,\n output,\n usageDetails,\n costDetails,\n prompt,\n}: LangfuseGenerationAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"generation\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n [LangfuseOtelSpanAttributes.OBSERVATION_MODEL]: model,\n [LangfuseOtelSpanAttributes.OBSERVATION_USAGE_DETAILS]:\n _serialize(usageDetails),\n [LangfuseOtelSpanAttributes.OBSERVATION_COST_DETAILS]:\n _serialize(costDetails),\n [LangfuseOtelSpanAttributes.OBSERVATION_COMPLETION_START_TIME]:\n _serialize(completionStartTime),\n [LangfuseOtelSpanAttributes.OBSERVATION_MODEL_PARAMETERS]:\n _serialize(modelParameters),\n ...(prompt && !prompt.isFallback\n ? {\n [LangfuseOtelSpanAttributes.OBSERVATION_PROMPT_NAME]: prompt.name,\n [LangfuseOtelSpanAttributes.OBSERVATION_PROMPT_VERSION]:\n prompt.version,\n }\n : {}),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n ) as Attributes;\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse event attributes.\n *\n * Converts user-friendly event attributes into the internal OpenTelemetry\n * attribute format required by the span processor. Events are point-in-time\n * observations that are automatically ended when created.\n *\n * @param attributes - Langfuse event attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createEventAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createEventAttributes({\n * input: { action: 'button_click', elementId: 'submit' },\n * level: 'DEFAULT',\n * metadata: { page: '/checkout', userId: '123' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createEventAttributes({\n metadata,\n input,\n output,\n level,\n statusMessage,\n version,\n}: LangfuseSpanAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"event\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Safely serializes an object to JSON string.\n *\n * @param obj - Object to serialize\n * @returns JSON string or undefined if null/undefined, error message if serialization fails\n * @internal\n */\nfunction _serialize(obj: unknown): string | undefined {\n try {\n return obj != null ? JSON.stringify(obj) : undefined;\n } catch {\n return \"<failed to serialize>\";\n }\n}\n\n/**\n * Flattens and serializes metadata into OpenTelemetry attribute format.\n *\n * Converts nested metadata objects into dot-notation attribute keys.\n * For example, `{ database: { host: 'localhost' } }` becomes\n * `{ 'langfuse.metadata.database.host': 'localhost' }`.\n *\n * @param metadata - Metadata object to flatten\n * @param type - Whether this is for observation or trace metadata\n * @returns Flattened metadata attributes\n * @internal\n */\nfunction _flattenAndSerializeMetadata(\n metadata: unknown,\n type: \"observation\" | \"trace\",\n): Record<string, string> {\n const prefix =\n type === \"observation\"\n ? LangfuseOtelSpanAttributes.OBSERVATION_METADATA\n : LangfuseOtelSpanAttributes.TRACE_METADATA;\n\n const metadataAttributes: Record<string, string> = {};\n\n if (metadata === undefined || metadata === null) {\n return metadataAttributes;\n }\n\n if (typeof metadata !== \"object\" || Array.isArray(metadata)) {\n const serialized = _serialize(metadata);\n if (serialized) {\n metadataAttributes[prefix] = serialized;\n }\n } else {\n for (const [key, value] of Object.entries(metadata)) {\n const serialized = typeof value === \"string\" ? value : _serialize(value);\n if (serialized) {\n metadataAttributes[`${prefix}.${key}`] = serialized;\n }\n }\n }\n\n return metadataAttributes;\n}\n","import { LANGFUSE_SDK_VERSION, LANGFUSE_TRACER_NAME } from \"@langfuse/core\";\nimport { trace } from \"@opentelemetry/api\";\n\n/**\n * Gets the OpenTelemetry tracer instance for Langfuse.\n *\n * This function returns a tracer specifically configured for Langfuse\n * with the correct tracer name and version. Used internally by all\n * Langfuse tracing functions to ensure consistent trace creation.\n *\n * @returns The Langfuse OpenTelemetry tracer instance\n *\n * @example\n * ```typescript\n * import { getLangfuseTracer } from '@langfuse/tracing';\n *\n * const tracer = getLangfuseTracer();\n * const span = tracer.startSpan('my-operation');\n * ```\n *\n * @public\n */\nexport function getLangfuseTracer() {\n return trace.getTracer(LANGFUSE_TRACER_NAME, LANGFUSE_SDK_VERSION);\n}\n","import { Span, TimeInput } from \"@opentelemetry/api\";\n\nimport {\n createEventAttributes,\n createGenerationAttributes,\n createSpanAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport {\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\nimport { getLangfuseTracer } from \"./utils.js\";\n\nimport { createEvent, startGeneration, startSpan } from \"./index.js\";\n\n/**\n * Union type representing any Langfuse observation wrapper.\n *\n * Used when you need to accept any type of Langfuse observation\n * (span, generation, or event).\n *\n * @public\n */\nexport type LangfuseObservation =\n | LangfuseSpan\n | LangfuseGeneration\n | LangfuseEvent;\n\n/**\n * Parameters for creating a Langfuse span wrapper.\n *\n * @internal\n */\ntype LangfuseSpanWrapperParams = {\n otelSpan: Span;\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes;\n};\n\n/**\n * Base class for all Langfuse observation wrappers.\n *\n * Provides common functionality for spans, generations, and events including\n * access to the underlying OpenTelemetry span, span ID, trace ID, and basic\n * operations like ending the observation and updating trace attributes.\n *\n * @internal\n */\nabstract class LangfuseSpanWrapper {\n /** The underlying OpenTelemetry span */\n public readonly otelSpan: Span;\n /** The span ID from the OpenTelemetry span context */\n public id: string;\n /** The trace ID from the OpenTelemetry span context */\n public traceId: string;\n\n constructor(params: LangfuseSpanWrapperParams) {\n this.otelSpan = params.otelSpan;\n this.id = params.otelSpan.spanContext().spanId;\n this.traceId = params.otelSpan.spanContext().traceId;\n }\n\n /** Gets the Langfuse OpenTelemetry tracer instance */\n protected get tracer() {\n return getLangfuseTracer();\n }\n\n /**\n * Ends the observation, marking it as complete.\n *\n * @param endTime - Optional end time, defaults to current time\n */\n public end(endTime?: TimeInput) {\n this.otelSpan.end(endTime);\n }\n\n /**\n * Updates the parent trace with new attributes.\n *\n * This sets trace-level attributes that apply to the entire trace,\n * not just this specific observation.\n *\n * @param attributes - Trace attributes to set\n * @returns This observation for method chaining\n */\n public updateTrace(attributes: LangfuseTraceAttributes) {\n this.otelSpan.setAttributes(createTraceAttributes(attributes));\n\n return this;\n }\n}\n\n/**\n * Parameters for creating a Langfuse span.\n *\n * @internal\n */\ntype LangfuseSpanParams = {\n otelSpan: Span;\n attributes?: LangfuseSpanAttributes;\n};\n\n/**\n * Langfuse span wrapper for general-purpose tracing.\n *\n * Spans are used to track operations, functions, or logical units of work.\n * They can contain other spans, generations, or events as children and have\n * a duration from start to end.\n *\n * @public\n */\nexport class LangfuseSpan extends LangfuseSpanWrapper {\n constructor(params: LangfuseSpanParams) {\n super(params);\n if (params.attributes) {\n this.otelSpan.setAttributes(createSpanAttributes(params.attributes));\n }\n }\n\n /**\n * Updates this span with new attributes.\n *\n * @param attributes - Span attributes to set\n * @returns This span for method chaining\n *\n * @example\n * ```typescript\n * span.update({\n * output: { result: 'success' },\n * level: 'DEFAULT',\n * metadata: { duration: 150 }\n * });\n * ```\n */\n public update(attributes: LangfuseSpanAttributes): LangfuseSpan {\n this.otelSpan.setAttributes(createSpanAttributes(attributes));\n\n return this;\n }\n\n /**\n * Starts a new child span within this span.\n *\n * @param name - Name of the child span\n * @param attributes - Optional attributes for the child span\n * @returns The new child span\n *\n * @example\n * ```typescript\n * const childSpan = parentSpan.startSpan('database-query', {\n * input: { query: 'SELECT * FROM users' },\n * metadata: { database: 'primary' }\n * });\n * ```\n */\n public startSpan(\n name: string,\n attributes?: LangfuseSpanAttributes,\n ): LangfuseSpan {\n return startSpan(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n\n /**\n * Starts a new child generation within this span.\n *\n * @param name - Name of the generation (typically the model name)\n * @param attributes - Optional generation-specific attributes\n * @returns The new child generation\n *\n * @example\n * ```typescript\n * const generation = parentSpan.startGeneration('gpt-4', {\n * input: [{ role: 'user', content: 'Hello!' }],\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 }\n * });\n * ```\n */\n public startGeneration(\n name: string,\n attributes?: LangfuseGenerationAttributes,\n ): LangfuseGeneration {\n return startGeneration(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n\n /**\n * Creates a new event within this span.\n *\n * Events are point-in-time occurrences and are automatically ended.\n *\n * @param name - Name of the event\n * @param attributes - Optional event attributes\n * @returns The created event (already ended)\n *\n * @example\n * ```typescript\n * parentSpan.createEvent('user-action', {\n * input: { action: 'click', button: 'submit' },\n * metadata: { userId: '123' }\n * });\n * ```\n */\n public createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n ): LangfuseEvent {\n return createEvent(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n}\n\n/**\n * Parameters for creating a Langfuse generation.\n *\n * @internal\n */\ntype LangfuseGenerationParams = {\n otelSpan: Span;\n attributes?: LangfuseGenerationAttributes;\n};\n\n/**\n * Langfuse generation wrapper for tracking LLM interactions.\n *\n * Generations are specialized observations for tracking language model\n * calls, including model parameters, usage metrics, costs, and prompts.\n *\n * @public\n */\nexport class LangfuseGeneration extends LangfuseSpanWrapper {\n constructor(params: LangfuseGenerationParams) {\n super(params);\n if (params.attributes) {\n this.otelSpan.setAttributes(\n createGenerationAttributes(params.attributes),\n );\n }\n }\n\n /**\n * Updates this generation with new attributes.\n *\n * @param attributes - Generation attributes to set\n * @returns This generation for method chaining\n *\n * @example\n * ```typescript\n * generation.update({\n * output: { role: 'assistant', content: 'Hello there!' },\n * usageDetails: {\n * promptTokens: 10,\n * completionTokens: 15,\n * totalTokens: 25\n * },\n * costDetails: { totalCost: 0.001 }\n * });\n * ```\n */\n update(attributes: LangfuseGenerationAttributes): LangfuseGeneration {\n this.otelSpan.setAttributes(createGenerationAttributes(attributes));\n\n return this;\n }\n\n /**\n * Creates a new event within this generation.\n *\n * Events are point-in-time occurrences and are automatically ended.\n *\n * @param name - Name of the event\n * @param attributes - Optional event attributes\n * @returns The created event (already ended)\n *\n * @example\n * ```typescript\n * generation.createEvent('token-limit-reached', {\n * level: 'WARNING',\n * metadata: { requestedTokens: 2000, maxTokens: 1500 }\n * });\n * ```\n */\n createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n ): LangfuseEvent {\n return createEvent(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n}\n\n/**\n * Parameters for creating a Langfuse event.\n *\n * @internal\n */\ntype LangfuseEventParams = {\n otelSpan: Span;\n attributes?: LangfuseEventAttributes;\n timestamp: TimeInput;\n};\n\n/**\n * Langfuse event wrapper for point-in-time observations.\n *\n * Events represent instantaneous occurrences or log entries within a trace.\n * Unlike spans and generations, they don't have duration and are automatically\n * ended when created.\n *\n * @public\n */\nexport class LangfuseEvent extends LangfuseSpanWrapper {\n constructor(params: LangfuseEventParams) {\n super(params);\n\n if (params.attributes) {\n this.otelSpan.setAttributes(createEventAttributes(params.attributes));\n }\n\n // Events are automatically ended at their timestamp\n this.otelSpan.end(params.timestamp);\n }\n}\n"],"mappings":"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","names":["import_core","import_api","import_core","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/attributes.ts","../src/tracerProvider.ts","../src/spanWrapper.ts"],"sourcesContent":["import { getGlobalLogger } from \"@langfuse/core\";\nimport {\n trace,\n context,\n TimeInput,\n SpanStatusCode,\n Span,\n Context,\n SpanContext,\n} from \"@opentelemetry/api\";\n\nimport {\n createGenerationAttributes,\n createSpanAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport {\n LangfuseEvent,\n LangfuseGeneration,\n LangfuseSpan,\n} from \"./spanWrapper.js\";\nimport { getLangfuseTracer } from \"./tracerProvider.js\";\nimport {\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\nexport type {\n LangfuseObservationType,\n ObservationLevel,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\nexport * from \"./spanWrapper.js\";\nexport {\n createTraceAttributes,\n createSpanAttributes,\n createGenerationAttributes,\n} from \"./attributes.js\";\nexport {\n setLangfuseTracerProvider,\n getLangfuseTracerProvider,\n getLangfuseTracer,\n} from \"./tracerProvider.js\";\n\nexport { LangfuseOtelSpanAttributes } from \"@langfuse/core\";\n\n/**\n * Options for starting observations (spans, generations, events).\n *\n * @public\n */\nexport type StartObservationOptions = {\n /** Custom start time for the observation */\n startTime?: Date;\n /** Parent span context to attach this observation to */\n parentSpanContext?: SpanContext;\n};\n\n/**\n * Creates an OpenTelemetry span with the Langfuse tracer.\n *\n * @param params - Parameters for span creation\n * @returns The created OpenTelemetry span\n * @internal\n */\nfunction createOtelSpan(params: {\n name: string;\n startTime?: TimeInput;\n parentSpanContext?: SpanContext;\n}): Span {\n return getLangfuseTracer().startSpan(\n params.name,\n { startTime: params.startTime },\n createParentContext(params.parentSpanContext),\n );\n}\n\n/**\n * Creates a parent context from a span context.\n *\n * @param parentSpanContext - The span context to use as parent\n * @returns The created context or undefined if no parent provided\n * @internal\n */\nfunction createParentContext(\n parentSpanContext?: SpanContext,\n): Context | undefined {\n if (!parentSpanContext) return;\n\n return trace.setSpanContext(context.active(), parentSpanContext);\n}\n\n/**\n * Wraps a promise to automatically end the span when the promise resolves or rejects.\n *\n * @param promise - The promise to wrap\n * @param span - The span to end when promise completes\n * @returns The wrapped promise\n * @internal\n */\nfunction wrapPromise<T>(promise: Promise<T>, span: Span): Promise<T> {\n return promise.then(\n (value) => {\n span.end(); // End span AFTER Promise resolves\n\n return value;\n },\n (err: unknown) => {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end(); // End span AFTER Promise rejects\n\n throw err;\n },\n );\n}\n\n/**\n * Creates and starts a new Langfuse span for general-purpose tracing.\n *\n * Spans are used to track operations, functions, or logical units of work.\n * They can contain other spans or generations as children.\n *\n * @param name - Name of the span\n * @param attributes - Optional attributes to set on the span\n * @param options - Optional configuration for the span\n * @returns A LangfuseSpan instance\n *\n * @example\n * ```typescript\n * import { startSpan } from '@langfuse/tracing';\n *\n * const span = startSpan('data-processing', {\n * input: { userId: '123', data: {...} },\n * metadata: { version: '1.0' },\n * level: 'DEFAULT'\n * });\n *\n * try {\n * // Do some work\n * const result = await processData();\n *\n * span.update({ output: result });\n * } catch (error) {\n * span.update({\n * level: 'ERROR',\n * statusMessage: error.message\n * });\n * } finally {\n * span.end();\n * }\n * ```\n *\n * @public\n */\nexport function startSpan(\n name: string,\n attributes?: LangfuseSpanAttributes,\n options?: {\n startTime?: TimeInput;\n parentSpanContext?: SpanContext;\n },\n): LangfuseSpan {\n const otelSpan = createOtelSpan({\n name,\n ...options,\n });\n\n return new LangfuseSpan({ otelSpan, attributes });\n}\n\n/**\n * Creates and starts a new Langfuse generation for tracking LLM calls.\n *\n * Generations are specialized observations for tracking language model\n * interactions, including model parameters, usage metrics, and costs.\n *\n * @param name - Name of the generation (typically the model or operation)\n * @param attributes - Optional generation-specific attributes\n * @param options - Optional configuration for the generation\n * @returns A LangfuseGeneration instance\n *\n * @example\n * ```typescript\n * import { startGeneration } from '@langfuse/tracing';\n *\n * const generation = startGeneration('openai-gpt-4', {\n * input: [{ role: 'user', content: 'Hello, world!' }],\n * model: 'gpt-4',\n * modelParameters: {\n * temperature: 0.7,\n * max_tokens: 150\n * },\n * metadata: { feature: 'chat' }\n * });\n *\n * try {\n * const response = await callOpenAI(messages);\n *\n * generation.update({\n * output: response.choices[0].message,\n * usageDetails: {\n * promptTokens: response.usage.prompt_tokens,\n * completionTokens: response.usage.completion_tokens,\n * totalTokens: response.usage.total_tokens\n * }\n * });\n * } finally {\n * generation.end();\n * }\n * ```\n *\n * @public\n */\nexport function startGeneration(\n name: string,\n attributes?: LangfuseGenerationAttributes,\n options?: StartObservationOptions,\n): LangfuseGeneration {\n const otelSpan = createOtelSpan({\n name,\n ...options,\n });\n\n return new LangfuseGeneration({ otelSpan, attributes });\n}\n\n/**\n * Creates a Langfuse event for point-in-time occurrences.\n *\n * Events are used to capture instantaneous occurrences or log entries\n * within a trace. Unlike spans, they represent a single point in time.\n *\n * @param name - Name of the event\n * @param attributes - Optional attributes for the event\n * @param options - Optional configuration for the event\n * @returns A LangfuseEvent instance (automatically ended)\n *\n * @example\n * ```typescript\n * import { createEvent } from '@langfuse/tracing';\n *\n * // Log a user action\n * createEvent('user-click', {\n * input: { buttonId: 'submit', userId: '123' },\n * metadata: { page: '/checkout' },\n * level: 'DEFAULT'\n * });\n *\n * // Log an error\n * createEvent('api-error', {\n * level: 'ERROR',\n * statusMessage: 'Failed to fetch user data',\n * metadata: { endpoint: '/api/users/123', statusCode: 500 }\n * });\n * ```\n *\n * @public\n */\nexport function createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n options?: StartObservationOptions,\n) {\n const timestamp = options?.startTime ?? new Date();\n\n const otelSpan = createOtelSpan({\n name,\n ...options,\n startTime: timestamp,\n });\n\n return new LangfuseEvent({ otelSpan, attributes, timestamp });\n}\n\n/**\n * Starts an active span and executes a function within its context.\n *\n * This function creates a span, sets it as the active span in the OpenTelemetry\n * context, executes the provided function, and automatically ends the span.\n * Perfect for wrapping operations where you want child spans to be automatically\n * linked.\n *\n * @param name - Name of the span\n * @param fn - Function to execute within the span context\n * @param options - Optional configuration for the span\n * @returns The return value of the executed function\n *\n * @example\n * ```typescript\n * import { startActiveSpan } from '@langfuse/tracing';\n *\n * // Synchronous function\n * const result = startActiveSpan('calculate-metrics', (span) => {\n * span.update({ input: { data: rawData } });\n *\n * const metrics = calculateMetrics(rawData);\n * span.update({ output: metrics });\n *\n * return metrics;\n * });\n *\n * // Asynchronous function\n * const data = await startActiveSpan('fetch-user-data', async (span) => {\n * span.update({ input: { userId: '123' } });\n *\n * const userData = await api.getUser('123');\n * span.update({ output: userData });\n *\n * return userData;\n * });\n * ```\n *\n * @public\n */\nexport function startActiveSpan<F extends (span: LangfuseSpan) => unknown>(\n name: string,\n fn: F,\n options?: StartObservationOptions,\n): ReturnType<F> {\n return getLangfuseTracer().startActiveSpan(\n name,\n { startTime: options?.startTime },\n createParentContext(options?.parentSpanContext) ?? context.active(),\n (span) => {\n try {\n const result = fn(new LangfuseSpan({ otelSpan: span }));\n\n if (result instanceof Promise) {\n return wrapPromise(result, span) as ReturnType<F>;\n } else {\n span.end();\n\n return result as ReturnType<F>;\n }\n } catch (err) {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end();\n\n throw err;\n }\n },\n );\n}\n\n/**\n * Starts an active generation and executes a function within its context.\n *\n * Similar to startActiveSpan but creates a generation for tracking LLM calls.\n * The generation is automatically ended when the function completes.\n *\n * @param name - Name of the generation\n * @param fn - Function to execute within the generation context\n * @param options - Optional configuration for the generation\n * @returns The return value of the executed function\n *\n * @example\n * ```typescript\n * import { startActiveGeneration } from '@langfuse/tracing';\n *\n * const response = await startActiveGeneration('openai-completion', async (generation) => {\n * generation.update({\n * input: { messages: [...] },\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 }\n * });\n *\n * const result = await openai.chat.completions.create({...});\n *\n * generation.update({\n * output: result.choices[0].message,\n * usageDetails: result.usage\n * });\n *\n * return result;\n * });\n * ```\n *\n * @public\n */\nexport function startActiveGeneration<\n F extends (span: LangfuseGeneration) => unknown,\n>(name: string, fn: F, options?: StartObservationOptions): ReturnType<F> {\n return getLangfuseTracer().startActiveSpan(\n name,\n { startTime: options?.startTime },\n createParentContext(options?.parentSpanContext) ?? context.active(),\n (span) => {\n try {\n const result = fn(new LangfuseGeneration({ otelSpan: span }));\n\n if (result instanceof Promise) {\n return wrapPromise(result, span) as ReturnType<F>;\n } else {\n span.end();\n\n return result as ReturnType<F>;\n }\n } catch (err) {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end();\n\n throw err;\n }\n },\n );\n}\n\n/**\n * Updates the currently active trace with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with trace-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Trace attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveTrace } from '@langfuse/tracing';\n *\n * // Inside an active span context\n * updateActiveTrace({\n * name: 'user-workflow',\n * userId: '123',\n * sessionId: 'session-456',\n * tags: ['production', 'critical'],\n * public: true\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveTrace(attributes: LangfuseTraceAttributes) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping trace update.\",\n );\n\n return;\n }\n\n span.setAttributes(createTraceAttributes(attributes));\n}\n\n/**\n * Updates the currently active span with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with span-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Span attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveSpan } from '@langfuse/tracing';\n *\n * // Inside an active span context\n * updateActiveSpan({\n * level: 'WARNING',\n * statusMessage: 'Operation completed with warnings',\n * metadata: { warningCount: 3 }\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveSpan(attributes: LangfuseSpanAttributes) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping span update.\",\n );\n\n return;\n }\n\n span.setAttributes(createSpanAttributes(attributes));\n}\n\n/**\n * Updates the currently active generation with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with generation-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Generation attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveGeneration } from '@langfuse/tracing';\n *\n * // Inside an active generation context\n * updateActiveGeneration({\n * usageDetails: {\n * promptTokens: 50,\n * completionTokens: 100,\n * totalTokens: 150\n * },\n * costDetails: { totalCost: 0.003 }\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveGeneration(\n attributes: LangfuseGenerationAttributes,\n) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping generation update.\",\n );\n\n return;\n }\n\n span.setAttributes(createGenerationAttributes(attributes));\n}\n\n/**\n * Options for the observe decorator function.\n *\n * @public\n */\nexport interface ObserveOptions {\n /** Name for the observation (defaults to function name) */\n name?: string;\n /** Type of observation to create */\n asType?: \"span\" | \"generation\";\n /** Whether to capture function input as observation input */\n captureInput?: boolean;\n /** Whether to capture function output as observation output */\n captureOutput?: boolean;\n /** Parent span context to attach this observation to */\n parentSpanContext?: SpanContext;\n}\n\n/**\n * Decorator function that automatically wraps a function with Langfuse tracing.\n *\n * This function creates a wrapper around the provided function that automatically:\n * - Creates a span or generation when the function is called\n * - Captures input arguments (if enabled)\n * - Captures return value/output (if enabled)\n * - Handles errors and sets appropriate status\n * - Ends the observation when the function completes\n *\n * @param fn - The function to wrap with tracing\n * @param options - Configuration options for the observation\n * @returns A wrapped version of the function that includes tracing\n *\n * @example\n * ```typescript\n * import { observe } from '@langfuse/tracing';\n *\n * // Wrap a regular function\n * const processData = observe(\n * async (userId: string, data: any) => {\n * // Function implementation\n * return await processUserData(userId, data);\n * },\n * {\n * name: 'process-user-data',\n * asType: 'span',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Wrap an LLM call\n * const generateText = observe(\n * async (prompt: string) => {\n * return await openai.chat.completions.create({\n * model: 'gpt-4',\n * messages: [{ role: 'user', content: prompt }]\n * });\n * },\n * {\n * name: 'openai-generation',\n * asType: 'generation',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Usage\n * const result = await processData('123', { key: 'value' });\n * const text = await generateText('Hello, world!');\n * ```\n *\n * @public\n */\nexport function observe<T extends (...args: unknown[]) => unknown>(\n fn: T,\n options: ObserveOptions = {},\n): T {\n const {\n name = fn.name || \"anonymous-function\",\n asType = \"span\",\n captureInput = true,\n captureOutput = true,\n parentSpanContext = undefined,\n } = options;\n\n const wrappedFunction = function (\n this: any,\n ...args: Parameters<T>\n ): ReturnType<T> {\n // Prepare input data\n const inputData = captureInput ? _captureArguments(args) : undefined;\n\n // Create the appropriate observation type\n const observation =\n asType === \"generation\"\n ? startGeneration(name, inputData ? { input: inputData } : {}, {\n parentSpanContext,\n })\n : startSpan(name, inputData ? { input: inputData } : {}, {\n parentSpanContext,\n });\n\n // Set the observation span as active in the context\n const activeContext = trace.setSpan(context.active(), observation.otelSpan);\n\n try {\n const result = context.with(activeContext, () => fn.apply(this, args));\n\n // Handle async functions - check if result is a Promise\n // TODO: handle returned generators for streamed responses\n if (result instanceof Promise) {\n return result.then(\n (value) => {\n if (captureOutput) {\n observation.update({ output: _captureOutput(value) });\n }\n observation.end();\n\n return value;\n },\n (error: unknown) => {\n observation\n .update({\n level: \"ERROR\",\n statusMessage:\n (error instanceof Error ? error.message : String(error)) ||\n \"Function threw an error\",\n output: captureOutput ? { error: String(error) } : undefined,\n })\n .end();\n\n throw error;\n },\n ) as ReturnType<T>;\n } else {\n // Handle sync functions\n if (captureOutput) {\n observation.update({ output: _captureOutput(result) });\n }\n observation.end();\n\n return result as ReturnType<T>;\n }\n } catch (error: unknown) {\n observation\n .update({\n level: \"ERROR\",\n statusMessage:\n (error instanceof Error ? error.message : String(error)) ||\n \"Function threw an error\",\n output: captureOutput ? { error: String(error) } : undefined,\n })\n .end();\n\n throw error;\n }\n };\n\n return wrappedFunction as T;\n}\n\n/**\n * Helper function to safely capture function arguments.\n *\n * @param args - Function arguments array\n * @returns Captured arguments or error message\n * @internal\n */\nfunction _captureArguments(args: unknown[]): unknown {\n try {\n if (args.length === 0) return undefined;\n if (args.length === 1) return args[0];\n return args;\n } catch {\n return \"<failed to capture arguments>\";\n }\n}\n\n/**\n * Helper function to safely capture function output.\n *\n * @param value - Function return value\n * @returns Captured output or error message\n * @internal\n */\nfunction _captureOutput(value: unknown): unknown {\n try {\n // Handle undefined/null\n if (value === undefined || value === null) return value;\n\n // For primitive types, return as-is\n if (typeof value !== \"object\") return value;\n\n // For objects, return them directly (serialization happens in span processor)\n return value;\n } catch {\n return \"<failed to capture output>\";\n }\n}\n\n/**\n * Creates a trace ID for OpenTelemetry spans.\n *\n * @param seed - A seed string for deterministic trace ID generation.\n * If provided (non-empty), the same seed will always generate the same trace ID.\n * If empty or falsy, generates a random trace ID.\n *\n * Using a seed is especially useful when trying to correlate external,\n * non-W3C compliant IDs with Langfuse trace IDs. This allows you to later\n * have a method available for scoring the Langfuse trace given only the\n * external ID by regenerating the same trace ID from the external ID.\n *\n * @returns A Promise that resolves to a 32-character lowercase hexadecimal string suitable for use as an OpenTelemetry trace ID.\n *\n * @example\n * ```typescript\n * // Deterministic trace ID from seed\n * const traceId1 = await createTraceId(\"my-session-123\");\n * const traceId2 = await createTraceId(\"my-session-123\");\n * console.log(traceId1 === traceId2); // true\n *\n * // Random trace ID\n * const randomId1 = await createTraceId(\"\");\n * const randomId2 = await createTraceId(\"\");\n * console.log(randomId1 === randomId2); // false\n *\n * // Use with spans\n * const span = startSpan(\"my-span\", {}, {\n * parentSpanContext: {\n * traceId: await createTraceId(\"session-456\"),\n * spanId: \"0123456789abcdef\",\n * traceFlags: 1\n * }\n * });\n *\n * // Correlating external IDs with Langfuse traces\n * const externalId = \"ext-12345-67890\";\n * const traceId = await createTraceId(externalId);\n *\n * // Later, when you need to score this trace, regenerate the same ID\n * const scoringTraceId = await createTraceId(externalId);\n * console.log(traceId === scoringTraceId); // true - can now find and score the trace\n * ```\n *\n * @public\n */\nexport async function createTraceId(seed?: string): Promise<string> {\n if (seed) {\n const data = new TextEncoder().encode(seed);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n\n const hashArray = new Uint8Array(hashBuffer);\n\n return uint8ArrayToHex(hashArray).slice(0, 32);\n }\n\n const randomValues = crypto.getRandomValues(new Uint8Array(16));\n\n return uint8ArrayToHex(randomValues);\n}\n\n/**\n * Converts a Uint8Array to a hexadecimal string.\n *\n * @param array - The byte array to convert\n * @returns Hexadecimal string representation\n * @internal\n */\nfunction uint8ArrayToHex(array: Uint8Array): string {\n return Array.from(array)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Gets the current active trace ID.\n *\n * If there is no span in the current context, returns undefined.\n *\n * @returns The trace ID of the currently active span, or undefined if no span is active\n *\n * @public\n */\nexport function getActiveTraceId(): string | undefined {\n return trace.getActiveSpan()?.spanContext().traceId;\n}\n\n/**\n * Gets the current active observation ID.\n *\n * If there is no OTEL span in the current context, returns undefined.\n *\n * @returns The ID of the currently active OTEL span, or undefined if no OTEL span is active\n *\n * @public\n */\nexport function getActiveSpanId(): string | undefined {\n return trace.getActiveSpan()?.spanContext().spanId;\n}\n","import { LangfuseOtelSpanAttributes } from \"@langfuse/core\";\nimport { type Attributes } from \"@opentelemetry/api\";\n\nimport {\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\n/**\n * Creates OpenTelemetry attributes from Langfuse trace attributes.\n *\n * Converts user-friendly trace attributes into the internal OpenTelemetry\n * attribute format required by the span processor.\n *\n * @param attributes - Langfuse trace attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createTraceAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createTraceAttributes({\n * name: 'user-checkout-flow',\n * userId: 'user-123',\n * sessionId: 'session-456',\n * tags: ['checkout', 'payment'],\n * metadata: { version: '2.1.0' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createTraceAttributes({\n name,\n userId,\n sessionId,\n version,\n release,\n input,\n output,\n metadata,\n tags,\n environment,\n public: isPublic,\n}: LangfuseTraceAttributes = {}): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.TRACE_NAME]: name,\n [LangfuseOtelSpanAttributes.TRACE_USER_ID]: userId,\n [LangfuseOtelSpanAttributes.TRACE_SESSION_ID]: sessionId,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.RELEASE]: release,\n [LangfuseOtelSpanAttributes.TRACE_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.TRACE_OUTPUT]: _serialize(output),\n [LangfuseOtelSpanAttributes.TRACE_TAGS]: tags,\n [LangfuseOtelSpanAttributes.ENVIRONMENT]: environment,\n [LangfuseOtelSpanAttributes.TRACE_PUBLIC]: isPublic,\n ..._flattenAndSerializeMetadata(metadata, \"trace\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse span attributes.\n *\n * Converts user-friendly span attributes into the internal OpenTelemetry\n * attribute format required by the span processor.\n *\n * @param attributes - Langfuse span attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createSpanAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createSpanAttributes({\n * input: { query: 'SELECT * FROM users' },\n * output: { rowCount: 42 },\n * level: 'DEFAULT',\n * metadata: { database: 'prod' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createSpanAttributes({\n metadata,\n input,\n output,\n level,\n statusMessage,\n version,\n}: LangfuseSpanAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"span\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse generation attributes.\n *\n * Converts user-friendly generation attributes into the internal OpenTelemetry\n * attribute format required by the span processor. Includes special handling\n * for LLM-specific fields like model parameters, usage, and costs.\n *\n * @param attributes - Langfuse generation attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createGenerationAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createGenerationAttributes({\n * input: [{ role: 'user', content: 'Hello!' }],\n * output: { role: 'assistant', content: 'Hi there!' },\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 },\n * usageDetails: {\n * promptTokens: 10,\n * completionTokens: 15,\n * totalTokens: 25\n * },\n * costDetails: { totalCost: 0.001 }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createGenerationAttributes({\n completionStartTime,\n metadata,\n level,\n statusMessage,\n version,\n model,\n modelParameters,\n input,\n output,\n usageDetails,\n costDetails,\n prompt,\n}: LangfuseGenerationAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"generation\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n [LangfuseOtelSpanAttributes.OBSERVATION_MODEL]: model,\n [LangfuseOtelSpanAttributes.OBSERVATION_USAGE_DETAILS]:\n _serialize(usageDetails),\n [LangfuseOtelSpanAttributes.OBSERVATION_COST_DETAILS]:\n _serialize(costDetails),\n [LangfuseOtelSpanAttributes.OBSERVATION_COMPLETION_START_TIME]:\n _serialize(completionStartTime),\n [LangfuseOtelSpanAttributes.OBSERVATION_MODEL_PARAMETERS]:\n _serialize(modelParameters),\n ...(prompt && !prompt.isFallback\n ? {\n [LangfuseOtelSpanAttributes.OBSERVATION_PROMPT_NAME]: prompt.name,\n [LangfuseOtelSpanAttributes.OBSERVATION_PROMPT_VERSION]:\n prompt.version,\n }\n : {}),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n ) as Attributes;\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse event attributes.\n *\n * Converts user-friendly event attributes into the internal OpenTelemetry\n * attribute format required by the span processor. Events are point-in-time\n * observations that are automatically ended when created.\n *\n * @param attributes - Langfuse event attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createEventAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createEventAttributes({\n * input: { action: 'button_click', elementId: 'submit' },\n * level: 'DEFAULT',\n * metadata: { page: '/checkout', userId: '123' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createEventAttributes({\n metadata,\n input,\n output,\n level,\n statusMessage,\n version,\n}: LangfuseSpanAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"event\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Safely serializes an object to JSON string.\n *\n * @param obj - Object to serialize\n * @returns JSON string or undefined if null/undefined, error message if serialization fails\n * @internal\n */\nfunction _serialize(obj: unknown): string | undefined {\n try {\n return obj != null ? JSON.stringify(obj) : undefined;\n } catch {\n return \"<failed to serialize>\";\n }\n}\n\n/**\n * Flattens and serializes metadata into OpenTelemetry attribute format.\n *\n * Converts nested metadata objects into dot-notation attribute keys.\n * For example, `{ database: { host: 'localhost' } }` becomes\n * `{ 'langfuse.metadata.database.host': 'localhost' }`.\n *\n * @param metadata - Metadata object to flatten\n * @param type - Whether this is for observation or trace metadata\n * @returns Flattened metadata attributes\n * @internal\n */\nfunction _flattenAndSerializeMetadata(\n metadata: unknown,\n type: \"observation\" | \"trace\",\n): Record<string, string> {\n const prefix =\n type === \"observation\"\n ? LangfuseOtelSpanAttributes.OBSERVATION_METADATA\n : LangfuseOtelSpanAttributes.TRACE_METADATA;\n\n const metadataAttributes: Record<string, string> = {};\n\n if (metadata === undefined || metadata === null) {\n return metadataAttributes;\n }\n\n if (typeof metadata !== \"object\" || Array.isArray(metadata)) {\n const serialized = _serialize(metadata);\n if (serialized) {\n metadataAttributes[prefix] = serialized;\n }\n } else {\n for (const [key, value] of Object.entries(metadata)) {\n const serialized = typeof value === \"string\" ? value : _serialize(value);\n if (serialized) {\n metadataAttributes[`${prefix}.${key}`] = serialized;\n }\n }\n }\n\n return metadataAttributes;\n}\n","import {\n getGlobalLogger,\n LANGFUSE_SDK_VERSION,\n LANGFUSE_TRACER_NAME,\n} from \"@langfuse/core\";\nimport { TracerProvider, trace } from \"@opentelemetry/api\";\n\nconst LANGFUSE_GLOBAL_SYMBOL = Symbol.for(\"langfuse\");\n\ntype LangfuseGlobalState = {\n isolatedTracerProvider: TracerProvider | null;\n};\n\nfunction createState(): LangfuseGlobalState {\n return {\n isolatedTracerProvider: null,\n };\n}\n\ninterface GlobalThis {\n [LANGFUSE_GLOBAL_SYMBOL]?: LangfuseGlobalState;\n}\n\nfunction getGlobalState(): LangfuseGlobalState {\n const initialState = createState();\n\n try {\n const g = globalThis as typeof globalThis & GlobalThis;\n\n if (typeof g !== \"object\" || g === null) {\n getGlobalLogger().warn(\n \"globalThis is not available, using fallback state\",\n );\n return initialState;\n }\n\n if (!g[LANGFUSE_GLOBAL_SYMBOL]) {\n Object.defineProperty(g, LANGFUSE_GLOBAL_SYMBOL, {\n value: initialState,\n writable: false, // lock the slot (not the contents)\n configurable: false,\n enumerable: false,\n });\n }\n\n return g[LANGFUSE_GLOBAL_SYMBOL]!;\n } catch (err) {\n if (err instanceof Error) {\n getGlobalLogger().error(`Failed to access global state: ${err.message}`);\n } else {\n getGlobalLogger().error(`Failed to access global state: ${String(err)}`);\n }\n\n return initialState;\n }\n}\n\n/**\n * Sets an isolated TracerProvider for Langfuse tracing operations.\n *\n * This allows Langfuse to use its own TracerProvider instance, separate from\n * the global OpenTelemetry TracerProvider. This is useful for avoiding conflicts\n * with other OpenTelemetry instrumentation in the application.\n *\n * ⚠️ **Limitation: Span Context Sharing**\n *\n * While this function isolates span processing and export, it does NOT provide\n * complete trace isolation. OpenTelemetry context (trace IDs, parent spans) is\n * still shared between the global and isolated providers. This means:\n *\n * - Spans created with the isolated provider inherit trace IDs from global spans\n * - Spans created with the isolated provider inherit parent relationships from global spans\n * - This can result in spans from different providers being part of the same logical trace\n *\n * **Why this happens:**\n * OpenTelemetry uses a global context propagation mechanism that operates at the\n * JavaScript runtime level, independent of individual TracerProvider instances.\n * The context (containing trace ID, span ID) flows through async boundaries and\n * is inherited by all spans created within that context, regardless of which\n * TracerProvider creates them.\n *\n * @example\n * ```typescript\n * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';\n * import { LangfuseSpanProcessor } from '@langfuse/otel';\n * import { setLangfuseTracerProvider } from '@langfuse/tracing';\n *\n * // Create provider with span processors in constructor\n * const provider = new NodeTracerProvider({\n * spanProcessors: [new LangfuseSpanProcessor()]\n * });\n *\n * setLangfuseTracerProvider(provider);\n *\n * // Note: Spans created with getLangfuseTracer() may still inherit\n * // context from spans created with the global tracer\n * ```\n *\n * @param provider - The TracerProvider instance to use, or null to clear the isolated provider\n * @public\n */\nexport function setLangfuseTracerProvider(provider: TracerProvider | null) {\n getGlobalState().isolatedTracerProvider = provider;\n}\n\n/**\n * Gets the TracerProvider for Langfuse tracing operations.\n *\n * Returns the isolated TracerProvider if one has been set via setLangfuseTracerProvider(),\n * otherwise falls back to the global OpenTelemetry TracerProvider.\n *\n * @example\n * ```typescript\n * import { getLangfuseTracerProvider } from '@langfuse/tracing';\n *\n * const provider = getLangfuseTracerProvider();\n * const tracer = provider.getTracer('my-tracer', '1.0.0');\n * ```\n *\n * @returns The TracerProvider instance to use for Langfuse tracing\n * @public\n */\nexport function getLangfuseTracerProvider(): TracerProvider {\n const { isolatedTracerProvider } = getGlobalState();\n\n if (isolatedTracerProvider) return isolatedTracerProvider;\n\n return trace.getTracerProvider();\n}\n\n/**\n * Gets the OpenTelemetry tracer instance for Langfuse.\n *\n * This function returns a tracer specifically configured for Langfuse\n * with the correct tracer name and version. Used internally by all\n * Langfuse tracing functions to ensure consistent trace creation.\n *\n * @returns The Langfuse OpenTelemetry tracer instance\n *\n * @example\n * ```typescript\n * import { getLangfuseTracer } from '@langfuse/tracing';\n *\n * const tracer = getLangfuseTracer();\n * const span = tracer.startSpan('my-operation');\n * ```\n *\n * @public\n */\nexport function getLangfuseTracer() {\n return getLangfuseTracerProvider().getTracer(\n LANGFUSE_TRACER_NAME,\n LANGFUSE_SDK_VERSION,\n );\n}\n","import { Span, TimeInput } from \"@opentelemetry/api\";\n\nimport {\n createEventAttributes,\n createGenerationAttributes,\n createSpanAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport { getLangfuseTracer } from \"./tracerProvider.js\";\nimport {\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\nimport { createEvent, startGeneration, startSpan } from \"./index.js\";\n\n/**\n * Union type representing any Langfuse observation wrapper.\n *\n * Used when you need to accept any type of Langfuse observation\n * (span, generation, or event).\n *\n * @public\n */\nexport type LangfuseObservation =\n | LangfuseSpan\n | LangfuseGeneration\n | LangfuseEvent;\n\n/**\n * Parameters for creating a Langfuse span wrapper.\n *\n * @internal\n */\ntype LangfuseSpanWrapperParams = {\n otelSpan: Span;\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes;\n};\n\n/**\n * Base class for all Langfuse observation wrappers.\n *\n * Provides common functionality for spans, generations, and events including\n * access to the underlying OpenTelemetry span, span ID, trace ID, and basic\n * operations like ending the observation and updating trace attributes.\n *\n * @internal\n */\nabstract class LangfuseSpanWrapper {\n /** The underlying OpenTelemetry span */\n public readonly otelSpan: Span;\n /** The span ID from the OpenTelemetry span context */\n public id: string;\n /** The trace ID from the OpenTelemetry span context */\n public traceId: string;\n\n constructor(params: LangfuseSpanWrapperParams) {\n this.otelSpan = params.otelSpan;\n this.id = params.otelSpan.spanContext().spanId;\n this.traceId = params.otelSpan.spanContext().traceId;\n }\n\n /** Gets the Langfuse OpenTelemetry tracer instance */\n protected get tracer() {\n return getLangfuseTracer();\n }\n\n /**\n * Ends the observation, marking it as complete.\n *\n * @param endTime - Optional end time, defaults to current time\n */\n public end(endTime?: TimeInput) {\n this.otelSpan.end(endTime);\n }\n\n /**\n * Updates the parent trace with new attributes.\n *\n * This sets trace-level attributes that apply to the entire trace,\n * not just this specific observation.\n *\n * @param attributes - Trace attributes to set\n * @returns This observation for method chaining\n */\n public updateTrace(attributes: LangfuseTraceAttributes) {\n this.otelSpan.setAttributes(createTraceAttributes(attributes));\n\n return this;\n }\n}\n\n/**\n * Parameters for creating a Langfuse span.\n *\n * @internal\n */\ntype LangfuseSpanParams = {\n otelSpan: Span;\n attributes?: LangfuseSpanAttributes;\n};\n\n/**\n * Langfuse span wrapper for general-purpose tracing.\n *\n * Spans are used to track operations, functions, or logical units of work.\n * They can contain other spans, generations, or events as children and have\n * a duration from start to end.\n *\n * @public\n */\nexport class LangfuseSpan extends LangfuseSpanWrapper {\n constructor(params: LangfuseSpanParams) {\n super(params);\n if (params.attributes) {\n this.otelSpan.setAttributes(createSpanAttributes(params.attributes));\n }\n }\n\n /**\n * Updates this span with new attributes.\n *\n * @param attributes - Span attributes to set\n * @returns This span for method chaining\n *\n * @example\n * ```typescript\n * span.update({\n * output: { result: 'success' },\n * level: 'DEFAULT',\n * metadata: { duration: 150 }\n * });\n * ```\n */\n public update(attributes: LangfuseSpanAttributes): LangfuseSpan {\n this.otelSpan.setAttributes(createSpanAttributes(attributes));\n\n return this;\n }\n\n /**\n * Starts a new child span within this span.\n *\n * @param name - Name of the child span\n * @param attributes - Optional attributes for the child span\n * @returns The new child span\n *\n * @example\n * ```typescript\n * const childSpan = parentSpan.startSpan('database-query', {\n * input: { query: 'SELECT * FROM users' },\n * metadata: { database: 'primary' }\n * });\n * ```\n */\n public startSpan(\n name: string,\n attributes?: LangfuseSpanAttributes,\n ): LangfuseSpan {\n return startSpan(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n\n /**\n * Starts a new child generation within this span.\n *\n * @param name - Name of the generation (typically the model name)\n * @param attributes - Optional generation-specific attributes\n * @returns The new child generation\n *\n * @example\n * ```typescript\n * const generation = parentSpan.startGeneration('gpt-4', {\n * input: [{ role: 'user', content: 'Hello!' }],\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 }\n * });\n * ```\n */\n public startGeneration(\n name: string,\n attributes?: LangfuseGenerationAttributes,\n ): LangfuseGeneration {\n return startGeneration(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n\n /**\n * Creates a new event within this span.\n *\n * Events are point-in-time occurrences and are automatically ended.\n *\n * @param name - Name of the event\n * @param attributes - Optional event attributes\n * @returns The created event (already ended)\n *\n * @example\n * ```typescript\n * parentSpan.createEvent('user-action', {\n * input: { action: 'click', button: 'submit' },\n * metadata: { userId: '123' }\n * });\n * ```\n */\n public createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n ): LangfuseEvent {\n return createEvent(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n}\n\n/**\n * Parameters for creating a Langfuse generation.\n *\n * @internal\n */\ntype LangfuseGenerationParams = {\n otelSpan: Span;\n attributes?: LangfuseGenerationAttributes;\n};\n\n/**\n * Langfuse generation wrapper for tracking LLM interactions.\n *\n * Generations are specialized observations for tracking language model\n * calls, including model parameters, usage metrics, costs, and prompts.\n *\n * @public\n */\nexport class LangfuseGeneration extends LangfuseSpanWrapper {\n constructor(params: LangfuseGenerationParams) {\n super(params);\n if (params.attributes) {\n this.otelSpan.setAttributes(\n createGenerationAttributes(params.attributes),\n );\n }\n }\n\n /**\n * Updates this generation with new attributes.\n *\n * @param attributes - Generation attributes to set\n * @returns This generation for method chaining\n *\n * @example\n * ```typescript\n * generation.update({\n * output: { role: 'assistant', content: 'Hello there!' },\n * usageDetails: {\n * promptTokens: 10,\n * completionTokens: 15,\n * totalTokens: 25\n * },\n * costDetails: { totalCost: 0.001 }\n * });\n * ```\n */\n update(attributes: LangfuseGenerationAttributes): LangfuseGeneration {\n this.otelSpan.setAttributes(createGenerationAttributes(attributes));\n\n return this;\n }\n\n /**\n * Creates a new event within this generation.\n *\n * Events are point-in-time occurrences and are automatically ended.\n *\n * @param name - Name of the event\n * @param attributes - Optional event attributes\n * @returns The created event (already ended)\n *\n * @example\n * ```typescript\n * generation.createEvent('token-limit-reached', {\n * level: 'WARNING',\n * metadata: { requestedTokens: 2000, maxTokens: 1500 }\n * });\n * ```\n */\n createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n ): LangfuseEvent {\n return createEvent(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n}\n\n/**\n * Parameters for creating a Langfuse event.\n *\n * @internal\n */\ntype LangfuseEventParams = {\n otelSpan: Span;\n attributes?: LangfuseEventAttributes;\n timestamp: TimeInput;\n};\n\n/**\n * Langfuse event wrapper for point-in-time observations.\n *\n * Events represent instantaneous occurrences or log entries within a trace.\n * Unlike spans and generations, they don't have duration and are automatically\n * ended when created.\n *\n * @public\n */\nexport class LangfuseEvent extends LangfuseSpanWrapper {\n constructor(params: LangfuseEventParams) {\n super(params);\n\n if (params.attributes) {\n this.otelSpan.setAttributes(createEventAttributes(params.attributes));\n }\n\n // Events are automatically ended at their timestamp\n this.otelSpan.end(params.timestamp);\n }\n}\n"],"mappings":"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","names":["import_core","import_api","import_core","import_core"]}
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
  *
@@ -739,6 +823,8 @@ interface ObserveOptions {
739
823
  captureInput?: boolean;
740
824
  /** Whether to capture function output as observation output */
741
825
  captureOutput?: boolean;
826
+ /** Parent span context to attach this observation to */
827
+ parentSpanContext?: SpanContext;
742
828
  }
743
829
  /**
744
830
  * Decorator function that automatically wraps a function with Langfuse tracing.
@@ -843,5 +929,25 @@ declare function observe<T extends (...args: unknown[]) => unknown>(fn: T, optio
843
929
  * @public
844
930
  */
845
931
  declare function createTraceId(seed?: string): Promise<string>;
932
+ /**
933
+ * Gets the current active trace ID.
934
+ *
935
+ * If there is no span in the current context, returns undefined.
936
+ *
937
+ * @returns The trace ID of the currently active span, or undefined if no span is active
938
+ *
939
+ * @public
940
+ */
941
+ declare function getActiveTraceId(): string | undefined;
942
+ /**
943
+ * Gets the current active observation ID.
944
+ *
945
+ * If there is no OTEL span in the current context, returns undefined.
946
+ *
947
+ * @returns The ID of the currently active OTEL span, or undefined if no OTEL span is active
948
+ *
949
+ * @public
950
+ */
951
+ declare function getActiveSpanId(): string | undefined;
846
952
 
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 };
953
+ 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, 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
  *
@@ -739,6 +823,8 @@ interface ObserveOptions {
739
823
  captureInput?: boolean;
740
824
  /** Whether to capture function output as observation output */
741
825
  captureOutput?: boolean;
826
+ /** Parent span context to attach this observation to */
827
+ parentSpanContext?: SpanContext;
742
828
  }
743
829
  /**
744
830
  * Decorator function that automatically wraps a function with Langfuse tracing.
@@ -843,5 +929,25 @@ declare function observe<T extends (...args: unknown[]) => unknown>(fn: T, optio
843
929
  * @public
844
930
  */
845
931
  declare function createTraceId(seed?: string): Promise<string>;
932
+ /**
933
+ * Gets the current active trace ID.
934
+ *
935
+ * If there is no span in the current context, returns undefined.
936
+ *
937
+ * @returns The trace ID of the currently active span, or undefined if no span is active
938
+ *
939
+ * @public
940
+ */
941
+ declare function getActiveTraceId(): string | undefined;
942
+ /**
943
+ * Gets the current active observation ID.
944
+ *
945
+ * If there is no OTEL span in the current context, returns undefined.
946
+ *
947
+ * @returns The ID of the currently active OTEL span, or undefined if no OTEL span is active
948
+ *
949
+ * @public
950
+ */
951
+ declare function getActiveSpanId(): string | undefined;
846
952
 
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 };
953
+ 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, 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
@@ -445,7 +495,7 @@ function startActiveGeneration(name, fn, options) {
445
495
  function updateActiveTrace(attributes) {
446
496
  const span = trace2.getActiveSpan();
447
497
  if (!span) {
448
- getGlobalLogger().warn(
498
+ getGlobalLogger2().warn(
449
499
  "No active OTEL span in context. Skipping trace update."
450
500
  );
451
501
  return;
@@ -455,7 +505,7 @@ function updateActiveTrace(attributes) {
455
505
  function updateActiveSpan(attributes) {
456
506
  const span = trace2.getActiveSpan();
457
507
  if (!span) {
458
- getGlobalLogger().warn(
508
+ getGlobalLogger2().warn(
459
509
  "No active OTEL span in context. Skipping span update."
460
510
  );
461
511
  return;
@@ -465,7 +515,7 @@ function updateActiveSpan(attributes) {
465
515
  function updateActiveGeneration(attributes) {
466
516
  const span = trace2.getActiveSpan();
467
517
  if (!span) {
468
- getGlobalLogger().warn(
518
+ getGlobalLogger2().warn(
469
519
  "No active OTEL span in context. Skipping generation update."
470
520
  );
471
521
  return;
@@ -477,14 +527,19 @@ function observe(fn, options = {}) {
477
527
  name = fn.name || "anonymous-function",
478
528
  asType = "span",
479
529
  captureInput = true,
480
- captureOutput = true
530
+ captureOutput = true,
531
+ parentSpanContext = void 0
481
532
  } = options;
482
- const wrappedFunction = (...args) => {
533
+ const wrappedFunction = function(...args) {
483
534
  const inputData = captureInput ? _captureArguments(args) : void 0;
484
- const observation = asType === "generation" ? startGeneration(name, inputData ? { input: inputData } : {}) : startSpan(name, inputData ? { input: inputData } : {});
535
+ const observation = asType === "generation" ? startGeneration(name, inputData ? { input: inputData } : {}, {
536
+ parentSpanContext
537
+ }) : startSpan(name, inputData ? { input: inputData } : {}, {
538
+ parentSpanContext
539
+ });
485
540
  const activeContext = trace2.setSpan(context.active(), observation.otelSpan);
486
541
  try {
487
- const result = context.with(activeContext, () => fn(...args));
542
+ const result = context.with(activeContext, () => fn.apply(this, args));
488
543
  if (result instanceof Promise) {
489
544
  return result.then(
490
545
  (value) => {
@@ -552,6 +607,14 @@ async function createTraceId(seed) {
552
607
  function uint8ArrayToHex(array) {
553
608
  return Array.from(array).map((b) => b.toString(16).padStart(2, "0")).join("");
554
609
  }
610
+ function getActiveTraceId() {
611
+ var _a;
612
+ return (_a = trace2.getActiveSpan()) == null ? void 0 : _a.spanContext().traceId;
613
+ }
614
+ function getActiveSpanId() {
615
+ var _a;
616
+ return (_a = trace2.getActiveSpan()) == null ? void 0 : _a.spanContext().spanId;
617
+ }
555
618
  export {
556
619
  LangfuseEvent,
557
620
  LangfuseGeneration,
@@ -562,7 +625,12 @@ export {
562
625
  createSpanAttributes,
563
626
  createTraceAttributes,
564
627
  createTraceId,
628
+ getActiveSpanId,
629
+ getActiveTraceId,
630
+ getLangfuseTracer,
631
+ getLangfuseTracerProvider,
565
632
  observe,
633
+ setLangfuseTracerProvider,
566
634
  startActiveGeneration,
567
635
  startActiveSpan,
568
636
  startGeneration,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/attributes.ts","../src/utils.ts","../src/spanWrapper.ts"],"sourcesContent":["import { getGlobalLogger } from \"@langfuse/core\";\nimport {\n trace,\n context,\n TimeInput,\n SpanStatusCode,\n Span,\n Context,\n SpanContext,\n} from \"@opentelemetry/api\";\n\nimport {\n createGenerationAttributes,\n createSpanAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport {\n LangfuseEvent,\n LangfuseGeneration,\n LangfuseSpan,\n} from \"./spanWrapper.js\";\nimport {\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\nimport { getLangfuseTracer } from \"./utils.js\";\n\nexport type {\n LangfuseObservationType,\n ObservationLevel,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\nexport * from \"./spanWrapper.js\";\nexport {\n createTraceAttributes,\n createSpanAttributes,\n createGenerationAttributes,\n} from \"./attributes.js\";\n\nexport { LangfuseOtelSpanAttributes } from \"@langfuse/core\";\n\n/**\n * Options for starting observations (spans, generations, events).\n *\n * @public\n */\nexport type StartObservationOptions = {\n /** Custom start time for the observation */\n startTime?: Date;\n /** Parent span context to attach this observation to */\n parentSpanContext?: SpanContext;\n};\n\n/**\n * Creates an OpenTelemetry span with the Langfuse tracer.\n *\n * @param params - Parameters for span creation\n * @returns The created OpenTelemetry span\n * @internal\n */\nfunction createOtelSpan(params: {\n name: string;\n startTime?: TimeInput;\n parentSpanContext?: SpanContext;\n}): Span {\n return getLangfuseTracer().startSpan(\n params.name,\n { startTime: params.startTime },\n createParentContext(params.parentSpanContext),\n );\n}\n\n/**\n * Creates a parent context from a span context.\n *\n * @param parentSpanContext - The span context to use as parent\n * @returns The created context or undefined if no parent provided\n * @internal\n */\nfunction createParentContext(\n parentSpanContext?: SpanContext,\n): Context | undefined {\n if (!parentSpanContext) return;\n\n return trace.setSpanContext(context.active(), parentSpanContext);\n}\n\n/**\n * Wraps a promise to automatically end the span when the promise resolves or rejects.\n *\n * @param promise - The promise to wrap\n * @param span - The span to end when promise completes\n * @returns The wrapped promise\n * @internal\n */\nfunction wrapPromise<T>(promise: Promise<T>, span: Span): Promise<T> {\n return promise.then(\n (value) => {\n span.end(); // End span AFTER Promise resolves\n\n return value;\n },\n (err: unknown) => {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end(); // End span AFTER Promise rejects\n\n throw err;\n },\n );\n}\n\n/**\n * Creates and starts a new Langfuse span for general-purpose tracing.\n *\n * Spans are used to track operations, functions, or logical units of work.\n * They can contain other spans or generations as children.\n *\n * @param name - Name of the span\n * @param attributes - Optional attributes to set on the span\n * @param options - Optional configuration for the span\n * @returns A LangfuseSpan instance\n *\n * @example\n * ```typescript\n * import { startSpan } from '@langfuse/tracing';\n *\n * const span = startSpan('data-processing', {\n * input: { userId: '123', data: {...} },\n * metadata: { version: '1.0' },\n * level: 'DEFAULT'\n * });\n *\n * try {\n * // Do some work\n * const result = await processData();\n *\n * span.update({ output: result });\n * } catch (error) {\n * span.update({\n * level: 'ERROR',\n * statusMessage: error.message\n * });\n * } finally {\n * span.end();\n * }\n * ```\n *\n * @public\n */\nexport function startSpan(\n name: string,\n attributes?: LangfuseSpanAttributes,\n options?: {\n startTime?: TimeInput;\n parentSpanContext?: SpanContext;\n },\n): LangfuseSpan {\n const otelSpan = createOtelSpan({\n name,\n ...options,\n });\n\n return new LangfuseSpan({ otelSpan, attributes });\n}\n\n/**\n * Creates and starts a new Langfuse generation for tracking LLM calls.\n *\n * Generations are specialized observations for tracking language model\n * interactions, including model parameters, usage metrics, and costs.\n *\n * @param name - Name of the generation (typically the model or operation)\n * @param attributes - Optional generation-specific attributes\n * @param options - Optional configuration for the generation\n * @returns A LangfuseGeneration instance\n *\n * @example\n * ```typescript\n * import { startGeneration } from '@langfuse/tracing';\n *\n * const generation = startGeneration('openai-gpt-4', {\n * input: [{ role: 'user', content: 'Hello, world!' }],\n * model: 'gpt-4',\n * modelParameters: {\n * temperature: 0.7,\n * max_tokens: 150\n * },\n * metadata: { feature: 'chat' }\n * });\n *\n * try {\n * const response = await callOpenAI(messages);\n *\n * generation.update({\n * output: response.choices[0].message,\n * usageDetails: {\n * promptTokens: response.usage.prompt_tokens,\n * completionTokens: response.usage.completion_tokens,\n * totalTokens: response.usage.total_tokens\n * }\n * });\n * } finally {\n * generation.end();\n * }\n * ```\n *\n * @public\n */\nexport function startGeneration(\n name: string,\n attributes?: LangfuseGenerationAttributes,\n options?: StartObservationOptions,\n): LangfuseGeneration {\n const otelSpan = createOtelSpan({\n name,\n ...options,\n });\n\n return new LangfuseGeneration({ otelSpan, attributes });\n}\n\n/**\n * Creates a Langfuse event for point-in-time occurrences.\n *\n * Events are used to capture instantaneous occurrences or log entries\n * within a trace. Unlike spans, they represent a single point in time.\n *\n * @param name - Name of the event\n * @param attributes - Optional attributes for the event\n * @param options - Optional configuration for the event\n * @returns A LangfuseEvent instance (automatically ended)\n *\n * @example\n * ```typescript\n * import { createEvent } from '@langfuse/tracing';\n *\n * // Log a user action\n * createEvent('user-click', {\n * input: { buttonId: 'submit', userId: '123' },\n * metadata: { page: '/checkout' },\n * level: 'DEFAULT'\n * });\n *\n * // Log an error\n * createEvent('api-error', {\n * level: 'ERROR',\n * statusMessage: 'Failed to fetch user data',\n * metadata: { endpoint: '/api/users/123', statusCode: 500 }\n * });\n * ```\n *\n * @public\n */\nexport function createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n options?: StartObservationOptions,\n) {\n const timestamp = options?.startTime ?? new Date();\n\n const otelSpan = createOtelSpan({\n name,\n ...options,\n startTime: timestamp,\n });\n\n return new LangfuseEvent({ otelSpan, attributes, timestamp });\n}\n\n/**\n * Starts an active span and executes a function within its context.\n *\n * This function creates a span, sets it as the active span in the OpenTelemetry\n * context, executes the provided function, and automatically ends the span.\n * Perfect for wrapping operations where you want child spans to be automatically\n * linked.\n *\n * @param name - Name of the span\n * @param fn - Function to execute within the span context\n * @param options - Optional configuration for the span\n * @returns The return value of the executed function\n *\n * @example\n * ```typescript\n * import { startActiveSpan } from '@langfuse/tracing';\n *\n * // Synchronous function\n * const result = startActiveSpan('calculate-metrics', (span) => {\n * span.update({ input: { data: rawData } });\n *\n * const metrics = calculateMetrics(rawData);\n * span.update({ output: metrics });\n *\n * return metrics;\n * });\n *\n * // Asynchronous function\n * const data = await startActiveSpan('fetch-user-data', async (span) => {\n * span.update({ input: { userId: '123' } });\n *\n * const userData = await api.getUser('123');\n * span.update({ output: userData });\n *\n * return userData;\n * });\n * ```\n *\n * @public\n */\nexport function startActiveSpan<F extends (span: LangfuseSpan) => unknown>(\n name: string,\n fn: F,\n options?: StartObservationOptions,\n): ReturnType<F> {\n return getLangfuseTracer().startActiveSpan(\n name,\n { startTime: options?.startTime },\n createParentContext(options?.parentSpanContext) ?? context.active(),\n (span) => {\n try {\n const result = fn(new LangfuseSpan({ otelSpan: span }));\n\n if (result instanceof Promise) {\n return wrapPromise(result, span) as ReturnType<F>;\n } else {\n span.end();\n\n return result as ReturnType<F>;\n }\n } catch (err) {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end();\n\n throw err;\n }\n },\n );\n}\n\n/**\n * Starts an active generation and executes a function within its context.\n *\n * Similar to startActiveSpan but creates a generation for tracking LLM calls.\n * The generation is automatically ended when the function completes.\n *\n * @param name - Name of the generation\n * @param fn - Function to execute within the generation context\n * @param options - Optional configuration for the generation\n * @returns The return value of the executed function\n *\n * @example\n * ```typescript\n * import { startActiveGeneration } from '@langfuse/tracing';\n *\n * const response = await startActiveGeneration('openai-completion', async (generation) => {\n * generation.update({\n * input: { messages: [...] },\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 }\n * });\n *\n * const result = await openai.chat.completions.create({...});\n *\n * generation.update({\n * output: result.choices[0].message,\n * usageDetails: result.usage\n * });\n *\n * return result;\n * });\n * ```\n *\n * @public\n */\nexport function startActiveGeneration<\n F extends (span: LangfuseGeneration) => unknown,\n>(name: string, fn: F, options?: StartObservationOptions): ReturnType<F> {\n return getLangfuseTracer().startActiveSpan(\n name,\n { startTime: options?.startTime },\n createParentContext(options?.parentSpanContext) ?? context.active(),\n (span) => {\n try {\n const result = fn(new LangfuseGeneration({ otelSpan: span }));\n\n if (result instanceof Promise) {\n return wrapPromise(result, span) as ReturnType<F>;\n } else {\n span.end();\n\n return result as ReturnType<F>;\n }\n } catch (err) {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end();\n\n throw err;\n }\n },\n );\n}\n\n/**\n * Updates the currently active trace with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with trace-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Trace attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveTrace } from '@langfuse/tracing';\n *\n * // Inside an active span context\n * updateActiveTrace({\n * name: 'user-workflow',\n * userId: '123',\n * sessionId: 'session-456',\n * tags: ['production', 'critical'],\n * public: true\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveTrace(attributes: LangfuseTraceAttributes) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping trace update.\",\n );\n\n return;\n }\n\n span.setAttributes(createTraceAttributes(attributes));\n}\n\n/**\n * Updates the currently active span with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with span-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Span attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveSpan } from '@langfuse/tracing';\n *\n * // Inside an active span context\n * updateActiveSpan({\n * level: 'WARNING',\n * statusMessage: 'Operation completed with warnings',\n * metadata: { warningCount: 3 }\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveSpan(attributes: LangfuseSpanAttributes) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping span update.\",\n );\n\n return;\n }\n\n span.setAttributes(createSpanAttributes(attributes));\n}\n\n/**\n * Updates the currently active generation with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with generation-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Generation attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveGeneration } from '@langfuse/tracing';\n *\n * // Inside an active generation context\n * updateActiveGeneration({\n * usageDetails: {\n * promptTokens: 50,\n * completionTokens: 100,\n * totalTokens: 150\n * },\n * costDetails: { totalCost: 0.003 }\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveGeneration(\n attributes: LangfuseGenerationAttributes,\n) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping generation update.\",\n );\n\n return;\n }\n\n span.setAttributes(createGenerationAttributes(attributes));\n}\n\n/**\n * Options for the observe decorator function.\n *\n * @public\n */\nexport interface ObserveOptions {\n /** Name for the observation (defaults to function name) */\n name?: string;\n /** Type of observation to create */\n asType?: \"span\" | \"generation\";\n /** Whether to capture function input as observation input */\n captureInput?: boolean;\n /** Whether to capture function output as observation output */\n captureOutput?: boolean;\n}\n\n/**\n * Decorator function that automatically wraps a function with Langfuse tracing.\n *\n * This function creates a wrapper around the provided function that automatically:\n * - Creates a span or generation when the function is called\n * - Captures input arguments (if enabled)\n * - Captures return value/output (if enabled)\n * - Handles errors and sets appropriate status\n * - Ends the observation when the function completes\n *\n * @param fn - The function to wrap with tracing\n * @param options - Configuration options for the observation\n * @returns A wrapped version of the function that includes tracing\n *\n * @example\n * ```typescript\n * import { observe } from '@langfuse/tracing';\n *\n * // Wrap a regular function\n * const processData = observe(\n * async (userId: string, data: any) => {\n * // Function implementation\n * return await processUserData(userId, data);\n * },\n * {\n * name: 'process-user-data',\n * asType: 'span',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Wrap an LLM call\n * const generateText = observe(\n * async (prompt: string) => {\n * return await openai.chat.completions.create({\n * model: 'gpt-4',\n * messages: [{ role: 'user', content: prompt }]\n * });\n * },\n * {\n * name: 'openai-generation',\n * asType: 'generation',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Usage\n * const result = await processData('123', { key: 'value' });\n * const text = await generateText('Hello, world!');\n * ```\n *\n * @public\n */\nexport function observe<T extends (...args: unknown[]) => unknown>(\n fn: T,\n options: ObserveOptions = {},\n): T {\n const {\n name = fn.name || \"anonymous-function\",\n asType = \"span\",\n captureInput = true,\n captureOutput = true,\n } = options;\n\n const wrappedFunction = (...args: Parameters<T>): ReturnType<T> => {\n // Prepare input data\n const inputData = captureInput ? _captureArguments(args) : undefined;\n\n // Create the appropriate observation type\n const observation =\n asType === \"generation\"\n ? startGeneration(name, inputData ? { input: inputData } : {})\n : startSpan(name, inputData ? { input: inputData } : {});\n\n // Set the observation span as active in the context\n const activeContext = trace.setSpan(context.active(), observation.otelSpan);\n\n try {\n const result = context.with(activeContext, () => fn(...args));\n\n // Handle async functions - check if result is a Promise\n // TODO: handle returned generators for streamed responses\n if (result instanceof Promise) {\n return result.then(\n (value) => {\n if (captureOutput) {\n observation.update({ output: _captureOutput(value) });\n }\n observation.end();\n\n return value;\n },\n (error: unknown) => {\n observation\n .update({\n level: \"ERROR\",\n statusMessage:\n (error instanceof Error ? error.message : String(error)) ||\n \"Function threw an error\",\n output: captureOutput ? { error: String(error) } : undefined,\n })\n .end();\n\n throw error;\n },\n ) as ReturnType<T>;\n } else {\n // Handle sync functions\n if (captureOutput) {\n observation.update({ output: _captureOutput(result) });\n }\n observation.end();\n\n return result as ReturnType<T>;\n }\n } catch (error: unknown) {\n observation\n .update({\n level: \"ERROR\",\n statusMessage:\n (error instanceof Error ? error.message : String(error)) ||\n \"Function threw an error\",\n output: captureOutput ? { error: String(error) } : undefined,\n })\n .end();\n\n throw error;\n }\n };\n\n return wrappedFunction as T;\n}\n\n/**\n * Helper function to safely capture function arguments.\n *\n * @param args - Function arguments array\n * @returns Captured arguments or error message\n * @internal\n */\nfunction _captureArguments(args: unknown[]): unknown {\n try {\n if (args.length === 0) return undefined;\n if (args.length === 1) return args[0];\n return args;\n } catch {\n return \"<failed to capture arguments>\";\n }\n}\n\n/**\n * Helper function to safely capture function output.\n *\n * @param value - Function return value\n * @returns Captured output or error message\n * @internal\n */\nfunction _captureOutput(value: unknown): unknown {\n try {\n // Handle undefined/null\n if (value === undefined || value === null) return value;\n\n // For primitive types, return as-is\n if (typeof value !== \"object\") return value;\n\n // For objects, return them directly (serialization happens in span processor)\n return value;\n } catch {\n return \"<failed to capture output>\";\n }\n}\n\n/**\n * Creates a trace ID for OpenTelemetry spans.\n *\n * @param seed - A seed string for deterministic trace ID generation.\n * If provided (non-empty), the same seed will always generate the same trace ID.\n * If empty or falsy, generates a random trace ID.\n *\n * Using a seed is especially useful when trying to correlate external,\n * non-W3C compliant IDs with Langfuse trace IDs. This allows you to later\n * have a method available for scoring the Langfuse trace given only the\n * external ID by regenerating the same trace ID from the external ID.\n *\n * @returns A Promise that resolves to a 32-character lowercase hexadecimal string suitable for use as an OpenTelemetry trace ID.\n *\n * @example\n * ```typescript\n * // Deterministic trace ID from seed\n * const traceId1 = await createTraceId(\"my-session-123\");\n * const traceId2 = await createTraceId(\"my-session-123\");\n * console.log(traceId1 === traceId2); // true\n *\n * // Random trace ID\n * const randomId1 = await createTraceId(\"\");\n * const randomId2 = await createTraceId(\"\");\n * console.log(randomId1 === randomId2); // false\n *\n * // Use with spans\n * const span = startSpan(\"my-span\", {}, {\n * parentSpanContext: {\n * traceId: await createTraceId(\"session-456\"),\n * spanId: \"0123456789abcdef\",\n * traceFlags: 1\n * }\n * });\n *\n * // Correlating external IDs with Langfuse traces\n * const externalId = \"ext-12345-67890\";\n * const traceId = await createTraceId(externalId);\n *\n * // Later, when you need to score this trace, regenerate the same ID\n * const scoringTraceId = await createTraceId(externalId);\n * console.log(traceId === scoringTraceId); // true - can now find and score the trace\n * ```\n *\n * @public\n */\nexport async function createTraceId(seed?: string): Promise<string> {\n if (seed) {\n const data = new TextEncoder().encode(seed);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n\n const hashArray = new Uint8Array(hashBuffer);\n\n return uint8ArrayToHex(hashArray).slice(0, 32);\n }\n\n const randomValues = crypto.getRandomValues(new Uint8Array(16));\n\n return uint8ArrayToHex(randomValues);\n}\n\n/**\n * Converts a Uint8Array to a hexadecimal string.\n *\n * @param array - The byte array to convert\n * @returns Hexadecimal string representation\n * @internal\n */\nfunction uint8ArrayToHex(array: Uint8Array): string {\n return Array.from(array)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n","import { LangfuseOtelSpanAttributes } from \"@langfuse/core\";\nimport { type Attributes } from \"@opentelemetry/api\";\n\nimport {\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\n/**\n * Creates OpenTelemetry attributes from Langfuse trace attributes.\n *\n * Converts user-friendly trace attributes into the internal OpenTelemetry\n * attribute format required by the span processor.\n *\n * @param attributes - Langfuse trace attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createTraceAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createTraceAttributes({\n * name: 'user-checkout-flow',\n * userId: 'user-123',\n * sessionId: 'session-456',\n * tags: ['checkout', 'payment'],\n * metadata: { version: '2.1.0' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createTraceAttributes({\n name,\n userId,\n sessionId,\n version,\n release,\n input,\n output,\n metadata,\n tags,\n environment,\n public: isPublic,\n}: LangfuseTraceAttributes = {}): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.TRACE_NAME]: name,\n [LangfuseOtelSpanAttributes.TRACE_USER_ID]: userId,\n [LangfuseOtelSpanAttributes.TRACE_SESSION_ID]: sessionId,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.RELEASE]: release,\n [LangfuseOtelSpanAttributes.TRACE_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.TRACE_OUTPUT]: _serialize(output),\n [LangfuseOtelSpanAttributes.TRACE_TAGS]: tags,\n [LangfuseOtelSpanAttributes.ENVIRONMENT]: environment,\n [LangfuseOtelSpanAttributes.TRACE_PUBLIC]: isPublic,\n ..._flattenAndSerializeMetadata(metadata, \"trace\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse span attributes.\n *\n * Converts user-friendly span attributes into the internal OpenTelemetry\n * attribute format required by the span processor.\n *\n * @param attributes - Langfuse span attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createSpanAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createSpanAttributes({\n * input: { query: 'SELECT * FROM users' },\n * output: { rowCount: 42 },\n * level: 'DEFAULT',\n * metadata: { database: 'prod' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createSpanAttributes({\n metadata,\n input,\n output,\n level,\n statusMessage,\n version,\n}: LangfuseSpanAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"span\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse generation attributes.\n *\n * Converts user-friendly generation attributes into the internal OpenTelemetry\n * attribute format required by the span processor. Includes special handling\n * for LLM-specific fields like model parameters, usage, and costs.\n *\n * @param attributes - Langfuse generation attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createGenerationAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createGenerationAttributes({\n * input: [{ role: 'user', content: 'Hello!' }],\n * output: { role: 'assistant', content: 'Hi there!' },\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 },\n * usageDetails: {\n * promptTokens: 10,\n * completionTokens: 15,\n * totalTokens: 25\n * },\n * costDetails: { totalCost: 0.001 }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createGenerationAttributes({\n completionStartTime,\n metadata,\n level,\n statusMessage,\n version,\n model,\n modelParameters,\n input,\n output,\n usageDetails,\n costDetails,\n prompt,\n}: LangfuseGenerationAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"generation\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n [LangfuseOtelSpanAttributes.OBSERVATION_MODEL]: model,\n [LangfuseOtelSpanAttributes.OBSERVATION_USAGE_DETAILS]:\n _serialize(usageDetails),\n [LangfuseOtelSpanAttributes.OBSERVATION_COST_DETAILS]:\n _serialize(costDetails),\n [LangfuseOtelSpanAttributes.OBSERVATION_COMPLETION_START_TIME]:\n _serialize(completionStartTime),\n [LangfuseOtelSpanAttributes.OBSERVATION_MODEL_PARAMETERS]:\n _serialize(modelParameters),\n ...(prompt && !prompt.isFallback\n ? {\n [LangfuseOtelSpanAttributes.OBSERVATION_PROMPT_NAME]: prompt.name,\n [LangfuseOtelSpanAttributes.OBSERVATION_PROMPT_VERSION]:\n prompt.version,\n }\n : {}),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n ) as Attributes;\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse event attributes.\n *\n * Converts user-friendly event attributes into the internal OpenTelemetry\n * attribute format required by the span processor. Events are point-in-time\n * observations that are automatically ended when created.\n *\n * @param attributes - Langfuse event attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createEventAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createEventAttributes({\n * input: { action: 'button_click', elementId: 'submit' },\n * level: 'DEFAULT',\n * metadata: { page: '/checkout', userId: '123' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createEventAttributes({\n metadata,\n input,\n output,\n level,\n statusMessage,\n version,\n}: LangfuseSpanAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"event\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Safely serializes an object to JSON string.\n *\n * @param obj - Object to serialize\n * @returns JSON string or undefined if null/undefined, error message if serialization fails\n * @internal\n */\nfunction _serialize(obj: unknown): string | undefined {\n try {\n return obj != null ? JSON.stringify(obj) : undefined;\n } catch {\n return \"<failed to serialize>\";\n }\n}\n\n/**\n * Flattens and serializes metadata into OpenTelemetry attribute format.\n *\n * Converts nested metadata objects into dot-notation attribute keys.\n * For example, `{ database: { host: 'localhost' } }` becomes\n * `{ 'langfuse.metadata.database.host': 'localhost' }`.\n *\n * @param metadata - Metadata object to flatten\n * @param type - Whether this is for observation or trace metadata\n * @returns Flattened metadata attributes\n * @internal\n */\nfunction _flattenAndSerializeMetadata(\n metadata: unknown,\n type: \"observation\" | \"trace\",\n): Record<string, string> {\n const prefix =\n type === \"observation\"\n ? LangfuseOtelSpanAttributes.OBSERVATION_METADATA\n : LangfuseOtelSpanAttributes.TRACE_METADATA;\n\n const metadataAttributes: Record<string, string> = {};\n\n if (metadata === undefined || metadata === null) {\n return metadataAttributes;\n }\n\n if (typeof metadata !== \"object\" || Array.isArray(metadata)) {\n const serialized = _serialize(metadata);\n if (serialized) {\n metadataAttributes[prefix] = serialized;\n }\n } else {\n for (const [key, value] of Object.entries(metadata)) {\n const serialized = typeof value === \"string\" ? value : _serialize(value);\n if (serialized) {\n metadataAttributes[`${prefix}.${key}`] = serialized;\n }\n }\n }\n\n return metadataAttributes;\n}\n","import { LANGFUSE_SDK_VERSION, LANGFUSE_TRACER_NAME } from \"@langfuse/core\";\nimport { trace } from \"@opentelemetry/api\";\n\n/**\n * Gets the OpenTelemetry tracer instance for Langfuse.\n *\n * This function returns a tracer specifically configured for Langfuse\n * with the correct tracer name and version. Used internally by all\n * Langfuse tracing functions to ensure consistent trace creation.\n *\n * @returns The Langfuse OpenTelemetry tracer instance\n *\n * @example\n * ```typescript\n * import { getLangfuseTracer } from '@langfuse/tracing';\n *\n * const tracer = getLangfuseTracer();\n * const span = tracer.startSpan('my-operation');\n * ```\n *\n * @public\n */\nexport function getLangfuseTracer() {\n return trace.getTracer(LANGFUSE_TRACER_NAME, LANGFUSE_SDK_VERSION);\n}\n","import { Span, TimeInput } from \"@opentelemetry/api\";\n\nimport {\n createEventAttributes,\n createGenerationAttributes,\n createSpanAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport {\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\nimport { getLangfuseTracer } from \"./utils.js\";\n\nimport { createEvent, startGeneration, startSpan } from \"./index.js\";\n\n/**\n * Union type representing any Langfuse observation wrapper.\n *\n * Used when you need to accept any type of Langfuse observation\n * (span, generation, or event).\n *\n * @public\n */\nexport type LangfuseObservation =\n | LangfuseSpan\n | LangfuseGeneration\n | LangfuseEvent;\n\n/**\n * Parameters for creating a Langfuse span wrapper.\n *\n * @internal\n */\ntype LangfuseSpanWrapperParams = {\n otelSpan: Span;\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes;\n};\n\n/**\n * Base class for all Langfuse observation wrappers.\n *\n * Provides common functionality for spans, generations, and events including\n * access to the underlying OpenTelemetry span, span ID, trace ID, and basic\n * operations like ending the observation and updating trace attributes.\n *\n * @internal\n */\nabstract class LangfuseSpanWrapper {\n /** The underlying OpenTelemetry span */\n public readonly otelSpan: Span;\n /** The span ID from the OpenTelemetry span context */\n public id: string;\n /** The trace ID from the OpenTelemetry span context */\n public traceId: string;\n\n constructor(params: LangfuseSpanWrapperParams) {\n this.otelSpan = params.otelSpan;\n this.id = params.otelSpan.spanContext().spanId;\n this.traceId = params.otelSpan.spanContext().traceId;\n }\n\n /** Gets the Langfuse OpenTelemetry tracer instance */\n protected get tracer() {\n return getLangfuseTracer();\n }\n\n /**\n * Ends the observation, marking it as complete.\n *\n * @param endTime - Optional end time, defaults to current time\n */\n public end(endTime?: TimeInput) {\n this.otelSpan.end(endTime);\n }\n\n /**\n * Updates the parent trace with new attributes.\n *\n * This sets trace-level attributes that apply to the entire trace,\n * not just this specific observation.\n *\n * @param attributes - Trace attributes to set\n * @returns This observation for method chaining\n */\n public updateTrace(attributes: LangfuseTraceAttributes) {\n this.otelSpan.setAttributes(createTraceAttributes(attributes));\n\n return this;\n }\n}\n\n/**\n * Parameters for creating a Langfuse span.\n *\n * @internal\n */\ntype LangfuseSpanParams = {\n otelSpan: Span;\n attributes?: LangfuseSpanAttributes;\n};\n\n/**\n * Langfuse span wrapper for general-purpose tracing.\n *\n * Spans are used to track operations, functions, or logical units of work.\n * They can contain other spans, generations, or events as children and have\n * a duration from start to end.\n *\n * @public\n */\nexport class LangfuseSpan extends LangfuseSpanWrapper {\n constructor(params: LangfuseSpanParams) {\n super(params);\n if (params.attributes) {\n this.otelSpan.setAttributes(createSpanAttributes(params.attributes));\n }\n }\n\n /**\n * Updates this span with new attributes.\n *\n * @param attributes - Span attributes to set\n * @returns This span for method chaining\n *\n * @example\n * ```typescript\n * span.update({\n * output: { result: 'success' },\n * level: 'DEFAULT',\n * metadata: { duration: 150 }\n * });\n * ```\n */\n public update(attributes: LangfuseSpanAttributes): LangfuseSpan {\n this.otelSpan.setAttributes(createSpanAttributes(attributes));\n\n return this;\n }\n\n /**\n * Starts a new child span within this span.\n *\n * @param name - Name of the child span\n * @param attributes - Optional attributes for the child span\n * @returns The new child span\n *\n * @example\n * ```typescript\n * const childSpan = parentSpan.startSpan('database-query', {\n * input: { query: 'SELECT * FROM users' },\n * metadata: { database: 'primary' }\n * });\n * ```\n */\n public startSpan(\n name: string,\n attributes?: LangfuseSpanAttributes,\n ): LangfuseSpan {\n return startSpan(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n\n /**\n * Starts a new child generation within this span.\n *\n * @param name - Name of the generation (typically the model name)\n * @param attributes - Optional generation-specific attributes\n * @returns The new child generation\n *\n * @example\n * ```typescript\n * const generation = parentSpan.startGeneration('gpt-4', {\n * input: [{ role: 'user', content: 'Hello!' }],\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 }\n * });\n * ```\n */\n public startGeneration(\n name: string,\n attributes?: LangfuseGenerationAttributes,\n ): LangfuseGeneration {\n return startGeneration(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n\n /**\n * Creates a new event within this span.\n *\n * Events are point-in-time occurrences and are automatically ended.\n *\n * @param name - Name of the event\n * @param attributes - Optional event attributes\n * @returns The created event (already ended)\n *\n * @example\n * ```typescript\n * parentSpan.createEvent('user-action', {\n * input: { action: 'click', button: 'submit' },\n * metadata: { userId: '123' }\n * });\n * ```\n */\n public createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n ): LangfuseEvent {\n return createEvent(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n}\n\n/**\n * Parameters for creating a Langfuse generation.\n *\n * @internal\n */\ntype LangfuseGenerationParams = {\n otelSpan: Span;\n attributes?: LangfuseGenerationAttributes;\n};\n\n/**\n * Langfuse generation wrapper for tracking LLM interactions.\n *\n * Generations are specialized observations for tracking language model\n * calls, including model parameters, usage metrics, costs, and prompts.\n *\n * @public\n */\nexport class LangfuseGeneration extends LangfuseSpanWrapper {\n constructor(params: LangfuseGenerationParams) {\n super(params);\n if (params.attributes) {\n this.otelSpan.setAttributes(\n createGenerationAttributes(params.attributes),\n );\n }\n }\n\n /**\n * Updates this generation with new attributes.\n *\n * @param attributes - Generation attributes to set\n * @returns This generation for method chaining\n *\n * @example\n * ```typescript\n * generation.update({\n * output: { role: 'assistant', content: 'Hello there!' },\n * usageDetails: {\n * promptTokens: 10,\n * completionTokens: 15,\n * totalTokens: 25\n * },\n * costDetails: { totalCost: 0.001 }\n * });\n * ```\n */\n update(attributes: LangfuseGenerationAttributes): LangfuseGeneration {\n this.otelSpan.setAttributes(createGenerationAttributes(attributes));\n\n return this;\n }\n\n /**\n * Creates a new event within this generation.\n *\n * Events are point-in-time occurrences and are automatically ended.\n *\n * @param name - Name of the event\n * @param attributes - Optional event attributes\n * @returns The created event (already ended)\n *\n * @example\n * ```typescript\n * generation.createEvent('token-limit-reached', {\n * level: 'WARNING',\n * metadata: { requestedTokens: 2000, maxTokens: 1500 }\n * });\n * ```\n */\n createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n ): LangfuseEvent {\n return createEvent(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n}\n\n/**\n * Parameters for creating a Langfuse event.\n *\n * @internal\n */\ntype LangfuseEventParams = {\n otelSpan: Span;\n attributes?: LangfuseEventAttributes;\n timestamp: TimeInput;\n};\n\n/**\n * Langfuse event wrapper for point-in-time observations.\n *\n * Events represent instantaneous occurrences or log entries within a trace.\n * Unlike spans and generations, they don't have duration and are automatically\n * ended when created.\n *\n * @public\n */\nexport class LangfuseEvent extends LangfuseSpanWrapper {\n constructor(params: LangfuseEventParams) {\n super(params);\n\n if (params.attributes) {\n this.otelSpan.setAttributes(createEventAttributes(params.attributes));\n }\n\n // Events are automatically ended at their timestamp\n this.otelSpan.end(params.timestamp);\n }\n}\n"],"mappings":"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","names":["trace","LangfuseOtelSpanAttributes","trace"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/attributes.ts","../src/tracerProvider.ts","../src/spanWrapper.ts"],"sourcesContent":["import { getGlobalLogger } from \"@langfuse/core\";\nimport {\n trace,\n context,\n TimeInput,\n SpanStatusCode,\n Span,\n Context,\n SpanContext,\n} from \"@opentelemetry/api\";\n\nimport {\n createGenerationAttributes,\n createSpanAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport {\n LangfuseEvent,\n LangfuseGeneration,\n LangfuseSpan,\n} from \"./spanWrapper.js\";\nimport { getLangfuseTracer } from \"./tracerProvider.js\";\nimport {\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\nexport type {\n LangfuseObservationType,\n ObservationLevel,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\nexport * from \"./spanWrapper.js\";\nexport {\n createTraceAttributes,\n createSpanAttributes,\n createGenerationAttributes,\n} from \"./attributes.js\";\nexport {\n setLangfuseTracerProvider,\n getLangfuseTracerProvider,\n getLangfuseTracer,\n} from \"./tracerProvider.js\";\n\nexport { LangfuseOtelSpanAttributes } from \"@langfuse/core\";\n\n/**\n * Options for starting observations (spans, generations, events).\n *\n * @public\n */\nexport type StartObservationOptions = {\n /** Custom start time for the observation */\n startTime?: Date;\n /** Parent span context to attach this observation to */\n parentSpanContext?: SpanContext;\n};\n\n/**\n * Creates an OpenTelemetry span with the Langfuse tracer.\n *\n * @param params - Parameters for span creation\n * @returns The created OpenTelemetry span\n * @internal\n */\nfunction createOtelSpan(params: {\n name: string;\n startTime?: TimeInput;\n parentSpanContext?: SpanContext;\n}): Span {\n return getLangfuseTracer().startSpan(\n params.name,\n { startTime: params.startTime },\n createParentContext(params.parentSpanContext),\n );\n}\n\n/**\n * Creates a parent context from a span context.\n *\n * @param parentSpanContext - The span context to use as parent\n * @returns The created context or undefined if no parent provided\n * @internal\n */\nfunction createParentContext(\n parentSpanContext?: SpanContext,\n): Context | undefined {\n if (!parentSpanContext) return;\n\n return trace.setSpanContext(context.active(), parentSpanContext);\n}\n\n/**\n * Wraps a promise to automatically end the span when the promise resolves or rejects.\n *\n * @param promise - The promise to wrap\n * @param span - The span to end when promise completes\n * @returns The wrapped promise\n * @internal\n */\nfunction wrapPromise<T>(promise: Promise<T>, span: Span): Promise<T> {\n return promise.then(\n (value) => {\n span.end(); // End span AFTER Promise resolves\n\n return value;\n },\n (err: unknown) => {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end(); // End span AFTER Promise rejects\n\n throw err;\n },\n );\n}\n\n/**\n * Creates and starts a new Langfuse span for general-purpose tracing.\n *\n * Spans are used to track operations, functions, or logical units of work.\n * They can contain other spans or generations as children.\n *\n * @param name - Name of the span\n * @param attributes - Optional attributes to set on the span\n * @param options - Optional configuration for the span\n * @returns A LangfuseSpan instance\n *\n * @example\n * ```typescript\n * import { startSpan } from '@langfuse/tracing';\n *\n * const span = startSpan('data-processing', {\n * input: { userId: '123', data: {...} },\n * metadata: { version: '1.0' },\n * level: 'DEFAULT'\n * });\n *\n * try {\n * // Do some work\n * const result = await processData();\n *\n * span.update({ output: result });\n * } catch (error) {\n * span.update({\n * level: 'ERROR',\n * statusMessage: error.message\n * });\n * } finally {\n * span.end();\n * }\n * ```\n *\n * @public\n */\nexport function startSpan(\n name: string,\n attributes?: LangfuseSpanAttributes,\n options?: {\n startTime?: TimeInput;\n parentSpanContext?: SpanContext;\n },\n): LangfuseSpan {\n const otelSpan = createOtelSpan({\n name,\n ...options,\n });\n\n return new LangfuseSpan({ otelSpan, attributes });\n}\n\n/**\n * Creates and starts a new Langfuse generation for tracking LLM calls.\n *\n * Generations are specialized observations for tracking language model\n * interactions, including model parameters, usage metrics, and costs.\n *\n * @param name - Name of the generation (typically the model or operation)\n * @param attributes - Optional generation-specific attributes\n * @param options - Optional configuration for the generation\n * @returns A LangfuseGeneration instance\n *\n * @example\n * ```typescript\n * import { startGeneration } from '@langfuse/tracing';\n *\n * const generation = startGeneration('openai-gpt-4', {\n * input: [{ role: 'user', content: 'Hello, world!' }],\n * model: 'gpt-4',\n * modelParameters: {\n * temperature: 0.7,\n * max_tokens: 150\n * },\n * metadata: { feature: 'chat' }\n * });\n *\n * try {\n * const response = await callOpenAI(messages);\n *\n * generation.update({\n * output: response.choices[0].message,\n * usageDetails: {\n * promptTokens: response.usage.prompt_tokens,\n * completionTokens: response.usage.completion_tokens,\n * totalTokens: response.usage.total_tokens\n * }\n * });\n * } finally {\n * generation.end();\n * }\n * ```\n *\n * @public\n */\nexport function startGeneration(\n name: string,\n attributes?: LangfuseGenerationAttributes,\n options?: StartObservationOptions,\n): LangfuseGeneration {\n const otelSpan = createOtelSpan({\n name,\n ...options,\n });\n\n return new LangfuseGeneration({ otelSpan, attributes });\n}\n\n/**\n * Creates a Langfuse event for point-in-time occurrences.\n *\n * Events are used to capture instantaneous occurrences or log entries\n * within a trace. Unlike spans, they represent a single point in time.\n *\n * @param name - Name of the event\n * @param attributes - Optional attributes for the event\n * @param options - Optional configuration for the event\n * @returns A LangfuseEvent instance (automatically ended)\n *\n * @example\n * ```typescript\n * import { createEvent } from '@langfuse/tracing';\n *\n * // Log a user action\n * createEvent('user-click', {\n * input: { buttonId: 'submit', userId: '123' },\n * metadata: { page: '/checkout' },\n * level: 'DEFAULT'\n * });\n *\n * // Log an error\n * createEvent('api-error', {\n * level: 'ERROR',\n * statusMessage: 'Failed to fetch user data',\n * metadata: { endpoint: '/api/users/123', statusCode: 500 }\n * });\n * ```\n *\n * @public\n */\nexport function createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n options?: StartObservationOptions,\n) {\n const timestamp = options?.startTime ?? new Date();\n\n const otelSpan = createOtelSpan({\n name,\n ...options,\n startTime: timestamp,\n });\n\n return new LangfuseEvent({ otelSpan, attributes, timestamp });\n}\n\n/**\n * Starts an active span and executes a function within its context.\n *\n * This function creates a span, sets it as the active span in the OpenTelemetry\n * context, executes the provided function, and automatically ends the span.\n * Perfect for wrapping operations where you want child spans to be automatically\n * linked.\n *\n * @param name - Name of the span\n * @param fn - Function to execute within the span context\n * @param options - Optional configuration for the span\n * @returns The return value of the executed function\n *\n * @example\n * ```typescript\n * import { startActiveSpan } from '@langfuse/tracing';\n *\n * // Synchronous function\n * const result = startActiveSpan('calculate-metrics', (span) => {\n * span.update({ input: { data: rawData } });\n *\n * const metrics = calculateMetrics(rawData);\n * span.update({ output: metrics });\n *\n * return metrics;\n * });\n *\n * // Asynchronous function\n * const data = await startActiveSpan('fetch-user-data', async (span) => {\n * span.update({ input: { userId: '123' } });\n *\n * const userData = await api.getUser('123');\n * span.update({ output: userData });\n *\n * return userData;\n * });\n * ```\n *\n * @public\n */\nexport function startActiveSpan<F extends (span: LangfuseSpan) => unknown>(\n name: string,\n fn: F,\n options?: StartObservationOptions,\n): ReturnType<F> {\n return getLangfuseTracer().startActiveSpan(\n name,\n { startTime: options?.startTime },\n createParentContext(options?.parentSpanContext) ?? context.active(),\n (span) => {\n try {\n const result = fn(new LangfuseSpan({ otelSpan: span }));\n\n if (result instanceof Promise) {\n return wrapPromise(result, span) as ReturnType<F>;\n } else {\n span.end();\n\n return result as ReturnType<F>;\n }\n } catch (err) {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end();\n\n throw err;\n }\n },\n );\n}\n\n/**\n * Starts an active generation and executes a function within its context.\n *\n * Similar to startActiveSpan but creates a generation for tracking LLM calls.\n * The generation is automatically ended when the function completes.\n *\n * @param name - Name of the generation\n * @param fn - Function to execute within the generation context\n * @param options - Optional configuration for the generation\n * @returns The return value of the executed function\n *\n * @example\n * ```typescript\n * import { startActiveGeneration } from '@langfuse/tracing';\n *\n * const response = await startActiveGeneration('openai-completion', async (generation) => {\n * generation.update({\n * input: { messages: [...] },\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 }\n * });\n *\n * const result = await openai.chat.completions.create({...});\n *\n * generation.update({\n * output: result.choices[0].message,\n * usageDetails: result.usage\n * });\n *\n * return result;\n * });\n * ```\n *\n * @public\n */\nexport function startActiveGeneration<\n F extends (span: LangfuseGeneration) => unknown,\n>(name: string, fn: F, options?: StartObservationOptions): ReturnType<F> {\n return getLangfuseTracer().startActiveSpan(\n name,\n { startTime: options?.startTime },\n createParentContext(options?.parentSpanContext) ?? context.active(),\n (span) => {\n try {\n const result = fn(new LangfuseGeneration({ otelSpan: span }));\n\n if (result instanceof Promise) {\n return wrapPromise(result, span) as ReturnType<F>;\n } else {\n span.end();\n\n return result as ReturnType<F>;\n }\n } catch (err) {\n span\n .setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n })\n .end();\n\n throw err;\n }\n },\n );\n}\n\n/**\n * Updates the currently active trace with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with trace-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Trace attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveTrace } from '@langfuse/tracing';\n *\n * // Inside an active span context\n * updateActiveTrace({\n * name: 'user-workflow',\n * userId: '123',\n * sessionId: 'session-456',\n * tags: ['production', 'critical'],\n * public: true\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveTrace(attributes: LangfuseTraceAttributes) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping trace update.\",\n );\n\n return;\n }\n\n span.setAttributes(createTraceAttributes(attributes));\n}\n\n/**\n * Updates the currently active span with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with span-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Span attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveSpan } from '@langfuse/tracing';\n *\n * // Inside an active span context\n * updateActiveSpan({\n * level: 'WARNING',\n * statusMessage: 'Operation completed with warnings',\n * metadata: { warningCount: 3 }\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveSpan(attributes: LangfuseSpanAttributes) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping span update.\",\n );\n\n return;\n }\n\n span.setAttributes(createSpanAttributes(attributes));\n}\n\n/**\n * Updates the currently active generation with new attributes.\n *\n * This function finds the currently active OpenTelemetry span and updates\n * it with generation-level attributes. If no active span is found, a warning is logged.\n *\n * @param attributes - Generation attributes to set\n *\n * @example\n * ```typescript\n * import { updateActiveGeneration } from '@langfuse/tracing';\n *\n * // Inside an active generation context\n * updateActiveGeneration({\n * usageDetails: {\n * promptTokens: 50,\n * completionTokens: 100,\n * totalTokens: 150\n * },\n * costDetails: { totalCost: 0.003 }\n * });\n * ```\n *\n * @public\n */\nexport function updateActiveGeneration(\n attributes: LangfuseGenerationAttributes,\n) {\n const span = trace.getActiveSpan();\n\n if (!span) {\n getGlobalLogger().warn(\n \"No active OTEL span in context. Skipping generation update.\",\n );\n\n return;\n }\n\n span.setAttributes(createGenerationAttributes(attributes));\n}\n\n/**\n * Options for the observe decorator function.\n *\n * @public\n */\nexport interface ObserveOptions {\n /** Name for the observation (defaults to function name) */\n name?: string;\n /** Type of observation to create */\n asType?: \"span\" | \"generation\";\n /** Whether to capture function input as observation input */\n captureInput?: boolean;\n /** Whether to capture function output as observation output */\n captureOutput?: boolean;\n /** Parent span context to attach this observation to */\n parentSpanContext?: SpanContext;\n}\n\n/**\n * Decorator function that automatically wraps a function with Langfuse tracing.\n *\n * This function creates a wrapper around the provided function that automatically:\n * - Creates a span or generation when the function is called\n * - Captures input arguments (if enabled)\n * - Captures return value/output (if enabled)\n * - Handles errors and sets appropriate status\n * - Ends the observation when the function completes\n *\n * @param fn - The function to wrap with tracing\n * @param options - Configuration options for the observation\n * @returns A wrapped version of the function that includes tracing\n *\n * @example\n * ```typescript\n * import { observe } from '@langfuse/tracing';\n *\n * // Wrap a regular function\n * const processData = observe(\n * async (userId: string, data: any) => {\n * // Function implementation\n * return await processUserData(userId, data);\n * },\n * {\n * name: 'process-user-data',\n * asType: 'span',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Wrap an LLM call\n * const generateText = observe(\n * async (prompt: string) => {\n * return await openai.chat.completions.create({\n * model: 'gpt-4',\n * messages: [{ role: 'user', content: prompt }]\n * });\n * },\n * {\n * name: 'openai-generation',\n * asType: 'generation',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Usage\n * const result = await processData('123', { key: 'value' });\n * const text = await generateText('Hello, world!');\n * ```\n *\n * @public\n */\nexport function observe<T extends (...args: unknown[]) => unknown>(\n fn: T,\n options: ObserveOptions = {},\n): T {\n const {\n name = fn.name || \"anonymous-function\",\n asType = \"span\",\n captureInput = true,\n captureOutput = true,\n parentSpanContext = undefined,\n } = options;\n\n const wrappedFunction = function (\n this: any,\n ...args: Parameters<T>\n ): ReturnType<T> {\n // Prepare input data\n const inputData = captureInput ? _captureArguments(args) : undefined;\n\n // Create the appropriate observation type\n const observation =\n asType === \"generation\"\n ? startGeneration(name, inputData ? { input: inputData } : {}, {\n parentSpanContext,\n })\n : startSpan(name, inputData ? { input: inputData } : {}, {\n parentSpanContext,\n });\n\n // Set the observation span as active in the context\n const activeContext = trace.setSpan(context.active(), observation.otelSpan);\n\n try {\n const result = context.with(activeContext, () => fn.apply(this, args));\n\n // Handle async functions - check if result is a Promise\n // TODO: handle returned generators for streamed responses\n if (result instanceof Promise) {\n return result.then(\n (value) => {\n if (captureOutput) {\n observation.update({ output: _captureOutput(value) });\n }\n observation.end();\n\n return value;\n },\n (error: unknown) => {\n observation\n .update({\n level: \"ERROR\",\n statusMessage:\n (error instanceof Error ? error.message : String(error)) ||\n \"Function threw an error\",\n output: captureOutput ? { error: String(error) } : undefined,\n })\n .end();\n\n throw error;\n },\n ) as ReturnType<T>;\n } else {\n // Handle sync functions\n if (captureOutput) {\n observation.update({ output: _captureOutput(result) });\n }\n observation.end();\n\n return result as ReturnType<T>;\n }\n } catch (error: unknown) {\n observation\n .update({\n level: \"ERROR\",\n statusMessage:\n (error instanceof Error ? error.message : String(error)) ||\n \"Function threw an error\",\n output: captureOutput ? { error: String(error) } : undefined,\n })\n .end();\n\n throw error;\n }\n };\n\n return wrappedFunction as T;\n}\n\n/**\n * Helper function to safely capture function arguments.\n *\n * @param args - Function arguments array\n * @returns Captured arguments or error message\n * @internal\n */\nfunction _captureArguments(args: unknown[]): unknown {\n try {\n if (args.length === 0) return undefined;\n if (args.length === 1) return args[0];\n return args;\n } catch {\n return \"<failed to capture arguments>\";\n }\n}\n\n/**\n * Helper function to safely capture function output.\n *\n * @param value - Function return value\n * @returns Captured output or error message\n * @internal\n */\nfunction _captureOutput(value: unknown): unknown {\n try {\n // Handle undefined/null\n if (value === undefined || value === null) return value;\n\n // For primitive types, return as-is\n if (typeof value !== \"object\") return value;\n\n // For objects, return them directly (serialization happens in span processor)\n return value;\n } catch {\n return \"<failed to capture output>\";\n }\n}\n\n/**\n * Creates a trace ID for OpenTelemetry spans.\n *\n * @param seed - A seed string for deterministic trace ID generation.\n * If provided (non-empty), the same seed will always generate the same trace ID.\n * If empty or falsy, generates a random trace ID.\n *\n * Using a seed is especially useful when trying to correlate external,\n * non-W3C compliant IDs with Langfuse trace IDs. This allows you to later\n * have a method available for scoring the Langfuse trace given only the\n * external ID by regenerating the same trace ID from the external ID.\n *\n * @returns A Promise that resolves to a 32-character lowercase hexadecimal string suitable for use as an OpenTelemetry trace ID.\n *\n * @example\n * ```typescript\n * // Deterministic trace ID from seed\n * const traceId1 = await createTraceId(\"my-session-123\");\n * const traceId2 = await createTraceId(\"my-session-123\");\n * console.log(traceId1 === traceId2); // true\n *\n * // Random trace ID\n * const randomId1 = await createTraceId(\"\");\n * const randomId2 = await createTraceId(\"\");\n * console.log(randomId1 === randomId2); // false\n *\n * // Use with spans\n * const span = startSpan(\"my-span\", {}, {\n * parentSpanContext: {\n * traceId: await createTraceId(\"session-456\"),\n * spanId: \"0123456789abcdef\",\n * traceFlags: 1\n * }\n * });\n *\n * // Correlating external IDs with Langfuse traces\n * const externalId = \"ext-12345-67890\";\n * const traceId = await createTraceId(externalId);\n *\n * // Later, when you need to score this trace, regenerate the same ID\n * const scoringTraceId = await createTraceId(externalId);\n * console.log(traceId === scoringTraceId); // true - can now find and score the trace\n * ```\n *\n * @public\n */\nexport async function createTraceId(seed?: string): Promise<string> {\n if (seed) {\n const data = new TextEncoder().encode(seed);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n\n const hashArray = new Uint8Array(hashBuffer);\n\n return uint8ArrayToHex(hashArray).slice(0, 32);\n }\n\n const randomValues = crypto.getRandomValues(new Uint8Array(16));\n\n return uint8ArrayToHex(randomValues);\n}\n\n/**\n * Converts a Uint8Array to a hexadecimal string.\n *\n * @param array - The byte array to convert\n * @returns Hexadecimal string representation\n * @internal\n */\nfunction uint8ArrayToHex(array: Uint8Array): string {\n return Array.from(array)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Gets the current active trace ID.\n *\n * If there is no span in the current context, returns undefined.\n *\n * @returns The trace ID of the currently active span, or undefined if no span is active\n *\n * @public\n */\nexport function getActiveTraceId(): string | undefined {\n return trace.getActiveSpan()?.spanContext().traceId;\n}\n\n/**\n * Gets the current active observation ID.\n *\n * If there is no OTEL span in the current context, returns undefined.\n *\n * @returns The ID of the currently active OTEL span, or undefined if no OTEL span is active\n *\n * @public\n */\nexport function getActiveSpanId(): string | undefined {\n return trace.getActiveSpan()?.spanContext().spanId;\n}\n","import { LangfuseOtelSpanAttributes } from \"@langfuse/core\";\nimport { type Attributes } from \"@opentelemetry/api\";\n\nimport {\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\n/**\n * Creates OpenTelemetry attributes from Langfuse trace attributes.\n *\n * Converts user-friendly trace attributes into the internal OpenTelemetry\n * attribute format required by the span processor.\n *\n * @param attributes - Langfuse trace attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createTraceAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createTraceAttributes({\n * name: 'user-checkout-flow',\n * userId: 'user-123',\n * sessionId: 'session-456',\n * tags: ['checkout', 'payment'],\n * metadata: { version: '2.1.0' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createTraceAttributes({\n name,\n userId,\n sessionId,\n version,\n release,\n input,\n output,\n metadata,\n tags,\n environment,\n public: isPublic,\n}: LangfuseTraceAttributes = {}): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.TRACE_NAME]: name,\n [LangfuseOtelSpanAttributes.TRACE_USER_ID]: userId,\n [LangfuseOtelSpanAttributes.TRACE_SESSION_ID]: sessionId,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.RELEASE]: release,\n [LangfuseOtelSpanAttributes.TRACE_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.TRACE_OUTPUT]: _serialize(output),\n [LangfuseOtelSpanAttributes.TRACE_TAGS]: tags,\n [LangfuseOtelSpanAttributes.ENVIRONMENT]: environment,\n [LangfuseOtelSpanAttributes.TRACE_PUBLIC]: isPublic,\n ..._flattenAndSerializeMetadata(metadata, \"trace\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse span attributes.\n *\n * Converts user-friendly span attributes into the internal OpenTelemetry\n * attribute format required by the span processor.\n *\n * @param attributes - Langfuse span attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createSpanAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createSpanAttributes({\n * input: { query: 'SELECT * FROM users' },\n * output: { rowCount: 42 },\n * level: 'DEFAULT',\n * metadata: { database: 'prod' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createSpanAttributes({\n metadata,\n input,\n output,\n level,\n statusMessage,\n version,\n}: LangfuseSpanAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"span\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse generation attributes.\n *\n * Converts user-friendly generation attributes into the internal OpenTelemetry\n * attribute format required by the span processor. Includes special handling\n * for LLM-specific fields like model parameters, usage, and costs.\n *\n * @param attributes - Langfuse generation attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createGenerationAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createGenerationAttributes({\n * input: [{ role: 'user', content: 'Hello!' }],\n * output: { role: 'assistant', content: 'Hi there!' },\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 },\n * usageDetails: {\n * promptTokens: 10,\n * completionTokens: 15,\n * totalTokens: 25\n * },\n * costDetails: { totalCost: 0.001 }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createGenerationAttributes({\n completionStartTime,\n metadata,\n level,\n statusMessage,\n version,\n model,\n modelParameters,\n input,\n output,\n usageDetails,\n costDetails,\n prompt,\n}: LangfuseGenerationAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"generation\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n [LangfuseOtelSpanAttributes.OBSERVATION_MODEL]: model,\n [LangfuseOtelSpanAttributes.OBSERVATION_USAGE_DETAILS]:\n _serialize(usageDetails),\n [LangfuseOtelSpanAttributes.OBSERVATION_COST_DETAILS]:\n _serialize(costDetails),\n [LangfuseOtelSpanAttributes.OBSERVATION_COMPLETION_START_TIME]:\n _serialize(completionStartTime),\n [LangfuseOtelSpanAttributes.OBSERVATION_MODEL_PARAMETERS]:\n _serialize(modelParameters),\n ...(prompt && !prompt.isFallback\n ? {\n [LangfuseOtelSpanAttributes.OBSERVATION_PROMPT_NAME]: prompt.name,\n [LangfuseOtelSpanAttributes.OBSERVATION_PROMPT_VERSION]:\n prompt.version,\n }\n : {}),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n ) as Attributes;\n}\n\n/**\n * Creates OpenTelemetry attributes from Langfuse event attributes.\n *\n * Converts user-friendly event attributes into the internal OpenTelemetry\n * attribute format required by the span processor. Events are point-in-time\n * observations that are automatically ended when created.\n *\n * @param attributes - Langfuse event attributes to convert\n * @returns OpenTelemetry attributes object with non-null values\n *\n * @example\n * ```typescript\n * import { createEventAttributes } from '@langfuse/tracing';\n *\n * const otelAttributes = createEventAttributes({\n * input: { action: 'button_click', elementId: 'submit' },\n * level: 'DEFAULT',\n * metadata: { page: '/checkout', userId: '123' }\n * });\n *\n * span.setAttributes(otelAttributes);\n * ```\n *\n * @public\n */\nexport function createEventAttributes({\n metadata,\n input,\n output,\n level,\n statusMessage,\n version,\n}: LangfuseSpanAttributes): Attributes {\n const attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: \"event\",\n [LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: level,\n [LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: statusMessage,\n [LangfuseOtelSpanAttributes.VERSION]: version,\n [LangfuseOtelSpanAttributes.OBSERVATION_INPUT]: _serialize(input),\n [LangfuseOtelSpanAttributes.OBSERVATION_OUTPUT]: _serialize(output),\n ..._flattenAndSerializeMetadata(metadata, \"observation\"),\n };\n\n return Object.fromEntries(\n Object.entries(attributes).filter(([_, v]) => v != null),\n );\n}\n\n/**\n * Safely serializes an object to JSON string.\n *\n * @param obj - Object to serialize\n * @returns JSON string or undefined if null/undefined, error message if serialization fails\n * @internal\n */\nfunction _serialize(obj: unknown): string | undefined {\n try {\n return obj != null ? JSON.stringify(obj) : undefined;\n } catch {\n return \"<failed to serialize>\";\n }\n}\n\n/**\n * Flattens and serializes metadata into OpenTelemetry attribute format.\n *\n * Converts nested metadata objects into dot-notation attribute keys.\n * For example, `{ database: { host: 'localhost' } }` becomes\n * `{ 'langfuse.metadata.database.host': 'localhost' }`.\n *\n * @param metadata - Metadata object to flatten\n * @param type - Whether this is for observation or trace metadata\n * @returns Flattened metadata attributes\n * @internal\n */\nfunction _flattenAndSerializeMetadata(\n metadata: unknown,\n type: \"observation\" | \"trace\",\n): Record<string, string> {\n const prefix =\n type === \"observation\"\n ? LangfuseOtelSpanAttributes.OBSERVATION_METADATA\n : LangfuseOtelSpanAttributes.TRACE_METADATA;\n\n const metadataAttributes: Record<string, string> = {};\n\n if (metadata === undefined || metadata === null) {\n return metadataAttributes;\n }\n\n if (typeof metadata !== \"object\" || Array.isArray(metadata)) {\n const serialized = _serialize(metadata);\n if (serialized) {\n metadataAttributes[prefix] = serialized;\n }\n } else {\n for (const [key, value] of Object.entries(metadata)) {\n const serialized = typeof value === \"string\" ? value : _serialize(value);\n if (serialized) {\n metadataAttributes[`${prefix}.${key}`] = serialized;\n }\n }\n }\n\n return metadataAttributes;\n}\n","import {\n getGlobalLogger,\n LANGFUSE_SDK_VERSION,\n LANGFUSE_TRACER_NAME,\n} from \"@langfuse/core\";\nimport { TracerProvider, trace } from \"@opentelemetry/api\";\n\nconst LANGFUSE_GLOBAL_SYMBOL = Symbol.for(\"langfuse\");\n\ntype LangfuseGlobalState = {\n isolatedTracerProvider: TracerProvider | null;\n};\n\nfunction createState(): LangfuseGlobalState {\n return {\n isolatedTracerProvider: null,\n };\n}\n\ninterface GlobalThis {\n [LANGFUSE_GLOBAL_SYMBOL]?: LangfuseGlobalState;\n}\n\nfunction getGlobalState(): LangfuseGlobalState {\n const initialState = createState();\n\n try {\n const g = globalThis as typeof globalThis & GlobalThis;\n\n if (typeof g !== \"object\" || g === null) {\n getGlobalLogger().warn(\n \"globalThis is not available, using fallback state\",\n );\n return initialState;\n }\n\n if (!g[LANGFUSE_GLOBAL_SYMBOL]) {\n Object.defineProperty(g, LANGFUSE_GLOBAL_SYMBOL, {\n value: initialState,\n writable: false, // lock the slot (not the contents)\n configurable: false,\n enumerable: false,\n });\n }\n\n return g[LANGFUSE_GLOBAL_SYMBOL]!;\n } catch (err) {\n if (err instanceof Error) {\n getGlobalLogger().error(`Failed to access global state: ${err.message}`);\n } else {\n getGlobalLogger().error(`Failed to access global state: ${String(err)}`);\n }\n\n return initialState;\n }\n}\n\n/**\n * Sets an isolated TracerProvider for Langfuse tracing operations.\n *\n * This allows Langfuse to use its own TracerProvider instance, separate from\n * the global OpenTelemetry TracerProvider. This is useful for avoiding conflicts\n * with other OpenTelemetry instrumentation in the application.\n *\n * ⚠️ **Limitation: Span Context Sharing**\n *\n * While this function isolates span processing and export, it does NOT provide\n * complete trace isolation. OpenTelemetry context (trace IDs, parent spans) is\n * still shared between the global and isolated providers. This means:\n *\n * - Spans created with the isolated provider inherit trace IDs from global spans\n * - Spans created with the isolated provider inherit parent relationships from global spans\n * - This can result in spans from different providers being part of the same logical trace\n *\n * **Why this happens:**\n * OpenTelemetry uses a global context propagation mechanism that operates at the\n * JavaScript runtime level, independent of individual TracerProvider instances.\n * The context (containing trace ID, span ID) flows through async boundaries and\n * is inherited by all spans created within that context, regardless of which\n * TracerProvider creates them.\n *\n * @example\n * ```typescript\n * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';\n * import { LangfuseSpanProcessor } from '@langfuse/otel';\n * import { setLangfuseTracerProvider } from '@langfuse/tracing';\n *\n * // Create provider with span processors in constructor\n * const provider = new NodeTracerProvider({\n * spanProcessors: [new LangfuseSpanProcessor()]\n * });\n *\n * setLangfuseTracerProvider(provider);\n *\n * // Note: Spans created with getLangfuseTracer() may still inherit\n * // context from spans created with the global tracer\n * ```\n *\n * @param provider - The TracerProvider instance to use, or null to clear the isolated provider\n * @public\n */\nexport function setLangfuseTracerProvider(provider: TracerProvider | null) {\n getGlobalState().isolatedTracerProvider = provider;\n}\n\n/**\n * Gets the TracerProvider for Langfuse tracing operations.\n *\n * Returns the isolated TracerProvider if one has been set via setLangfuseTracerProvider(),\n * otherwise falls back to the global OpenTelemetry TracerProvider.\n *\n * @example\n * ```typescript\n * import { getLangfuseTracerProvider } from '@langfuse/tracing';\n *\n * const provider = getLangfuseTracerProvider();\n * const tracer = provider.getTracer('my-tracer', '1.0.0');\n * ```\n *\n * @returns The TracerProvider instance to use for Langfuse tracing\n * @public\n */\nexport function getLangfuseTracerProvider(): TracerProvider {\n const { isolatedTracerProvider } = getGlobalState();\n\n if (isolatedTracerProvider) return isolatedTracerProvider;\n\n return trace.getTracerProvider();\n}\n\n/**\n * Gets the OpenTelemetry tracer instance for Langfuse.\n *\n * This function returns a tracer specifically configured for Langfuse\n * with the correct tracer name and version. Used internally by all\n * Langfuse tracing functions to ensure consistent trace creation.\n *\n * @returns The Langfuse OpenTelemetry tracer instance\n *\n * @example\n * ```typescript\n * import { getLangfuseTracer } from '@langfuse/tracing';\n *\n * const tracer = getLangfuseTracer();\n * const span = tracer.startSpan('my-operation');\n * ```\n *\n * @public\n */\nexport function getLangfuseTracer() {\n return getLangfuseTracerProvider().getTracer(\n LANGFUSE_TRACER_NAME,\n LANGFUSE_SDK_VERSION,\n );\n}\n","import { Span, TimeInput } from \"@opentelemetry/api\";\n\nimport {\n createEventAttributes,\n createGenerationAttributes,\n createSpanAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport { getLangfuseTracer } from \"./tracerProvider.js\";\nimport {\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\nimport { createEvent, startGeneration, startSpan } from \"./index.js\";\n\n/**\n * Union type representing any Langfuse observation wrapper.\n *\n * Used when you need to accept any type of Langfuse observation\n * (span, generation, or event).\n *\n * @public\n */\nexport type LangfuseObservation =\n | LangfuseSpan\n | LangfuseGeneration\n | LangfuseEvent;\n\n/**\n * Parameters for creating a Langfuse span wrapper.\n *\n * @internal\n */\ntype LangfuseSpanWrapperParams = {\n otelSpan: Span;\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes;\n};\n\n/**\n * Base class for all Langfuse observation wrappers.\n *\n * Provides common functionality for spans, generations, and events including\n * access to the underlying OpenTelemetry span, span ID, trace ID, and basic\n * operations like ending the observation and updating trace attributes.\n *\n * @internal\n */\nabstract class LangfuseSpanWrapper {\n /** The underlying OpenTelemetry span */\n public readonly otelSpan: Span;\n /** The span ID from the OpenTelemetry span context */\n public id: string;\n /** The trace ID from the OpenTelemetry span context */\n public traceId: string;\n\n constructor(params: LangfuseSpanWrapperParams) {\n this.otelSpan = params.otelSpan;\n this.id = params.otelSpan.spanContext().spanId;\n this.traceId = params.otelSpan.spanContext().traceId;\n }\n\n /** Gets the Langfuse OpenTelemetry tracer instance */\n protected get tracer() {\n return getLangfuseTracer();\n }\n\n /**\n * Ends the observation, marking it as complete.\n *\n * @param endTime - Optional end time, defaults to current time\n */\n public end(endTime?: TimeInput) {\n this.otelSpan.end(endTime);\n }\n\n /**\n * Updates the parent trace with new attributes.\n *\n * This sets trace-level attributes that apply to the entire trace,\n * not just this specific observation.\n *\n * @param attributes - Trace attributes to set\n * @returns This observation for method chaining\n */\n public updateTrace(attributes: LangfuseTraceAttributes) {\n this.otelSpan.setAttributes(createTraceAttributes(attributes));\n\n return this;\n }\n}\n\n/**\n * Parameters for creating a Langfuse span.\n *\n * @internal\n */\ntype LangfuseSpanParams = {\n otelSpan: Span;\n attributes?: LangfuseSpanAttributes;\n};\n\n/**\n * Langfuse span wrapper for general-purpose tracing.\n *\n * Spans are used to track operations, functions, or logical units of work.\n * They can contain other spans, generations, or events as children and have\n * a duration from start to end.\n *\n * @public\n */\nexport class LangfuseSpan extends LangfuseSpanWrapper {\n constructor(params: LangfuseSpanParams) {\n super(params);\n if (params.attributes) {\n this.otelSpan.setAttributes(createSpanAttributes(params.attributes));\n }\n }\n\n /**\n * Updates this span with new attributes.\n *\n * @param attributes - Span attributes to set\n * @returns This span for method chaining\n *\n * @example\n * ```typescript\n * span.update({\n * output: { result: 'success' },\n * level: 'DEFAULT',\n * metadata: { duration: 150 }\n * });\n * ```\n */\n public update(attributes: LangfuseSpanAttributes): LangfuseSpan {\n this.otelSpan.setAttributes(createSpanAttributes(attributes));\n\n return this;\n }\n\n /**\n * Starts a new child span within this span.\n *\n * @param name - Name of the child span\n * @param attributes - Optional attributes for the child span\n * @returns The new child span\n *\n * @example\n * ```typescript\n * const childSpan = parentSpan.startSpan('database-query', {\n * input: { query: 'SELECT * FROM users' },\n * metadata: { database: 'primary' }\n * });\n * ```\n */\n public startSpan(\n name: string,\n attributes?: LangfuseSpanAttributes,\n ): LangfuseSpan {\n return startSpan(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n\n /**\n * Starts a new child generation within this span.\n *\n * @param name - Name of the generation (typically the model name)\n * @param attributes - Optional generation-specific attributes\n * @returns The new child generation\n *\n * @example\n * ```typescript\n * const generation = parentSpan.startGeneration('gpt-4', {\n * input: [{ role: 'user', content: 'Hello!' }],\n * model: 'gpt-4',\n * modelParameters: { temperature: 0.7 }\n * });\n * ```\n */\n public startGeneration(\n name: string,\n attributes?: LangfuseGenerationAttributes,\n ): LangfuseGeneration {\n return startGeneration(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n\n /**\n * Creates a new event within this span.\n *\n * Events are point-in-time occurrences and are automatically ended.\n *\n * @param name - Name of the event\n * @param attributes - Optional event attributes\n * @returns The created event (already ended)\n *\n * @example\n * ```typescript\n * parentSpan.createEvent('user-action', {\n * input: { action: 'click', button: 'submit' },\n * metadata: { userId: '123' }\n * });\n * ```\n */\n public createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n ): LangfuseEvent {\n return createEvent(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n}\n\n/**\n * Parameters for creating a Langfuse generation.\n *\n * @internal\n */\ntype LangfuseGenerationParams = {\n otelSpan: Span;\n attributes?: LangfuseGenerationAttributes;\n};\n\n/**\n * Langfuse generation wrapper for tracking LLM interactions.\n *\n * Generations are specialized observations for tracking language model\n * calls, including model parameters, usage metrics, costs, and prompts.\n *\n * @public\n */\nexport class LangfuseGeneration extends LangfuseSpanWrapper {\n constructor(params: LangfuseGenerationParams) {\n super(params);\n if (params.attributes) {\n this.otelSpan.setAttributes(\n createGenerationAttributes(params.attributes),\n );\n }\n }\n\n /**\n * Updates this generation with new attributes.\n *\n * @param attributes - Generation attributes to set\n * @returns This generation for method chaining\n *\n * @example\n * ```typescript\n * generation.update({\n * output: { role: 'assistant', content: 'Hello there!' },\n * usageDetails: {\n * promptTokens: 10,\n * completionTokens: 15,\n * totalTokens: 25\n * },\n * costDetails: { totalCost: 0.001 }\n * });\n * ```\n */\n update(attributes: LangfuseGenerationAttributes): LangfuseGeneration {\n this.otelSpan.setAttributes(createGenerationAttributes(attributes));\n\n return this;\n }\n\n /**\n * Creates a new event within this generation.\n *\n * Events are point-in-time occurrences and are automatically ended.\n *\n * @param name - Name of the event\n * @param attributes - Optional event attributes\n * @returns The created event (already ended)\n *\n * @example\n * ```typescript\n * generation.createEvent('token-limit-reached', {\n * level: 'WARNING',\n * metadata: { requestedTokens: 2000, maxTokens: 1500 }\n * });\n * ```\n */\n createEvent(\n name: string,\n attributes?: LangfuseEventAttributes,\n ): LangfuseEvent {\n return createEvent(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n}\n\n/**\n * Parameters for creating a Langfuse event.\n *\n * @internal\n */\ntype LangfuseEventParams = {\n otelSpan: Span;\n attributes?: LangfuseEventAttributes;\n timestamp: TimeInput;\n};\n\n/**\n * Langfuse event wrapper for point-in-time observations.\n *\n * Events represent instantaneous occurrences or log entries within a trace.\n * Unlike spans and generations, they don't have duration and are automatically\n * ended when created.\n *\n * @public\n */\nexport class LangfuseEvent extends LangfuseSpanWrapper {\n constructor(params: LangfuseEventParams) {\n super(params);\n\n if (params.attributes) {\n this.otelSpan.setAttributes(createEventAttributes(params.attributes));\n }\n\n // Events are automatically ended at their timestamp\n this.otelSpan.end(params.timestamp);\n }\n}\n"],"mappings":"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","names":["getGlobalLogger","trace","LangfuseOtelSpanAttributes","trace","getGlobalLogger"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langfuse/tracing",
3
- "version": "4.0.0-beta.2",
3
+ "version": "4.0.0-beta.3",
4
4
  "author": "Langfuse",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -23,7 +23,7 @@
23
23
  "dist"
24
24
  ],
25
25
  "dependencies": {
26
- "@langfuse/core": "^4.0.0-beta.2"
26
+ "@langfuse/core": "^4.0.0-beta.3"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "@opentelemetry/api": "^1.9.0"