{"version":3,"sources":["../src/shutdown.ts","../src/flatten-attributes.ts","../src/structured-error.ts","../src/request-logger.ts","../src/gen-ai-metrics.ts","../src/gen-ai-events.ts"],"names":["getEventQueue","getSdk","getLogger","_closeEmbeddedDevtools","resetEvents","resetMetrics","resetEventQueue","ctx","SpanStatusCode","AsyncLocalStorage","span","otelTrace","createTraceContext","attrs","AggregationType"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Graceful shutdown with flush and cleanup\n */\n\nimport { getSdk, getLogger, _closeEmbeddedDevtools } from './init';\nimport { getEventQueue, resetEventQueue } from './track';\nimport { resetEvents } from './event';\nimport { resetMetrics } from './metric';\n\n/**\n * Flush all pending telemetry\n *\n * Flushes both events events and OpenTelemetry spans to their destinations.\n * Includes timeout protection to prevent hanging in serverless environments.\n *\n * Safe to call multiple times.\n *\n * @param options - Optional configuration\n * @param options.timeout - Timeout in milliseconds (default: 2000ms)\n * @param options.forShutdown - If true, permanently disables the events queue after flush (used internally by shutdown())\n *\n * @example Manual flush in serverless\n * ```typescript\n * import { flush } from 'autotel';\n *\n * export const handler = async (event) => {\n *   // ... process event\n *   await flush(); // Flush before function returns\n *   return result;\n * };\n * ```\n *\n * @example With custom timeout\n * ```typescript\n * await flush({ timeout: 5000 }); // 5 second timeout\n * ```\n */\nexport async function flush(options?: {\n  timeout?: number;\n  forShutdown?: boolean;\n}): Promise<void> {\n  const timeout = options?.timeout ?? 2000;\n  const forShutdown = options?.forShutdown ?? false;\n\n  const doFlush = async () => {\n    // Flush events queue (or shutdown queue when tearing down)\n    const eventsQueue = getEventQueue();\n    if (eventsQueue) {\n      if (forShutdown) {\n        await eventsQueue.shutdown();\n      } else {\n        await eventsQueue.flush();\n      }\n    }\n\n    // Flush OpenTelemetry spans\n    // This ensures spans are exported immediately, critical for serverless\n    const sdk = getSdk();\n    if (sdk) {\n      try {\n        // Type assertion needed as getTracerProvider is not in the public NodeSDK interface\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        const sdkAny = sdk as any;\n        if (typeof sdkAny.getTracerProvider === 'function') {\n          const tracerProvider = sdkAny.getTracerProvider();\n          if (\n            tracerProvider &&\n            typeof tracerProvider.forceFlush === 'function'\n          ) {\n            await tracerProvider.forceFlush();\n          }\n        }\n      } catch {\n        // Ignore errors when accessing tracer provider (may not be available in test mocks)\n      }\n    }\n  };\n\n  // Add timeout protection to prevent hanging\n  let timeoutHandle: NodeJS.Timeout | undefined;\n  try {\n    await Promise.race([\n      doFlush().finally(() => {\n        // Clear timeout as soon as flush completes\n        if (timeoutHandle) {\n          clearTimeout(timeoutHandle);\n        }\n      }),\n      new Promise<void>((_, reject) => {\n        timeoutHandle = setTimeout(\n          () => reject(new Error('Flush timeout')),\n          timeout,\n        );\n        // Use unref() to allow Node to exit if flush completes first\n        // This prevents the 2s delay in serverless when flush succeeds immediately\n        timeoutHandle.unref();\n      }),\n    ]);\n  } catch (error) {\n    // Clear timeout on error too\n    if (timeoutHandle) {\n      clearTimeout(timeoutHandle);\n    }\n    const logger = getLogger();\n    logger.error(\n      {\n        err: error instanceof Error ? error : new Error(String(error)),\n      },\n      '[autotel] Flush error',\n    );\n    throw error;\n  }\n}\n\n/**\n * Shutdown telemetry and cleanup resources\n *\n * - Flushes all pending data\n * - Shuts down OpenTelemetry SDK\n * - Cleans up resources\n *\n * Call this before process exit.\n *\n * Always performs cleanup even if flush fails, preventing resource leaks\n * in serverless handlers or tests.\n *\n * @example Express server\n * ```typescript\n * const server = app.listen(3000)\n *\n * process.on('SIGTERM', async () => {\n *   await server.close()\n *   await shutdown()\n *   process.exit(0)\n * })\n * ```\n */\nexport async function shutdown(): Promise<void> {\n  const logger = getLogger();\n  let shutdownError: Error | null = null;\n\n  // Attempt to flush (with queue shutdown so new events are rejected), but continue with cleanup even if it fails\n  try {\n    await flush({ forShutdown: true });\n  } catch (error) {\n    const err = error instanceof Error ? error : new Error(String(error));\n    shutdownError = err;\n    logger.error(\n      {\n        err,\n      },\n      '[autotel] Flush failed during shutdown, continuing cleanup',\n    );\n  }\n\n  // Always shutdown SDK and clean up resources\n  try {\n    // Shutdown OpenTelemetry SDK\n    const sdk = getSdk();\n    if (sdk) {\n      await sdk.shutdown();\n    }\n  } catch (error) {\n    const err = error instanceof Error ? error : new Error(String(error));\n\n    // Ignore ECONNREFUSED errors - this happens when no OTLP endpoint was configured\n    // The SDK tries to flush exporters that don't exist, which is harmless\n    const isConnectionRefused =\n      typeof error === 'object' &&\n      error !== null &&\n      'code' in error &&\n      error.code === 'ECONNREFUSED';\n\n    if (!isConnectionRefused) {\n      // Only store/log non-connection errors\n      if (!shutdownError) {\n        shutdownError = err;\n      }\n      logger.error({ err }, '[autotel] SDK shutdown failed');\n    }\n  } finally {\n    await _closeEmbeddedDevtools();\n\n    // Clean up singleton Maps and queues to prevent memory leaks\n    // This runs even if SDK shutdown fails\n    const eventsQueue = getEventQueue();\n    if (eventsQueue && typeof eventsQueue.cleanup === 'function') {\n      eventsQueue.cleanup();\n    }\n    resetEvents();\n    resetMetrics();\n    resetEventQueue();\n  }\n\n  // Rethrow first error after cleanup completes\n  // This allows tests and CI to detect failures while still ensuring cleanup\n  if (shutdownError) {\n    throw shutdownError;\n  }\n}\n\n/**\n * Register automatic shutdown hooks for common signals\n *\n * Handles:\n * - SIGTERM (Docker/K8s graceful shutdown)\n * - SIGINT (Ctrl+C)\n *\n * @internal Called automatically on module load\n */\nfunction registerShutdownHooks(): void {\n  if (typeof process === 'undefined') return; // Not in Node.js\n\n  const signals: NodeJS.Signals[] = ['SIGTERM', 'SIGINT'];\n  let shuttingDown = false;\n\n  for (const signal of signals) {\n    process.on(signal, async () => {\n      if (shuttingDown) return; // Prevent double shutdown\n      shuttingDown = true;\n\n      if (process.env.NODE_ENV !== 'test') {\n        getLogger().info(\n          {},\n          `[autotel] Received ${signal}, flushing telemetry...`,\n        );\n      }\n\n      try {\n        await shutdown();\n      } catch (error) {\n        getLogger().error(\n          {\n            err: error instanceof Error ? error : undefined,\n          },\n          '[autotel] Error during shutdown',\n        );\n      } finally {\n        process.exit(0);\n      }\n    });\n  }\n}\n\n// Auto-register shutdown hooks\nregisterShutdownHooks();\n","import type { AttributeValue } from './trace-context';\n\n/**\n * Convert an unknown value to an OTel-compatible AttributeValue.\n * Returns undefined when the value cannot be represented.\n */\nexport function toAttributeValue(value: unknown): AttributeValue | undefined {\n  if (\n    typeof value === 'string' ||\n    typeof value === 'number' ||\n    typeof value === 'boolean'\n  ) {\n    return value;\n  }\n  if (Array.isArray(value)) {\n    if (\n      value.every((v) => typeof v === 'string') ||\n      value.every((v) => typeof v === 'number') ||\n      value.every((v) => typeof v === 'boolean')\n    ) {\n      return value as AttributeValue;\n    }\n    try {\n      return JSON.stringify(value);\n    } catch {\n      return '<serialization-failed>';\n    }\n  }\n  if (value instanceof Date) {\n    return value.toISOString();\n  }\n  if (value instanceof Error) {\n    return value.message;\n  }\n  return undefined;\n}\n\n/**\n * Recursively flatten a nested object into dot-notation OTel attributes.\n * Includes circular reference protection via WeakSet.\n */\nexport function flattenToAttributes(\n  fields: Record<string, unknown>,\n  prefix = '',\n): Record<string, AttributeValue> {\n  const out: Record<string, AttributeValue> = {};\n  const seen = new WeakSet<object>();\n\n  function flatten(obj: Record<string, unknown>, currentPrefix: string): void {\n    for (const [key, value] of Object.entries(obj)) {\n      if (value == null) continue;\n      const nextKey = currentPrefix ? `${currentPrefix}.${key}` : key;\n\n      const attr = toAttributeValue(value);\n      if (attr !== undefined) {\n        out[nextKey] = attr;\n        continue;\n      }\n\n      if (typeof value === 'object' && value.constructor === Object) {\n        if (seen.has(value)) {\n          out[nextKey] = '<circular-reference>';\n          continue;\n        }\n        seen.add(value);\n        flatten(value as Record<string, unknown>, nextKey);\n        continue;\n      }\n\n      try {\n        out[nextKey] = JSON.stringify(value);\n      } catch {\n        out[nextKey] = '<serialization-failed>';\n      }\n    }\n  }\n\n  flatten(fields, prefix);\n  return out;\n}\n","import { SpanStatusCode } from '@opentelemetry/api';\nimport type { AttributeValue, TraceContext } from './trace-context';\nimport { flattenToAttributes } from './flatten-attributes';\n\nconst internalKey = Symbol.for('autotel.error.internal');\n\nexport interface StructuredErrorInput {\n  message: string;\n  why?: string;\n  fix?: string;\n  link?: string;\n  code?: string | number;\n  status?: number;\n  cause?: unknown;\n  details?: Record<string, unknown>;\n  name?: string;\n  /** Backend-only context. Omitted from toJSON() and never serialized to clients. */\n  internal?: Record<string, unknown>;\n}\n\nexport interface StructuredError extends Error {\n  why?: string;\n  fix?: string;\n  link?: string;\n  code?: string | number;\n  status?: number;\n  details?: Record<string, unknown>;\n  /** Backend-only context. Omitted from toJSON() and never serialized to clients. */\n  readonly internal?: Record<string, unknown>;\n}\n\nexport function createStructuredError(\n  input: StructuredErrorInput,\n): StructuredError {\n  const error = new Error(input.message, {\n    cause: input.cause,\n  }) as StructuredError;\n\n  error.name = input.name ?? 'StructuredError';\n  if (input.why !== undefined) error.why = input.why;\n  if (input.fix !== undefined) error.fix = input.fix;\n  if (input.link !== undefined) error.link = input.link;\n  if (input.code !== undefined) error.code = input.code;\n  if (input.status !== undefined) error.status = input.status;\n  if (input.details !== undefined) error.details = input.details;\n\n  if (input.internal !== undefined) {\n    Object.defineProperty(error, internalKey, {\n      value: input.internal,\n      enumerable: false,\n      writable: false,\n      configurable: true,\n    });\n  }\n\n  Object.defineProperty(error, 'internal', {\n    get() {\n      return (\n        this as StructuredError & { [internalKey]?: Record<string, unknown> }\n      )[internalKey];\n    },\n    enumerable: false,\n    configurable: true,\n  });\n\n  error.toString = () => {\n    const lines = [`${error.name}: ${error.message}`];\n    if (error.why) lines.push(`  Why: ${error.why}`);\n    if (error.fix) lines.push(`  Fix: ${error.fix}`);\n    if (error.link) lines.push(`  Link: ${error.link}`);\n    if (error.code !== undefined) lines.push(`  Code: ${error.code}`);\n    if (error.status !== undefined) lines.push(`  Status: ${error.status}`);\n    if (error.cause) {\n      const cause = error.cause as Error;\n      lines.push(`  Caused by: ${cause.name}: ${cause.message}`);\n    }\n    return lines.join('\\n');\n  };\n\n  return error;\n}\n\nexport function structuredErrorToJSON(\n  error: StructuredError,\n): Record<string, unknown> {\n  const result: Record<string, unknown> = {\n    name: error.name,\n    message: error.message,\n  };\n\n  if (error.status !== undefined) result.status = error.status;\n  if (error.why || error.fix || error.link) {\n    result.data = {\n      ...(error.why && { why: error.why }),\n      ...(error.fix && { fix: error.fix }),\n      ...(error.link && { link: error.link }),\n    };\n  }\n  if (error.code !== undefined) result.code = error.code;\n  if (error.details) result.details = error.details;\n  if (error.cause instanceof Error) {\n    result.cause = { name: error.cause.name, message: error.cause.message };\n  }\n\n  return result;\n}\n\nexport function getStructuredErrorAttributes(\n  error: Error,\n): Record<string, AttributeValue> {\n  const structured = error as StructuredError;\n  const attributes: Record<string, AttributeValue> = {\n    'error.type': error.name || 'Error',\n    'error.message': error.message,\n  };\n\n  if (error.stack) attributes['error.stack'] = error.stack;\n  if (structured.why) attributes['error.why'] = structured.why;\n  if (structured.fix) attributes['error.fix'] = structured.fix;\n  if (structured.link) attributes['error.link'] = structured.link;\n  if (structured.code !== undefined) {\n    attributes['error.code'] =\n      typeof structured.code === 'string'\n        ? structured.code\n        : String(structured.code);\n  }\n  if (structured.status !== undefined) {\n    attributes['error.status'] = structured.status;\n  }\n  if (structured.details) {\n    Object.assign(\n      attributes,\n      flattenToAttributes(structured.details, 'error.details'),\n    );\n  }\n\n  return attributes;\n}\n\nexport function recordStructuredError(\n  ctx: Pick<TraceContext, 'recordException' | 'setAttributes' | 'setStatus'>,\n  error: Error,\n): void {\n  ctx.recordException(error);\n  ctx.setStatus({\n    code: SpanStatusCode.ERROR,\n    message: error.message,\n  });\n  ctx.setAttributes(getStructuredErrorAttributes(error));\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport { trace as otelTrace } from '@opentelemetry/api';\nimport type { TraceContext } from './trace-context';\nimport { createTraceContext } from './trace-context';\nimport { recordStructuredError } from './structured-error';\nimport { flattenToAttributes } from './flatten-attributes';\n\nconst POST_EMIT_FORK_HINT =\n  \"For intentional background work tied to this request, use log.fork('label', fn) when available.\";\n\nfunction warnPostEmit(method: string, detail: string): void {\n  console.warn(\n    `[autotel] ${method} called after the wide event was emitted — ${detail} This data will not appear in observability. ${POST_EMIT_FORK_HINT}`,\n  );\n}\n\nfunction mergeInto(\n  target: Record<string, unknown>,\n  source: Record<string, unknown>,\n): void {\n  for (const key in source) {\n    const sourceVal = source[key];\n    if (sourceVal === undefined) continue;\n    const targetVal = target[key];\n    if (\n      sourceVal !== null &&\n      typeof sourceVal === 'object' &&\n      !Array.isArray(sourceVal) &&\n      targetVal !== null &&\n      typeof targetVal === 'object' &&\n      !Array.isArray(targetVal)\n    ) {\n      mergeInto(\n        targetVal as Record<string, unknown>,\n        sourceVal as Record<string, unknown>,\n      );\n    } else if (Array.isArray(targetVal) && Array.isArray(sourceVal)) {\n      target[key] = [...targetVal, ...sourceVal];\n    } else {\n      target[key] = sourceVal;\n    }\n  }\n}\n\nconst requestContextStore = new AsyncLocalStorage<TraceContext>();\n\nexport function runWithRequestContext<T>(ctx: TraceContext, fn: () => T): T {\n  return requestContextStore.run(ctx, fn);\n}\n\nexport interface RequestLogger {\n  set(fields: Record<string, unknown>): void;\n  info(message: string, fields?: Record<string, unknown>): void;\n  warn(message: string, fields?: Record<string, unknown>): void;\n  error(error: Error | string, fields?: Record<string, unknown>): void;\n  getContext(): Record<string, unknown>;\n  emitNow(overrides?: Record<string, unknown>): RequestLogSnapshot;\n  fork(label: string, fn: () => void | Promise<void>): void;\n}\n\nexport interface RequestLogSnapshot {\n  timestamp: string;\n  traceId: string;\n  spanId: string;\n  correlationId: string;\n  context: Record<string, unknown>;\n}\n\nexport interface RequestLoggerOptions {\n  /** Callback invoked by emitNow() for manual fan-out. */\n  onEmit?: (snapshot: RequestLogSnapshot) => void | Promise<void>;\n}\n\nfunction resolveContext(ctx?: TraceContext): TraceContext {\n  if (ctx) return ctx;\n\n  const stored = requestContextStore.getStore();\n  if (stored) return stored;\n\n  const span = otelTrace.getActiveSpan();\n  if (!span) {\n    throw new Error(\n      '[autotel] getRequestLogger() requires an active span or runWithRequestContext(). Wrap your handler with trace() or use runWithRequestContext().',\n    );\n  }\n  return createTraceContext(span);\n}\n\nexport function getRequestLogger(\n  ctx?: TraceContext,\n  options?: RequestLoggerOptions,\n): RequestLogger {\n  const activeContext = resolveContext(ctx);\n  let contextState: Record<string, unknown> = {};\n  let emitted = false;\n  let lastSnapshot: RequestLogSnapshot | null = null;\n\n  const addLogEvent = (\n    level: 'info' | 'warn' | 'error',\n    message: string,\n    fields?: Record<string, unknown>,\n  ) => {\n    const attrs = fields ? flattenToAttributes(fields) : undefined;\n    activeContext.addEvent(`log.${level}`, {\n      message,\n      ...attrs,\n    });\n  };\n\n  const sealCheck = (method: string, keys: string[]): void => {\n    if (emitted) {\n      warnPostEmit(\n        method,\n        `Keys dropped: ${keys.length ? keys.join(', ') : '(empty)'}.`,\n      );\n    }\n  };\n\n  return {\n    set(fields: Record<string, unknown>) {\n      sealCheck('log.set()', Object.keys(fields));\n      if (emitted) return;\n      mergeInto(contextState, fields);\n      activeContext.setAttributes(flattenToAttributes(fields));\n    },\n\n    info(message: string, fields?: Record<string, unknown>) {\n      const keys = fields\n        ? ['message', ...Object.keys(fields).filter((k) => k !== 'requestLogs')]\n        : ['message'];\n      sealCheck('log.info()', keys);\n      if (emitted) return;\n      addLogEvent('info', message, fields);\n      if (fields) {\n        mergeInto(contextState, fields);\n        activeContext.setAttributes(flattenToAttributes(fields));\n      }\n    },\n\n    warn(message: string, fields?: Record<string, unknown>) {\n      const keys = fields\n        ? ['message', ...Object.keys(fields).filter((k) => k !== 'requestLogs')]\n        : ['message'];\n      sealCheck('log.warn()', keys);\n      if (emitted) return;\n      addLogEvent('warn', message, fields);\n      activeContext.setAttribute('autotel.log.level', 'warn');\n      if (fields) {\n        mergeInto(contextState, fields);\n        activeContext.setAttributes(flattenToAttributes(fields));\n      }\n    },\n\n    error(error: Error | string, fields?: Record<string, unknown>) {\n      const keys = fields ? [...Object.keys(fields), 'error'] : ['error'];\n      sealCheck('log.error()', keys);\n      if (emitted) return;\n      const err = typeof error === 'string' ? new Error(error) : error;\n      recordStructuredError(activeContext, err);\n      addLogEvent('error', err.message, fields);\n\n      if (fields) {\n        mergeInto(contextState, fields);\n        activeContext.setAttributes(flattenToAttributes(fields));\n      }\n      activeContext.setAttribute('autotel.log.level', 'error');\n    },\n\n    getContext() {\n      return { ...contextState };\n    },\n\n    emitNow(overrides?: Record<string, unknown>): RequestLogSnapshot {\n      if (emitted) {\n        warnPostEmit('log.emitNow()', 'Ignoring duplicate emit.');\n        return lastSnapshot as RequestLogSnapshot;\n      }\n\n      const mergedContext = {\n        ...contextState,\n        ...(overrides ?? {}),\n      };\n      const flattened = flattenToAttributes(mergedContext);\n      activeContext.setAttributes(flattened);\n\n      const snapshot: RequestLogSnapshot = {\n        timestamp: new Date().toISOString(),\n        traceId: activeContext.traceId,\n        spanId: activeContext.spanId,\n        correlationId: activeContext.correlationId,\n        context: mergedContext,\n      };\n\n      activeContext.addEvent('log.emit.manual', {\n        ...flattened,\n      });\n\n      if (options?.onEmit) {\n        Promise.resolve(options.onEmit(snapshot)).catch((error) => {\n          console.warn('[autotel] request logger onEmit failed:', error);\n        });\n      }\n\n      emitted = true;\n      lastSnapshot = snapshot;\n      return snapshot;\n    },\n\n    fork(label: string, fn: () => void | Promise<void>): void {\n      const parentRequestId = activeContext.correlationId;\n      if (typeof parentRequestId !== 'string' || parentRequestId.length === 0) {\n        throw new Error(\n          '[autotel] log.fork() requires the parent logger to have a correlationId. ' +\n            'Ensure the request was created by autotel middleware.',\n        );\n      }\n\n      const tracer = otelTrace.getTracer('autotel.request-logger');\n      void tracer.startActiveSpan(`request.fork:${label}`, (childSpan) => {\n        const childContext: TraceContext = {\n          ...createTraceContext(childSpan),\n          correlationId: crypto.randomUUID(),\n        };\n\n        requestContextStore.run(childContext, () => {\n          const childLog = getRequestLogger(childContext);\n          childLog.set({\n            operation: label,\n            _parentCorrelationId: parentRequestId,\n          });\n\n          void Promise.resolve()\n            .then(() => fn())\n            .then(() => {\n              childLog.emitNow();\n            })\n            .catch((err: unknown) => {\n              const error = err instanceof Error ? err : new Error(String(err));\n              childLog.error(error);\n              childLog.emitNow();\n            })\n            .finally(() => {\n              childSpan.end();\n            });\n        });\n      });\n    },\n  };\n}\n","/**\n * LLM-tuned histogram buckets.\n *\n * Default OpenTelemetry histogram buckets target HTTP latency (0ms–10s)\n * and small counter values. LLM workloads have very different shapes:\n *\n *   - **Duration**: single-token prompts can be fast (50ms), long\n *     generations and reasoning models can run for minutes. Default buckets\n *     crush everything above 10s into one bucket.\n *   - **Token usage**: heavily right-skewed. A single request can range\n *     from tens of tokens to the million-token context windows.\n *   - **Cost (USD)**: per-request values are tiny (fractions of a cent),\n *     so linear buckets waste resolution at the low end.\n *\n * This module exposes empirically-chosen bucket arrays and a View helper\n * so users can apply them to their `MeterProvider` without knowing the\n * exact instrument names emitted by OpenAI/Anthropic/Traceloop plugins.\n *\n * @example\n * ```typescript\n * import { NodeSDK } from '@opentelemetry/sdk-node';\n * import { genAiMetricViews } from 'autotel';\n *\n * const sdk = new NodeSDK({\n *   serviceName: 'my-agent',\n *   views: [...genAiMetricViews()],\n * });\n * sdk.start();\n * ```\n */\n\nimport { AggregationType, type ViewOptions } from '@opentelemetry/sdk-metrics';\n\n/**\n * Duration buckets for LLM operations, in **seconds**. Covers fast\n * completions (50ms) through long-running reasoning jobs (5 min).\n *\n * Aligns with the OTel GenAI semantic conventions' published advice for\n * `gen_ai.client.operation.duration`.\n */\nexport const GEN_AI_DURATION_BUCKETS_SECONDS: readonly number[] = Object.freeze(\n  [0.01, 0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 20, 30, 60, 120, 300],\n);\n\n/**\n * Token-count buckets for prompt, completion, and total token histograms.\n * Ranges from tiny prompts to million-token context windows.\n *\n * Aligns with the OTel GenAI semantic conventions' published advice for\n * `gen_ai.client.token.usage`.\n */\nexport const GEN_AI_TOKEN_USAGE_BUCKETS: readonly number[] = Object.freeze([\n  1, 4, 16, 64, 256, 1_024, 4_096, 16_384, 65_536, 262_144, 1_048_576,\n  4_194_304,\n]);\n\n/**\n * USD cost buckets. Sub-cent resolution at the low end (fractions of a\n * cent per small call) up to tens of dollars (batch jobs, Opus/o1 runs).\n */\nexport const GEN_AI_COST_USD_BUCKETS: readonly number[] = Object.freeze([\n  0.000_01, 0.000_1, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10, 50,\n]);\n\n/**\n * Instrument-level advice object for `createHistogram(name, advice)`.\n * Use when you control the instrument creation (e.g. custom business\n * LLM metrics); `genAiMetricViews()` is better when the metric comes\n * from a third-party plugin.\n */\nexport function llmHistogramAdvice(kind: 'duration' | 'tokens' | 'cost'): {\n  advice: { explicitBucketBoundaries: number[] };\n} {\n  const boundaries =\n    kind === 'duration'\n      ? GEN_AI_DURATION_BUCKETS_SECONDS\n      : kind === 'tokens'\n        ? GEN_AI_TOKEN_USAGE_BUCKETS\n        : GEN_AI_COST_USD_BUCKETS;\n  return { advice: { explicitBucketBoundaries: [...boundaries] } };\n}\n\n/**\n * Returns `View`s that re-bucket the standard OTel GenAI histograms. Pass\n * the result to your `MeterProvider`'s `views` option.\n *\n * Matches instrument names emitted by:\n * - OpenTelemetry GenAI autoinstrumentation\n * - OpenInference / OpenLLMetry (traceloop)\n * - Arize Phoenix, LangSmith, etc. that follow the OTel spec\n *\n * Add more instrument patterns via the `extra` argument if you emit\n * custom LLM metrics.\n */\nexport function genAiMetricViews(\n  extra: {\n    instrumentName: string;\n    kind: 'duration' | 'tokens' | 'cost';\n  }[] = [],\n): ViewOptions[] {\n  const defaults: Array<{\n    instrumentName: string;\n    kind: 'duration' | 'tokens' | 'cost';\n  }> = [\n    { instrumentName: 'gen_ai.client.operation.duration', kind: 'duration' },\n    { instrumentName: 'gen_ai.client.token.usage', kind: 'tokens' },\n    // Autotel-emitted cost metric. No-op if you don't emit it.\n    { instrumentName: 'gen_ai.client.cost.usd', kind: 'cost' },\n  ];\n\n  return [...defaults, ...extra].map(\n    ({ instrumentName, kind }) =>\n      ({\n        instrumentName,\n        aggregation: {\n          type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM,\n          options: {\n            boundaries:\n              kind === 'duration'\n                ? [...GEN_AI_DURATION_BUCKETS_SECONDS]\n                : kind === 'tokens'\n                  ? [...GEN_AI_TOKEN_USAGE_BUCKETS]\n                  : [...GEN_AI_COST_USD_BUCKETS],\n          },\n        },\n      }) satisfies ViewOptions,\n  );\n}\n","/**\n * Span event helpers for LLM lifecycle, aligned with the OpenTelemetry\n * GenAI semantic conventions.\n *\n * Span events are timestamped points within a span — they render as dots\n * on the trace timeline in Jaeger / Tempo / Langfuse / Arize. Use them\n * to mark lifecycle moments the span attributes alone can't express:\n *\n *   - When the prompt was sent (vs. when the first token arrived)\n *   - When each retry attempt started, and why\n *   - When a streaming response produced its first token (TTFT)\n *   - When a tool was invoked\n *\n * Every helper pins the event name + attribute keys to the published\n * spec so downstream tooling (autotel-mcp, Langfuse, vendor UIs) can\n * render them consistently.\n *\n * @example\n * ```typescript\n * import { trace, recordPromptSent, recordResponseReceived, recordRetry } from 'autotel';\n *\n * export const chat = trace('chat', ctx => async (prompt: string) => {\n *   recordPromptSent(ctx, { model: 'gpt-4o', messageCount: 1 });\n *\n *   for (let attempt = 1; attempt <= 3; attempt++) {\n *     try {\n *       const res = await openai.chat.completions.create({...});\n *       recordResponseReceived(ctx, {\n *         model: res.model,\n *         promptTokens: res.usage?.prompt_tokens,\n *         completionTokens: res.usage?.completion_tokens,\n *         finishReasons: res.choices.map(c => c.finish_reason),\n *       });\n *       return res;\n *     } catch (err) {\n *       recordRetry(ctx, { attempt, reason: 'rate_limit', delayMs: 500 });\n *       await sleep(500 * attempt);\n *     }\n *   }\n * });\n * ```\n */\n\nimport type { TraceContext } from './trace-context';\n\ntype EventAttrs = Record<string, string | number | boolean>;\n\n/** Attributes expected on a `gen_ai.prompt.sent` event. */\nexport interface PromptSentEvent {\n  /** Model the caller intends to invoke (may differ from response model). */\n  model?: string;\n  /** Estimated input token count, when known before the call. */\n  promptTokens?: number;\n  /** Number of messages in a chat request (system + user + assistant). */\n  messageCount?: number;\n  /** Free-form operation kind — `chat` / `completion` / `embedding`. */\n  operation?: string;\n}\n\n/** Attributes expected on a `gen_ai.response.received` event. */\nexport interface ResponseReceivedEvent {\n  /** Model the provider actually served (may be more specific than requested). */\n  model?: string;\n  promptTokens?: number;\n  completionTokens?: number;\n  totalTokens?: number;\n  /** `stop`, `length`, `content_filter`, `tool_calls`, etc. */\n  finishReasons?: string[];\n}\n\n/** Attributes expected on a `gen_ai.retry` event. */\nexport interface RetryEvent {\n  attempt: number;\n  /** `rate_limit` | `timeout` | `provider_error` | custom label. */\n  reason?: string;\n  /** How long we'll wait before the next attempt. */\n  delayMs?: number;\n  /** HTTP status that triggered the retry, when applicable. */\n  statusCode?: number;\n}\n\n/** Attributes expected on a `gen_ai.tool.call` event. */\nexport interface ToolCallEvent {\n  toolName: string;\n  /** Call identifier so responses can be correlated back to calls. */\n  toolCallId?: string;\n  /** Pre-serialised tool arguments; omit if sensitive. */\n  arguments?: string;\n}\n\n/** Attributes expected on a `gen_ai.stream.first_token` event. */\nexport interface StreamFirstTokenEvent {\n  /** Tokens streamed so far, if the caller tracks that. */\n  tokensSoFar?: number;\n}\n\n/**\n * Record that a prompt was dispatched to the provider. Typically called\n * before `await provider.chat.completions.create(...)`.\n */\nexport function recordPromptSent(\n  ctx: TraceContext,\n  event: PromptSentEvent = {},\n): void {\n  ctx.addEvent('gen_ai.prompt.sent', buildPromptSentAttrs(event));\n}\n\n/**\n * Record a successful provider response. Call after the response arrives\n * (for non-streaming) or after the stream completes.\n */\nexport function recordResponseReceived(\n  ctx: TraceContext,\n  event: ResponseReceivedEvent = {},\n): void {\n  ctx.addEvent('gen_ai.response.received', buildResponseAttrs(event));\n}\n\n/**\n * Record a retry attempt on an LLM call. Call *before* sleeping for\n * `delayMs` so the event timestamp accurately marks when the retry\n * decision was made.\n */\nexport function recordRetry(ctx: TraceContext, event: RetryEvent): void {\n  ctx.addEvent('gen_ai.retry', buildRetryAttrs(event));\n}\n\n/**\n * Record a tool / function call made in the course of an agent step.\n * Emits an event rather than a child span because many frameworks fire\n * several tool calls within a single provider response.\n */\nexport function recordToolCall(ctx: TraceContext, event: ToolCallEvent): void {\n  ctx.addEvent('gen_ai.tool.call', buildToolCallAttrs(event));\n}\n\n/**\n * Record the time-to-first-token for a streaming response. Pair with\n * `recordResponseReceived` at the end so the span carries both the TTFT\n * marker and the final usage numbers.\n */\nexport function recordStreamFirstToken(\n  ctx: TraceContext,\n  event: StreamFirstTokenEvent = {},\n): void {\n  ctx.addEvent('gen_ai.stream.first_token', buildStreamFirstTokenAttrs(event));\n}\n\n// ---- Attribute builders -------------------------------------------------\n\nfunction buildPromptSentAttrs(event: PromptSentEvent): EventAttrs {\n  const attrs: EventAttrs = {};\n  if (event.model) attrs['gen_ai.request.model'] = event.model;\n  if (event.promptTokens !== undefined)\n    attrs['gen_ai.usage.input_tokens'] = event.promptTokens;\n  if (event.messageCount !== undefined)\n    attrs['gen_ai.request.message_count'] = event.messageCount;\n  if (event.operation) attrs['gen_ai.operation.name'] = event.operation;\n  return attrs;\n}\n\nfunction buildResponseAttrs(event: ResponseReceivedEvent): EventAttrs {\n  const attrs: EventAttrs = {};\n  if (event.model) attrs['gen_ai.response.model'] = event.model;\n  if (event.promptTokens !== undefined)\n    attrs['gen_ai.usage.input_tokens'] = event.promptTokens;\n  if (event.completionTokens !== undefined)\n    attrs['gen_ai.usage.output_tokens'] = event.completionTokens;\n  if (event.totalTokens !== undefined)\n    attrs['gen_ai.usage.total_tokens'] = event.totalTokens;\n  if (event.finishReasons && event.finishReasons.length > 0) {\n    // Arrays aren't primitive AttributeValues on this context, so join.\n    attrs['gen_ai.response.finish_reasons'] = event.finishReasons.join(',');\n  }\n  return attrs;\n}\n\nfunction buildRetryAttrs(event: RetryEvent): EventAttrs {\n  const attrs: EventAttrs = { 'retry.attempt': event.attempt };\n  if (event.reason) attrs['retry.reason'] = event.reason;\n  if (event.delayMs !== undefined) attrs['retry.delay_ms'] = event.delayMs;\n  if (event.statusCode !== undefined)\n    attrs['http.response.status_code'] = event.statusCode;\n  return attrs;\n}\n\nfunction buildToolCallAttrs(event: ToolCallEvent): EventAttrs {\n  const attrs: EventAttrs = { 'gen_ai.tool.name': event.toolName };\n  if (event.toolCallId) attrs['gen_ai.tool.call.id'] = event.toolCallId;\n  if (event.arguments) attrs['gen_ai.tool.arguments'] = event.arguments;\n  return attrs;\n}\n\nfunction buildStreamFirstTokenAttrs(event: StreamFirstTokenEvent): EventAttrs {\n  const attrs: EventAttrs = {};\n  if (event.tokensSoFar !== undefined)\n    attrs['gen_ai.stream.tokens_so_far'] = event.tokensSoFar;\n  return attrs;\n}\n"]}