{"version":3,"sources":["../src/observability-sdk/exporters/langwatch-trace-exporter.ts","../src/observability-sdk/exporters/trace-filters.ts","../src/observability-sdk/exporters/langwatch-logs-exporter.ts","../src/observability-sdk/semconv/events.ts","../src/observability-sdk/logger/index.ts","../src/observability-sdk/logger/implementation.ts"],"sourcesContent":["import { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport { type ReadableSpan } from \"@opentelemetry/sdk-trace-base\";\nimport { type ExportResult } from '@opentelemetry/core';\nimport {\n  DEFAULT_ENDPOINT,\n  LANGWATCH_SDK_LANGUAGE,\n  LANGWATCH_SDK_NAME_OBSERVABILITY,\n  LANGWATCH_SDK_RUNTIME,\n  LANGWATCH_SDK_VERSION,\n  TRACES_PATH,\n} from \"../../internal/constants\";\nimport { buildAuthHeaders } from \"../../internal/api/auth\";\nimport {\n  type TraceFilter,\n  type Criteria,\n  type Match,\n  applyFilters,\n} from \"./trace-filters\";\n\n/**\n * Configuration options for the LangWatchTraceExporter.\n *\n * @property endpoint - Custom LangWatch endpoint URL. Falls back to LANGWATCH_ENDPOINT env var or default.\n * @property apiKey - API key for authentication. Falls back to LANGWATCH_API_KEY env var.\n * @property filters - Array of filters applied sequentially to spans before export.\n *                     Default: `[{ preset: \"excludeHttpRequests\" }]` to reduce framework noise.\n *                     Pass `null` or `[]` to disable all filtering.\n */\nexport interface LangWatchTraceExporterOptions {\n  endpoint?: string;\n  apiKey?: string;\n  /**\n   * Project identifier. Required when `apiKey` is a Personal Access Token\n   * (`pat-lw-*`); ignored for legacy `sk-lw-*` keys. Falls back to\n   * `LANGWATCH_PROJECT_ID`.\n   */\n  projectId?: string;\n  filters?: TraceFilter[] | null;\n}\n\nexport type { TraceFilter, Criteria, Match };\n\n/**\n * LangWatchTraceExporter extends the OpenTelemetry OTLP HTTP trace exporter\n * to send trace data to LangWatch with proper authentication and metadata headers.\n *\n * ## Features\n * - Automatic authorization header configuration via API key\n * - SDK version and runtime identification headers\n * - Proper endpoint URL construction for LangWatch ingestion\n * - Intent-based span filtering with presets and custom criteria\n *\n * ## Filtering Behavior\n * - **Default**: HTTP request spans are excluded to reduce framework noise\n * - **Pipeline**: Filters are applied sequentially with AND semantics\n * - **Matching**: All string comparisons are case-sensitive by default\n * - **Array Syntax**: All criteria require arrays of Match objects for explicit filtering\n *\n * ## Filter Types\n * - **Presets**: Pre-configured common filters (`vercelAIOnly`, `excludeHttpRequests`)\n * - **Include**: Keep only spans matching criteria (OR within field, AND across fields)\n * - **Exclude**: Remove spans matching criteria (OR within field, AND across fields)\n *\n * @example Basic usage with default filtering\n * ```typescript\n * import { LangWatchTraceExporter } from '@langwatch/observability';\n *\n * // Default: excludes HTTP request spans\n * const exporter = new LangWatchTraceExporter();\n * ```\n *\n * @example Using presets\n * ```typescript\n * // Keep only Vercel AI SDK spans\n * const exporterAI = new LangWatchTraceExporter({\n *   filters: [{ preset: 'vercelAIOnly' }],\n * });\n *\n * // Explicitly exclude HTTP requests (same as default)\n * const exporterNoHttp = new LangWatchTraceExporter({\n *   filters: [{ preset: 'excludeHttpRequests' }],\n * });\n *\n * // No filtering at all (send all spans)\n * const exporterAll = new LangWatchTraceExporter({\n *   filters: null, // or filters: []\n * });\n * ```\n *\n * @example Custom filtering with criteria\n * ```typescript\n * // Include only spans with specific scope\n * const exporter1 = new LangWatchTraceExporter({\n *   filters: [\n *     { include: { instrumentationScopeName: [{ equals: 'ai' }] } }\n *   ],\n * });\n *\n * // Exclude spans by name pattern\n * const exporter2 = new LangWatchTraceExporter({\n *   filters: [\n *     { exclude: { name: [{ startsWith: 'internal.' }] } }\n *   ],\n * });\n *\n * // Case-insensitive matching\n * const exporter3 = new LangWatchTraceExporter({\n *   filters: [\n *     { include: { name: [{ equals: 'chat.completion', ignoreCase: true }] } }\n *   ],\n * });\n * ```\n *\n * @example Filter pipelines (AND semantics)\n * ```typescript\n * // Keep AI spans, then remove HTTP requests\n * const exporter = new LangWatchTraceExporter({\n *   filters: [\n *     { include: { instrumentationScopeName: [{ equals: 'ai' }] } },\n *     { preset: 'excludeHttpRequests' },\n *   ],\n * });\n * ```\n *\n * @example OR semantics within a field\n * ```typescript\n * // Include spans with name starting with 'chat.' OR 'llm.'\n * const exporter = new LangWatchTraceExporter({\n *   filters: [\n *     {\n *       include: {\n *         name: [\n *           { startsWith: 'chat.' },\n *           { startsWith: 'llm.' }\n *         ]\n *       }\n *     }\n *   ],\n * });\n * ```\n *\n * @example Using regex patterns\n * ```typescript\n * const exporter = new LangWatchTraceExporter({\n *   filters: [\n *     {\n *       include: {\n *         name: [{ matches: /^(chat|llm)\\./i }]\n *       }\n *     }\n *   ],\n * });\n * ```\n */\nexport class LangWatchTraceExporter extends OTLPTraceExporter {\n  private readonly filters: TraceFilter[];\n  /**\n   * Creates a new LangWatchTraceExporter instance.\n   *\n   * @param opts - Configuration options for the exporter\n   * @param opts.apiKey - API key for LangWatch authentication.\n   *                     Falls back to `LANGWATCH_API_KEY` environment variable, then empty string.\n   * @param opts.endpoint - Custom endpoint URL for LangWatch ingestion.\n   *                       Falls back to `LANGWATCH_ENDPOINT` environment variable, then default endpoint.\n   * @param opts.filters - Array of filters applied sequentially to spans before export (AND semantics).\n   *                      When omitted, defaults to `[{ preset: \"excludeHttpRequests\" }]`.\n   *                      Pass `null` or `[]` to disable all filtering and send all spans.\n   *\n   * @example\n   * ```typescript\n   * // With API key and default filtering\n   * const exporter = new LangWatchTraceExporter({\n   *   apiKey: 'your-api-key'\n   * });\n   *\n   * // With custom endpoint and no filtering\n   * const exporter = new LangWatchTraceExporter({\n   *   endpoint: 'https://custom.langwatch.ai',\n   *   filters: null\n   * });\n   * ```\n   */\n  constructor(opts?: LangWatchTraceExporterOptions) {\n    const apiKey = opts?.apiKey ?? process.env.LANGWATCH_API_KEY ?? \"\";\n    const projectId = opts?.projectId ?? process.env.LANGWATCH_PROJECT_ID;\n    const endpoint =\n      opts?.endpoint ??\n      process.env.LANGWATCH_ENDPOINT ??\n      DEFAULT_ENDPOINT;\n\n    const url = new URL(TRACES_PATH, endpoint);\n    const otelEndpoint = url.toString();\n\n    super({\n      headers: {\n        \"x-langwatch-sdk-name\": LANGWATCH_SDK_NAME_OBSERVABILITY,\n        \"x-langwatch-sdk-language\": LANGWATCH_SDK_LANGUAGE,\n        \"x-langwatch-sdk-version\": LANGWATCH_SDK_VERSION,\n        \"x-langwatch-sdk-runtime\": LANGWATCH_SDK_RUNTIME(),\n        ...buildAuthHeaders({ apiKey, projectId }),\n      },\n      url: otelEndpoint.toString(),\n    });\n\n    // Handle filters: null or [] = no filtering, undefined = default, array = use provided\n    if (opts?.filters === null || (Array.isArray(opts?.filters) && opts.filters.length === 0)) {\n      this.filters = [];\n    } else if (Array.isArray(opts?.filters)) {\n      this.filters = opts.filters;\n    } else {\n      this.filters = [{ preset: \"excludeHttpRequests\" }];\n    }\n  }\n\n  export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void {\n    const filtered = applyFilters(this.filters, spans);\n    super.export(filtered, resultCallback);\n  }\n}\n","import { type ReadableSpan } from \"@opentelemetry/sdk-trace-base\";\n\nexport interface Criteria {\n  instrumentationScopeName?: Match[];\n  name?: Match[];\n}\n\nexport interface Match {\n  equals?: string;\n  startsWith?: string;\n  matches?: RegExp;\n  ignoreCase?: boolean;\n}\n\nexport type TraceFilter =\n  | { preset: \"vercelAIOnly\" | \"excludeHttpRequests\" }\n  | { include: Criteria }\n  | { exclude: Criteria };\n\n/**\n * Applies a sequence of filters to an array of spans using AND semantics.\n * Each filter in the sequence is applied to the result of the previous filter,\n * progressively narrowing down the set of spans.\n *\n * @param filters - Array of filter rules to apply sequentially\n * @param spans - Array of spans to filter\n * @returns Filtered array of spans that match all filter criteria\n *\n * @example\n * ```typescript\n * const filters: TraceFilter[] = [\n *   { include: { instrumentationScopeName: [{ equals: 'ai' }] } },\n *   { preset: 'excludeHttpRequests' }\n * ];\n * const filtered = applyFilters(filters, spans);\n * // Returns only AI spans that are not HTTP requests\n * ```\n */\nexport function applyFilters(\n  filters: TraceFilter[] | undefined,\n  spans: ReadableSpan[]\n): ReadableSpan[] {\n  if (!filters || filters.length === 0) return spans;\n  return filters.reduce((current, rule) => applyFilterRule(rule, current), spans);\n}\n\n/**\n * Applies a single filter rule to an array of spans.\n * Handles three types of filters: presets, include rules, and exclude rules.\n *\n * @param rule - Single filter rule (preset, include, or exclude)\n * @param spans - Array of spans to filter\n * @returns Filtered array of spans based on the rule\n *\n * @example\n * ```typescript\n * // Using preset\n * const filtered1 = applyFilterRule({ preset: 'vercelAIOnly' }, spans);\n *\n * // Using include\n * const filtered2 = applyFilterRule(\n *   { include: { name: [{ startsWith: 'llm.' }] } },\n *   spans\n * );\n *\n * // Using exclude\n * const filtered3 = applyFilterRule(\n *   { exclude: { instrumentationScopeName: [{ equals: 'http' }] } },\n *   spans\n * );\n * ```\n */\nexport function applyFilterRule(rule: TraceFilter, spans: ReadableSpan[]): ReadableSpan[] {\n  if (\"preset\" in rule && rule.preset) {\n    return applyPreset(\n      (rule as { preset: TraceFilter extends { preset: infer P } ? P : never }).preset as any,\n      spans\n    );\n  }\n\n  if (\"include\" in rule && rule.include) {\n    const criteria = (rule as { include: Criteria }).include;\n    return spans.filter((s) => matchesCriteria(s, criteria));\n  }\n\n  if (\"exclude\" in rule && rule.exclude) {\n    const criteria = (rule as { exclude: Criteria }).exclude;\n    return spans.filter((s) => !matchesCriteria(s, criteria));\n  }\n\n  return spans;\n}\n\n/**\n * Applies a preset filter to an array of spans.\n * Presets are predefined common filtering patterns.\n *\n * Available presets:\n * - `vercelAIOnly`: Keeps only spans from the Vercel AI SDK (instrumentationScope.name === 'ai')\n * - `excludeHttpRequests`: Removes spans that appear to be HTTP requests (span name starts with HTTP verb)\n *\n * @param preset - Name of the preset filter to apply\n * @param spans - Array of spans to filter\n * @returns Filtered array of spans based on the preset\n *\n * @example\n * ```typescript\n * // Keep only Vercel AI spans\n * const aiSpans = applyPreset('vercelAIOnly', spans);\n *\n * // Remove HTTP request spans\n * const noHttpSpans = applyPreset('excludeHttpRequests', spans);\n * ```\n */\nexport function applyPreset(\n  preset: \"vercelAIOnly\" | \"excludeHttpRequests\",\n  spans: ReadableSpan[]\n): ReadableSpan[] {\n  if (preset === \"vercelAIOnly\") return spans.filter((s) => isVercelAiSpan(s));\n  if (preset === \"excludeHttpRequests\") return spans.filter((s) => !isHttpRequestSpan(s));\n\n  return spans;\n}\n\n/**\n * Checks if a span matches the given criteria.\n * All specified criteria fields must match (AND semantics within a criteria object).\n * Within each field, matchers are evaluated with OR semantics (any matcher can match).\n *\n * @param span - Span to evaluate\n * @param criteria - Criteria to match against (instrumentationScopeName and/or name)\n * @returns True if the span matches all specified criteria, false otherwise\n *\n * @example\n * ```typescript\n * const criteria: Criteria = {\n *   instrumentationScopeName: [{ equals: 'ai' }],\n *   name: [{ startsWith: 'llm.' }, { startsWith: 'chat.' }]\n * };\n * const matches = matchesCriteria(span, criteria);\n * // Returns true if scope is 'ai' AND name starts with 'llm.' OR 'chat.'\n * ```\n */\nexport function matchesCriteria(span: ReadableSpan, criteria: Criteria): boolean {\n  if (criteria.instrumentationScopeName !== void 0) {\n    const scopeName = span.instrumentationScope?.name ?? \"\";\n    const ok = criteria.instrumentationScopeName.some((m) => valueMatches(scopeName, m));\n    if (!ok) return false;\n  }\n\n  if (criteria.name !== void 0) {\n    const ok = criteria.name.some((m) => valueMatches(span.name ?? \"\", m));\n    if (!ok) return false;\n  }\n\n  return true;\n}\n\n/**\n * Evaluates if a string value matches a given match rule.\n * Supports three types of matching: exact equality, prefix matching, and regex matching.\n * All matching is case-sensitive by default unless `ignoreCase` is explicitly set to true.\n *\n * @param value - String value to evaluate\n * @param rule - Match rule specifying the matching criteria\n * @returns True if the value matches the rule, false otherwise\n *\n * @example\n * ```typescript\n * // Exact match (case-sensitive by default)\n * valueMatches('GET /api/users', { equals: 'GET /api/users' }); // true\n * valueMatches('get /api/users', { equals: 'GET /api/users' }); // false\n *\n * // Case-insensitive exact match\n * valueMatches('get /api/users', { equals: 'GET /api/users', ignoreCase: true }); // true\n *\n * // Prefix match\n * valueMatches('GET /api/users', { startsWith: 'GET' }); // true\n * valueMatches('POST /api/users', { startsWith: 'GET' }); // false\n *\n * // Regex match\n * valueMatches('GET /api/users', { matches: /^(GET|POST)\\b/ }); // true\n *\n * // Case-insensitive regex\n * valueMatches('get /api/users', { matches: /^GET\\b/, ignoreCase: true }); // true\n * ```\n */\nexport function valueMatches(value: string, rule: Match): boolean {\n  const raw = value ?? \"\";\n  const ignoreCase = rule.ignoreCase ?? false;\n\n  if (rule.equals !== void 0) {\n    return ignoreCase\n      ? raw.localeCompare(rule.equals, void 0, { sensitivity: \"base\" }) === 0\n      : raw === rule.equals;\n  }\n\n  if (rule.startsWith !== void 0) {\n    return ignoreCase\n      ? raw.toLowerCase().startsWith(rule.startsWith.toLowerCase())\n      : raw.startsWith(rule.startsWith);\n  }\n\n  if (rule.matches instanceof RegExp) {\n    const re =\n      ignoreCase && !rule.matches.flags.includes(\"i\")\n        ? new RegExp(rule.matches.source, (rule.matches.flags || \"\") + \"i\")\n        : rule.matches;\n    return re.test(raw);\n  }\n\n  return false;\n}\n\n/**\n * Checks if a span is from the Vercel AI SDK.\n * A span is considered a Vercel AI span if its instrumentation scope name is 'ai' (case-insensitive).\n *\n * @param span - Span to check\n * @returns True if the span is from the Vercel AI SDK, false otherwise\n *\n * @example\n * ```typescript\n * if (isVercelAiSpan(span)) {\n *   console.log('This is a Vercel AI operation');\n * }\n * ```\n */\nexport function isVercelAiSpan(span: ReadableSpan): boolean {\n  const scope = span.instrumentationScope?.name?.toLowerCase?.() ?? \"\";\n  return scope === \"ai\";\n}\n\n/**\n * Checks if a span appears to be an HTTP request based on its name.\n * A span is considered an HTTP request if its name starts with a common HTTP verb\n * (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD) followed by a word boundary.\n *\n * @param span - Span to check\n * @returns True if the span appears to be an HTTP request, false otherwise\n *\n * @example\n * ```typescript\n * // These would return true:\n * // span.name = \"GET /api/users\"\n * // span.name = \"POST /api/data\"\n * // span.name = \"DELETE /resource/123\"\n *\n * if (isHttpRequestSpan(span)) {\n *   console.log('This is an HTTP request span');\n * }\n * ```\n */\nexport function isHttpRequestSpan(span: ReadableSpan): boolean {\n  const name = span.name ?? \"\";\n  const verbMatch = /^(GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD)\\b/i.test(name);\n  return verbMatch;\n}\n","import { OTLPLogExporter } from \"@opentelemetry/exporter-logs-otlp-http\";\nimport {\n  DEFAULT_ENDPOINT,\n  LANGWATCH_SDK_LANGUAGE,\n  LANGWATCH_SDK_NAME_OBSERVABILITY,\n  LANGWATCH_SDK_RUNTIME,\n  LANGWATCH_SDK_VERSION,\n  LOGS_PATH,\n} from \"../../internal/constants\";\n\nexport interface LangWatchLogsExporterOptions {\n  endpoint?: string;\n  apiKey?: string;\n}\n\n/**\n * LangWatchLogsExporter extends the OpenTelemetry OTLP HTTP logs exporter\n * to send logs to LangWatch with proper authentication and metadata headers.\n *\n * This exporter automatically configures:\n * - Authorization headers using the provided API key or environment variables/fallback\n * - SDK version and language identification headers\n * - Proper endpoint configuration for LangWatch ingestion using provided URL or environment variables/fallback\n *\n * @example\n * ```typescript\n * import { LangWatchLogsExporter } from '@langwatch/observability';\n *\n * // Using environment variables/fallback configuration\n * const exporter = new LangWatchLogsExporter();\n *\n * // Using custom options\n * const exporter = new LangWatchLogsExporter({\n *   apiKey: 'your-api-key',\n *   endpoint: 'https://custom.langwatch.com'\n * });\n * ```\n */\nexport class LangWatchLogsExporter extends OTLPLogExporter {\n  /**\n   * Creates a new LangWatchLogsExporter instance.\n   *\n   * @param opts - Optional configuration options for the exporter.\n   * @param opts.apiKey - Optional API key for LangWatch authentication. If not provided,\n   *                     will use environment variables or fallback configuration.\n   * @param opts.endpoint - Optional custom endpoint URL for LangWatch ingestion.\n   *                       If not provided, will use environment variables or fallback configuration.\n   */\n  constructor(opts?: LangWatchLogsExporterOptions) {\n    const apiKey = opts?.apiKey ?? process.env.LANGWATCH_API_KEY ?? \"\";\n    const endpoint =\n      opts?.endpoint ??\n      process.env.LANGWATCH_ENDPOINT ??\n      DEFAULT_ENDPOINT;\n\n    const url = new URL(LOGS_PATH, endpoint);\n    const otelEndpoint = url.toString();\n\n    super({\n      headers: {\n        \"x-langwatch-sdk-name\": LANGWATCH_SDK_NAME_OBSERVABILITY,\n        \"x-langwatch-sdk-language\": LANGWATCH_SDK_LANGUAGE,\n        \"x-langwatch-sdk-version\": LANGWATCH_SDK_VERSION,\n        \"x-langwatch-sdk-runtime\": LANGWATCH_SDK_RUNTIME(),\n        ...(apiKey ? { authorization: `Bearer ${apiKey}` } : {}),\n      },\n      url: otelEndpoint.toString(),\n    });\n  }\n}\n","/*\n  This file contains the values for the OpenTelemetry semantic conventions for GenAI log\n  record event names.\n\n  👉 https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-events/\n*/\n\n/**\n * GenAI system message event name\n * Used for log records representing system messages in AI conversations\n */\nexport const LOG_EVNT_GEN_AI_SYSTEM_MESSAGE = \"gen.ai.system_message\";\n\n/**\n * GenAI user message event name\n * Used for log records representing user messages in AI conversations\n */\nexport const LOG_EVNT_GEN_AI_USER_MESSAGE = \"gen.ai.user_message\";\n\n/**\n * GenAI assistant message event name\n * Used for log records representing assistant responses in AI conversations\n */\nexport const LOG_EVNT_GEN_AI_ASSISTANT_MESSAGE = \"gen.ai.assistant_message\";\n\n/**\n * GenAI tool message event name\n * Used for log records representing tool calls or responses in AI conversations\n */\nexport const LOG_EVNT_GEN_AI_TOOL_MESSAGE = \"gen.ai.tool_message\";\n\n/**\n * GenAI choice event name\n * Used for log records representing choices made by AI models\n */\nexport const LOG_EVNT_GEN_AI_CHOICE = \"gen.ai.choice\";\n\n/**\n * LangWatch LangChain callback event name\n * Used for log records representing LangChain callback events\n */\nexport const EVNT_LANGWATCH_LANGCHAIN_CALLBACK = \"langwatch.langchain.callback\";\n","import {\n  type Logger,\n  type LoggerProvider,\n  NoopLoggerProvider,\n} from \"@opentelemetry/api-logs\";\nimport {\n  type LangWatchLogger,\n} from \"./types\";\nimport { LangWatchLoggerInternal } from \"./implementation\";\n\n/**\n * The LangWatch-specific global logger provider. It may not be the same as the current\n * OpenTelemetry global logger provider, but it's the last one the `setupObservability`\n * knows about.\n * @internal\n */\nlet currentLoggerProvider: LoggerProvider = new NoopLoggerProvider();\n\n/**\n * @module observability/logger\n * @description\n * Provides LangWatch logger integration with OpenTelemetry, including logger provider\n * management and logger creation utilities.\n *\n * @remarks\n * This module allows you to set a global logger provider, retrieve LangWatch loggers,\n * and wrap OpenTelemetry loggers with LangWatch-specific functionality.\n *\n * @see {@link setLangWatchLoggerProvider}\n * @see {@link getLangWatchLogger}\n * @see {@link getLangWatchLoggerFromProvider}\n * @see {@link createLangWatchLogger}\n */\nexport function setLangWatchLoggerProvider(\n  loggerProvider: LoggerProvider,\n): void {\n  currentLoggerProvider = loggerProvider;\n}\n\n/**\n * Retrieves a LangWatch logger with the specified name and optional version.\n *\n * @param name - The name of the logger (typically your service or module name).\n * @param version - (Optional) The version of the logger.\n * @returns A {@link LangWatchLogger} instance.\n *\n * @remarks\n * Uses the logger provider set during observability setup. If no provider is set, returns\n * a NoOp logger.\n *\n * @example\n * ```ts\n * const logger = getLangWatchLogger(\"my-service\");\n * logger.info(\"Service started\");\n * ```\n *\n * @see {@link setLangWatchLoggerProvider}\n */\nexport function getLangWatchLogger(\n  name: string,\n  version?: string,\n): LangWatchLogger {\n  return getLangWatchLoggerFromProvider(currentLoggerProvider, name, version);\n}\n\n/**\n * Retrieves a LangWatch logger from a specific OpenTelemetry logger provider.\n *\n * @param loggerProvider - The OpenTelemetry logger provider to use.\n * @param name - The name of the logger.\n * @param version - (Optional) The version of the logger.\n * @returns A {@link LangWatchLogger} instance.\n *\n * @remarks\n * Use this function if you want to use a custom logger provider instead of the global one.\n *\n * @example\n * ```ts\n * const customProvider = new LoggerProvider();\n * const logger = getLangWatchLoggerFromProvider(customProvider, \"custom-service\");\n * ```\n */\nexport function getLangWatchLoggerFromProvider(\n  loggerProvider: LoggerProvider,\n  name: string,\n  version?: string,\n): LangWatchLogger {\n  return createLangWatchLogger(loggerProvider.getLogger(name, version));\n}\n\n/**\n * Wraps an OpenTelemetry logger as a LangWatch logger.\n *\n * @param logger - The OpenTelemetry logger to wrap.\n * @returns A {@link LangWatchLogger} instance.\n *\n * @example\n * ```ts\n * import { Logger } from \"@opentelemetry/api-logs\";\n * const otelLogger = new Logger();\n * const lwLogger = createLangWatchLogger(otelLogger);\n * lwLogger.info(\"Wrapped logger\");\n * ```\n */\nexport function createLangWatchLogger(logger: Logger): LangWatchLogger {\n  return new LangWatchLoggerInternal(logger);\n}\n\n// Export types and implementation\nexport * from \"./types\";\nexport * from \"./implementation\";\n","import {\n  type AnyValue,\n  type Logger,\n} from \"@opentelemetry/api-logs\";\nimport {\n  type EmitOptions,\n  type LangWatchLogger,\n  type LangWatchLogRecord,\n  type LangWatchSpanGenAIAssistantMessageEventBody,\n  type LangWatchSpanGenAIChoiceEventBody,\n  type LangWatchSpanGenAISystemMessageEventBody,\n  type LangWatchSpanGenAIToolMessageEventBody,\n  type LangWatchSpanGenAIUserMessageEventBody,\n} from \"./types\";\nimport { shouldCaptureOutput } from \"../config\";\nimport * as intSemconv from \"../semconv\";\nimport { type SemConvLogRecordAttributes } from \"../semconv\";\nimport { context } from \"@opentelemetry/api\";\n\n/**\n * Internal implementation of {@link LangWatchLogger}.\n *\n * @remarks\n * This class wraps an OpenTelemetry logger and adds LangWatch-specific functionality for\n * structured logging and event emission.\n * Not intended for direct use; use {@link getLangWatchLogger} or\n * {@link createLangWatchLogger} instead.\n */\nexport class LangWatchLoggerInternal implements LangWatchLogger {\n  constructor(private logger: Logger) {}\n\n  emit(logRecord: LangWatchLogRecord, options?: EmitOptions): void {\n    // Handle output capture configuration\n    if (!shouldCaptureOutput()) {\n      logRecord.body = void 0;\n    }\n\n    // Set context if not provided and not explicitly excluded\n    if (!logRecord.context && !options?.excludeContext) {\n      logRecord.context = context.active();\n    }\n\n    // Emit the log record through the underlying OpenTelemetry logger\n    this.logger.emit(logRecord);\n  }\n\n  emitGenAISystemMessageEvent(\n    body: LangWatchSpanGenAISystemMessageEventBody,\n    system?: intSemconv.VAL_GEN_AI_SYSTEMS | (string & {}),\n    attributes?: SemConvLogRecordAttributes,\n  ): void {\n    this.emitGenAIEvent(\n      intSemconv.LOG_EVNT_GEN_AI_SYSTEM_MESSAGE,\n      { ...body, role: body.role ?? \"system\" } satisfies LangWatchSpanGenAISystemMessageEventBody,\n      {\n        ...attributes,\n        \"gen_ai.system\": system,\n      },\n    );\n  }\n\n  emitGenAIUserMessageEvent(\n    body: LangWatchSpanGenAIUserMessageEventBody,\n    system?: intSemconv.VAL_GEN_AI_SYSTEMS | (string & {}),\n    attributes?: SemConvLogRecordAttributes,\n  ) {\n    this.emitGenAIEvent(\n      intSemconv.LOG_EVNT_GEN_AI_USER_MESSAGE,\n      { ...body, role: body.role ?? \"user\" } satisfies LangWatchSpanGenAIUserMessageEventBody,\n      {\n        ...attributes,\n        \"gen_ai.system\": system,\n      },\n    );\n  }\n\n  emitGenAIAssistantMessageEvent(\n    body: LangWatchSpanGenAIAssistantMessageEventBody,\n    system?: intSemconv.VAL_GEN_AI_SYSTEMS | (string & {}),\n    attributes?: SemConvLogRecordAttributes,\n  ) {\n    this.emitGenAIEvent(\n      intSemconv.LOG_EVNT_GEN_AI_ASSISTANT_MESSAGE,\n      { ...body, role: body.role ?? \"assistant\" } satisfies LangWatchSpanGenAIAssistantMessageEventBody,\n      {\n        ...attributes,\n        \"gen_ai.system\": system,\n      },\n    );\n  }\n\n  emitGenAIToolMessageEvent(\n    body: LangWatchSpanGenAIToolMessageEventBody,\n    system?: intSemconv.VAL_GEN_AI_SYSTEMS | (string & {}),\n    attributes?: SemConvLogRecordAttributes,\n  ) {\n    if (body.role === void 0) {\n      body.role = \"tool\";\n    }\n\n    this.emitGenAIEvent(\n      intSemconv.LOG_EVNT_GEN_AI_TOOL_MESSAGE,\n      { ...body },\n      {\n        ...attributes,\n        \"gen_ai.system\": system,\n      },\n    );\n  }\n\n  emitGenAIChoiceEvent(\n    body: LangWatchSpanGenAIChoiceEventBody,\n    system?: intSemconv.VAL_GEN_AI_SYSTEMS | (string & {}),\n    attributes?: SemConvLogRecordAttributes,\n  ) {\n    if (body.message && body.message.role === void 0) {\n      body.message.role = \"assistant\";\n    }\n\n    this.emitGenAIEvent(\n      intSemconv.LOG_EVNT_GEN_AI_CHOICE,\n      {\n        ...body,\n        message: { ...body.message, role: body.message?.role ?? \"assistant\" },\n      } satisfies LangWatchSpanGenAIChoiceEventBody,\n      {\n        ...attributes,\n        \"gen_ai.system\": system,\n      },\n    );\n  }\n\n  private emitGenAIEvent(\n    eventName: string,\n    body: AnyValue,\n    attributes?: SemConvLogRecordAttributes,\n  ): void {\n    this.emit({\n      eventName,\n      context: context.active(),\n      attributes: { ...attributes },\n      body: shouldCaptureOutput() ? body : void 0,\n      observedTimestamp: new Date().getTime(),\n    });\n  }\n}\n"],"mappings":"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","names":["_a"]}