@elasticdash/tracing 0.0.3 → 0.0.5

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/attributes.ts","../src/tracerProvider.ts","../src/spanWrapper.ts"],"sourcesContent":["import { getGlobalLogger, LangfuseOtelSpanAttributes } from \"@elasticdash/core\";\nimport {\n trace,\n context,\n TimeInput,\n SpanStatusCode,\n Span,\n Context,\n SpanContext,\n} from \"@opentelemetry/api\";\n\nimport {\n createObservationAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport {\n LangfuseAgent,\n LangfuseEvent,\n LangfuseGeneration,\n LangfuseSpan,\n LangfuseTool,\n LangfuseChain,\n LangfuseEmbedding,\n LangfuseEvaluator,\n LangfuseGuardrail,\n LangfuseRetriever,\n LangfuseObservation,\n} from \"./spanWrapper.js\";\nimport { getLangfuseTracer } from \"./tracerProvider.js\";\nimport {\n LangfuseChainAttributes,\n LangfuseEmbeddingAttributes,\n LangfuseEvaluatorAttributes,\n LangfuseGuardrailAttributes,\n LangfuseRetrieverAttributes,\n LangfuseToolAttributes,\n LangfuseAgentAttributes,\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseObservationType,\n LangfuseSpanAttributes,\n LangfuseTraceAttributes,\n LangfuseObservationAttributes,\n} from \"./types.js\";\n\nexport type {\n LangfuseObservationType,\n ObservationLevel,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseObservationAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\nexport * from \"./spanWrapper.js\";\nexport {\n createTraceAttributes,\n createObservationAttributes,\n} from \"./attributes.js\";\nexport {\n setLangfuseTracerProvider,\n getLangfuseTracerProvider,\n getLangfuseTracer,\n} from \"./tracerProvider.js\";\nexport {\n propagateAttributes,\n type PropagateAttributesParams,\n} from \"@elasticdash/core\";\n\nexport { LangfuseOtelSpanAttributes } from \"@elasticdash/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 * Options for starting an observations set to active in context\n *\n * Extends StartObservationOptions with additional context-specific configuration.\n *\n * @public\n */\nexport type StartActiveObservationContext = StartObservationOptions & {\n /** Whether to automatically end the observation when exiting the context. Default is true */\n endOnExit?: boolean;\n};\n\n/**\n * Options for startObservation function.\n *\n * @public\n */\nexport type StartObservationOpts = StartObservationOptions & {\n /** Type of observation to create. Defaults to 'span' */\n asType?: LangfuseObservationType;\n};\n\n/**\n * Options for startActiveObservation function.\n *\n * @public\n */\nexport type StartActiveObservationOpts = StartActiveObservationContext & {\n /** Type of observation to create. Defaults to 'span' */\n asType?: LangfuseObservationType;\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>(\n promise: Promise<T>,\n span: Span,\n endOnExit: boolean | undefined,\n): Promise<T> {\n return promise.then(\n (value) => {\n if (endOnExit !== false) {\n span.end(); // End span AFTER Promise resolves\n }\n\n return value;\n },\n (err: unknown) => {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n });\n\n if (endOnExit !== false) {\n span.end(); // End span AFTER Promise rejects\n }\n\n throw err;\n },\n );\n}\n\n// Function overloads for proper type inference\nexport function startObservation(\n name: string,\n attributes: LangfuseGenerationAttributes,\n options: StartObservationOpts & { asType: \"generation\" },\n): LangfuseGeneration;\nexport function startObservation(\n name: string,\n attributes: LangfuseEventAttributes,\n options: StartObservationOpts & { asType: \"event\" },\n): LangfuseEvent;\nexport function startObservation(\n name: string,\n attributes: LangfuseAgentAttributes,\n options: StartObservationOpts & { asType: \"agent\" },\n): LangfuseAgent;\nexport function startObservation(\n name: string,\n attributes: LangfuseToolAttributes,\n options: StartObservationOpts & { asType: \"tool\" },\n): LangfuseTool;\nexport function startObservation(\n name: string,\n attributes: LangfuseChainAttributes,\n options: StartObservationOpts & { asType: \"chain\" },\n): LangfuseChain;\nexport function startObservation(\n name: string,\n attributes: LangfuseRetrieverAttributes,\n options: StartObservationOpts & { asType: \"retriever\" },\n): LangfuseRetriever;\nexport function startObservation(\n name: string,\n attributes: LangfuseEvaluatorAttributes,\n options: StartObservationOpts & { asType: \"evaluator\" },\n): LangfuseEvaluator;\nexport function startObservation(\n name: string,\n attributes: LangfuseGuardrailAttributes,\n options: StartObservationOpts & { asType: \"guardrail\" },\n): LangfuseGuardrail;\nexport function startObservation(\n name: string,\n attributes: LangfuseEmbeddingAttributes,\n options: StartObservationOpts & { asType: \"embedding\" },\n): LangfuseEmbedding;\nexport function startObservation(\n name: string,\n attributes?: LangfuseSpanAttributes,\n options?: StartObservationOpts & { asType?: \"span\" },\n): LangfuseSpan;\n/**\n * Creates and starts a new Langfuse observation with automatic TypeScript type inference.\n *\n * This is the primary method for creating observations in Langfuse. It supports multiple\n * observation types with full TypeScript type safety - the return type is automatically\n * inferred based on the `asType` parameter.\n *\n * ## Supported Observation Types\n * - **span** (default): General-purpose operations, functions, or workflows\n * - **generation**: LLM calls, text generation, or AI model interactions\n * - **embedding**: Text embedding generation or vector operations\n * - **agent**: AI agent workflows with tool usage and decision making\n * - **tool**: Individual tool calls, API requests, or function invocations\n * - **chain**: Multi-step processes like RAG pipelines or sequential operations\n * - **retriever**: Document retrieval, vector search, or knowledge base queries\n * - **evaluator**: Quality assessment, scoring, or evaluation operations\n * - **guardrail**: Safety checks, content filtering, or validation operations\n * - **event**: Point-in-time occurrences or log entries (automatically ended)\n *\n * @param name - Descriptive name for the observation (e.g., 'openai-gpt-4', 'vector-search')\n * @param attributes - Type-specific attributes (input, output, metadata, etc.)\n * @param options - Configuration options including observation type and timing\n * @returns Strongly-typed observation object based on `asType` parameter\n *\n * @example\n * ```typescript\n * import { startObservation } from '@elasticdash/tracing';\n *\n * // Span for general operations (default)\n * const span = startObservation('user-workflow', {\n * input: { userId: '123', action: 'checkout' },\n * metadata: { version: '2.1.0', feature: 'new-checkout' }\n * });\n * span.update({ output: { success: true, orderId: '456' } });\n * span.end();\n *\n * // Generation for LLM interactions\n * const generation = startObservation('openai-gpt-4', {\n * input: [{ role: 'user', content: 'Explain quantum computing' }],\n * model: 'gpt-4-turbo',\n * modelParameters: { temperature: 0.7, maxTokens: 500 }\n * }, { asType: 'generation' });\n *\n * generation.update({\n * output: { role: 'assistant', content: 'Quantum computing...' },\n * usageDetails: { promptTokens: 12, completionTokens: 150, totalTokens: 162 },\n * costDetails: { totalCost: 0.002, currency: 'USD' }\n * });\n * generation.end();\n *\n * // Agent for AI workflows with tools\n * const agent = startObservation('research-agent', {\n * input: { query: 'Latest developments in renewable energy' },\n * metadata: { tools: ['web-search', 'pdf-reader'], model: 'gpt-4' }\n * }, { asType: 'agent' });\n *\n * // Tool for individual API calls\n * const weatherTool = startObservation('weather-api', {\n * input: { location: 'San Francisco', units: 'metric' },\n * metadata: { provider: 'openweather', timeout: 5000 }\n * }, { asType: 'tool' });\n *\n * // Chain for multi-step RAG pipeline\n * const ragChain = startObservation('rag-qa-pipeline', {\n * input: { question: 'How does photosynthesis work?' },\n * metadata: { steps: ['retrieve', 'rerank', 'generate'], vectorDb: 'pinecone' }\n * }, { asType: 'chain' });\n *\n * // Retriever for vector search\n * const retriever = startObservation('vector-search', {\n * input: { query: 'machine learning algorithms', topK: 5 },\n * metadata: { vectorStore: 'chroma', similarity: 'cosine' }\n * }, { asType: 'retriever' });\n *\n * // Evaluator for quality assessment\n * const evaluator = startObservation('quality-check', {\n * input: {\n * response: 'Paris is the capital of France',\n * reference: 'The capital city of France is Paris'\n * },\n * metadata: { metric: 'semantic-similarity', threshold: 0.8 }\n * }, { asType: 'evaluator' });\n *\n * // Guardrail for content filtering\n * const guardrail = startObservation('content-filter', {\n * input: { text: 'User message content', policies: ['no-profanity', 'no-pii'] },\n * metadata: { strictMode: true, version: 'v2' }\n * }, { asType: 'guardrail' });\n *\n * // Embedding for text vectorization\n * const embedding = startObservation('text-embedder', {\n * input: { texts: ['Hello world', 'Machine learning'] },\n * model: 'text-embedding-ada-002',\n * metadata: { dimensions: 1536 }\n * }, { asType: 'embedding' });\n *\n * // Event for point-in-time occurrences (auto-ended)\n * const event = startObservation('user-login', {\n * input: { userId: '123', method: 'oauth' },\n * level: 'DEFAULT',\n * metadata: { ip: '192.168.1.1', userAgent: 'Chrome/120.0' }\n * }, { asType: 'event' });\n *\n * // Nested observations with parent context\n * const parentSpan = startObservation('ai-pipeline');\n * const childRetriever = startObservation('doc-search', {\n * input: { query: 'AI safety' }\n * }, {\n * asType: 'retriever',\n * parentSpanContext: parentSpan.otelSpan.spanContext()\n * });\n * ```\n *\n * @see {@link startActiveObservation} for function-scoped observations with automatic context management\n * @see {@link observe} for decorator-style observation wrapping\n *\n * @public\n */\nexport function startObservation(\n name: string,\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes\n | LangfuseAgentAttributes\n | LangfuseToolAttributes\n | LangfuseChainAttributes\n | LangfuseRetrieverAttributes\n | LangfuseEvaluatorAttributes\n | LangfuseGuardrailAttributes\n | LangfuseEmbeddingAttributes,\n options?: StartObservationOpts,\n): LangfuseObservation {\n const { asType = \"span\", ...observationOptions } = options || {};\n\n const otelSpan = createOtelSpan({\n name,\n ...observationOptions,\n });\n\n switch (asType) {\n case \"generation\":\n return new LangfuseGeneration({\n otelSpan,\n attributes,\n });\n\n case \"embedding\":\n return new LangfuseEmbedding({\n otelSpan,\n attributes,\n });\n\n case \"agent\":\n return new LangfuseAgent({\n otelSpan,\n attributes,\n });\n\n case \"tool\":\n return new LangfuseTool({\n otelSpan,\n attributes,\n });\n\n case \"chain\":\n return new LangfuseChain({\n otelSpan,\n attributes,\n });\n\n case \"retriever\":\n return new LangfuseRetriever({\n otelSpan,\n attributes,\n });\n\n case \"evaluator\":\n return new LangfuseEvaluator({\n otelSpan,\n attributes,\n });\n\n case \"guardrail\":\n return new LangfuseGuardrail({\n otelSpan,\n attributes,\n });\n\n case \"event\": {\n const timestamp = observationOptions?.startTime ?? new Date();\n\n return new LangfuseEvent({\n otelSpan,\n attributes: attributes as LangfuseEventAttributes,\n timestamp,\n });\n }\n case \"span\":\n default:\n return new LangfuseSpan({\n otelSpan,\n attributes: attributes as LangfuseSpanAttributes,\n });\n }\n}\n\n// Function overloads for proper type inference\nexport function startActiveObservation<\n F extends (generation: LangfuseGeneration) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"generation\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (embedding: LangfuseEmbedding) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"embedding\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (agent: LangfuseAgent) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"agent\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (tool: LangfuseTool) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"tool\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (chain: LangfuseChain) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"chain\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (retriever: LangfuseRetriever) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"retriever\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (evaluator: LangfuseEvaluator) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"evaluator\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (guardrail: LangfuseGuardrail) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"guardrail\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (span: LangfuseSpan) => unknown,\n>(\n name: string,\n fn: F,\n options?: StartActiveObservationOpts & { asType?: \"span\" },\n): ReturnType<F>;\n/**\n * Starts an active observation and executes a function within its context with automatic lifecycle management.\n *\n * This function creates an observation, sets it as the active span in the OpenTelemetry context,\n * executes your function with the observation instance, and automatically handles cleanup.\n * It supports all observation types with full TypeScript type inference based on `asType`.\n *\n * ## Key Features\n * - **Automatic Context Management**: Sets the observation as active in the current execution context\n * - **Lifecycle Automation**: Creates, activates, and ends observations automatically\n * - **Type Safety**: Function parameter is strongly typed based on `asType`\n * - **Promise Support**: Handles both synchronous and asynchronous functions seamlessly\n * - **Error Handling**: Automatically sets error status and ends observations on exceptions\n * - **Nested Observations**: Child observations created within the function inherit the context\n *\n * ## When to Use\n * - When you want automatic observation lifecycle management\n * - For function-scoped operations where the observation maps to the function's execution\n * - When you need the observation to be active for child operations\n * - For async operations where manual `.end()` calls are error-prone\n *\n * @param name - Descriptive name for the observation\n * @param fn - Function to execute within the observation context (receives typed observation instance)\n * @param options - Configuration options including observation type and lifecycle settings\n * @returns The exact return value of the executed function (preserves type and async behavior)\n *\n * @example\n * ```typescript\n * import { startActiveObservation } from '@elasticdash/tracing';\n *\n * // Span for general operations (default)\n * const result = startActiveObservation('user-checkout', (span) => {\n * span.update({ input: { userId: '123', cart: items } });\n *\n * // Any child observations created here inherit this span's context\n * const validation = processPayment(paymentData);\n *\n * span.update({ output: { orderId: 'ord_456', success: true } });\n * return validation;\n * });\n *\n * // Generation for LLM interactions with automatic error handling\n * const response = await startActiveObservation(\n * 'openai-completion',\n * async (generation) => {\n * generation.update({\n * input: { messages: [{ role: 'user', content: 'Explain AI ethics' }] },\n * model: 'gpt-4-turbo',\n * modelParameters: { temperature: 0.7, maxTokens: 500 }\n * });\n *\n * try {\n * const result = await openai.chat.completions.create({\n * model: 'gpt-4-turbo',\n * messages: [{ role: 'user', content: 'Explain AI ethics' }],\n * temperature: 0.7,\n * max_tokens: 500\n * });\n *\n * generation.update({\n * output: result.choices[0].message,\n * usageDetails: {\n * promptTokens: result.usage?.prompt_tokens,\n * completionTokens: result.usage?.completion_tokens,\n * totalTokens: result.usage?.total_tokens\n * },\n * costDetails: { totalCost: 0.002, currency: 'USD' }\n * });\n *\n * return result.choices[0].message.content;\n * } catch (error) {\n * generation.update({\n * level: 'ERROR',\n * statusMessage: error.message,\n * output: { error: error.message }\n * });\n * throw error;\n * }\n * },\n * { asType: 'generation' }\n * );\n *\n * // Agent workflow with nested tool calls\n * const agentResult = await startActiveObservation(\n * 'research-agent',\n * async (agent) => {\n * agent.update({\n * input: { query: 'Latest climate change research' },\n * metadata: { tools: ['web-search', 'arxiv-search'], model: 'gpt-4' }\n * });\n *\n * // Tool calls inherit the agent context automatically\n * const webResults = await startActiveObservation(\n * 'web-search-tool',\n * async (tool) => {\n * tool.update({ input: { query: 'climate change 2024' } });\n * const results = await searchWeb('climate change 2024');\n * tool.update({ output: results });\n * return results;\n * },\n * { asType: 'tool' }\n * );\n *\n * const analysis = await analyzeResults(webResults);\n *\n * agent.update({\n * output: { analysis, sources: webResults.length },\n * metadata: { processingTime: Date.now() }\n * });\n *\n * return analysis;\n * },\n * { asType: 'agent' }\n * );\n *\n * // RAG Chain with retriever and generation steps\n * const answer = await startActiveObservation(\n * 'rag-qa-chain',\n * async (chain) => {\n * chain.update({\n * input: { question: 'How does photosynthesis work?' },\n * metadata: { vectorDb: 'pinecone', model: 'gpt-4' }\n * });\n *\n * // Retrieval step\n * const docs = await startActiveObservation(\n * 'vector-retrieval',\n * async (retriever) => {\n * retriever.update({\n * input: { query: 'photosynthesis mechanism', topK: 5 },\n * metadata: { similarity: 'cosine' }\n * });\n * const results = await vectorSearch('photosynthesis mechanism');\n * retriever.update({ output: { documents: results } });\n * return results;\n * },\n * { asType: 'retriever' }\n * );\n *\n * // Generation step\n * const response = await startActiveObservation(\n * 'answer-generation',\n * async (generation) => {\n * const context = docs.map(d => d.content).join('\\n');\n * generation.update({\n * input: { question: 'How does photosynthesis work?', context },\n * model: 'gpt-4'\n * });\n *\n * const answer = await generateAnswer(context);\n * generation.update({ output: { answer } });\n * return answer;\n * },\n * { asType: 'generation' }\n * );\n *\n * chain.update({\n * output: { answer: response, sources: docs.length }\n * });\n *\n * return response;\n * },\n * { asType: 'chain' }\n * );\n *\n * // Quality evaluation with automatic metrics\n * const evaluation = startActiveObservation(\n * 'response-evaluator',\n * (evaluator) => {\n * evaluator.update({\n * input: {\n * response: 'Paris is the capital of France.',\n * reference: 'The capital city of France is Paris.'\n * },\n * metadata: { metric: 'semantic-similarity' }\n * });\n *\n * const score = calculateSimilarity(response, reference);\n * const passed = score > 0.8;\n *\n * evaluator.update({\n * output: { score, passed, grade: passed ? 'excellent' : 'needs_improvement' }\n * });\n *\n * return { score, passed };\n * },\n * { asType: 'evaluator' }\n * );\n *\n * // Content filtering with guardrails\n * const safetyCheck = startActiveObservation(\n * 'content-guardrail',\n * (guardrail) => {\n * guardrail.update({\n * input: { text: userMessage, policies: ['no-profanity', 'no-pii'] },\n * metadata: { strictMode: true }\n * });\n *\n * const violations = checkContent(userMessage);\n * const allowed = violations.length === 0;\n *\n * guardrail.update({\n * output: { allowed, violations, confidence: 0.95 }\n * });\n *\n * return { allowed, violations };\n * },\n * { asType: 'guardrail' }\n * );\n *\n * // Text embedding generation\n * const embeddings = await startActiveObservation(\n * 'text-embeddings',\n * async (embedding) => {\n * const texts = ['Hello world', 'Machine learning'];\n * embedding.update({\n * input: { texts },\n * model: 'text-embedding-ada-002',\n * metadata: { dimensions: 1536 }\n * });\n *\n * const vectors = await generateEmbeddings(texts);\n *\n * embedding.update({\n * output: { embeddings: vectors },\n * usageDetails: { totalTokens: texts.join(' ').split(' ').length }\n * });\n *\n * return vectors;\n * },\n * { asType: 'embedding' }\n * );\n *\n * // Disable automatic ending (advanced use case)\n * const longRunningSpan = await startActiveObservation(\n * 'background-process',\n * async (span) => {\n * span.update({ input: { taskId: '123' } });\n *\n * // Process continues after function returns\n * startBackgroundTask(span);\n *\n * return 'process-started';\n * },\n * { asType: 'span', endOnExit: false } // Manual ending required\n * );\n * ```\n *\n * @see {@link startObservation} for manual observation lifecycle management\n * @see {@link observe} for decorator-style function wrapping\n *\n * @public\n */\nexport function startActiveObservation<\n F extends (observation: LangfuseSpan | LangfuseGeneration) => unknown,\n>(name: string, fn: F, options?: StartActiveObservationOpts): ReturnType<F> {\n const { asType = \"span\", ...observationOptions } = options || {};\n\n return getLangfuseTracer().startActiveSpan(\n name,\n { startTime: observationOptions?.startTime },\n createParentContext(observationOptions?.parentSpanContext) ??\n context.active(),\n (span) => {\n try {\n let observation: LangfuseObservation;\n\n switch (asType) {\n case \"generation\":\n observation = new LangfuseGeneration({\n otelSpan: span,\n });\n break;\n\n case \"embedding\":\n observation = new LangfuseEmbedding({\n otelSpan: span,\n });\n break;\n\n case \"agent\":\n observation = new LangfuseAgent({\n otelSpan: span,\n });\n break;\n\n case \"tool\":\n observation = new LangfuseTool({\n otelSpan: span,\n });\n break;\n\n case \"chain\":\n observation = new LangfuseChain({\n otelSpan: span,\n });\n break;\n\n case \"retriever\":\n observation = new LangfuseRetriever({\n otelSpan: span,\n });\n break;\n\n case \"evaluator\":\n observation = new LangfuseEvaluator({\n otelSpan: span,\n });\n break;\n\n case \"guardrail\":\n observation = new LangfuseGuardrail({\n otelSpan: span,\n });\n break;\n\n case \"event\": {\n const timestamp = observationOptions?.startTime ?? new Date();\n observation = new LangfuseEvent({\n otelSpan: span,\n timestamp,\n });\n break;\n }\n case \"span\":\n default:\n observation = new LangfuseSpan({\n otelSpan: span,\n });\n }\n\n const result = fn(observation as Parameters<F>[0]);\n\n if (result instanceof Promise) {\n return wrapPromise(\n result,\n span,\n observationOptions?.endOnExit,\n ) as ReturnType<F>;\n } else {\n if (observationOptions?.endOnExit !== false) {\n span.end();\n }\n\n return result as ReturnType<F>;\n }\n } catch (err) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n });\n\n if (observationOptions?.endOnExit !== false) {\n span.end();\n }\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 '@elasticdash/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 observation with new attributes.\n *\n * This function finds the currently active OpenTelemetry span in the execution context\n * and updates it with Langfuse-specific attributes. It supports all observation types\n * through TypeScript overloads, providing type safety for attributes based on the\n * specified `asType` parameter. If no active span exists, the update is skipped with a warning.\n *\n * ## Type Safety\n * - Automatic type inference based on `asType` parameter\n * - Compile-time validation of attribute compatibility\n * - IntelliSense support for observation-specific attributes\n *\n * ## Context Requirements\n * - Must be called within an active OpenTelemetry span context\n * - Typically used inside `startActiveObservation` callbacks or manual span contexts\n * - Relies on OpenTelemetry's context propagation mechanism\n *\n * ## Supported Observation Types\n * - **span** (default): General-purpose operations and workflows\n * - **generation**: LLM calls and AI model interactions\n * - **agent**: AI agent workflows with tool usage\n * - **tool**: Individual tool calls and API requests\n * - **chain**: Multi-step processes and pipelines\n * - **retriever**: Document retrieval and search operations\n * - **evaluator**: Quality assessment and scoring\n * - **guardrail**: Safety checks and content filtering\n * - **embedding**: Text embedding and vector operations\n *\n * @param attributes - Observation-specific attributes to update (type varies by observation type)\n * @param options - Configuration specifying observation type (defaults to 'span')\n *\n * @example\n * ```typescript\n * import { updateActiveObservation, startActiveObservation } from '@elasticdash/tracing';\n *\n * // Update active span (default)\n * await startActiveObservation('data-processing', async (observation) => {\n * // Process data...\n * const result = await processData(inputData);\n *\n * // Update with results\n * updateActiveObservation({\n * output: { processedRecords: result.count },\n * metadata: { processingTime: result.duration }\n * });\n * });\n *\n * // Update active generation\n * await startActiveObservation('llm-call', async () => {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4',\n * messages: [{ role: 'user', content: 'Hello' }]\n * });\n *\n * // Update with LLM-specific attributes\n * updateActiveObservation({\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 * costDetails: {\n * totalCost: 0.025,\n * currency: 'USD'\n * }\n * }, { asType: 'generation' });\n * }, {}, { asType: 'generation' });\n *\n * // Update active tool execution\n * await startActiveObservation('web-search', async () => {\n * const results = await searchAPI('latest news');\n *\n * updateActiveObservation({\n * output: {\n * results: results,\n * count: results.length,\n * relevanceScore: 0.89\n * },\n * metadata: {\n * searchLatency: 150,\n * cacheHit: false\n * }\n * }, { asType: 'tool' });\n * }, {}, { asType: 'tool' });\n *\n * // Update active agent workflow\n * await startActiveObservation('research-agent', async () => {\n * // Agent performs multiple operations...\n * const findings = await conductResearch();\n *\n * updateActiveObservation({\n * output: {\n * completed: true,\n * toolsUsed: ['web-search', 'summarizer'],\n * iterationsRequired: 3,\n * confidence: 0.92\n * },\n * metadata: {\n * efficiency: 0.85,\n * qualityScore: 0.88\n * }\n * }, { asType: 'agent' });\n * }, {}, { asType: 'agent' });\n *\n * // Update active chain workflow\n * await startActiveObservation('rag-pipeline', async () => {\n * // Execute multi-step RAG process...\n * const finalResponse = await executeRAGPipeline();\n *\n * updateActiveObservation({\n * output: {\n * finalResponse: finalResponse,\n * stepsCompleted: 4,\n * documentsRetrieved: 8,\n * qualityScore: 0.91\n * },\n * metadata: {\n * pipelineEfficiency: 0.87,\n * totalLatency: 3200\n * }\n * }, { asType: 'chain' });\n * }, {}, { asType: 'chain' });\n * ```\n *\n * @see {@link startActiveObservation} - For creating active observation contexts\n * @see {@link updateActiveTrace} - For updating trace-level attributes\n *\n * @public\n */\nexport function updateActiveObservation(\n attributes: LangfuseSpanAttributes,\n options?: { asType: \"span\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseGenerationAttributes,\n options: { asType: \"generation\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseAgentAttributes,\n options: { asType: \"agent\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseToolAttributes,\n options: { asType: \"tool\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseChainAttributes,\n options: { asType: \"chain\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseEmbeddingAttributes,\n options: { asType: \"embedding\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseEvaluatorAttributes,\n options: { asType: \"evaluator\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseGuardrailAttributes,\n options: { asType: \"guardrail\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseRetrieverAttributes,\n options: { asType: \"retriever\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseObservationAttributes,\n options?: { asType?: LangfuseObservationType },\n): void {\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 const otelAttributes = createObservationAttributes(\n options?.asType ?? \"span\",\n attributes,\n );\n\n // If no 'asType' was provided, drop the observation type OTEL attribute\n // to avoid inadvertendly overwriting the type to \"span\"\n if (!options?.asType) {\n otelAttributes[LangfuseOtelSpanAttributes.OBSERVATION_TYPE] = undefined;\n }\n\n span.setAttributes(otelAttributes);\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?: LangfuseObservationType;\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 /** Whether to automatically end the observation when exiting the context. Default is true */\n endOnExit?: boolean;\n}\n\n/**\n * Decorator function that automatically wraps any function with Langfuse observability.\n *\n * This higher-order function creates a traced version of your function that automatically\n * handles observation lifecycle, input/output capture, and error tracking. It's perfect\n * for instrumenting existing functions without modifying their internal logic.\n *\n * ## Key Features\n * - **Zero Code Changes**: Wrap existing functions without modifying their implementation\n * - **Automatic I/O Capture**: Optionally captures function arguments and return values\n * - **Error Tracking**: Automatically captures exceptions and sets error status\n * - **Type Preservation**: Maintains original function signature and return types\n * - **Async Support**: Works seamlessly with both sync and async functions\n * - **Flexible Configuration**: Control observation type, naming, and capture behavior\n *\n * ## Use Cases\n * - Instrumenting business logic functions\n * - Wrapping API calls and external service interactions\n * - Adding observability to utility functions\n * - Creating traced versions of third-party functions\n * - Decorating class methods for observability\n *\n * @param fn - The function to wrap with observability (preserves original signature)\n * @param options - Configuration for observation behavior and capture settings\n * @returns An instrumented version of the function with identical behavior plus tracing\n *\n * @example\n * ```typescript\n * import { observe } from '@elasticdash/tracing';\n *\n * // Basic function wrapping with automatic I/O capture\n * const processOrder = observe(\n * async (orderId: string, items: CartItem[]) => {\n * const validation = await validateOrder(orderId, items);\n * const payment = await processPayment(validation);\n * const shipping = await scheduleShipping(payment);\n * return { orderId, status: 'confirmed', trackingId: shipping.id };\n * },\n * {\n * name: 'process-order',\n * asType: 'span',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // LLM function with generation tracking\n * const generateSummary = observe(\n * async (document: string, maxWords: number = 100) => {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4-turbo',\n * messages: [\n * { role: 'system', content: `Summarize in ${maxWords} words or less` },\n * { role: 'user', content: document }\n * ],\n * max_tokens: maxWords * 2\n * });\n * return response.choices[0].message.content;\n * },\n * {\n * name: 'document-summarizer',\n * asType: 'generation',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Database query with automatic error tracking\n * const fetchUserProfile = observe(\n * async (userId: string) => {\n * const user = await db.users.findUnique({ where: { id: userId } });\n * if (!user) throw new Error(`User ${userId} not found`);\n *\n * const preferences = await db.preferences.findMany({\n * where: { userId }\n * });\n *\n * return { ...user, preferences };\n * },\n * {\n * name: 'fetch-user-profile',\n * asType: 'span',\n * captureInput: false, // Don't capture sensitive user IDs\n * captureOutput: true\n * }\n * );\n *\n * // Vector search with retriever semantics\n * const searchDocuments = observe(\n * async (query: string, topK: number = 5) => {\n * const embedding = await embedText(query);\n * const results = await vectorDb.search(embedding, topK);\n * return results.map(r => ({\n * content: r.metadata.content,\n * score: r.score,\n * source: r.metadata.source\n * }));\n * },\n * {\n * name: 'document-search',\n * asType: 'retriever',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Quality evaluation function\n * const evaluateResponse = observe(\n * (response: string, reference: string, metric: string = 'similarity') => {\n * let score: number;\n *\n * switch (metric) {\n * case 'similarity':\n * score = calculateCosineSimilarity(response, reference);\n * break;\n * case 'bleu':\n * score = calculateBleuScore(response, reference);\n * break;\n * default:\n * throw new Error(`Unknown metric: ${metric}`);\n * }\n *\n * return {\n * score,\n * passed: score > 0.8,\n * metric,\n * grade: score > 0.9 ? 'excellent' : score > 0.7 ? 'good' : 'needs_improvement'\n * };\n * },\n * {\n * name: 'response-evaluator',\n * asType: 'evaluator',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Content moderation with guardrails\n * const moderateContent = observe(\n * async (text: string, policies: string[] = ['profanity', 'spam']) => {\n * const violations = [];\n *\n * for (const policy of policies) {\n * const result = await checkPolicy(text, policy);\n * if (result.violation) {\n * violations.push({ policy, severity: result.severity });\n * }\n * }\n *\n * return {\n * allowed: violations.length === 0,\n * violations,\n * confidence: 0.95\n * };\n * },\n * {\n * name: 'content-moderator',\n * asType: 'guardrail',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // AI agent function with tool usage\n * const researchAgent = observe(\n * async (query: string, maxSources: number = 3) => {\n * // Search for relevant documents\n * const documents = await searchDocuments(query, maxSources * 2);\n *\n * // Filter and rank results\n * const topDocs = documents\n * .filter(d => d.score > 0.7)\n * .slice(0, maxSources);\n *\n * // Generate comprehensive answer\n * const context = topDocs.map(d => d.content).join('\\n\\n');\n * const answer = await generateSummary(\n * `Based on: ${context}\\n\\nQuestion: ${query}`,\n * 200\n * );\n *\n * return {\n * answer,\n * sources: topDocs.map(d => d.source),\n * confidence: Math.min(...topDocs.map(d => d.score))\n * };\n * },\n * {\n * name: 'research-agent',\n * asType: 'agent',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Class method decoration\n * class UserService {\n * private db: Database;\n *\n * // Wrap methods during class construction\n * constructor(database: Database) {\n * this.db = database;\n * this.createUser = observe(this.createUser.bind(this), {\n * name: 'create-user',\n * asType: 'span',\n * captureInput: false, // Sensitive data\n * captureOutput: true\n * });\n * }\n *\n * async createUser(userData: UserData) {\n * // Implementation automatically traced\n * return await this.db.users.create(userData);\n * }\n * }\n *\n * // Chain composition - functions remain composable\n * const processDocument = observe(\n * async (document: string) => {\n * const summary = await generateSummary(document, 150);\n * const moderation = await moderateContent(summary);\n * const evaluation = evaluateResponse(summary, document, 'similarity');\n *\n * return {\n * summary: moderation.allowed ? summary : '[Content Filtered]',\n * safe: moderation.allowed,\n * quality: evaluation.score\n * };\n * },\n * {\n * name: 'document-processor',\n * asType: 'chain',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Usage - functions work exactly as before, just with observability\n * const order = await processOrder('ord_123', cartItems);\n * const profile = await fetchUserProfile('user_456');\n * const research = await researchAgent('What is quantum computing?');\n * const processed = await processDocument(documentText);\n * ```\n *\n * @see {@link startObservation} for manual observation creation\n * @see {@link startActiveObservation} for function-scoped observations\n *\n * @public\n */\nexport function observe<T extends (...args: any[]) => any>(\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 = startObservation(\n name,\n inputData ? { input: inputData } : {},\n {\n asType: asType as \"span\", // typecast necessary as ts cannot narrow down type\n parentSpanContext,\n },\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 if (result instanceof Promise) {\n return result.then(\n (value) => {\n if (captureOutput) {\n observation.update({ output: _captureOutput(value) });\n }\n\n if (options?.endOnExit !== false) {\n observation.end();\n }\n\n return value;\n },\n (error: unknown) => {\n observation.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\n if (options?.endOnExit !== false) {\n observation.end();\n }\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\n if (options?.endOnExit !== false) {\n observation.end();\n }\n\n return result as ReturnType<T>;\n }\n } catch (error: unknown) {\n observation.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\n if (options?.endOnExit !== false) {\n observation.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 = startObservation(\"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 \"@elasticdash/core\";\nimport { type Attributes } from \"@opentelemetry/api\";\n\nimport {\n LangfuseObservationAttributes,\n LangfuseObservationType,\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 '@elasticdash/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\nexport function createObservationAttributes(\n type: LangfuseObservationType,\n attributes: LangfuseObservationAttributes,\n): Attributes {\n const {\n metadata,\n input,\n output,\n level,\n statusMessage,\n version,\n completionStartTime,\n model,\n modelParameters,\n usageDetails,\n costDetails,\n prompt,\n } = attributes;\n\n let otelAttributes: Attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: type,\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(otelAttributes).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 if (typeof obj === \"string\") return obj;\n\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 \"@elasticdash/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 '@elasticdash/otel';\n * import { setLangfuseTracerProvider } from '@elasticdash/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 '@elasticdash/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 '@elasticdash/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 createObservationAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport { getLangfuseTracer } from \"./tracerProvider.js\";\nimport {\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\nimport type {\n LangfuseAgentAttributes,\n LangfuseChainAttributes,\n LangfuseEmbeddingAttributes,\n LangfuseEvaluatorAttributes,\n LangfuseGuardrailAttributes,\n LangfuseObservationAttributes,\n LangfuseObservationType,\n LangfuseRetrieverAttributes,\n LangfuseToolAttributes,\n} from \"./types.js\";\n\nimport { startObservation } from \"./index.js\";\n\n/**\n * Union type representing any Langfuse observation wrapper.\n *\n * This type encompasses all observation types supported by Langfuse, providing\n * a unified interface for handling different kinds of traced operations. It's\n * particularly useful for generic functions that work with any observation type.\n *\n * ## Included Types\n * - **LangfuseSpan**: General-purpose operations and workflows\n * - **LangfuseGeneration**: LLM calls and AI model interactions\n * - **LangfuseEmbedding**: Text embedding and vector operations\n * - **LangfuseAgent**: AI agent workflows with tool usage\n * - **LangfuseTool**: Individual tool calls and API requests\n * - **LangfuseChain**: Multi-step processes and pipelines\n * - **LangfuseRetriever**: Document retrieval and search operations\n * - **LangfuseEvaluator**: Quality assessment and scoring\n * - **LangfuseGuardrail**: Safety checks and content filtering\n * - **LangfuseEvent**: Point-in-time occurrences and log entries\n *\n * @example\n * ```typescript\n * // Function accepting any observation type\n * function logObservation(obs: LangfuseObservation) {\n * console.log(`Observation ${obs.id} in trace ${obs.traceId}`);\n *\n * // All observations have common methods\n * obs.updateTrace({ tags: ['logged'] });\n * obs.end();\n * }\n *\n * // Works with any observation type\n * const span = startObservation('test-span');\n * const generation = startObservation('llm-call', {}, { asType: 'generation' });\n * const agent = startObservation('ai-agent', {}, { asType: 'agent' });\n *\n * logObservation(span);\n * logObservation(generation);\n * logObservation(agent);\n * ```\n *\n * @public\n */\nexport type LangfuseObservation =\n | LangfuseSpan\n | LangfuseGeneration\n | LangfuseEvent\n | LangfuseAgent\n | LangfuseTool\n | LangfuseChain\n | LangfuseRetriever\n | LangfuseEvaluator\n | LangfuseGuardrail\n | LangfuseEmbedding;\n\n/**\n * Parameters for creating a Langfuse observation wrapper.\n *\n * @internal\n */\ntype LangfuseObservationParams = {\n otelSpan: Span;\n type: LangfuseObservationType;\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes;\n};\n\n/**\n * Base class for all Langfuse observation wrappers providing unified functionality.\n *\n * This abstract class serves as the foundation for all observation types in Langfuse,\n * encapsulating common operations and properties shared across spans, generations,\n * events, and specialized observation types like agents, tools, and chains.\n *\n * ## Core Capabilities\n * - **OpenTelemetry Integration**: Wraps OTEL spans with Langfuse-specific functionality\n * - **Unique Identification**: Provides span ID and trace ID for correlation\n * - **Lifecycle Management**: Handles observation creation, updates, and completion\n * - **Trace Context**: Enables updating trace-level attributes from any observation\n * - **Hierarchical Structure**: Supports creating nested child observations\n * - **Type Safety**: Ensures type-safe attribute handling based on observation type\n *\n * ## Common Properties\n * - `id`: Unique identifier for this observation (OpenTelemetry span ID)\n * - `traceId`: Identifier of the parent trace containing this observation\n * - `otelSpan`: Direct access to the underlying OpenTelemetry span\n * - `type`: The observation type (span, generation, event, etc.)\n *\n * ## Common Methods\n * - `end()`: Marks the observation as complete with optional timestamp\n * - `updateTrace()`: Sets trace-level attributes like user ID, session ID, tags\n * - `startObservation()`: Creates child observations with inherited context\n *\n * @example\n * ```typescript\n * // All observation types share these common capabilities\n * const observation: LangfuseObservation = startObservation('my-operation');\n *\n * // Common properties available on all observations\n * console.log(`Observation ID: ${observation.id}`);\n * console.log(`Trace ID: ${observation.traceId}`);\n * console.log(`Type: ${observation.type}`);\n *\n * // Common methods available on all observations\n * observation.updateTrace({\n * userId: 'user-123',\n * sessionId: 'session-456',\n * tags: ['production', 'api-v2']\n * });\n *\n * // Create child observations\n * const child = observation.startObservation('child-operation', {\n * input: { step: 'processing' }\n * });\n *\n * // End observations\n * child.end();\n * observation.end();\n * ```\n *\n * @internal\n */\nabstract class LangfuseBaseObservation {\n /** The underlying OpenTelemetry span */\n public readonly otelSpan: Span;\n /** The underlying OpenTelemetry span */\n public readonly type: LangfuseObservationType;\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: LangfuseObservationParams) {\n this.otelSpan = params.otelSpan;\n this.id = params.otelSpan.spanContext().spanId;\n this.traceId = params.otelSpan.spanContext().traceId;\n this.type = params.type;\n\n if (params.attributes) {\n this.otelSpan.setAttributes(\n createObservationAttributes(params.type, params.attributes),\n );\n }\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 updateOtelSpanAttributes(attributes: LangfuseObservationAttributes) {\n this.otelSpan.setAttributes(\n createObservationAttributes(this.type, attributes),\n );\n }\n\n /**\n * Updates the parent trace with new attributes.\n */\n public updateTrace(attributes: LangfuseTraceAttributes) {\n this.otelSpan.setAttributes(createTraceAttributes(attributes));\n\n return this;\n }\n\n /**\n * Creates a new child observation within this observation's context with full type safety.\n *\n * This method enables hierarchical tracing by creating child observations that inherit\n * the parent's trace context. It supports all observation types with automatic TypeScript\n * type inference based on the `asType` parameter, ensuring compile-time safety for\n * attributes and return types.\n *\n * ## Hierarchy & Context\n * - Child observations automatically inherit the parent's trace ID and span context\n * - Creates proper parent-child relationships in the trace structure\n * - Enables distributed tracing across nested operations\n * - Maintains correlation between related operations\n *\n * ## Type Safety\n * - Return type is automatically inferred from `asType` parameter\n * - Attributes parameter is type-checked based on observation type\n * - Compile-time validation prevents type mismatches\n * - Full IntelliSense support for observation-specific attributes\n *\n * @param name - Descriptive name for the child observation\n * @param attributes - Type-specific attributes (varies by observation type)\n * @param options - Configuration including observation type (defaults to 'span')\n * @returns Strongly-typed observation instance based on `asType`\n *\n * @example\n * ```typescript\n * // Within any observation (span, generation, agent, etc.)\n * const parentObservation = startObservation('ai-workflow');\n *\n * // Create child span (default)\n * const dataProcessing = parentObservation.startObservation('data-processing', {\n * input: { userId: '123', dataSize: 1024 },\n * metadata: { processor: 'fast-lane', version: '2.1' }\n * }); // Returns LangfuseSpan\n *\n * // Create child generation with full LLM attributes\n * const llmCall = parentObservation.startObservation('openai-gpt-4', {\n * input: [{ role: 'system', content: 'You are a helpful assistant' },\n * { role: 'user', content: 'Explain machine learning' }],\n * model: 'gpt-4-turbo',\n * modelParameters: {\n * temperature: 0.7,\n * maxTokens: 500,\n * topP: 1.0\n * },\n * metadata: { priority: 'high', timeout: 30000 }\n * }, { asType: 'generation' }); // Returns LangfuseGeneration\n *\n * // Create child agent for complex reasoning\n * const reasoningAgent = parentObservation.startObservation('reasoning-agent', {\n * input: {\n * task: 'Analyze market trends',\n * context: 'Q4 2024 financial data'\n * },\n * metadata: {\n * model: 'gpt-4',\n * tools: ['calculator', 'web-search', 'data-analysis'],\n * maxIterations: 5\n * }\n * }, { asType: 'agent' }); // Returns LangfuseAgent\n *\n * // Create child tool for external API calls\n * const apiCall = reasoningAgent.startObservation('market-data-api', {\n * input: {\n * endpoint: '/market/trends',\n * params: { symbol: 'AAPL', period: '1Y' }\n * },\n * metadata: {\n * provider: 'alpha-vantage',\n * rateLimit: 5,\n * timeout: 10000\n * }\n * }, { asType: 'tool' }); // Returns LangfuseTool\n *\n * // Create child retriever for document search\n * const docSearch = parentObservation.startObservation('document-retrieval', {\n * input: {\n * query: 'sustainable energy solutions',\n * filters: { year: '2024', category: 'research' },\n * topK: 10\n * },\n * metadata: {\n * vectorStore: 'pinecone',\n * embeddingModel: 'text-embedding-ada-002',\n * similarity: 'cosine'\n * }\n * }, { asType: 'retriever' }); // Returns LangfuseRetriever\n *\n * // Create child evaluator for quality assessment\n * const qualityCheck = parentObservation.startObservation('response-evaluator', {\n * input: {\n * response: llmCall.output?.content,\n * reference: 'Expected high-quality explanation',\n * criteria: ['accuracy', 'clarity', 'completeness']\n * },\n * metadata: {\n * evaluator: 'custom-bert-scorer',\n * threshold: 0.8,\n * metrics: ['bleu', 'rouge', 'semantic-similarity']\n * }\n * }, { asType: 'evaluator' }); // Returns LangfuseEvaluator\n *\n * // Create child guardrail for safety checking\n * const safetyCheck = parentObservation.startObservation('content-guardrail', {\n * input: {\n * text: llmCall.output?.content,\n * policies: ['no-harmful-content', 'no-personal-info', 'professional-tone']\n * },\n * metadata: {\n * guardrailVersion: 'v2.1',\n * strictMode: true,\n * confidence: 0.95\n * }\n * }, { asType: 'guardrail' }); // Returns LangfuseGuardrail\n *\n * // Create child embedding for vector generation\n * const textEmbedding = parentObservation.startObservation('text-embedder', {\n * input: {\n * texts: ['Document summary', 'Key insights', 'Conclusions'],\n * batchSize: 3\n * },\n * model: 'text-embedding-ada-002',\n * metadata: {\n * dimensions: 1536,\n * normalization: 'l2',\n * purpose: 'semantic-search'\n * }\n * }, { asType: 'embedding' }); // Returns LangfuseEmbedding\n *\n * // Create child event for point-in-time logging\n * const userAction = parentObservation.startObservation('user-interaction', {\n * input: {\n * action: 'button-click',\n * element: 'generate-report',\n * timestamp: new Date().toISOString()\n * },\n * level: 'DEFAULT',\n * metadata: {\n * sessionId: 'sess_123',\n * userId: 'user_456',\n * browser: 'Chrome 120.0'\n * }\n * }, { asType: 'event' }); // Returns LangfuseEvent (auto-ended)\n *\n * // Chain operations - each child inherits context\n * dataProcessing.update({ output: { processed: true, records: 1000 } });\n * dataProcessing.end();\n *\n * llmCall.update({\n * output: { role: 'assistant', content: 'Machine learning is...' },\n * usageDetails: { promptTokens: 25, completionTokens: 150 }\n * });\n * llmCall.end();\n *\n * parentObservation.update({\n * output: {\n * workflowCompleted: true,\n * childOperations: 8,\n * totalDuration: Date.now() - startTime\n * }\n * });\n * parentObservation.end();\n * ```\n *\n * @see {@link startObservation} for creating root-level observations\n * @see {@link startActiveObservation} for function-scoped child observations\n */\n public startObservation(\n name: string,\n attributes: LangfuseGenerationAttributes,\n options: { asType: \"generation\" },\n ): LangfuseGeneration;\n public startObservation(\n name: string,\n attributes: LangfuseEventAttributes,\n options: { asType: \"event\" },\n ): LangfuseEvent;\n public startObservation(\n name: string,\n attributes: LangfuseAgentAttributes,\n options: { asType: \"agent\" },\n ): LangfuseAgent;\n public startObservation(\n name: string,\n attributes: LangfuseToolAttributes,\n options: { asType: \"tool\" },\n ): LangfuseTool;\n public startObservation(\n name: string,\n attributes: LangfuseChainAttributes,\n options: { asType: \"chain\" },\n ): LangfuseChain;\n public startObservation(\n name: string,\n attributes: LangfuseRetrieverAttributes,\n options: { asType: \"retriever\" },\n ): LangfuseRetriever;\n public startObservation(\n name: string,\n attributes: LangfuseEvaluatorAttributes,\n options: { asType: \"evaluator\" },\n ): LangfuseEvaluator;\n public startObservation(\n name: string,\n attributes: LangfuseGuardrailAttributes,\n options: { asType: \"guardrail\" },\n ): LangfuseGuardrail;\n public startObservation(\n name: string,\n attributes: LangfuseEmbeddingAttributes,\n options: { asType: \"embedding\" },\n ): LangfuseEmbedding;\n public startObservation(\n name: string,\n attributes?: LangfuseSpanAttributes,\n options?: { asType?: \"span\" },\n ): LangfuseSpan;\n public startObservation(\n name: string,\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes\n | LangfuseAgentAttributes\n | LangfuseToolAttributes\n | LangfuseChainAttributes\n | LangfuseRetrieverAttributes\n | LangfuseEvaluatorAttributes\n | LangfuseGuardrailAttributes\n | LangfuseEmbeddingAttributes,\n options?: { asType?: LangfuseObservationType },\n ): LangfuseObservation {\n const { asType = \"span\" } = options || {};\n\n return startObservation(name, attributes, {\n asType: asType as \"span\", // typecast necessary as ts cannot narrow the type correctly\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n}\n\ntype LangfuseSpanParams = {\n otelSpan: Span;\n attributes?: LangfuseSpanAttributes;\n};\n\n/**\n * General-purpose observation wrapper for tracking operations, functions, and workflows.\n *\n * LangfuseSpan is the default and most versatile observation type, designed for tracing\n * any operation that has a defined start and end time. It serves as the foundation for\n * building hierarchical traces and can contain any other observation type as children.\n *\n * ## Primary Use Cases\n * - **Business Logic**: User workflows, order processing, data transformations\n * - **API Operations**: REST endpoint handling, database queries, external service calls\n * - **System Operations**: File I/O, network requests, background jobs\n * - **Pipeline Steps**: Data processing stages, validation steps, orchestration\n * - **Application Functions**: Any measurable operation in your application\n *\n * ## Key Features\n * - **Hierarchical Structure**: Can contain child observations of any type\n * - **Flexible Attributes**: Supports arbitrary input, output, and metadata\n * - **Duration Tracking**: Automatically measures execution time from start to end\n * - **Status Monitoring**: Tracks success/failure states and error conditions\n * - **Context Propagation**: Maintains trace context for distributed operations\n *\n * ## Span Lifecycle\n * 1. **Creation**: Span starts automatically when created\n * 2. **Updates**: Add input data, intermediate state, metadata as needed\n * 3. **Child Operations**: Create nested observations for sub-operations\n * 4. **Completion**: Update with final output and call `.end()` to finish\n *\n * @example\n * ```typescript\n * // Basic span tracking\n * const span = startObservation('user-authentication', {\n * input: { username: 'john_doe', method: 'oauth' },\n * metadata: { provider: 'google' }\n * });\n *\n * try {\n * const user = await authenticateUser(credentials);\n * span.update({\n * output: { userId: user.id, success: true }\n * });\n * } catch (error) {\n * span.update({\n * level: 'ERROR',\n * output: { success: false, error: error.message }\n * });\n * } finally {\n * span.end();\n * }\n *\n * // Nested operations\n * const workflow = startObservation('order-processing', {\n * input: { orderId: 'ord_123' }\n * });\n *\n * const validation = workflow.startObservation('validation', {\n * input: { items: cartItems }\n * });\n * validation.update({ output: { valid: true } });\n * validation.end();\n *\n * const payment = workflow.startObservation('payment', {\n * input: { amount: 100 }\n * });\n * payment.update({ output: { status: 'completed' } });\n * payment.end();\n *\n * workflow.update({\n * output: { status: 'confirmed', steps: 2 }\n * });\n * workflow.end();\n * ```\n *\n * @see {@link startObservation} - Factory function for creating spans\n * @see {@link startActiveObservation} - Function-scoped span creation\n * @see {@link LangfuseGeneration} - For LLM and AI model interactions\n * @see {@link LangfuseEvent} - For point-in-time occurrences\n *\n * @public\n */\nexport class LangfuseSpan extends LangfuseBaseObservation {\n constructor(params: LangfuseSpanParams) {\n super({ ...params, type: \"span\" });\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 super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseAgentParams = {\n otelSpan: Span;\n attributes?: LangfuseAgentAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking AI agent workflows and autonomous operations.\n *\n * LangfuseAgent is designed for observing intelligent agent systems that combine reasoning,\n * tool usage, memory management, and decision-making in autonomous workflows. It captures\n * the complex multi-step nature of agent operations, including planning, execution, and\n * self-correction cycles typical in advanced AI agent architectures.\n *\n * ## Primary Use Cases\n * - **Autonomous AI Agents**: ReAct, AutoGPT, LangGraph agent implementations\n * - **Tool-Using Agents**: Function calling agents with external API access\n * - **Multi-Step Reasoning**: Chain-of-thought, tree-of-thought agent workflows\n * - **Planning Agents**: Goal decomposition and task planning systems\n * - **Conversational Agents**: Multi-turn dialogue agents with memory\n * - **Code Generation Agents**: AI assistants that write, test, and debug code\n *\n * ## Key Features\n * - **Multi-Step Tracking**: Captures entire agent workflow from planning to execution\n * - **Tool Integration**: Records all tool calls and their results within agent context\n * - **Decision Logic**: Tracks reasoning steps, decisions, and strategy adaptations\n * - **Memory Management**: Observes how agents maintain and use context across steps\n * - **Error Recovery**: Monitors how agents handle failures and adapt their approach\n * - **Performance Metrics**: Measures agent efficiency, success rates, and resource usage\n *\n * ## Agent-Specific Patterns\n * - **Planning Phase**: Initial goal analysis and strategy formulation\n * - **Execution Loop**: Iterative action-observation-reasoning cycles\n * - **Tool Selection**: Dynamic tool choice based on context and goals\n * - **Self-Correction**: Error detection and strategy adjustment\n * - **Memory Updates**: Context retention and knowledge accumulation\n * - **Final Synthesis**: Result compilation and quality assessment\n *\n * @example\n * ```typescript\n * // Basic agent workflow\n * const agent = startObservation('research-agent', {\n * input: {\n * task: 'Research renewable energy trends',\n * tools: ['web-search', 'summarizer'],\n * maxIterations: 3\n * }\n * }, { asType: 'agent' });\n *\n * // Agent uses tools and makes decisions\n * const searchTool = agent.startObservation('web-search', {\n * input: { query: 'renewable energy 2024' }\n * }, { asType: 'tool' });\n *\n * const results = await webSearch('renewable energy 2024');\n * searchTool.update({ output: results });\n * searchTool.end();\n *\n * // Agent generates final response\n * const generation = agent.startObservation('synthesize-findings', {\n * input: results,\n * model: 'gpt-4'\n * }, { asType: 'generation' });\n *\n * const response = await llm.generate(results);\n * generation.update({ output: response });\n * generation.end();\n *\n * agent.update({\n * output: {\n * completed: true,\n * toolsUsed: 1,\n * finalResponse: response\n * }\n * });\n * agent.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'agent' }` - Factory function\n * @see {@link startActiveObservation} with `{ asType: 'agent' }` - Function-scoped agent\n * @see {@link LangfuseTool} - For individual tool executions within agents\n * @see {@link LangfuseChain} - For structured multi-step workflows\n *\n * @public\n */\nexport class LangfuseAgent extends LangfuseBaseObservation {\n constructor(params: LangfuseAgentParams) {\n super({ ...params, type: \"agent\" });\n }\n\n /**\n * Updates this agent observation with new attributes.\n *\n * @param attributes - Agent attributes to set\n * @returns This agent for method chaining\n *\n * @example\n * ```typescript\n * agent.update({\n * output: {\n * taskCompleted: true,\n * iterationsUsed: 5,\n * toolsInvoked: ['web-search', 'calculator', 'summarizer'],\n * finalResult: 'Research completed with high confidence'\n * },\n * metadata: {\n * efficiency: 0.85,\n * qualityScore: 0.92,\n * resourcesConsumed: { tokens: 15000, apiCalls: 12 }\n * }\n * });\n * ```\n */\n public update(attributes: LangfuseAgentAttributes): LangfuseAgent {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseToolParams = {\n otelSpan: Span;\n attributes?: LangfuseToolAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking individual tool calls and external API interactions.\n *\n * LangfuseTool is designed for observing discrete tool invocations within agent workflows,\n * function calling scenarios, or standalone API integrations. It captures the input parameters,\n * execution results, performance metrics, and error conditions of tool operations, making it\n * essential for debugging tool reliability and optimizing tool selection strategies.\n *\n * ## Primary Use Cases\n * - **Function Calling**: OpenAI function calls, Anthropic tool use, Claude function calling\n * - **External APIs**: REST API calls, GraphQL queries, database operations\n * - **System Tools**: File operations, shell commands, system integrations\n * - **Data Processing Tools**: Calculators, converters, validators, parsers\n * - **Search Tools**: Web search, vector search, document retrieval\n * - **Content Tools**: Image generation, text processing, format conversion\n *\n * ## Key Features\n * - **Parameter Tracking**: Complete input parameter logging and validation\n * - **Result Capture**: Full output data and metadata from tool execution\n * - **Performance Monitoring**: Execution time, success rates, retry attempts\n * - **Error Analysis**: Detailed error tracking with context and recovery info\n * - **Usage Analytics**: Frequency, patterns, and efficiency metrics\n * - **Integration Health**: API status, rate limits, and service availability\n *\n * ## Tool-Specific Patterns\n * - **Input Validation**: Parameter checking and sanitization before execution\n * - **Execution Monitoring**: Real-time performance and status tracking\n * - **Result Processing**: Output validation, transformation, and formatting\n * - **Error Handling**: Retry logic, fallbacks, and graceful degradation\n * - **Caching Integration**: Result caching and cache hit/miss tracking\n * - **Rate Limiting**: Request throttling and quota management\n *\n * @example\n * ```typescript\n * // Web search tool\n * const searchTool = startObservation('web-search', {\n * input: {\n * query: 'latest AI developments',\n * maxResults: 10\n * },\n * metadata: { provider: 'google-api' }\n * }, { asType: 'tool' });\n *\n * try {\n * const results = await webSearch('latest AI developments');\n *\n * searchTool.update({\n * output: {\n * results: results,\n * count: results.length\n * },\n * metadata: {\n * latency: 1200,\n * cacheHit: false\n * }\n * });\n * } catch (error) {\n * searchTool.update({\n * level: 'ERROR',\n * statusMessage: 'Search failed',\n * output: { error: error.message }\n * });\n * } finally {\n * searchTool.end();\n * }\n *\n * // Database query tool\n * const dbTool = startObservation('db-query', {\n * input: {\n * query: 'SELECT * FROM users WHERE active = true',\n * timeout: 30000\n * }\n * }, { asType: 'tool' });\n *\n * const result = await db.query('SELECT * FROM users WHERE active = true');\n * dbTool.update({\n * output: { rowCount: result.length },\n * metadata: { executionTime: 150 }\n * });\n * dbTool.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'tool' }` - Factory function\n * @see {@link startActiveObservation} with `{ asType: 'tool' }` - Function-scoped tool\n * @see {@link LangfuseAgent} - For agent workflows that use multiple tools\n * @see {@link LangfuseChain} - For orchestrated tool sequences\n *\n * @public\n */\nexport class LangfuseTool extends LangfuseBaseObservation {\n constructor(params: LangfuseToolParams) {\n super({ ...params, type: \"tool\" });\n }\n\n /**\n * Updates this tool observation with new attributes.\n *\n * @param attributes - Tool attributes to set\n * @returns This tool for method chaining\n *\n * @example\n * ```typescript\n * tool.update({\n * output: {\n * result: searchResults,\n * count: searchResults.length,\n * relevanceScore: 0.89,\n * executionTime: 1250\n * },\n * metadata: {\n * cacheHit: false,\n * apiCost: 0.025,\n * rateLimitRemaining: 950\n * }\n * });\n * ```\n */\n public update(attributes: LangfuseToolAttributes): LangfuseTool {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseChainParams = {\n otelSpan: Span;\n attributes?: LangfuseChainAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking structured multi-step workflows and process chains.\n *\n * LangfuseChain is designed for observing sequential, parallel, or conditional workflow orchestration\n * where multiple operations are coordinated to achieve a larger goal. It captures the flow of data\n * between steps, manages dependencies, tracks progress through complex pipelines, and provides\n * insights into workflow performance and reliability patterns.\n *\n * ## Primary Use Cases\n * - **Data Processing Pipelines**: ETL processes, data transformation workflows\n * - **Business Process Automation**: Order processing, approval workflows, document processing\n * - **LangChain Integration**: LangChain chain execution and orchestration\n * - **RAG Pipelines**: Document retrieval → context preparation → generation → post-processing\n * - **Multi-Model Workflows**: Preprocessing → model inference → post-processing → validation\n * - **Content Production**: Research → drafting → review → editing → publishing\n *\n * ## Key Features\n * - **Step Orchestration**: Sequential, parallel, and conditional step execution tracking\n * - **Data Flow Management**: Input/output tracking between pipeline steps\n * - **Dependency Resolution**: Manages complex step dependencies and prerequisites\n * - **Progress Monitoring**: Real-time workflow progress and completion status\n * - **Error Propagation**: Handles failures, retries, and recovery across workflow steps\n * - **Performance Analytics**: Bottleneck identification and optimization insights\n *\n * ## Chain-Specific Patterns\n * - **Pipeline Setup**: Workflow definition, step configuration, and dependency mapping\n * - **Sequential Execution**: Step-by-step processing with state management\n * - **Parallel Processing**: Concurrent step execution with synchronization\n * - **Conditional Logic**: Dynamic branching based on intermediate results\n * - **Error Recovery**: Failure handling, rollback, and alternative path execution\n * - **Result Aggregation**: Combining outputs from multiple workflow branches\n *\n * @example\n * ```typescript\n * // RAG processing chain\n * const ragChain = startObservation('rag-chain', {\n * input: {\n * query: 'What is renewable energy?',\n * steps: ['retrieval', 'generation']\n * }\n * }, { asType: 'chain' });\n *\n * // Step 1: Document retrieval\n * const retrieval = ragChain.startObservation('document-retrieval', {\n * input: { query: 'renewable energy' }\n * }, { asType: 'retriever' });\n *\n * const docs = await vectorSearch('renewable energy');\n * retrieval.update({ output: { documents: docs, count: docs.length } });\n * retrieval.end();\n *\n * // Step 2: Generate response\n * const generation = ragChain.startObservation('response-generation', {\n * input: {\n * query: 'What is renewable energy?',\n * context: docs\n * },\n * model: 'gpt-4'\n * }, { asType: 'generation' });\n *\n * const response = await llm.generate({\n * prompt: buildPrompt('What is renewable energy?', docs)\n * });\n *\n * generation.update({ output: response });\n * generation.end();\n *\n * ragChain.update({\n * output: {\n * finalResponse: response,\n * stepsCompleted: 2,\n * documentsUsed: docs.length\n * }\n * });\n * ragChain.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'chain' }` - Factory function\n * @see {@link startActiveObservation} with `{ asType: 'chain' }` - Function-scoped chain\n * @see {@link LangfuseSpan} - For individual workflow steps\n * @see {@link LangfuseAgent} - For intelligent workflow orchestration\n *\n * @public\n */\nexport class LangfuseChain extends LangfuseBaseObservation {\n constructor(params: LangfuseChainParams) {\n super({ ...params, type: \"chain\" });\n }\n\n /**\n * Updates this chain observation with new attributes.\n *\n * @param attributes - Chain attributes to set\n * @returns This chain for method chaining\n *\n * @example\n * ```typescript\n * chain.update({\n * output: {\n * stepsCompleted: 5,\n * stepsSuccessful: 4,\n * finalResult: processedData,\n * pipelineEfficiency: 0.87\n * },\n * metadata: {\n * bottleneckStep: 'data-validation',\n * parallelizationOpportunities: ['step-2', 'step-3'],\n * optimizationSuggestions: ['cache-intermediate-results']\n * }\n * });\n * ```\n */\n public update(attributes: LangfuseChainAttributes): LangfuseChain {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseRetrieverParams = {\n otelSpan: Span;\n attributes?: LangfuseRetrieverAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking document retrieval and search operations.\n *\n * LangfuseRetriever is designed for observing information retrieval systems that search,\n * filter, and rank content from various data sources. It captures search queries, retrieval\n * strategies, result quality metrics, and performance characteristics of search operations,\n * making it essential for RAG systems, knowledge bases, and content discovery workflows.\n *\n * ## Primary Use Cases\n * - **Vector Search**: Semantic similarity search using embeddings and vector databases\n * - **Document Retrieval**: Full-text search, keyword matching, and document filtering\n * - **Knowledge Base Query**: FAQ systems, help documentation, and knowledge management\n * - **RAG Systems**: Retrieval step in retrieval-augmented generation pipelines\n * - **Recommendation Systems**: Content recommendations and similarity-based suggestions\n * - **Data Mining**: Information extraction and content discovery from large datasets\n *\n * ## Key Features\n * - **Query Analysis**: Input query processing, expansion, and optimization tracking\n * - **Search Strategy**: Retrieval algorithms, ranking functions, and filtering criteria\n * - **Result Quality**: Relevance scores, diversity metrics, and retrieval effectiveness\n * - **Performance Metrics**: Search latency, index size, and throughput measurements\n * - **Source Tracking**: Data source attribution and content provenance information\n * - **Ranking Intelligence**: Personalization, context awareness, and result optimization\n *\n * @example\n * ```typescript\n * // Vector search retrieval\n * const retriever = startObservation('vector-search', {\n * input: {\n * query: 'machine learning applications',\n * topK: 10,\n * similarityThreshold: 0.7\n * },\n * metadata: {\n * vectorDB: 'pinecone',\n * embeddingModel: 'text-embedding-ada-002'\n * }\n * }, { asType: 'retriever' });\n *\n * const results = await vectorDB.search({\n * query: 'machine learning applications',\n * topK: 10,\n * threshold: 0.7\n * });\n *\n * retriever.update({\n * output: {\n * documents: results,\n * count: results.length,\n * avgSimilarity: 0.89\n * },\n * metadata: {\n * searchLatency: 150,\n * cacheHit: false\n * }\n * });\n * retriever.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'retriever' }` - Factory function\n * @see {@link LangfuseChain} - For multi-step RAG pipelines\n * @see {@link LangfuseEmbedding} - For embedding generation used in vector search\n *\n * @public\n */\nexport class LangfuseRetriever extends LangfuseBaseObservation {\n constructor(params: LangfuseRetrieverParams) {\n super({ ...params, type: \"retriever\" });\n }\n\n /**\n * Updates this retriever observation with new attributes.\n *\n * @param attributes - Retriever attributes to set\n * @returns This retriever for method chaining\n */\n public update(attributes: LangfuseRetrieverAttributes): LangfuseRetriever {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseEvaluatorParams = {\n otelSpan: Span;\n attributes?: LangfuseEvaluatorAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking quality assessment and evaluation operations.\n *\n * LangfuseEvaluator is designed for observing evaluation systems that assess, score, and\n * validate the quality of AI outputs, content, or system performance. It captures evaluation\n * criteria, scoring methodologies, benchmark comparisons, and quality metrics, making it\n * essential for AI system validation, content moderation, and performance monitoring.\n *\n * ## Primary Use Cases\n * - **LLM Output Evaluation**: Response quality, factual accuracy, and relevance assessment\n * - **Content Quality Assessment**: Writing quality, tone analysis, and style validation\n * - **Automated Testing**: System performance validation and regression testing\n * - **Bias Detection**: Fairness evaluation and bias identification in AI systems\n * - **Safety Evaluation**: Content safety, harm detection, and compliance checking\n * - **Benchmark Comparison**: Performance comparison against reference standards\n *\n * ## Key Features\n * - **Multi-Criteria Scoring**: Comprehensive evaluation across multiple quality dimensions\n * - **Automated Assessment**: AI-powered evaluation using specialized models and algorithms\n * - **Human Evaluation**: Integration with human reviewers and expert assessment\n * - **Benchmark Tracking**: Performance comparison against established baselines\n * - **Quality Metrics**: Detailed scoring with confidence intervals and reliability measures\n * - **Trend Analysis**: Quality tracking over time with improvement recommendations\n *\n * @example\n * ```typescript\n * // Response quality evaluation\n * const evaluator = startObservation('response-quality-eval', {\n * input: {\n * response: 'Machine learning is a subset of artificial intelligence...',\n * criteria: ['accuracy', 'completeness', 'clarity']\n * }\n * }, { asType: 'evaluator' });\n *\n * const evaluation = await evaluateResponse({\n * response: 'Machine learning is a subset of artificial intelligence...',\n * criteria: ['accuracy', 'completeness', 'clarity']\n * });\n *\n * evaluator.update({\n * output: {\n * overallScore: 0.87,\n * criteriaScores: {\n * accuracy: 0.92,\n * completeness: 0.85,\n * clarity: 0.90\n * },\n * passed: true\n * }\n * });\n * evaluator.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'evaluator' }` - Factory function\n * @see {@link LangfuseGeneration} - For LLM outputs being evaluated\n * @see {@link LangfuseGuardrail} - For safety and compliance enforcement\n *\n * @public\n */\nexport class LangfuseEvaluator extends LangfuseBaseObservation {\n constructor(params: LangfuseEvaluatorParams) {\n super({ ...params, type: \"evaluator\" });\n }\n\n /**\n * Updates this evaluator observation with new attributes.\n *\n * @param attributes - Evaluator attributes to set\n * @returns This evaluator for method chaining\n */\n public update(attributes: LangfuseEvaluatorAttributes): LangfuseEvaluator {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseGuardrailParams = {\n otelSpan: Span;\n attributes?: LangfuseGuardrailAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking safety checks and compliance enforcement.\n *\n * LangfuseGuardrail is designed for observing safety and compliance systems that prevent,\n * detect, and mitigate harmful, inappropriate, or policy-violating content and behaviors\n * in AI applications. It captures safety policies, violation detection, risk assessment,\n * and mitigation actions, ensuring responsible AI deployment and regulatory compliance.\n *\n * ## Primary Use Cases\n * - **Content Moderation**: Harmful content detection and filtering in user inputs/outputs\n * - **Safety Enforcement**: PII detection, toxicity filtering, and inappropriate content blocking\n * - **Compliance Monitoring**: Regulatory compliance, industry standards, and policy enforcement\n * - **Bias Mitigation**: Fairness checks and bias prevention in AI decision-making\n * - **Privacy Protection**: Data privacy safeguards and sensitive information redaction\n * - **Behavioral Monitoring**: User behavior analysis and anomaly detection\n *\n * ## Key Features\n * - **Multi-Policy Enforcement**: Simultaneous checking against multiple safety policies\n * - **Risk Assessment**: Quantitative risk scoring with confidence intervals\n * - **Real-Time Detection**: Low-latency safety checks for interactive applications\n * - **Context Awareness**: Contextual safety evaluation considering user and application context\n * - **Mitigation Actions**: Automatic content blocking, filtering, and redaction capabilities\n * - **Audit Trail**: Comprehensive logging for compliance and safety incident investigation\n *\n * @example\n * ```typescript\n * // Content safety guardrail\n * const guardrail = startObservation('content-safety-check', {\n * input: {\n * content: userMessage,\n * policies: ['no-toxicity', 'no-hate-speech'],\n * strictMode: false\n * }\n * }, { asType: 'guardrail' });\n *\n * const safetyCheck = await checkContentSafety({\n * text: userMessage,\n * policies: ['no-toxicity', 'no-hate-speech']\n * });\n *\n * guardrail.update({\n * output: {\n * safe: safetyCheck.safe,\n * riskScore: 0.15,\n * violations: [],\n * action: 'allow'\n * }\n * });\n * guardrail.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'guardrail' }` - Factory function\n * @see {@link LangfuseEvaluator} - For detailed quality and safety assessment\n * @see {@link LangfuseGeneration} - For protecting LLM outputs with guardrails\n *\n * @public\n */\nexport class LangfuseGuardrail extends LangfuseBaseObservation {\n constructor(params: LangfuseGuardrailParams) {\n super({ ...params, type: \"guardrail\" });\n }\n\n /**\n * Updates this guardrail observation with new attributes.\n *\n * @param attributes - Guardrail attributes to set\n * @returns This guardrail for method chaining\n */\n public update(attributes: LangfuseGuardrailAttributes): LangfuseGuardrail {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\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 * Specialized observation wrapper for tracking LLM interactions, AI model calls, and text generation.\n *\n * LangfuseGeneration is purpose-built for observing AI model interactions, providing rich\n * metadata capture for prompts, completions, model parameters, token usage, and costs.\n * It's the go-to observation type for any operation involving language models, chat APIs,\n * completion APIs, or other generative AI services.\n *\n * ## Primary Use Cases\n * - **LLM API Calls**: OpenAI, Anthropic, Cohere, Azure OpenAI, AWS Bedrock\n * - **Chat Completions**: Multi-turn conversations and dialogue systems\n * - **Text Generation**: Content creation, summarization, translation\n * - **Code Generation**: AI-powered code completion and generation\n * - **RAG Systems**: Generation step in retrieval-augmented generation\n * - **AI Agents**: LLM reasoning and decision-making within agent workflows\n *\n * ## Key Features\n * - **Rich LLM Metadata**: Model name, parameters, prompts, completions\n * - **Usage Tracking**: Token counts (prompt, completion, total)\n * - **Cost Monitoring**: Automatic cost calculation and tracking\n * - **Performance Metrics**: Latency, throughput, tokens per second\n * - **Prompt Engineering**: Version control for prompts and templates\n * - **Error Handling**: Rate limits, timeouts, model-specific errors\n *\n * ## Generation-Specific Attributes\n * - `model`: Model identifier (e.g., 'gpt-4-turbo', 'claude-3-sonnet')\n * - `modelParameters`: Temperature, max tokens, top-p, frequency penalty\n * - `input`: Prompt or message array for the model\n * - `output`: Model response, completion, or generated content\n * - `usageDetails`: Token consumption (prompt, completion, total)\n * - `costDetails`: Financial cost breakdown and pricing\n * - `prompt`: Structured prompt object with name, version, variables\n *\n * @example\n * ```typescript\n * // Basic LLM generation tracking\n * const generation = startObservation('openai-completion', {\n * model: 'gpt-4-turbo',\n * input: [\n * { role: 'system', content: 'You are a helpful assistant.' },\n * { role: 'user', content: 'Explain quantum computing' }\n * ],\n * modelParameters: {\n * temperature: 0.7,\n * maxTokens: 500\n * }\n * }, { asType: 'generation' });\n *\n * try {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4-turbo',\n * messages: [\n * { role: 'system', content: 'You are a helpful assistant.' },\n * { role: 'user', content: 'Explain quantum computing' }\n * ],\n * temperature: 0.7,\n * max_tokens: 500\n * });\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 * costDetails: {\n * totalCost: 0.025,\n * currency: 'USD'\n * }\n * });\n * } catch (error) {\n * generation.update({\n * level: 'ERROR',\n * statusMessage: `API error: ${error.message}`,\n * output: { error: error.message }\n * });\n * } finally {\n * generation.end();\n * }\n *\n * // RAG generation example\n * const ragGeneration = startObservation('rag-response', {\n * model: 'gpt-4',\n * input: [\n * { role: 'system', content: 'Answer based on provided context.' },\n * { role: 'user', content: `Context: ${context}\\n\\nQuestion: ${question}` }\n * ],\n * modelParameters: { temperature: 0.1 }\n * }, { asType: 'generation' });\n *\n * const response = await llm.generate({ prompt, context });\n * ragGeneration.update({\n * output: response,\n * metadata: { contextSources: 3 }\n * });\n * ragGeneration.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'generation' }` - Factory function\n * @see {@link startActiveObservation} with `{ asType: 'generation' }` - Function-scoped generation\n * @see {@link LangfuseSpan} - For general-purpose operations\n * @see {@link LangfuseEmbedding} - For text embedding and vector operations\n *\n * @public\n */\nexport class LangfuseGeneration extends LangfuseBaseObservation {\n constructor(params: LangfuseGenerationParams) {\n super({ ...params, type: \"generation\" });\n }\n\n update(attributes: LangfuseGenerationAttributes): LangfuseGeneration {\n this.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseEmbeddingParams = {\n otelSpan: Span;\n attributes?: LangfuseEmbeddingAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking text embedding and vector generation operations.\n *\n * LangfuseEmbedding is designed for observing embedding model interactions that convert\n * text, images, or other content into high-dimensional vector representations. It captures\n * embedding model parameters, input preprocessing, vector characteristics, and performance\n * metrics, making it essential for semantic search, RAG systems, and similarity-based applications.\n *\n * ## Primary Use Cases\n * - **Text Embeddings**: Converting text to vectors for semantic search and similarity\n * - **Document Indexing**: Creating vector representations for large document collections\n * - **Semantic Search**: Enabling similarity-based search and content discovery\n * - **RAG Preparation**: Embedding documents and queries for retrieval-augmented generation\n * - **Clustering Analysis**: Grouping similar content using vector representations\n * - **Recommendation Systems**: Content similarity for personalized recommendations\n *\n * ## Key Features\n * - **Model Tracking**: Embedding model selection, version, and parameter monitoring\n * - **Input Processing**: Text preprocessing, tokenization, and normalization tracking\n * - **Vector Analysis**: Dimensionality, magnitude, and quality metrics for generated embeddings\n * - **Batch Processing**: Efficient handling of multiple texts in single embedding operations\n * - **Performance Monitoring**: Embedding generation speed, cost tracking, and efficiency metrics\n * - **Quality Assessment**: Vector quality evaluation and embedding effectiveness measurement\n *\n * @example\n * ```typescript\n * // Text embedding generation\n * const embedding = startObservation('text-embedder', {\n * input: {\n * texts: [\n * 'Machine learning is a subset of AI',\n * 'Deep learning uses neural networks'\n * ],\n * batchSize: 2\n * },\n * model: 'text-embedding-ada-002'\n * }, { asType: 'embedding' });\n *\n * const embedResult = await generateEmbeddings({\n * texts: [\n * 'Machine learning is a subset of AI',\n * 'Deep learning uses neural networks'\n * ],\n * model: 'text-embedding-ada-002'\n * });\n *\n * embedding.update({\n * output: {\n * embeddings: embedResult.vectors,\n * count: embedResult.vectors.length,\n * dimensions: 1536\n * },\n * usageDetails: {\n * totalTokens: embedResult.tokenCount\n * },\n * metadata: {\n * processingTime: 340\n * }\n * });\n * embedding.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'embedding' }` - Factory function\n * @see {@link LangfuseRetriever} - For using embeddings in vector search\n * @see {@link LangfuseGeneration} - For LLM operations that may use embeddings\n *\n * @public\n */\nexport class LangfuseEmbedding extends LangfuseBaseObservation {\n constructor(params: LangfuseEmbeddingParams) {\n super({ ...params, type: \"embedding\" });\n }\n\n /**\n * Updates this embedding observation with new attributes.\n *\n * @param attributes - Embedding attributes to set\n * @returns This embedding for method chaining\n */\n update(attributes: LangfuseEmbeddingAttributes): LangfuseEmbedding {\n this.updateOtelSpanAttributes(attributes);\n\n return this;\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 LangfuseBaseObservation {\n constructor(params: LangfuseEventParams) {\n super({ ...params, type: \"event\" });\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","_a"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/attributes.ts","../src/tracerProvider.ts","../src/spanWrapper.ts"],"sourcesContent":["import { getGlobalLogger, LangfuseOtelSpanAttributes } from \"@elasticdash/core\";\nimport {\n trace,\n context,\n TimeInput,\n SpanStatusCode,\n Span,\n Context,\n SpanContext,\n} from \"@opentelemetry/api\";\n\nimport {\n createObservationAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport {\n LangfuseAgent,\n LangfuseEvent,\n LangfuseGeneration,\n LangfuseSpan,\n LangfuseTool,\n LangfuseChain,\n LangfuseEmbedding,\n LangfuseEvaluator,\n LangfuseGuardrail,\n LangfuseRetriever,\n LangfuseObservation,\n} from \"./spanWrapper.js\";\nimport { getLangfuseTracer } from \"./tracerProvider.js\";\nimport {\n LangfuseChainAttributes,\n LangfuseEmbeddingAttributes,\n LangfuseEvaluatorAttributes,\n LangfuseGuardrailAttributes,\n LangfuseRetrieverAttributes,\n LangfuseToolAttributes,\n LangfuseAgentAttributes,\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseObservationType,\n LangfuseSpanAttributes,\n LangfuseTraceAttributes,\n LangfuseObservationAttributes,\n} from \"./types.js\";\n\nexport type {\n LangfuseObservationType,\n ObservationLevel,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseGenerationAttributes,\n LangfuseObservationAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\n\nexport * from \"./spanWrapper.js\";\nexport {\n createTraceAttributes,\n createObservationAttributes,\n} from \"./attributes.js\";\nexport {\n setLangfuseTracerProvider,\n getLangfuseTracerProvider,\n getLangfuseTracer,\n} from \"./tracerProvider.js\";\nexport {\n propagateAttributes,\n type PropagateAttributesParams,\n} from \"@elasticdash/core\";\n\nexport { LangfuseOtelSpanAttributes } from \"@elasticdash/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 * Options for starting an observations set to active in context\n *\n * Extends StartObservationOptions with additional context-specific configuration.\n *\n * @public\n */\nexport type StartActiveObservationContext = StartObservationOptions & {\n /** Whether to automatically end the observation when exiting the context. Default is true */\n endOnExit?: boolean;\n};\n\n/**\n * Options for startObservation function.\n *\n * @public\n */\nexport type StartObservationOpts = StartObservationOptions & {\n /** Type of observation to create. Defaults to 'span' */\n asType?: LangfuseObservationType;\n};\n\n/**\n * Options for startActiveObservation function.\n *\n * @public\n */\nexport type StartActiveObservationOpts = StartActiveObservationContext & {\n /** Type of observation to create. Defaults to 'span' */\n asType?: LangfuseObservationType;\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>(\n promise: Promise<T>,\n span: Span,\n endOnExit: boolean | undefined,\n): Promise<T> {\n return promise.then(\n (value) => {\n if (endOnExit !== false) {\n span.end(); // End span AFTER Promise resolves\n }\n\n return value;\n },\n (err: unknown) => {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n });\n\n if (endOnExit !== false) {\n span.end(); // End span AFTER Promise rejects\n }\n\n throw err;\n },\n );\n}\n\n// Function overloads for proper type inference\nexport function startObservation(\n name: string,\n attributes: LangfuseGenerationAttributes,\n options: StartObservationOpts & { asType: \"generation\" },\n): LangfuseGeneration;\nexport function startObservation(\n name: string,\n attributes: LangfuseEventAttributes,\n options: StartObservationOpts & { asType: \"event\" },\n): LangfuseEvent;\nexport function startObservation(\n name: string,\n attributes: LangfuseAgentAttributes,\n options: StartObservationOpts & { asType: \"agent\" },\n): LangfuseAgent;\nexport function startObservation(\n name: string,\n attributes: LangfuseToolAttributes,\n options: StartObservationOpts & { asType: \"tool\" },\n): LangfuseTool;\nexport function startObservation(\n name: string,\n attributes: LangfuseChainAttributes,\n options: StartObservationOpts & { asType: \"chain\" },\n): LangfuseChain;\nexport function startObservation(\n name: string,\n attributes: LangfuseRetrieverAttributes,\n options: StartObservationOpts & { asType: \"retriever\" },\n): LangfuseRetriever;\nexport function startObservation(\n name: string,\n attributes: LangfuseEvaluatorAttributes,\n options: StartObservationOpts & { asType: \"evaluator\" },\n): LangfuseEvaluator;\nexport function startObservation(\n name: string,\n attributes: LangfuseGuardrailAttributes,\n options: StartObservationOpts & { asType: \"guardrail\" },\n): LangfuseGuardrail;\nexport function startObservation(\n name: string,\n attributes: LangfuseEmbeddingAttributes,\n options: StartObservationOpts & { asType: \"embedding\" },\n): LangfuseEmbedding;\nexport function startObservation(\n name: string,\n attributes?: LangfuseSpanAttributes,\n options?: StartObservationOpts & { asType?: \"span\" },\n): LangfuseSpan;\n/**\n * Creates and starts a new Langfuse observation with automatic TypeScript type inference.\n *\n * This is the primary method for creating observations in Langfuse. It supports multiple\n * observation types with full TypeScript type safety - the return type is automatically\n * inferred based on the `asType` parameter.\n *\n * ## Supported Observation Types\n * - **span** (default): General-purpose operations, functions, or workflows\n * - **generation**: LLM calls, text generation, or AI model interactions\n * - **embedding**: Text embedding generation or vector operations\n * - **agent**: AI agent workflows with tool usage and decision making\n * - **tool**: Individual tool calls, API requests, or function invocations\n * - **chain**: Multi-step processes like RAG pipelines or sequential operations\n * - **retriever**: Document retrieval, vector search, or knowledge base queries\n * - **evaluator**: Quality assessment, scoring, or evaluation operations\n * - **guardrail**: Safety checks, content filtering, or validation operations\n * - **event**: Point-in-time occurrences or log entries (automatically ended)\n *\n * @param name - Descriptive name for the observation (e.g., 'openai-gpt-4', 'vector-search')\n * @param attributes - Type-specific attributes (input, output, metadata, etc.)\n * @param options - Configuration options including observation type and timing\n * @returns Strongly-typed observation object based on `asType` parameter\n *\n * @example\n * ```typescript\n * import { startObservation } from '@elasticdash/tracing';\n *\n * // Span for general operations (default)\n * const span = startObservation('user-workflow', {\n * input: { userId: '123', action: 'checkout' },\n * metadata: { version: '2.1.0', feature: 'new-checkout' }\n * });\n * span.update({ output: { success: true, orderId: '456' } });\n * span.end();\n *\n * // Generation for LLM interactions\n * const generation = startObservation('openai-gpt-4', {\n * input: [{ role: 'user', content: 'Explain quantum computing' }],\n * model: 'gpt-4-turbo',\n * modelParameters: { temperature: 0.7, maxTokens: 500 }\n * }, { asType: 'generation' });\n *\n * generation.update({\n * output: { role: 'assistant', content: 'Quantum computing...' },\n * usageDetails: { promptTokens: 12, completionTokens: 150, totalTokens: 162 },\n * costDetails: { totalCost: 0.002, currency: 'USD' }\n * });\n * generation.end();\n *\n * // Agent for AI workflows with tools\n * const agent = startObservation('research-agent', {\n * input: { query: 'Latest developments in renewable energy' },\n * metadata: { tools: ['web-search', 'pdf-reader'], model: 'gpt-4' }\n * }, { asType: 'agent' });\n *\n * // Tool for individual API calls\n * const weatherTool = startObservation('weather-api', {\n * input: { location: 'San Francisco', units: 'metric' },\n * metadata: { provider: 'openweather', timeout: 5000 }\n * }, { asType: 'tool' });\n *\n * // Chain for multi-step RAG pipeline\n * const ragChain = startObservation('rag-qa-pipeline', {\n * input: { question: 'How does photosynthesis work?' },\n * metadata: { steps: ['retrieve', 'rerank', 'generate'], vectorDb: 'pinecone' }\n * }, { asType: 'chain' });\n *\n * // Retriever for vector search\n * const retriever = startObservation('vector-search', {\n * input: { query: 'machine learning algorithms', topK: 5 },\n * metadata: { vectorStore: 'chroma', similarity: 'cosine' }\n * }, { asType: 'retriever' });\n *\n * // Evaluator for quality assessment\n * const evaluator = startObservation('quality-check', {\n * input: {\n * response: 'Paris is the capital of France',\n * reference: 'The capital city of France is Paris'\n * },\n * metadata: { metric: 'semantic-similarity', threshold: 0.8 }\n * }, { asType: 'evaluator' });\n *\n * // Guardrail for content filtering\n * const guardrail = startObservation('content-filter', {\n * input: { text: 'User message content', policies: ['no-profanity', 'no-pii'] },\n * metadata: { strictMode: true, version: 'v2' }\n * }, { asType: 'guardrail' });\n *\n * // Embedding for text vectorization\n * const embedding = startObservation('text-embedder', {\n * input: { texts: ['Hello world', 'Machine learning'] },\n * model: 'text-embedding-ada-002',\n * metadata: { dimensions: 1536 }\n * }, { asType: 'embedding' });\n *\n * // Event for point-in-time occurrences (auto-ended)\n * const event = startObservation('user-login', {\n * input: { userId: '123', method: 'oauth' },\n * level: 'DEFAULT',\n * metadata: { ip: '192.168.1.1', userAgent: 'Chrome/120.0' }\n * }, { asType: 'event' });\n *\n * // Nested observations with parent context\n * const parentSpan = startObservation('ai-pipeline');\n * const childRetriever = startObservation('doc-search', {\n * input: { query: 'AI safety' }\n * }, {\n * asType: 'retriever',\n * parentSpanContext: parentSpan.otelSpan.spanContext()\n * });\n * ```\n *\n * @see {@link startActiveObservation} for function-scoped observations with automatic context management\n * @see {@link observe} for decorator-style observation wrapping\n *\n * @public\n */\nexport function startObservation(\n name: string,\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes\n | LangfuseAgentAttributes\n | LangfuseToolAttributes\n | LangfuseChainAttributes\n | LangfuseRetrieverAttributes\n | LangfuseEvaluatorAttributes\n | LangfuseGuardrailAttributes\n | LangfuseEmbeddingAttributes,\n options?: StartObservationOpts,\n): LangfuseObservation {\n const { asType = \"span\", ...observationOptions } = options || {};\n\n const otelSpan = createOtelSpan({\n name,\n ...observationOptions,\n });\n\n switch (asType) {\n case \"generation\":\n return new LangfuseGeneration({\n otelSpan,\n attributes,\n });\n\n case \"embedding\":\n return new LangfuseEmbedding({\n otelSpan,\n attributes,\n });\n\n case \"agent\":\n return new LangfuseAgent({\n otelSpan,\n attributes,\n });\n\n case \"tool\":\n return new LangfuseTool({\n otelSpan,\n attributes,\n });\n\n case \"chain\":\n return new LangfuseChain({\n otelSpan,\n attributes,\n });\n\n case \"retriever\":\n return new LangfuseRetriever({\n otelSpan,\n attributes,\n });\n\n case \"evaluator\":\n return new LangfuseEvaluator({\n otelSpan,\n attributes,\n });\n\n case \"guardrail\":\n return new LangfuseGuardrail({\n otelSpan,\n attributes,\n });\n\n case \"event\": {\n const timestamp = observationOptions?.startTime ?? new Date();\n\n return new LangfuseEvent({\n otelSpan,\n attributes: attributes as LangfuseEventAttributes,\n timestamp,\n });\n }\n case \"span\":\n default:\n return new LangfuseSpan({\n otelSpan,\n attributes: attributes as LangfuseSpanAttributes,\n });\n }\n}\n\n// Function overloads for proper type inference\nexport function startActiveObservation<\n F extends (generation: LangfuseGeneration) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"generation\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (embedding: LangfuseEmbedding) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"embedding\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (agent: LangfuseAgent) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"agent\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (tool: LangfuseTool) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"tool\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (chain: LangfuseChain) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"chain\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (retriever: LangfuseRetriever) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"retriever\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (evaluator: LangfuseEvaluator) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"evaluator\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (guardrail: LangfuseGuardrail) => unknown,\n>(\n name: string,\n fn: F,\n options: StartActiveObservationOpts & { asType: \"guardrail\" },\n): ReturnType<F>;\n\nexport function startActiveObservation<\n F extends (span: LangfuseSpan) => unknown,\n>(\n name: string,\n fn: F,\n options?: StartActiveObservationOpts & { asType?: \"span\" },\n): ReturnType<F>;\n/**\n * Starts an active observation and executes a function within its context with automatic lifecycle management.\n *\n * This function creates an observation, sets it as the active span in the OpenTelemetry context,\n * executes your function with the observation instance, and automatically handles cleanup.\n * It supports all observation types with full TypeScript type inference based on `asType`.\n *\n * ## Key Features\n * - **Automatic Context Management**: Sets the observation as active in the current execution context\n * - **Lifecycle Automation**: Creates, activates, and ends observations automatically\n * - **Type Safety**: Function parameter is strongly typed based on `asType`\n * - **Promise Support**: Handles both synchronous and asynchronous functions seamlessly\n * - **Error Handling**: Automatically sets error status and ends observations on exceptions\n * - **Nested Observations**: Child observations created within the function inherit the context\n *\n * ## When to Use\n * - When you want automatic observation lifecycle management\n * - For function-scoped operations where the observation maps to the function's execution\n * - When you need the observation to be active for child operations\n * - For async operations where manual `.end()` calls are error-prone\n *\n * @param name - Descriptive name for the observation\n * @param fn - Function to execute within the observation context (receives typed observation instance)\n * @param options - Configuration options including observation type and lifecycle settings\n * @returns The exact return value of the executed function (preserves type and async behavior)\n *\n * @example\n * ```typescript\n * import { startActiveObservation } from '@elasticdash/tracing';\n *\n * // Span for general operations (default)\n * const result = startActiveObservation('user-checkout', (span) => {\n * span.update({ input: { userId: '123', cart: items } });\n *\n * // Any child observations created here inherit this span's context\n * const validation = processPayment(paymentData);\n *\n * span.update({ output: { orderId: 'ord_456', success: true } });\n * return validation;\n * });\n *\n * // Generation for LLM interactions with automatic error handling\n * const response = await startActiveObservation(\n * 'openai-completion',\n * async (generation) => {\n * generation.update({\n * input: { messages: [{ role: 'user', content: 'Explain AI ethics' }] },\n * model: 'gpt-4-turbo',\n * modelParameters: { temperature: 0.7, maxTokens: 500 }\n * });\n *\n * try {\n * const result = await openai.chat.completions.create({\n * model: 'gpt-4-turbo',\n * messages: [{ role: 'user', content: 'Explain AI ethics' }],\n * temperature: 0.7,\n * max_tokens: 500\n * });\n *\n * generation.update({\n * output: result.choices[0].message,\n * usageDetails: {\n * promptTokens: result.usage?.prompt_tokens,\n * completionTokens: result.usage?.completion_tokens,\n * totalTokens: result.usage?.total_tokens\n * },\n * costDetails: { totalCost: 0.002, currency: 'USD' }\n * });\n *\n * return result.choices[0].message.content;\n * } catch (error) {\n * generation.update({\n * level: 'ERROR',\n * statusMessage: error.message,\n * output: { error: error.message }\n * });\n * throw error;\n * }\n * },\n * { asType: 'generation' }\n * );\n *\n * // Agent workflow with nested tool calls\n * const agentResult = await startActiveObservation(\n * 'research-agent',\n * async (agent) => {\n * agent.update({\n * input: { query: 'Latest climate change research' },\n * metadata: { tools: ['web-search', 'arxiv-search'], model: 'gpt-4' }\n * });\n *\n * // Tool calls inherit the agent context automatically\n * const webResults = await startActiveObservation(\n * 'web-search-tool',\n * async (tool) => {\n * tool.update({ input: { query: 'climate change 2024' } });\n * const results = await searchWeb('climate change 2024');\n * tool.update({ output: results });\n * return results;\n * },\n * { asType: 'tool' }\n * );\n *\n * const analysis = await analyzeResults(webResults);\n *\n * agent.update({\n * output: { analysis, sources: webResults.length },\n * metadata: { processingTime: Date.now() }\n * });\n *\n * return analysis;\n * },\n * { asType: 'agent' }\n * );\n *\n * // RAG Chain with retriever and generation steps\n * const answer = await startActiveObservation(\n * 'rag-qa-chain',\n * async (chain) => {\n * chain.update({\n * input: { question: 'How does photosynthesis work?' },\n * metadata: { vectorDb: 'pinecone', model: 'gpt-4' }\n * });\n *\n * // Retrieval step\n * const docs = await startActiveObservation(\n * 'vector-retrieval',\n * async (retriever) => {\n * retriever.update({\n * input: { query: 'photosynthesis mechanism', topK: 5 },\n * metadata: { similarity: 'cosine' }\n * });\n * const results = await vectorSearch('photosynthesis mechanism');\n * retriever.update({ output: { documents: results } });\n * return results;\n * },\n * { asType: 'retriever' }\n * );\n *\n * // Generation step\n * const response = await startActiveObservation(\n * 'answer-generation',\n * async (generation) => {\n * const context = docs.map(d => d.content).join('\\n');\n * generation.update({\n * input: { question: 'How does photosynthesis work?', context },\n * model: 'gpt-4'\n * });\n *\n * const answer = await generateAnswer(context);\n * generation.update({ output: { answer } });\n * return answer;\n * },\n * { asType: 'generation' }\n * );\n *\n * chain.update({\n * output: { answer: response, sources: docs.length }\n * });\n *\n * return response;\n * },\n * { asType: 'chain' }\n * );\n *\n * // Quality evaluation with automatic metrics\n * const evaluation = startActiveObservation(\n * 'response-evaluator',\n * (evaluator) => {\n * evaluator.update({\n * input: {\n * response: 'Paris is the capital of France.',\n * reference: 'The capital city of France is Paris.'\n * },\n * metadata: { metric: 'semantic-similarity' }\n * });\n *\n * const score = calculateSimilarity(response, reference);\n * const passed = score > 0.8;\n *\n * evaluator.update({\n * output: { score, passed, grade: passed ? 'excellent' : 'needs_improvement' }\n * });\n *\n * return { score, passed };\n * },\n * { asType: 'evaluator' }\n * );\n *\n * // Content filtering with guardrails\n * const safetyCheck = startActiveObservation(\n * 'content-guardrail',\n * (guardrail) => {\n * guardrail.update({\n * input: { text: userMessage, policies: ['no-profanity', 'no-pii'] },\n * metadata: { strictMode: true }\n * });\n *\n * const violations = checkContent(userMessage);\n * const allowed = violations.length === 0;\n *\n * guardrail.update({\n * output: { allowed, violations, confidence: 0.95 }\n * });\n *\n * return { allowed, violations };\n * },\n * { asType: 'guardrail' }\n * );\n *\n * // Text embedding generation\n * const embeddings = await startActiveObservation(\n * 'text-embeddings',\n * async (embedding) => {\n * const texts = ['Hello world', 'Machine learning'];\n * embedding.update({\n * input: { texts },\n * model: 'text-embedding-ada-002',\n * metadata: { dimensions: 1536 }\n * });\n *\n * const vectors = await generateEmbeddings(texts);\n *\n * embedding.update({\n * output: { embeddings: vectors },\n * usageDetails: { totalTokens: texts.join(' ').split(' ').length }\n * });\n *\n * return vectors;\n * },\n * { asType: 'embedding' }\n * );\n *\n * // Disable automatic ending (advanced use case)\n * const longRunningSpan = await startActiveObservation(\n * 'background-process',\n * async (span) => {\n * span.update({ input: { taskId: '123' } });\n *\n * // Process continues after function returns\n * startBackgroundTask(span);\n *\n * return 'process-started';\n * },\n * { asType: 'span', endOnExit: false } // Manual ending required\n * );\n * ```\n *\n * @see {@link startObservation} for manual observation lifecycle management\n * @see {@link observe} for decorator-style function wrapping\n *\n * @public\n */\nexport function startActiveObservation<\n F extends (observation: LangfuseSpan | LangfuseGeneration) => unknown,\n>(name: string, fn: F, options?: StartActiveObservationOpts): ReturnType<F> {\n const { asType = \"span\", ...observationOptions } = options || {};\n\n return getLangfuseTracer().startActiveSpan(\n name,\n { startTime: observationOptions?.startTime },\n createParentContext(observationOptions?.parentSpanContext) ??\n context.active(),\n (span) => {\n try {\n let observation: LangfuseObservation;\n\n switch (asType) {\n case \"generation\":\n observation = new LangfuseGeneration({\n otelSpan: span,\n });\n break;\n\n case \"embedding\":\n observation = new LangfuseEmbedding({\n otelSpan: span,\n });\n break;\n\n case \"agent\":\n observation = new LangfuseAgent({\n otelSpan: span,\n });\n break;\n\n case \"tool\":\n observation = new LangfuseTool({\n otelSpan: span,\n });\n break;\n\n case \"chain\":\n observation = new LangfuseChain({\n otelSpan: span,\n });\n break;\n\n case \"retriever\":\n observation = new LangfuseRetriever({\n otelSpan: span,\n });\n break;\n\n case \"evaluator\":\n observation = new LangfuseEvaluator({\n otelSpan: span,\n });\n break;\n\n case \"guardrail\":\n observation = new LangfuseGuardrail({\n otelSpan: span,\n });\n break;\n\n case \"event\": {\n const timestamp = observationOptions?.startTime ?? new Date();\n observation = new LangfuseEvent({\n otelSpan: span,\n timestamp,\n });\n break;\n }\n case \"span\":\n default:\n observation = new LangfuseSpan({\n otelSpan: span,\n });\n }\n\n const result = fn(observation as Parameters<F>[0]);\n\n if (result instanceof Promise) {\n return wrapPromise(\n result,\n span,\n observationOptions?.endOnExit,\n ) as ReturnType<F>;\n } else {\n if (observationOptions?.endOnExit !== false) {\n span.end();\n }\n\n return result as ReturnType<F>;\n }\n } catch (err) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : \"Unknown error\",\n });\n\n if (observationOptions?.endOnExit !== false) {\n span.end();\n }\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 '@elasticdash/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 observation with new attributes.\n *\n * This function finds the currently active OpenTelemetry span in the execution context\n * and updates it with Langfuse-specific attributes. It supports all observation types\n * through TypeScript overloads, providing type safety for attributes based on the\n * specified `asType` parameter. If no active span exists, the update is skipped with a warning.\n *\n * ## Type Safety\n * - Automatic type inference based on `asType` parameter\n * - Compile-time validation of attribute compatibility\n * - IntelliSense support for observation-specific attributes\n *\n * ## Context Requirements\n * - Must be called within an active OpenTelemetry span context\n * - Typically used inside `startActiveObservation` callbacks or manual span contexts\n * - Relies on OpenTelemetry's context propagation mechanism\n *\n * ## Supported Observation Types\n * - **span** (default): General-purpose operations and workflows\n * - **generation**: LLM calls and AI model interactions\n * - **agent**: AI agent workflows with tool usage\n * - **tool**: Individual tool calls and API requests\n * - **chain**: Multi-step processes and pipelines\n * - **retriever**: Document retrieval and search operations\n * - **evaluator**: Quality assessment and scoring\n * - **guardrail**: Safety checks and content filtering\n * - **embedding**: Text embedding and vector operations\n *\n * @param attributes - Observation-specific attributes to update (type varies by observation type)\n * @param options - Configuration specifying observation type (defaults to 'span')\n *\n * @example\n * ```typescript\n * import { updateActiveObservation, startActiveObservation } from '@elasticdash/tracing';\n *\n * // Update active span (default)\n * await startActiveObservation('data-processing', async (observation) => {\n * // Process data...\n * const result = await processData(inputData);\n *\n * // Update with results\n * updateActiveObservation({\n * output: { processedRecords: result.count },\n * metadata: { processingTime: result.duration }\n * });\n * });\n *\n * // Update active generation\n * await startActiveObservation('llm-call', async () => {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4',\n * messages: [{ role: 'user', content: 'Hello' }]\n * });\n *\n * // Update with LLM-specific attributes\n * updateActiveObservation({\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 * costDetails: {\n * totalCost: 0.025,\n * currency: 'USD'\n * }\n * }, { asType: 'generation' });\n * }, {}, { asType: 'generation' });\n *\n * // Update active tool execution\n * await startActiveObservation('web-search', async () => {\n * const results = await searchAPI('latest news');\n *\n * updateActiveObservation({\n * output: {\n * results: results,\n * count: results.length,\n * relevanceScore: 0.89\n * },\n * metadata: {\n * searchLatency: 150,\n * cacheHit: false\n * }\n * }, { asType: 'tool' });\n * }, {}, { asType: 'tool' });\n *\n * // Update active agent workflow\n * await startActiveObservation('research-agent', async () => {\n * // Agent performs multiple operations...\n * const findings = await conductResearch();\n *\n * updateActiveObservation({\n * output: {\n * completed: true,\n * toolsUsed: ['web-search', 'summarizer'],\n * iterationsRequired: 3,\n * confidence: 0.92\n * },\n * metadata: {\n * efficiency: 0.85,\n * qualityScore: 0.88\n * }\n * }, { asType: 'agent' });\n * }, {}, { asType: 'agent' });\n *\n * // Update active chain workflow\n * await startActiveObservation('rag-pipeline', async () => {\n * // Execute multi-step RAG process...\n * const finalResponse = await executeRAGPipeline();\n *\n * updateActiveObservation({\n * output: {\n * finalResponse: finalResponse,\n * stepsCompleted: 4,\n * documentsRetrieved: 8,\n * qualityScore: 0.91\n * },\n * metadata: {\n * pipelineEfficiency: 0.87,\n * totalLatency: 3200\n * }\n * }, { asType: 'chain' });\n * }, {}, { asType: 'chain' });\n * ```\n *\n * @see {@link startActiveObservation} - For creating active observation contexts\n * @see {@link updateActiveTrace} - For updating trace-level attributes\n *\n * @public\n */\nexport function updateActiveObservation(\n attributes: LangfuseSpanAttributes,\n options?: { asType: \"span\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseGenerationAttributes,\n options: { asType: \"generation\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseAgentAttributes,\n options: { asType: \"agent\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseToolAttributes,\n options: { asType: \"tool\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseChainAttributes,\n options: { asType: \"chain\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseEmbeddingAttributes,\n options: { asType: \"embedding\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseEvaluatorAttributes,\n options: { asType: \"evaluator\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseGuardrailAttributes,\n options: { asType: \"guardrail\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseRetrieverAttributes,\n options: { asType: \"retriever\" },\n): void;\nexport function updateActiveObservation(\n attributes: LangfuseObservationAttributes,\n options?: { asType?: LangfuseObservationType },\n): void {\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 const otelAttributes = createObservationAttributes(\n options?.asType ?? \"span\",\n attributes,\n );\n\n // If no 'asType' was provided, drop the observation type OTEL attribute\n // to avoid inadvertendly overwriting the type to \"span\"\n if (!options?.asType) {\n otelAttributes[LangfuseOtelSpanAttributes.OBSERVATION_TYPE] = undefined;\n }\n\n span.setAttributes(otelAttributes);\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?: LangfuseObservationType;\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 /** Whether to automatically end the observation when exiting the context. Default is true */\n endOnExit?: boolean;\n}\n\n/**\n * Decorator function that automatically wraps any function with Langfuse observability.\n *\n * This higher-order function creates a traced version of your function that automatically\n * handles observation lifecycle, input/output capture, and error tracking. It's perfect\n * for instrumenting existing functions without modifying their internal logic.\n *\n * ## Key Features\n * - **Zero Code Changes**: Wrap existing functions without modifying their implementation\n * - **Automatic I/O Capture**: Optionally captures function arguments and return values\n * - **Error Tracking**: Automatically captures exceptions and sets error status\n * - **Type Preservation**: Maintains original function signature and return types\n * - **Async Support**: Works seamlessly with both sync and async functions\n * - **Flexible Configuration**: Control observation type, naming, and capture behavior\n *\n * ## Use Cases\n * - Instrumenting business logic functions\n * - Wrapping API calls and external service interactions\n * - Adding observability to utility functions\n * - Creating traced versions of third-party functions\n * - Decorating class methods for observability\n *\n * @param fn - The function to wrap with observability (preserves original signature)\n * @param options - Configuration for observation behavior and capture settings\n * @returns An instrumented version of the function with identical behavior plus tracing\n *\n * @example\n * ```typescript\n * import { observe } from '@elasticdash/tracing';\n *\n * // Basic function wrapping with automatic I/O capture\n * const processOrder = observe(\n * async (orderId: string, items: CartItem[]) => {\n * const validation = await validateOrder(orderId, items);\n * const payment = await processPayment(validation);\n * const shipping = await scheduleShipping(payment);\n * return { orderId, status: 'confirmed', trackingId: shipping.id };\n * },\n * {\n * name: 'process-order',\n * asType: 'span',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // LLM function with generation tracking\n * const generateSummary = observe(\n * async (document: string, maxWords: number = 100) => {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4-turbo',\n * messages: [\n * { role: 'system', content: `Summarize in ${maxWords} words or less` },\n * { role: 'user', content: document }\n * ],\n * max_tokens: maxWords * 2\n * });\n * return response.choices[0].message.content;\n * },\n * {\n * name: 'document-summarizer',\n * asType: 'generation',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Database query with automatic error tracking\n * const fetchUserProfile = observe(\n * async (userId: string) => {\n * const user = await db.users.findUnique({ where: { id: userId } });\n * if (!user) throw new Error(`User ${userId} not found`);\n *\n * const preferences = await db.preferences.findMany({\n * where: { userId }\n * });\n *\n * return { ...user, preferences };\n * },\n * {\n * name: 'fetch-user-profile',\n * asType: 'span',\n * captureInput: false, // Don't capture sensitive user IDs\n * captureOutput: true\n * }\n * );\n *\n * // Vector search with retriever semantics\n * const searchDocuments = observe(\n * async (query: string, topK: number = 5) => {\n * const embedding = await embedText(query);\n * const results = await vectorDb.search(embedding, topK);\n * return results.map(r => ({\n * content: r.metadata.content,\n * score: r.score,\n * source: r.metadata.source\n * }));\n * },\n * {\n * name: 'document-search',\n * asType: 'retriever',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Quality evaluation function\n * const evaluateResponse = observe(\n * (response: string, reference: string, metric: string = 'similarity') => {\n * let score: number;\n *\n * switch (metric) {\n * case 'similarity':\n * score = calculateCosineSimilarity(response, reference);\n * break;\n * case 'bleu':\n * score = calculateBleuScore(response, reference);\n * break;\n * default:\n * throw new Error(`Unknown metric: ${metric}`);\n * }\n *\n * return {\n * score,\n * passed: score > 0.8,\n * metric,\n * grade: score > 0.9 ? 'excellent' : score > 0.7 ? 'good' : 'needs_improvement'\n * };\n * },\n * {\n * name: 'response-evaluator',\n * asType: 'evaluator',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Content moderation with guardrails\n * const moderateContent = observe(\n * async (text: string, policies: string[] = ['profanity', 'spam']) => {\n * const violations = [];\n *\n * for (const policy of policies) {\n * const result = await checkPolicy(text, policy);\n * if (result.violation) {\n * violations.push({ policy, severity: result.severity });\n * }\n * }\n *\n * return {\n * allowed: violations.length === 0,\n * violations,\n * confidence: 0.95\n * };\n * },\n * {\n * name: 'content-moderator',\n * asType: 'guardrail',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // AI agent function with tool usage\n * const researchAgent = observe(\n * async (query: string, maxSources: number = 3) => {\n * // Search for relevant documents\n * const documents = await searchDocuments(query, maxSources * 2);\n *\n * // Filter and rank results\n * const topDocs = documents\n * .filter(d => d.score > 0.7)\n * .slice(0, maxSources);\n *\n * // Generate comprehensive answer\n * const context = topDocs.map(d => d.content).join('\\n\\n');\n * const answer = await generateSummary(\n * `Based on: ${context}\\n\\nQuestion: ${query}`,\n * 200\n * );\n *\n * return {\n * answer,\n * sources: topDocs.map(d => d.source),\n * confidence: Math.min(...topDocs.map(d => d.score))\n * };\n * },\n * {\n * name: 'research-agent',\n * asType: 'agent',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Class method decoration\n * class UserService {\n * private db: Database;\n *\n * // Wrap methods during class construction\n * constructor(database: Database) {\n * this.db = database;\n * this.createUser = observe(this.createUser.bind(this), {\n * name: 'create-user',\n * asType: 'span',\n * captureInput: false, // Sensitive data\n * captureOutput: true\n * });\n * }\n *\n * async createUser(userData: UserData) {\n * // Implementation automatically traced\n * return await this.db.users.create(userData);\n * }\n * }\n *\n * // Chain composition - functions remain composable\n * const processDocument = observe(\n * async (document: string) => {\n * const summary = await generateSummary(document, 150);\n * const moderation = await moderateContent(summary);\n * const evaluation = evaluateResponse(summary, document, 'similarity');\n *\n * return {\n * summary: moderation.allowed ? summary : '[Content Filtered]',\n * safe: moderation.allowed,\n * quality: evaluation.score\n * };\n * },\n * {\n * name: 'document-processor',\n * asType: 'chain',\n * captureInput: true,\n * captureOutput: true\n * }\n * );\n *\n * // Usage - functions work exactly as before, just with observability\n * const order = await processOrder('ord_123', cartItems);\n * const profile = await fetchUserProfile('user_456');\n * const research = await researchAgent('What is quantum computing?');\n * const processed = await processDocument(documentText);\n * ```\n *\n * @see {@link startObservation} for manual observation creation\n * @see {@link startActiveObservation} for function-scoped observations\n *\n * @public\n */\nexport function observe<T extends (...args: any[]) => any>(\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 = startObservation(\n name,\n inputData ? { input: inputData } : {},\n {\n asType: asType as \"span\", // typecast necessary as ts cannot narrow down type\n parentSpanContext,\n },\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 if (result instanceof Promise) {\n return result.then(\n (value) => {\n if (captureOutput) {\n observation.update({ output: _captureOutput(value) });\n }\n\n if (options?.endOnExit !== false) {\n observation.end();\n }\n\n return value;\n },\n (error: unknown) => {\n observation.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\n if (options?.endOnExit !== false) {\n observation.end();\n }\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\n if (options?.endOnExit !== false) {\n observation.end();\n }\n\n return result as ReturnType<T>;\n }\n } catch (error: unknown) {\n observation.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\n if (options?.endOnExit !== false) {\n observation.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 = startObservation(\"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 \"@elasticdash/core\";\nimport { type Attributes } from \"@opentelemetry/api\";\n\nimport {\n LangfuseObservationAttributes,\n LangfuseObservationType,\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 '@elasticdash/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\nexport function createObservationAttributes(\n type: LangfuseObservationType,\n attributes: LangfuseObservationAttributes,\n): Attributes {\n const {\n metadata,\n input,\n output,\n level,\n statusMessage,\n version,\n completionStartTime,\n model,\n modelParameters,\n usageDetails,\n costDetails,\n prompt,\n } = attributes;\n\n let otelAttributes: Attributes = {\n [LangfuseOtelSpanAttributes.OBSERVATION_TYPE]: type,\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(otelAttributes).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 if (typeof obj === \"string\") return obj;\n\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 ELASTICDASH_SDK_VERSION,\n ELASTICDASH_TRACER_NAME,\n} from \"@elasticdash/core\";\nimport { TracerProvider, trace } from \"@opentelemetry/api\";\n\nconst ELASTICDASH_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 [ELASTICDASH_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[ELASTICDASH_GLOBAL_SYMBOL]) {\n Object.defineProperty(g, ELASTICDASH_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[ELASTICDASH_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 '@elasticdash/otel';\n * import { setLangfuseTracerProvider } from '@elasticdash/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 '@elasticdash/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 '@elasticdash/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 ELASTICDASH_TRACER_NAME,\n ELASTICDASH_SDK_VERSION,\n );\n}\n","import { Span, TimeInput } from \"@opentelemetry/api\";\n\nimport {\n createObservationAttributes,\n createTraceAttributes,\n} from \"./attributes.js\";\nimport { getLangfuseTracer } from \"./tracerProvider.js\";\nimport {\n LangfuseGenerationAttributes,\n LangfuseSpanAttributes,\n LangfuseEventAttributes,\n LangfuseTraceAttributes,\n} from \"./types.js\";\nimport type {\n LangfuseAgentAttributes,\n LangfuseChainAttributes,\n LangfuseEmbeddingAttributes,\n LangfuseEvaluatorAttributes,\n LangfuseGuardrailAttributes,\n LangfuseObservationAttributes,\n LangfuseObservationType,\n LangfuseRetrieverAttributes,\n LangfuseToolAttributes,\n} from \"./types.js\";\n\nimport { startObservation } from \"./index.js\";\n\n/**\n * Union type representing any Langfuse observation wrapper.\n *\n * This type encompasses all observation types supported by Langfuse, providing\n * a unified interface for handling different kinds of traced operations. It's\n * particularly useful for generic functions that work with any observation type.\n *\n * ## Included Types\n * - **LangfuseSpan**: General-purpose operations and workflows\n * - **LangfuseGeneration**: LLM calls and AI model interactions\n * - **LangfuseEmbedding**: Text embedding and vector operations\n * - **LangfuseAgent**: AI agent workflows with tool usage\n * - **LangfuseTool**: Individual tool calls and API requests\n * - **LangfuseChain**: Multi-step processes and pipelines\n * - **LangfuseRetriever**: Document retrieval and search operations\n * - **LangfuseEvaluator**: Quality assessment and scoring\n * - **LangfuseGuardrail**: Safety checks and content filtering\n * - **LangfuseEvent**: Point-in-time occurrences and log entries\n *\n * @example\n * ```typescript\n * // Function accepting any observation type\n * function logObservation(obs: LangfuseObservation) {\n * console.log(`Observation ${obs.id} in trace ${obs.traceId}`);\n *\n * // All observations have common methods\n * obs.updateTrace({ tags: ['logged'] });\n * obs.end();\n * }\n *\n * // Works with any observation type\n * const span = startObservation('test-span');\n * const generation = startObservation('llm-call', {}, { asType: 'generation' });\n * const agent = startObservation('ai-agent', {}, { asType: 'agent' });\n *\n * logObservation(span);\n * logObservation(generation);\n * logObservation(agent);\n * ```\n *\n * @public\n */\nexport type LangfuseObservation =\n | LangfuseSpan\n | LangfuseGeneration\n | LangfuseEvent\n | LangfuseAgent\n | LangfuseTool\n | LangfuseChain\n | LangfuseRetriever\n | LangfuseEvaluator\n | LangfuseGuardrail\n | LangfuseEmbedding;\n\n/**\n * Parameters for creating a Langfuse observation wrapper.\n *\n * @internal\n */\ntype LangfuseObservationParams = {\n otelSpan: Span;\n type: LangfuseObservationType;\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes;\n};\n\n/**\n * Base class for all Langfuse observation wrappers providing unified functionality.\n *\n * This abstract class serves as the foundation for all observation types in Langfuse,\n * encapsulating common operations and properties shared across spans, generations,\n * events, and specialized observation types like agents, tools, and chains.\n *\n * ## Core Capabilities\n * - **OpenTelemetry Integration**: Wraps OTEL spans with Langfuse-specific functionality\n * - **Unique Identification**: Provides span ID and trace ID for correlation\n * - **Lifecycle Management**: Handles observation creation, updates, and completion\n * - **Trace Context**: Enables updating trace-level attributes from any observation\n * - **Hierarchical Structure**: Supports creating nested child observations\n * - **Type Safety**: Ensures type-safe attribute handling based on observation type\n *\n * ## Common Properties\n * - `id`: Unique identifier for this observation (OpenTelemetry span ID)\n * - `traceId`: Identifier of the parent trace containing this observation\n * - `otelSpan`: Direct access to the underlying OpenTelemetry span\n * - `type`: The observation type (span, generation, event, etc.)\n *\n * ## Common Methods\n * - `end()`: Marks the observation as complete with optional timestamp\n * - `updateTrace()`: Sets trace-level attributes like user ID, session ID, tags\n * - `startObservation()`: Creates child observations with inherited context\n *\n * @example\n * ```typescript\n * // All observation types share these common capabilities\n * const observation: LangfuseObservation = startObservation('my-operation');\n *\n * // Common properties available on all observations\n * console.log(`Observation ID: ${observation.id}`);\n * console.log(`Trace ID: ${observation.traceId}`);\n * console.log(`Type: ${observation.type}`);\n *\n * // Common methods available on all observations\n * observation.updateTrace({\n * userId: 'user-123',\n * sessionId: 'session-456',\n * tags: ['production', 'api-v2']\n * });\n *\n * // Create child observations\n * const child = observation.startObservation('child-operation', {\n * input: { step: 'processing' }\n * });\n *\n * // End observations\n * child.end();\n * observation.end();\n * ```\n *\n * @internal\n */\nabstract class LangfuseBaseObservation {\n /** The underlying OpenTelemetry span */\n public readonly otelSpan: Span;\n /** The underlying OpenTelemetry span */\n public readonly type: LangfuseObservationType;\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: LangfuseObservationParams) {\n this.otelSpan = params.otelSpan;\n this.id = params.otelSpan.spanContext().spanId;\n this.traceId = params.otelSpan.spanContext().traceId;\n this.type = params.type;\n\n if (params.attributes) {\n this.otelSpan.setAttributes(\n createObservationAttributes(params.type, params.attributes),\n );\n }\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 updateOtelSpanAttributes(attributes: LangfuseObservationAttributes) {\n this.otelSpan.setAttributes(\n createObservationAttributes(this.type, attributes),\n );\n }\n\n /**\n * Updates the parent trace with new attributes.\n */\n public updateTrace(attributes: LangfuseTraceAttributes) {\n this.otelSpan.setAttributes(createTraceAttributes(attributes));\n\n return this;\n }\n\n /**\n * Creates a new child observation within this observation's context with full type safety.\n *\n * This method enables hierarchical tracing by creating child observations that inherit\n * the parent's trace context. It supports all observation types with automatic TypeScript\n * type inference based on the `asType` parameter, ensuring compile-time safety for\n * attributes and return types.\n *\n * ## Hierarchy & Context\n * - Child observations automatically inherit the parent's trace ID and span context\n * - Creates proper parent-child relationships in the trace structure\n * - Enables distributed tracing across nested operations\n * - Maintains correlation between related operations\n *\n * ## Type Safety\n * - Return type is automatically inferred from `asType` parameter\n * - Attributes parameter is type-checked based on observation type\n * - Compile-time validation prevents type mismatches\n * - Full IntelliSense support for observation-specific attributes\n *\n * @param name - Descriptive name for the child observation\n * @param attributes - Type-specific attributes (varies by observation type)\n * @param options - Configuration including observation type (defaults to 'span')\n * @returns Strongly-typed observation instance based on `asType`\n *\n * @example\n * ```typescript\n * // Within any observation (span, generation, agent, etc.)\n * const parentObservation = startObservation('ai-workflow');\n *\n * // Create child span (default)\n * const dataProcessing = parentObservation.startObservation('data-processing', {\n * input: { userId: '123', dataSize: 1024 },\n * metadata: { processor: 'fast-lane', version: '2.1' }\n * }); // Returns LangfuseSpan\n *\n * // Create child generation with full LLM attributes\n * const llmCall = parentObservation.startObservation('openai-gpt-4', {\n * input: [{ role: 'system', content: 'You are a helpful assistant' },\n * { role: 'user', content: 'Explain machine learning' }],\n * model: 'gpt-4-turbo',\n * modelParameters: {\n * temperature: 0.7,\n * maxTokens: 500,\n * topP: 1.0\n * },\n * metadata: { priority: 'high', timeout: 30000 }\n * }, { asType: 'generation' }); // Returns LangfuseGeneration\n *\n * // Create child agent for complex reasoning\n * const reasoningAgent = parentObservation.startObservation('reasoning-agent', {\n * input: {\n * task: 'Analyze market trends',\n * context: 'Q4 2024 financial data'\n * },\n * metadata: {\n * model: 'gpt-4',\n * tools: ['calculator', 'web-search', 'data-analysis'],\n * maxIterations: 5\n * }\n * }, { asType: 'agent' }); // Returns LangfuseAgent\n *\n * // Create child tool for external API calls\n * const apiCall = reasoningAgent.startObservation('market-data-api', {\n * input: {\n * endpoint: '/market/trends',\n * params: { symbol: 'AAPL', period: '1Y' }\n * },\n * metadata: {\n * provider: 'alpha-vantage',\n * rateLimit: 5,\n * timeout: 10000\n * }\n * }, { asType: 'tool' }); // Returns LangfuseTool\n *\n * // Create child retriever for document search\n * const docSearch = parentObservation.startObservation('document-retrieval', {\n * input: {\n * query: 'sustainable energy solutions',\n * filters: { year: '2024', category: 'research' },\n * topK: 10\n * },\n * metadata: {\n * vectorStore: 'pinecone',\n * embeddingModel: 'text-embedding-ada-002',\n * similarity: 'cosine'\n * }\n * }, { asType: 'retriever' }); // Returns LangfuseRetriever\n *\n * // Create child evaluator for quality assessment\n * const qualityCheck = parentObservation.startObservation('response-evaluator', {\n * input: {\n * response: llmCall.output?.content,\n * reference: 'Expected high-quality explanation',\n * criteria: ['accuracy', 'clarity', 'completeness']\n * },\n * metadata: {\n * evaluator: 'custom-bert-scorer',\n * threshold: 0.8,\n * metrics: ['bleu', 'rouge', 'semantic-similarity']\n * }\n * }, { asType: 'evaluator' }); // Returns LangfuseEvaluator\n *\n * // Create child guardrail for safety checking\n * const safetyCheck = parentObservation.startObservation('content-guardrail', {\n * input: {\n * text: llmCall.output?.content,\n * policies: ['no-harmful-content', 'no-personal-info', 'professional-tone']\n * },\n * metadata: {\n * guardrailVersion: 'v2.1',\n * strictMode: true,\n * confidence: 0.95\n * }\n * }, { asType: 'guardrail' }); // Returns LangfuseGuardrail\n *\n * // Create child embedding for vector generation\n * const textEmbedding = parentObservation.startObservation('text-embedder', {\n * input: {\n * texts: ['Document summary', 'Key insights', 'Conclusions'],\n * batchSize: 3\n * },\n * model: 'text-embedding-ada-002',\n * metadata: {\n * dimensions: 1536,\n * normalization: 'l2',\n * purpose: 'semantic-search'\n * }\n * }, { asType: 'embedding' }); // Returns LangfuseEmbedding\n *\n * // Create child event for point-in-time logging\n * const userAction = parentObservation.startObservation('user-interaction', {\n * input: {\n * action: 'button-click',\n * element: 'generate-report',\n * timestamp: new Date().toISOString()\n * },\n * level: 'DEFAULT',\n * metadata: {\n * sessionId: 'sess_123',\n * userId: 'user_456',\n * browser: 'Chrome 120.0'\n * }\n * }, { asType: 'event' }); // Returns LangfuseEvent (auto-ended)\n *\n * // Chain operations - each child inherits context\n * dataProcessing.update({ output: { processed: true, records: 1000 } });\n * dataProcessing.end();\n *\n * llmCall.update({\n * output: { role: 'assistant', content: 'Machine learning is...' },\n * usageDetails: { promptTokens: 25, completionTokens: 150 }\n * });\n * llmCall.end();\n *\n * parentObservation.update({\n * output: {\n * workflowCompleted: true,\n * childOperations: 8,\n * totalDuration: Date.now() - startTime\n * }\n * });\n * parentObservation.end();\n * ```\n *\n * @see {@link startObservation} for creating root-level observations\n * @see {@link startActiveObservation} for function-scoped child observations\n */\n public startObservation(\n name: string,\n attributes: LangfuseGenerationAttributes,\n options: { asType: \"generation\" },\n ): LangfuseGeneration;\n public startObservation(\n name: string,\n attributes: LangfuseEventAttributes,\n options: { asType: \"event\" },\n ): LangfuseEvent;\n public startObservation(\n name: string,\n attributes: LangfuseAgentAttributes,\n options: { asType: \"agent\" },\n ): LangfuseAgent;\n public startObservation(\n name: string,\n attributes: LangfuseToolAttributes,\n options: { asType: \"tool\" },\n ): LangfuseTool;\n public startObservation(\n name: string,\n attributes: LangfuseChainAttributes,\n options: { asType: \"chain\" },\n ): LangfuseChain;\n public startObservation(\n name: string,\n attributes: LangfuseRetrieverAttributes,\n options: { asType: \"retriever\" },\n ): LangfuseRetriever;\n public startObservation(\n name: string,\n attributes: LangfuseEvaluatorAttributes,\n options: { asType: \"evaluator\" },\n ): LangfuseEvaluator;\n public startObservation(\n name: string,\n attributes: LangfuseGuardrailAttributes,\n options: { asType: \"guardrail\" },\n ): LangfuseGuardrail;\n public startObservation(\n name: string,\n attributes: LangfuseEmbeddingAttributes,\n options: { asType: \"embedding\" },\n ): LangfuseEmbedding;\n public startObservation(\n name: string,\n attributes?: LangfuseSpanAttributes,\n options?: { asType?: \"span\" },\n ): LangfuseSpan;\n public startObservation(\n name: string,\n attributes?:\n | LangfuseSpanAttributes\n | LangfuseGenerationAttributes\n | LangfuseEventAttributes\n | LangfuseAgentAttributes\n | LangfuseToolAttributes\n | LangfuseChainAttributes\n | LangfuseRetrieverAttributes\n | LangfuseEvaluatorAttributes\n | LangfuseGuardrailAttributes\n | LangfuseEmbeddingAttributes,\n options?: { asType?: LangfuseObservationType },\n ): LangfuseObservation {\n const { asType = \"span\" } = options || {};\n\n return startObservation(name, attributes, {\n asType: asType as \"span\", // typecast necessary as ts cannot narrow the type correctly\n parentSpanContext: this.otelSpan.spanContext(),\n });\n }\n}\n\ntype LangfuseSpanParams = {\n otelSpan: Span;\n attributes?: LangfuseSpanAttributes;\n};\n\n/**\n * General-purpose observation wrapper for tracking operations, functions, and workflows.\n *\n * LangfuseSpan is the default and most versatile observation type, designed for tracing\n * any operation that has a defined start and end time. It serves as the foundation for\n * building hierarchical traces and can contain any other observation type as children.\n *\n * ## Primary Use Cases\n * - **Business Logic**: User workflows, order processing, data transformations\n * - **API Operations**: REST endpoint handling, database queries, external service calls\n * - **System Operations**: File I/O, network requests, background jobs\n * - **Pipeline Steps**: Data processing stages, validation steps, orchestration\n * - **Application Functions**: Any measurable operation in your application\n *\n * ## Key Features\n * - **Hierarchical Structure**: Can contain child observations of any type\n * - **Flexible Attributes**: Supports arbitrary input, output, and metadata\n * - **Duration Tracking**: Automatically measures execution time from start to end\n * - **Status Monitoring**: Tracks success/failure states and error conditions\n * - **Context Propagation**: Maintains trace context for distributed operations\n *\n * ## Span Lifecycle\n * 1. **Creation**: Span starts automatically when created\n * 2. **Updates**: Add input data, intermediate state, metadata as needed\n * 3. **Child Operations**: Create nested observations for sub-operations\n * 4. **Completion**: Update with final output and call `.end()` to finish\n *\n * @example\n * ```typescript\n * // Basic span tracking\n * const span = startObservation('user-authentication', {\n * input: { username: 'john_doe', method: 'oauth' },\n * metadata: { provider: 'google' }\n * });\n *\n * try {\n * const user = await authenticateUser(credentials);\n * span.update({\n * output: { userId: user.id, success: true }\n * });\n * } catch (error) {\n * span.update({\n * level: 'ERROR',\n * output: { success: false, error: error.message }\n * });\n * } finally {\n * span.end();\n * }\n *\n * // Nested operations\n * const workflow = startObservation('order-processing', {\n * input: { orderId: 'ord_123' }\n * });\n *\n * const validation = workflow.startObservation('validation', {\n * input: { items: cartItems }\n * });\n * validation.update({ output: { valid: true } });\n * validation.end();\n *\n * const payment = workflow.startObservation('payment', {\n * input: { amount: 100 }\n * });\n * payment.update({ output: { status: 'completed' } });\n * payment.end();\n *\n * workflow.update({\n * output: { status: 'confirmed', steps: 2 }\n * });\n * workflow.end();\n * ```\n *\n * @see {@link startObservation} - Factory function for creating spans\n * @see {@link startActiveObservation} - Function-scoped span creation\n * @see {@link LangfuseGeneration} - For LLM and AI model interactions\n * @see {@link LangfuseEvent} - For point-in-time occurrences\n *\n * @public\n */\nexport class LangfuseSpan extends LangfuseBaseObservation {\n constructor(params: LangfuseSpanParams) {\n super({ ...params, type: \"span\" });\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 super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseAgentParams = {\n otelSpan: Span;\n attributes?: LangfuseAgentAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking AI agent workflows and autonomous operations.\n *\n * LangfuseAgent is designed for observing intelligent agent systems that combine reasoning,\n * tool usage, memory management, and decision-making in autonomous workflows. It captures\n * the complex multi-step nature of agent operations, including planning, execution, and\n * self-correction cycles typical in advanced AI agent architectures.\n *\n * ## Primary Use Cases\n * - **Autonomous AI Agents**: ReAct, AutoGPT, LangGraph agent implementations\n * - **Tool-Using Agents**: Function calling agents with external API access\n * - **Multi-Step Reasoning**: Chain-of-thought, tree-of-thought agent workflows\n * - **Planning Agents**: Goal decomposition and task planning systems\n * - **Conversational Agents**: Multi-turn dialogue agents with memory\n * - **Code Generation Agents**: AI assistants that write, test, and debug code\n *\n * ## Key Features\n * - **Multi-Step Tracking**: Captures entire agent workflow from planning to execution\n * - **Tool Integration**: Records all tool calls and their results within agent context\n * - **Decision Logic**: Tracks reasoning steps, decisions, and strategy adaptations\n * - **Memory Management**: Observes how agents maintain and use context across steps\n * - **Error Recovery**: Monitors how agents handle failures and adapt their approach\n * - **Performance Metrics**: Measures agent efficiency, success rates, and resource usage\n *\n * ## Agent-Specific Patterns\n * - **Planning Phase**: Initial goal analysis and strategy formulation\n * - **Execution Loop**: Iterative action-observation-reasoning cycles\n * - **Tool Selection**: Dynamic tool choice based on context and goals\n * - **Self-Correction**: Error detection and strategy adjustment\n * - **Memory Updates**: Context retention and knowledge accumulation\n * - **Final Synthesis**: Result compilation and quality assessment\n *\n * @example\n * ```typescript\n * // Basic agent workflow\n * const agent = startObservation('research-agent', {\n * input: {\n * task: 'Research renewable energy trends',\n * tools: ['web-search', 'summarizer'],\n * maxIterations: 3\n * }\n * }, { asType: 'agent' });\n *\n * // Agent uses tools and makes decisions\n * const searchTool = agent.startObservation('web-search', {\n * input: { query: 'renewable energy 2024' }\n * }, { asType: 'tool' });\n *\n * const results = await webSearch('renewable energy 2024');\n * searchTool.update({ output: results });\n * searchTool.end();\n *\n * // Agent generates final response\n * const generation = agent.startObservation('synthesize-findings', {\n * input: results,\n * model: 'gpt-4'\n * }, { asType: 'generation' });\n *\n * const response = await llm.generate(results);\n * generation.update({ output: response });\n * generation.end();\n *\n * agent.update({\n * output: {\n * completed: true,\n * toolsUsed: 1,\n * finalResponse: response\n * }\n * });\n * agent.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'agent' }` - Factory function\n * @see {@link startActiveObservation} with `{ asType: 'agent' }` - Function-scoped agent\n * @see {@link LangfuseTool} - For individual tool executions within agents\n * @see {@link LangfuseChain} - For structured multi-step workflows\n *\n * @public\n */\nexport class LangfuseAgent extends LangfuseBaseObservation {\n constructor(params: LangfuseAgentParams) {\n super({ ...params, type: \"agent\" });\n }\n\n /**\n * Updates this agent observation with new attributes.\n *\n * @param attributes - Agent attributes to set\n * @returns This agent for method chaining\n *\n * @example\n * ```typescript\n * agent.update({\n * output: {\n * taskCompleted: true,\n * iterationsUsed: 5,\n * toolsInvoked: ['web-search', 'calculator', 'summarizer'],\n * finalResult: 'Research completed with high confidence'\n * },\n * metadata: {\n * efficiency: 0.85,\n * qualityScore: 0.92,\n * resourcesConsumed: { tokens: 15000, apiCalls: 12 }\n * }\n * });\n * ```\n */\n public update(attributes: LangfuseAgentAttributes): LangfuseAgent {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseToolParams = {\n otelSpan: Span;\n attributes?: LangfuseToolAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking individual tool calls and external API interactions.\n *\n * LangfuseTool is designed for observing discrete tool invocations within agent workflows,\n * function calling scenarios, or standalone API integrations. It captures the input parameters,\n * execution results, performance metrics, and error conditions of tool operations, making it\n * essential for debugging tool reliability and optimizing tool selection strategies.\n *\n * ## Primary Use Cases\n * - **Function Calling**: OpenAI function calls, Anthropic tool use, Claude function calling\n * - **External APIs**: REST API calls, GraphQL queries, database operations\n * - **System Tools**: File operations, shell commands, system integrations\n * - **Data Processing Tools**: Calculators, converters, validators, parsers\n * - **Search Tools**: Web search, vector search, document retrieval\n * - **Content Tools**: Image generation, text processing, format conversion\n *\n * ## Key Features\n * - **Parameter Tracking**: Complete input parameter logging and validation\n * - **Result Capture**: Full output data and metadata from tool execution\n * - **Performance Monitoring**: Execution time, success rates, retry attempts\n * - **Error Analysis**: Detailed error tracking with context and recovery info\n * - **Usage Analytics**: Frequency, patterns, and efficiency metrics\n * - **Integration Health**: API status, rate limits, and service availability\n *\n * ## Tool-Specific Patterns\n * - **Input Validation**: Parameter checking and sanitization before execution\n * - **Execution Monitoring**: Real-time performance and status tracking\n * - **Result Processing**: Output validation, transformation, and formatting\n * - **Error Handling**: Retry logic, fallbacks, and graceful degradation\n * - **Caching Integration**: Result caching and cache hit/miss tracking\n * - **Rate Limiting**: Request throttling and quota management\n *\n * @example\n * ```typescript\n * // Web search tool\n * const searchTool = startObservation('web-search', {\n * input: {\n * query: 'latest AI developments',\n * maxResults: 10\n * },\n * metadata: { provider: 'google-api' }\n * }, { asType: 'tool' });\n *\n * try {\n * const results = await webSearch('latest AI developments');\n *\n * searchTool.update({\n * output: {\n * results: results,\n * count: results.length\n * },\n * metadata: {\n * latency: 1200,\n * cacheHit: false\n * }\n * });\n * } catch (error) {\n * searchTool.update({\n * level: 'ERROR',\n * statusMessage: 'Search failed',\n * output: { error: error.message }\n * });\n * } finally {\n * searchTool.end();\n * }\n *\n * // Database query tool\n * const dbTool = startObservation('db-query', {\n * input: {\n * query: 'SELECT * FROM users WHERE active = true',\n * timeout: 30000\n * }\n * }, { asType: 'tool' });\n *\n * const result = await db.query('SELECT * FROM users WHERE active = true');\n * dbTool.update({\n * output: { rowCount: result.length },\n * metadata: { executionTime: 150 }\n * });\n * dbTool.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'tool' }` - Factory function\n * @see {@link startActiveObservation} with `{ asType: 'tool' }` - Function-scoped tool\n * @see {@link LangfuseAgent} - For agent workflows that use multiple tools\n * @see {@link LangfuseChain} - For orchestrated tool sequences\n *\n * @public\n */\nexport class LangfuseTool extends LangfuseBaseObservation {\n constructor(params: LangfuseToolParams) {\n super({ ...params, type: \"tool\" });\n }\n\n /**\n * Updates this tool observation with new attributes.\n *\n * @param attributes - Tool attributes to set\n * @returns This tool for method chaining\n *\n * @example\n * ```typescript\n * tool.update({\n * output: {\n * result: searchResults,\n * count: searchResults.length,\n * relevanceScore: 0.89,\n * executionTime: 1250\n * },\n * metadata: {\n * cacheHit: false,\n * apiCost: 0.025,\n * rateLimitRemaining: 950\n * }\n * });\n * ```\n */\n public update(attributes: LangfuseToolAttributes): LangfuseTool {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseChainParams = {\n otelSpan: Span;\n attributes?: LangfuseChainAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking structured multi-step workflows and process chains.\n *\n * LangfuseChain is designed for observing sequential, parallel, or conditional workflow orchestration\n * where multiple operations are coordinated to achieve a larger goal. It captures the flow of data\n * between steps, manages dependencies, tracks progress through complex pipelines, and provides\n * insights into workflow performance and reliability patterns.\n *\n * ## Primary Use Cases\n * - **Data Processing Pipelines**: ETL processes, data transformation workflows\n * - **Business Process Automation**: Order processing, approval workflows, document processing\n * - **LangChain Integration**: LangChain chain execution and orchestration\n * - **RAG Pipelines**: Document retrieval → context preparation → generation → post-processing\n * - **Multi-Model Workflows**: Preprocessing → model inference → post-processing → validation\n * - **Content Production**: Research → drafting → review → editing → publishing\n *\n * ## Key Features\n * - **Step Orchestration**: Sequential, parallel, and conditional step execution tracking\n * - **Data Flow Management**: Input/output tracking between pipeline steps\n * - **Dependency Resolution**: Manages complex step dependencies and prerequisites\n * - **Progress Monitoring**: Real-time workflow progress and completion status\n * - **Error Propagation**: Handles failures, retries, and recovery across workflow steps\n * - **Performance Analytics**: Bottleneck identification and optimization insights\n *\n * ## Chain-Specific Patterns\n * - **Pipeline Setup**: Workflow definition, step configuration, and dependency mapping\n * - **Sequential Execution**: Step-by-step processing with state management\n * - **Parallel Processing**: Concurrent step execution with synchronization\n * - **Conditional Logic**: Dynamic branching based on intermediate results\n * - **Error Recovery**: Failure handling, rollback, and alternative path execution\n * - **Result Aggregation**: Combining outputs from multiple workflow branches\n *\n * @example\n * ```typescript\n * // RAG processing chain\n * const ragChain = startObservation('rag-chain', {\n * input: {\n * query: 'What is renewable energy?',\n * steps: ['retrieval', 'generation']\n * }\n * }, { asType: 'chain' });\n *\n * // Step 1: Document retrieval\n * const retrieval = ragChain.startObservation('document-retrieval', {\n * input: { query: 'renewable energy' }\n * }, { asType: 'retriever' });\n *\n * const docs = await vectorSearch('renewable energy');\n * retrieval.update({ output: { documents: docs, count: docs.length } });\n * retrieval.end();\n *\n * // Step 2: Generate response\n * const generation = ragChain.startObservation('response-generation', {\n * input: {\n * query: 'What is renewable energy?',\n * context: docs\n * },\n * model: 'gpt-4'\n * }, { asType: 'generation' });\n *\n * const response = await llm.generate({\n * prompt: buildPrompt('What is renewable energy?', docs)\n * });\n *\n * generation.update({ output: response });\n * generation.end();\n *\n * ragChain.update({\n * output: {\n * finalResponse: response,\n * stepsCompleted: 2,\n * documentsUsed: docs.length\n * }\n * });\n * ragChain.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'chain' }` - Factory function\n * @see {@link startActiveObservation} with `{ asType: 'chain' }` - Function-scoped chain\n * @see {@link LangfuseSpan} - For individual workflow steps\n * @see {@link LangfuseAgent} - For intelligent workflow orchestration\n *\n * @public\n */\nexport class LangfuseChain extends LangfuseBaseObservation {\n constructor(params: LangfuseChainParams) {\n super({ ...params, type: \"chain\" });\n }\n\n /**\n * Updates this chain observation with new attributes.\n *\n * @param attributes - Chain attributes to set\n * @returns This chain for method chaining\n *\n * @example\n * ```typescript\n * chain.update({\n * output: {\n * stepsCompleted: 5,\n * stepsSuccessful: 4,\n * finalResult: processedData,\n * pipelineEfficiency: 0.87\n * },\n * metadata: {\n * bottleneckStep: 'data-validation',\n * parallelizationOpportunities: ['step-2', 'step-3'],\n * optimizationSuggestions: ['cache-intermediate-results']\n * }\n * });\n * ```\n */\n public update(attributes: LangfuseChainAttributes): LangfuseChain {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseRetrieverParams = {\n otelSpan: Span;\n attributes?: LangfuseRetrieverAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking document retrieval and search operations.\n *\n * LangfuseRetriever is designed for observing information retrieval systems that search,\n * filter, and rank content from various data sources. It captures search queries, retrieval\n * strategies, result quality metrics, and performance characteristics of search operations,\n * making it essential for RAG systems, knowledge bases, and content discovery workflows.\n *\n * ## Primary Use Cases\n * - **Vector Search**: Semantic similarity search using embeddings and vector databases\n * - **Document Retrieval**: Full-text search, keyword matching, and document filtering\n * - **Knowledge Base Query**: FAQ systems, help documentation, and knowledge management\n * - **RAG Systems**: Retrieval step in retrieval-augmented generation pipelines\n * - **Recommendation Systems**: Content recommendations and similarity-based suggestions\n * - **Data Mining**: Information extraction and content discovery from large datasets\n *\n * ## Key Features\n * - **Query Analysis**: Input query processing, expansion, and optimization tracking\n * - **Search Strategy**: Retrieval algorithms, ranking functions, and filtering criteria\n * - **Result Quality**: Relevance scores, diversity metrics, and retrieval effectiveness\n * - **Performance Metrics**: Search latency, index size, and throughput measurements\n * - **Source Tracking**: Data source attribution and content provenance information\n * - **Ranking Intelligence**: Personalization, context awareness, and result optimization\n *\n * @example\n * ```typescript\n * // Vector search retrieval\n * const retriever = startObservation('vector-search', {\n * input: {\n * query: 'machine learning applications',\n * topK: 10,\n * similarityThreshold: 0.7\n * },\n * metadata: {\n * vectorDB: 'pinecone',\n * embeddingModel: 'text-embedding-ada-002'\n * }\n * }, { asType: 'retriever' });\n *\n * const results = await vectorDB.search({\n * query: 'machine learning applications',\n * topK: 10,\n * threshold: 0.7\n * });\n *\n * retriever.update({\n * output: {\n * documents: results,\n * count: results.length,\n * avgSimilarity: 0.89\n * },\n * metadata: {\n * searchLatency: 150,\n * cacheHit: false\n * }\n * });\n * retriever.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'retriever' }` - Factory function\n * @see {@link LangfuseChain} - For multi-step RAG pipelines\n * @see {@link LangfuseEmbedding} - For embedding generation used in vector search\n *\n * @public\n */\nexport class LangfuseRetriever extends LangfuseBaseObservation {\n constructor(params: LangfuseRetrieverParams) {\n super({ ...params, type: \"retriever\" });\n }\n\n /**\n * Updates this retriever observation with new attributes.\n *\n * @param attributes - Retriever attributes to set\n * @returns This retriever for method chaining\n */\n public update(attributes: LangfuseRetrieverAttributes): LangfuseRetriever {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseEvaluatorParams = {\n otelSpan: Span;\n attributes?: LangfuseEvaluatorAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking quality assessment and evaluation operations.\n *\n * LangfuseEvaluator is designed for observing evaluation systems that assess, score, and\n * validate the quality of AI outputs, content, or system performance. It captures evaluation\n * criteria, scoring methodologies, benchmark comparisons, and quality metrics, making it\n * essential for AI system validation, content moderation, and performance monitoring.\n *\n * ## Primary Use Cases\n * - **LLM Output Evaluation**: Response quality, factual accuracy, and relevance assessment\n * - **Content Quality Assessment**: Writing quality, tone analysis, and style validation\n * - **Automated Testing**: System performance validation and regression testing\n * - **Bias Detection**: Fairness evaluation and bias identification in AI systems\n * - **Safety Evaluation**: Content safety, harm detection, and compliance checking\n * - **Benchmark Comparison**: Performance comparison against reference standards\n *\n * ## Key Features\n * - **Multi-Criteria Scoring**: Comprehensive evaluation across multiple quality dimensions\n * - **Automated Assessment**: AI-powered evaluation using specialized models and algorithms\n * - **Human Evaluation**: Integration with human reviewers and expert assessment\n * - **Benchmark Tracking**: Performance comparison against established baselines\n * - **Quality Metrics**: Detailed scoring with confidence intervals and reliability measures\n * - **Trend Analysis**: Quality tracking over time with improvement recommendations\n *\n * @example\n * ```typescript\n * // Response quality evaluation\n * const evaluator = startObservation('response-quality-eval', {\n * input: {\n * response: 'Machine learning is a subset of artificial intelligence...',\n * criteria: ['accuracy', 'completeness', 'clarity']\n * }\n * }, { asType: 'evaluator' });\n *\n * const evaluation = await evaluateResponse({\n * response: 'Machine learning is a subset of artificial intelligence...',\n * criteria: ['accuracy', 'completeness', 'clarity']\n * });\n *\n * evaluator.update({\n * output: {\n * overallScore: 0.87,\n * criteriaScores: {\n * accuracy: 0.92,\n * completeness: 0.85,\n * clarity: 0.90\n * },\n * passed: true\n * }\n * });\n * evaluator.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'evaluator' }` - Factory function\n * @see {@link LangfuseGeneration} - For LLM outputs being evaluated\n * @see {@link LangfuseGuardrail} - For safety and compliance enforcement\n *\n * @public\n */\nexport class LangfuseEvaluator extends LangfuseBaseObservation {\n constructor(params: LangfuseEvaluatorParams) {\n super({ ...params, type: \"evaluator\" });\n }\n\n /**\n * Updates this evaluator observation with new attributes.\n *\n * @param attributes - Evaluator attributes to set\n * @returns This evaluator for method chaining\n */\n public update(attributes: LangfuseEvaluatorAttributes): LangfuseEvaluator {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseGuardrailParams = {\n otelSpan: Span;\n attributes?: LangfuseGuardrailAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking safety checks and compliance enforcement.\n *\n * LangfuseGuardrail is designed for observing safety and compliance systems that prevent,\n * detect, and mitigate harmful, inappropriate, or policy-violating content and behaviors\n * in AI applications. It captures safety policies, violation detection, risk assessment,\n * and mitigation actions, ensuring responsible AI deployment and regulatory compliance.\n *\n * ## Primary Use Cases\n * - **Content Moderation**: Harmful content detection and filtering in user inputs/outputs\n * - **Safety Enforcement**: PII detection, toxicity filtering, and inappropriate content blocking\n * - **Compliance Monitoring**: Regulatory compliance, industry standards, and policy enforcement\n * - **Bias Mitigation**: Fairness checks and bias prevention in AI decision-making\n * - **Privacy Protection**: Data privacy safeguards and sensitive information redaction\n * - **Behavioral Monitoring**: User behavior analysis and anomaly detection\n *\n * ## Key Features\n * - **Multi-Policy Enforcement**: Simultaneous checking against multiple safety policies\n * - **Risk Assessment**: Quantitative risk scoring with confidence intervals\n * - **Real-Time Detection**: Low-latency safety checks for interactive applications\n * - **Context Awareness**: Contextual safety evaluation considering user and application context\n * - **Mitigation Actions**: Automatic content blocking, filtering, and redaction capabilities\n * - **Audit Trail**: Comprehensive logging for compliance and safety incident investigation\n *\n * @example\n * ```typescript\n * // Content safety guardrail\n * const guardrail = startObservation('content-safety-check', {\n * input: {\n * content: userMessage,\n * policies: ['no-toxicity', 'no-hate-speech'],\n * strictMode: false\n * }\n * }, { asType: 'guardrail' });\n *\n * const safetyCheck = await checkContentSafety({\n * text: userMessage,\n * policies: ['no-toxicity', 'no-hate-speech']\n * });\n *\n * guardrail.update({\n * output: {\n * safe: safetyCheck.safe,\n * riskScore: 0.15,\n * violations: [],\n * action: 'allow'\n * }\n * });\n * guardrail.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'guardrail' }` - Factory function\n * @see {@link LangfuseEvaluator} - For detailed quality and safety assessment\n * @see {@link LangfuseGeneration} - For protecting LLM outputs with guardrails\n *\n * @public\n */\nexport class LangfuseGuardrail extends LangfuseBaseObservation {\n constructor(params: LangfuseGuardrailParams) {\n super({ ...params, type: \"guardrail\" });\n }\n\n /**\n * Updates this guardrail observation with new attributes.\n *\n * @param attributes - Guardrail attributes to set\n * @returns This guardrail for method chaining\n */\n public update(attributes: LangfuseGuardrailAttributes): LangfuseGuardrail {\n super.updateOtelSpanAttributes(attributes);\n\n return this;\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 * Specialized observation wrapper for tracking LLM interactions, AI model calls, and text generation.\n *\n * LangfuseGeneration is purpose-built for observing AI model interactions, providing rich\n * metadata capture for prompts, completions, model parameters, token usage, and costs.\n * It's the go-to observation type for any operation involving language models, chat APIs,\n * completion APIs, or other generative AI services.\n *\n * ## Primary Use Cases\n * - **LLM API Calls**: OpenAI, Anthropic, Cohere, Azure OpenAI, AWS Bedrock\n * - **Chat Completions**: Multi-turn conversations and dialogue systems\n * - **Text Generation**: Content creation, summarization, translation\n * - **Code Generation**: AI-powered code completion and generation\n * - **RAG Systems**: Generation step in retrieval-augmented generation\n * - **AI Agents**: LLM reasoning and decision-making within agent workflows\n *\n * ## Key Features\n * - **Rich LLM Metadata**: Model name, parameters, prompts, completions\n * - **Usage Tracking**: Token counts (prompt, completion, total)\n * - **Cost Monitoring**: Automatic cost calculation and tracking\n * - **Performance Metrics**: Latency, throughput, tokens per second\n * - **Prompt Engineering**: Version control for prompts and templates\n * - **Error Handling**: Rate limits, timeouts, model-specific errors\n *\n * ## Generation-Specific Attributes\n * - `model`: Model identifier (e.g., 'gpt-4-turbo', 'claude-3-sonnet')\n * - `modelParameters`: Temperature, max tokens, top-p, frequency penalty\n * - `input`: Prompt or message array for the model\n * - `output`: Model response, completion, or generated content\n * - `usageDetails`: Token consumption (prompt, completion, total)\n * - `costDetails`: Financial cost breakdown and pricing\n * - `prompt`: Structured prompt object with name, version, variables\n *\n * @example\n * ```typescript\n * // Basic LLM generation tracking\n * const generation = startObservation('openai-completion', {\n * model: 'gpt-4-turbo',\n * input: [\n * { role: 'system', content: 'You are a helpful assistant.' },\n * { role: 'user', content: 'Explain quantum computing' }\n * ],\n * modelParameters: {\n * temperature: 0.7,\n * maxTokens: 500\n * }\n * }, { asType: 'generation' });\n *\n * try {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4-turbo',\n * messages: [\n * { role: 'system', content: 'You are a helpful assistant.' },\n * { role: 'user', content: 'Explain quantum computing' }\n * ],\n * temperature: 0.7,\n * max_tokens: 500\n * });\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 * costDetails: {\n * totalCost: 0.025,\n * currency: 'USD'\n * }\n * });\n * } catch (error) {\n * generation.update({\n * level: 'ERROR',\n * statusMessage: `API error: ${error.message}`,\n * output: { error: error.message }\n * });\n * } finally {\n * generation.end();\n * }\n *\n * // RAG generation example\n * const ragGeneration = startObservation('rag-response', {\n * model: 'gpt-4',\n * input: [\n * { role: 'system', content: 'Answer based on provided context.' },\n * { role: 'user', content: `Context: ${context}\\n\\nQuestion: ${question}` }\n * ],\n * modelParameters: { temperature: 0.1 }\n * }, { asType: 'generation' });\n *\n * const response = await llm.generate({ prompt, context });\n * ragGeneration.update({\n * output: response,\n * metadata: { contextSources: 3 }\n * });\n * ragGeneration.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'generation' }` - Factory function\n * @see {@link startActiveObservation} with `{ asType: 'generation' }` - Function-scoped generation\n * @see {@link LangfuseSpan} - For general-purpose operations\n * @see {@link LangfuseEmbedding} - For text embedding and vector operations\n *\n * @public\n */\nexport class LangfuseGeneration extends LangfuseBaseObservation {\n constructor(params: LangfuseGenerationParams) {\n super({ ...params, type: \"generation\" });\n }\n\n update(attributes: LangfuseGenerationAttributes): LangfuseGeneration {\n this.updateOtelSpanAttributes(attributes);\n\n return this;\n }\n}\n\ntype LangfuseEmbeddingParams = {\n otelSpan: Span;\n attributes?: LangfuseEmbeddingAttributes;\n};\n\n/**\n * Specialized observation wrapper for tracking text embedding and vector generation operations.\n *\n * LangfuseEmbedding is designed for observing embedding model interactions that convert\n * text, images, or other content into high-dimensional vector representations. It captures\n * embedding model parameters, input preprocessing, vector characteristics, and performance\n * metrics, making it essential for semantic search, RAG systems, and similarity-based applications.\n *\n * ## Primary Use Cases\n * - **Text Embeddings**: Converting text to vectors for semantic search and similarity\n * - **Document Indexing**: Creating vector representations for large document collections\n * - **Semantic Search**: Enabling similarity-based search and content discovery\n * - **RAG Preparation**: Embedding documents and queries for retrieval-augmented generation\n * - **Clustering Analysis**: Grouping similar content using vector representations\n * - **Recommendation Systems**: Content similarity for personalized recommendations\n *\n * ## Key Features\n * - **Model Tracking**: Embedding model selection, version, and parameter monitoring\n * - **Input Processing**: Text preprocessing, tokenization, and normalization tracking\n * - **Vector Analysis**: Dimensionality, magnitude, and quality metrics for generated embeddings\n * - **Batch Processing**: Efficient handling of multiple texts in single embedding operations\n * - **Performance Monitoring**: Embedding generation speed, cost tracking, and efficiency metrics\n * - **Quality Assessment**: Vector quality evaluation and embedding effectiveness measurement\n *\n * @example\n * ```typescript\n * // Text embedding generation\n * const embedding = startObservation('text-embedder', {\n * input: {\n * texts: [\n * 'Machine learning is a subset of AI',\n * 'Deep learning uses neural networks'\n * ],\n * batchSize: 2\n * },\n * model: 'text-embedding-ada-002'\n * }, { asType: 'embedding' });\n *\n * const embedResult = await generateEmbeddings({\n * texts: [\n * 'Machine learning is a subset of AI',\n * 'Deep learning uses neural networks'\n * ],\n * model: 'text-embedding-ada-002'\n * });\n *\n * embedding.update({\n * output: {\n * embeddings: embedResult.vectors,\n * count: embedResult.vectors.length,\n * dimensions: 1536\n * },\n * usageDetails: {\n * totalTokens: embedResult.tokenCount\n * },\n * metadata: {\n * processingTime: 340\n * }\n * });\n * embedding.end();\n * ```\n *\n * @see {@link startObservation} with `{ asType: 'embedding' }` - Factory function\n * @see {@link LangfuseRetriever} - For using embeddings in vector search\n * @see {@link LangfuseGeneration} - For LLM operations that may use embeddings\n *\n * @public\n */\nexport class LangfuseEmbedding extends LangfuseBaseObservation {\n constructor(params: LangfuseEmbeddingParams) {\n super({ ...params, type: \"embedding\" });\n }\n\n /**\n * Updates this embedding observation with new attributes.\n *\n * @param attributes - Embedding attributes to set\n * @returns This embedding for method chaining\n */\n update(attributes: LangfuseEmbeddingAttributes): LangfuseEmbedding {\n this.updateOtelSpanAttributes(attributes);\n\n return this;\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 LangfuseBaseObservation {\n constructor(params: LangfuseEventParams) {\n super({ ...params, type: \"event\" });\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","_a"]}