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

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/README.md ADDED
@@ -0,0 +1,24 @@
1
+ ![GitHub Banner](https://github.com/langfuse/langfuse-js/assets/2834609/d1613347-445f-4e91-9e84-428fda9c3659)
2
+
3
+ # @langfuse/tracing
4
+
5
+ This is the tracing package of the Langfuse JS SDK containing the instrumentation methods for instrumenting your LLM app such as `startActiveSpan`, `startActiveGeneration`, and the `observe` wrapper.
6
+
7
+ ## Packages
8
+
9
+ | Package | NPM | Description | Environments |
10
+ | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------ |
11
+ | [@langfuse/client](./packages/client) | [![NPM](https://img.shields.io/npm/v/@langfuse/client.svg)](https://www.npmjs.com/package/@langfuse/client) | Langfuse API client for universal JavaScript environments | Universal JS |
12
+ | [@langfuse/tracing](./packages/tracing) | [![NPM](https://img.shields.io/npm/v/@langfuse/tracing.svg)](https://www.npmjs.com/package/@langfuse/tracing) | Langfuse instrumentation methods based on OpenTelemetry | Node.js 20+ |
13
+ | [@langfuse/otel](./packages/otel) | [![NPM](https://img.shields.io/npm/v/@langfuse/otel.svg)](https://www.npmjs.com/package/@langfuse/otel) | Langfuse OpenTelemetry export helpers | Node.js 20+ |
14
+ | [@langfuse/openai](./packages/openai) | [![NPM](https://img.shields.io/npm/v/@langfuse/openai.svg)](https://www.npmjs.com/package/@langfuse/openai) | Langfuse integration for OpenAI SDK | Universal JS |
15
+ | [@langfuse/langchain](./packages/langchain) | [![NPM](https://img.shields.io/npm/v/@langfuse/langchain.svg)](https://www.npmjs.com/package/@langfuse/langchain) | Langfuse integration for LangChain | Universal JS |
16
+
17
+ ## Documentation
18
+
19
+ - Docs: https://langfuse.com/docs/sdk/typescript
20
+ - Reference: https://js.reference.langfuse.com
21
+
22
+ ## License
23
+
24
+ [MIT](LICENSE)
package/dist/index.cjs CHANGED
@@ -195,12 +195,27 @@ var LangfuseSpanWrapper = class {
195
195
  this.id = params.otelSpan.spanContext().spanId;
196
196
  this.traceId = params.otelSpan.spanContext().traceId;
197
197
  }
198
+ /** Gets the Langfuse OpenTelemetry tracer instance */
198
199
  get tracer() {
199
200
  return getLangfuseTracer();
200
201
  }
202
+ /**
203
+ * Ends the observation, marking it as complete.
204
+ *
205
+ * @param endTime - Optional end time, defaults to current time
206
+ */
201
207
  end(endTime) {
202
208
  this.otelSpan.end(endTime);
203
209
  }
210
+ /**
211
+ * Updates the parent trace with new attributes.
212
+ *
213
+ * This sets trace-level attributes that apply to the entire trace,
214
+ * not just this specific observation.
215
+ *
216
+ * @param attributes - Trace attributes to set
217
+ * @returns This observation for method chaining
218
+ */
204
219
  updateTrace(attributes) {
205
220
  this.otelSpan.setAttributes(createTraceAttributes(attributes));
206
221
  return this;
@@ -213,20 +228,83 @@ var LangfuseSpan = class extends LangfuseSpanWrapper {
213
228
  this.otelSpan.setAttributes(createSpanAttributes(params.attributes));
214
229
  }
215
230
  }
231
+ /**
232
+ * Updates this span with new attributes.
233
+ *
234
+ * @param attributes - Span attributes to set
235
+ * @returns This span for method chaining
236
+ *
237
+ * @example
238
+ * ```typescript
239
+ * span.update({
240
+ * output: { result: 'success' },
241
+ * level: 'DEFAULT',
242
+ * metadata: { duration: 150 }
243
+ * });
244
+ * ```
245
+ */
216
246
  update(attributes) {
217
247
  this.otelSpan.setAttributes(createSpanAttributes(attributes));
218
248
  return this;
219
249
  }
250
+ /**
251
+ * Starts a new child span within this span.
252
+ *
253
+ * @param name - Name of the child span
254
+ * @param attributes - Optional attributes for the child span
255
+ * @returns The new child span
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * const childSpan = parentSpan.startSpan('database-query', {
260
+ * input: { query: 'SELECT * FROM users' },
261
+ * metadata: { database: 'primary' }
262
+ * });
263
+ * ```
264
+ */
220
265
  startSpan(name, attributes) {
221
266
  return startSpan(name, attributes, {
222
267
  parentSpanContext: this.otelSpan.spanContext()
223
268
  });
224
269
  }
270
+ /**
271
+ * Starts a new child generation within this span.
272
+ *
273
+ * @param name - Name of the generation (typically the model name)
274
+ * @param attributes - Optional generation-specific attributes
275
+ * @returns The new child generation
276
+ *
277
+ * @example
278
+ * ```typescript
279
+ * const generation = parentSpan.startGeneration('gpt-4', {
280
+ * input: [{ role: 'user', content: 'Hello!' }],
281
+ * model: 'gpt-4',
282
+ * modelParameters: { temperature: 0.7 }
283
+ * });
284
+ * ```
285
+ */
225
286
  startGeneration(name, attributes) {
226
287
  return startGeneration(name, attributes, {
227
288
  parentSpanContext: this.otelSpan.spanContext()
228
289
  });
229
290
  }
291
+ /**
292
+ * Creates a new event within this span.
293
+ *
294
+ * Events are point-in-time occurrences and are automatically ended.
295
+ *
296
+ * @param name - Name of the event
297
+ * @param attributes - Optional event attributes
298
+ * @returns The created event (already ended)
299
+ *
300
+ * @example
301
+ * ```typescript
302
+ * parentSpan.createEvent('user-action', {
303
+ * input: { action: 'click', button: 'submit' },
304
+ * metadata: { userId: '123' }
305
+ * });
306
+ * ```
307
+ */
230
308
  createEvent(name, attributes) {
231
309
  return createEvent(name, attributes, {
232
310
  parentSpanContext: this.otelSpan.spanContext()
@@ -242,10 +320,46 @@ var LangfuseGeneration = class extends LangfuseSpanWrapper {
242
320
  );
243
321
  }
244
322
  }
323
+ /**
324
+ * Updates this generation with new attributes.
325
+ *
326
+ * @param attributes - Generation attributes to set
327
+ * @returns This generation for method chaining
328
+ *
329
+ * @example
330
+ * ```typescript
331
+ * generation.update({
332
+ * output: { role: 'assistant', content: 'Hello there!' },
333
+ * usageDetails: {
334
+ * promptTokens: 10,
335
+ * completionTokens: 15,
336
+ * totalTokens: 25
337
+ * },
338
+ * costDetails: { totalCost: 0.001 }
339
+ * });
340
+ * ```
341
+ */
245
342
  update(attributes) {
246
343
  this.otelSpan.setAttributes(createGenerationAttributes(attributes));
247
344
  return this;
248
345
  }
346
+ /**
347
+ * Creates a new event within this generation.
348
+ *
349
+ * Events are point-in-time occurrences and are automatically ended.
350
+ *
351
+ * @param name - Name of the event
352
+ * @param attributes - Optional event attributes
353
+ * @returns The created event (already ended)
354
+ *
355
+ * @example
356
+ * ```typescript
357
+ * generation.createEvent('token-limit-reached', {
358
+ * level: 'WARNING',
359
+ * metadata: { requestedTokens: 2000, maxTokens: 1500 }
360
+ * });
361
+ * ```
362
+ */
249
363
  createEvent(name, attributes) {
250
364
  return createEvent(name, attributes, {
251
365
  parentSpanContext: this.otelSpan.spanContext()
@@ -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\nexport type StartObservationOptions = {\n startTime?: Date;\n parentSpanContext?: SpanContext;\n};\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\nfunction createParentContext(\n parentSpanContext?: SpanContext,\n): Context | undefined {\n if (!parentSpanContext) return;\n\n return trace.setSpanContext(context.active(), parentSpanContext);\n}\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\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\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\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\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\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\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\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\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\nexport interface ObserveOptions {\n name?: string;\n asType?: \"span\" | \"generation\";\n captureInput?: boolean;\n captureOutput?: boolean;\n}\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// Helper function to safely capture function arguments\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// Helper function to safely capture function output\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 */\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\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\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\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\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\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\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\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\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\nexport type LangfuseObservation =\n | LangfuseSpan\n | LangfuseGeneration\n | LangfuseEvent;\n\ntype LangfuseSpanWrapperParams = {\n otelSpan: Span;\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes;\n};\n\nabstract class LangfuseSpanWrapper {\n public readonly otelSpan: Span;\n public id: string;\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 protected get tracer() {\n return getLangfuseTracer();\n }\n\n public end(endTime?: TimeInput) {\n this.otelSpan.end(endTime);\n }\n\n public updateTrace(attributes: LangfuseTraceAttributes) {\n this.otelSpan.setAttributes(createTraceAttributes(attributes));\n\n return this;\n }\n}\n\ntype LangfuseSpanParams = {\n otelSpan: Span;\n attributes?: LangfuseSpanAttributes;\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 public update(attributes: LangfuseSpanAttributes): LangfuseSpan {\n this.otelSpan.setAttributes(createSpanAttributes(attributes));\n\n return this;\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 public startGeneration(\n name: string,\n attributes?: LangfuseGenerationAttributes,\n ): LangfuseGeneration {\n return startGeneration(name, attributes, {\n parentSpanContext: this.otelSpan.spanContext(),\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\ntype LangfuseGenerationParams = {\n otelSpan: Span;\n attributes?: LangfuseGenerationAttributes;\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 update(attributes: LangfuseGenerationAttributes): LangfuseGeneration {\n this.otelSpan.setAttributes(createGenerationAttributes(attributes));\n\n return this;\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\ntype LangfuseEventParams = {\n otelSpan: Span;\n attributes?: LangfuseEventAttributes;\n timestamp: TimeInput;\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 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/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"]}