autotel 3.1.1 → 3.3.0

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.
Files changed (105) hide show
  1. package/dist/attribute-redacting-processor.cjs +8 -8
  2. package/dist/attribute-redacting-processor.js +1 -1
  3. package/dist/attributes.cjs +21 -21
  4. package/dist/attributes.js +2 -2
  5. package/dist/auto.cjs +3 -3
  6. package/dist/auto.js +2 -2
  7. package/dist/{chunk-MYWQELNY.js → chunk-32AXF4MA.js} +30 -8
  8. package/dist/chunk-32AXF4MA.js.map +1 -0
  9. package/dist/{chunk-6X2GG65S.cjs → chunk-3MZJ7Y24.cjs} +5 -5
  10. package/dist/{chunk-6X2GG65S.cjs.map → chunk-3MZJ7Y24.cjs.map} +1 -1
  11. package/dist/{chunk-DDXIUZEG.js → chunk-454CH4OV.js} +3 -3
  12. package/dist/{chunk-DDXIUZEG.js.map → chunk-454CH4OV.js.map} +1 -1
  13. package/dist/{chunk-MXO6LXV5.cjs → chunk-4RA6HIYF.cjs} +5 -5
  14. package/dist/{chunk-MXO6LXV5.cjs.map → chunk-4RA6HIYF.cjs.map} +1 -1
  15. package/dist/{chunk-6TFJF7SS.js → chunk-4TAQQZDU.js} +3 -3
  16. package/dist/{chunk-6TFJF7SS.js.map → chunk-4TAQQZDU.js.map} +1 -1
  17. package/dist/{chunk-LIYNUGML.cjs → chunk-DQSVSGK3.cjs} +23 -32
  18. package/dist/chunk-DQSVSGK3.cjs.map +1 -0
  19. package/dist/{chunk-PEEUMQ3R.js → chunk-FZROHTZZ.js} +3 -3
  20. package/dist/{chunk-PEEUMQ3R.js.map → chunk-FZROHTZZ.js.map} +1 -1
  21. package/dist/{chunk-DQ2SUROF.cjs → chunk-M3LFHHTN.cjs} +4 -4
  22. package/dist/{chunk-DQ2SUROF.cjs.map → chunk-M3LFHHTN.cjs.map} +1 -1
  23. package/dist/{chunk-ZPERWNOP.cjs → chunk-MQH5OOZK.cjs} +17 -17
  24. package/dist/{chunk-ZPERWNOP.cjs.map → chunk-MQH5OOZK.cjs.map} +1 -1
  25. package/dist/{chunk-NXLRY2CE.cjs → chunk-NEIB3TLD.cjs} +10 -8
  26. package/dist/chunk-NEIB3TLD.cjs.map +1 -0
  27. package/dist/{chunk-MHPYLMQS.js → chunk-OACAWYLR.js} +4 -4
  28. package/dist/{chunk-MHPYLMQS.js.map → chunk-OACAWYLR.js.map} +1 -1
  29. package/dist/{chunk-52ALHU7T.js → chunk-OPCTN527.js} +3 -3
  30. package/dist/{chunk-52ALHU7T.js.map → chunk-OPCTN527.js.map} +1 -1
  31. package/dist/{chunk-YPQMAE6U.cjs → chunk-QICFEFD6.cjs} +7 -7
  32. package/dist/{chunk-YPQMAE6U.cjs.map → chunk-QICFEFD6.cjs.map} +1 -1
  33. package/dist/{chunk-45B2GD4P.cjs → chunk-QJYWKAC5.cjs} +32 -10
  34. package/dist/chunk-QJYWKAC5.cjs.map +1 -0
  35. package/dist/{chunk-JVWJDHDB.js → chunk-RUPKBKUF.js} +10 -8
  36. package/dist/chunk-RUPKBKUF.js.map +1 -0
  37. package/dist/{chunk-FTBBBPT6.js → chunk-TGV2XF57.js} +13 -22
  38. package/dist/chunk-TGV2XF57.js.map +1 -0
  39. package/dist/{chunk-T7CPAGOI.js → chunk-U4D5IBSB.js} +4 -4
  40. package/dist/chunk-U4D5IBSB.js.map +1 -0
  41. package/dist/{chunk-KPDIEVVV.cjs → chunk-U72TGONP.cjs} +32 -32
  42. package/dist/chunk-U72TGONP.cjs.map +1 -0
  43. package/dist/correlation-id.cjs +11 -11
  44. package/dist/correlation-id.js +3 -3
  45. package/dist/decorators.cjs +5 -5
  46. package/dist/decorators.js +4 -4
  47. package/dist/event-subscriber.d.cts +15 -1
  48. package/dist/event-subscriber.d.ts +15 -1
  49. package/dist/event.cjs +7 -7
  50. package/dist/event.js +4 -4
  51. package/dist/functional.cjs +12 -12
  52. package/dist/functional.js +4 -4
  53. package/dist/http.cjs +4 -4
  54. package/dist/http.js +3 -3
  55. package/dist/index.cjs +280 -94
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.cts +209 -4
  58. package/dist/index.d.ts +209 -4
  59. package/dist/index.js +191 -14
  60. package/dist/index.js.map +1 -1
  61. package/dist/{init-BSyIyDs5.d.ts → init-DyE43paw.d.ts} +7 -2
  62. package/dist/{init-D9Bxx39e.d.cts → init-gyesUMwz.d.cts} +7 -2
  63. package/dist/instrumentation.cjs +9 -9
  64. package/dist/instrumentation.js +2 -2
  65. package/dist/messaging.cjs +8 -8
  66. package/dist/messaging.js +5 -5
  67. package/dist/semantic-helpers.cjs +9 -9
  68. package/dist/semantic-helpers.js +5 -5
  69. package/dist/webhook.cjs +6 -6
  70. package/dist/webhook.js +4 -4
  71. package/dist/workflow-distributed.cjs +6 -6
  72. package/dist/workflow-distributed.js +4 -4
  73. package/dist/workflow.cjs +9 -9
  74. package/dist/workflow.js +5 -5
  75. package/dist/yaml-config.d.cts +1 -1
  76. package/dist/yaml-config.d.ts +1 -1
  77. package/package.json +1 -1
  78. package/skills/build-audit-trails/SKILL.md +150 -5
  79. package/skills/build-audit-trails/references/audit-queries.md +73 -0
  80. package/skills/build-audit-trails/references/framework-wiring.md +187 -0
  81. package/skills/review-otel-patterns/SKILL.md +41 -0
  82. package/src/attribute-redacting-processor.ts +12 -9
  83. package/src/define-event.test.ts +41 -0
  84. package/src/define-event.ts +77 -0
  85. package/src/error-catalog.test.ts +128 -0
  86. package/src/error-catalog.ts +259 -0
  87. package/src/event-queue.ts +4 -0
  88. package/src/event-subscriber.ts +15 -0
  89. package/src/functional.ts +2 -1
  90. package/src/gen-ai-cost.test.ts +81 -0
  91. package/src/gen-ai-cost.ts +145 -0
  92. package/src/index.ts +35 -0
  93. package/src/init-auto-redactor.test.ts +53 -0
  94. package/src/init.ts +46 -7
  95. package/src/track.ts +3 -0
  96. package/src/validation.test.ts +7 -3
  97. package/src/validation.ts +19 -21
  98. package/dist/chunk-45B2GD4P.cjs.map +0 -1
  99. package/dist/chunk-FTBBBPT6.js.map +0 -1
  100. package/dist/chunk-JVWJDHDB.js.map +0 -1
  101. package/dist/chunk-KPDIEVVV.cjs.map +0 -1
  102. package/dist/chunk-LIYNUGML.cjs.map +0 -1
  103. package/dist/chunk-MYWQELNY.js.map +0 -1
  104. package/dist/chunk-NXLRY2CE.cjs.map +0 -1
  105. package/dist/chunk-T7CPAGOI.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/trace-hybrid.ts","../src/shutdown.ts","../src/request-logger.ts","../src/drain-toolkit.ts","../src/enricher-toolkit.ts","../src/gen-ai-metrics.ts","../src/gen-ai-events.ts"],"names":["otelTraceApi","trace","getEventQueue","getSdk","getLogger","_closeEmbeddedDevtools","resetEvents","resetMetrics","resetEventQueue","AsyncLocalStorage","ctx","span","otelTrace","createTraceContext","attrs","flattenToAttributes","emitCorrelatedEvent","recordStructuredError","request","mergeInto","AggregationType"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Hybrid `trace` export: callable like autotel's `trace(fn)`, AND exposes the\n * full `@opentelemetry/api` `TraceAPI` surface (`trace.getActiveSpan()`,\n * `trace.getTracer()`, …) so existing OTel code \"just works\" when imported\n * from `autotel`.\n *\n * Implementation: `Object.assign` mutates the autotel `trace` function to\n * attach the OTel TraceAPI methods. Because every reference to `trace` across\n * autotel resolves to the same function instance, this is a one-time, global\n * augmentation.\n */\n\nimport { trace as otelTraceApi } from '@opentelemetry/api';\nimport { trace as autotelTraceFn } from './functional';\n\nconst otelMethods = {\n // Class methods on TraceAPI — bind to the singleton.\n setGlobalTracerProvider:\n otelTraceApi.setGlobalTracerProvider.bind(otelTraceApi),\n getTracerProvider: otelTraceApi.getTracerProvider.bind(otelTraceApi),\n getTracer: otelTraceApi.getTracer.bind(otelTraceApi),\n disable: otelTraceApi.disable.bind(otelTraceApi),\n // Instance fields on TraceAPI — already standalone, copy by reference.\n wrapSpanContext: otelTraceApi.wrapSpanContext,\n isSpanContextValid: otelTraceApi.isSpanContextValid,\n deleteSpan: otelTraceApi.deleteSpan,\n getSpan: otelTraceApi.getSpan,\n getActiveSpan: otelTraceApi.getActiveSpan,\n getSpanContext: otelTraceApi.getSpanContext,\n setSpan: otelTraceApi.setSpan,\n setSpanContext: otelTraceApi.setSpanContext,\n};\n\nexport const trace: typeof autotelTraceFn & typeof otelTraceApi = Object.assign(\n autotelTraceFn,\n otelMethods,\n) as typeof autotelTraceFn & typeof otelTraceApi;\n","/**\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 { 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';\nimport { emitCorrelatedEvent } from './correlated-events';\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(\n label: string,\n fn: () => void | Promise<void>,\n options?: ForkOptions,\n ): 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\n/**\n * Optional lifecycle hooks for adapters that need to track child loggers\n * spawned by `log.fork()` (e.g. active logger maps in framework integrations).\n */\nexport interface ForkLifecycle {\n /** Called after the child logger is created, before `fn` runs. */\n onChildEnter?: (child: RequestLogger) => void;\n /** Called after the child has finished (emit + drain), success or failure. */\n onChildExit?: (child: RequestLogger) => void;\n}\n\nexport interface ForkOptions {\n lifecycle?: ForkLifecycle;\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 emitCorrelatedEvent(activeContext, `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 emitCorrelatedEvent(activeContext, '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(\n label: string,\n fn: () => void | Promise<void>,\n forkOptions?: ForkOptions,\n ): 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 const lifecycle = forkOptions?.lifecycle;\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 lifecycle?.onChildEnter?.(childLog);\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 try {\n lifecycle?.onChildExit?.(childLog);\n } catch (hookError) {\n console.warn(\n '[autotel] fork onChildExit hook threw:',\n hookError,\n );\n }\n childSpan.end();\n });\n });\n });\n },\n };\n}\n","export interface DrainOptions<TContext, TConfig, TPayload = TContext> {\n /** Stable identifier used in error logs. */\n name: string;\n /** Return null to skip draining (e.g. missing API key in dev). */\n resolve: () => TConfig | null | Promise<TConfig | null>;\n /** Transform contexts into payloads. Defaults to identity. */\n transform?: (contexts: TContext[]) => TPayload[];\n /** Transport implementation. */\n send: (payloads: TPayload[], config: TConfig) => Promise<void>;\n}\n\nexport interface HttpDrainRequest {\n url: string;\n headers: Record<string, string>;\n body: string;\n}\n\nexport interface HttpDrainOptions<\n TContext,\n TConfig,\n TPayload = TContext,\n> extends Omit<DrainOptions<TContext, TConfig, TPayload>, 'send'> {\n encode: (payloads: TPayload[], config: TConfig) => HttpDrainRequest | null;\n timeoutMs?: number;\n retries?: number;\n resolveTimeoutMs?: (config: TConfig) => number | undefined;\n resolveRetries?: (config: TConfig) => number | undefined;\n}\n\nconst DEFAULT_TIMEOUT_MS = 5000;\nconst DEFAULT_RETRIES = 2;\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const t = setTimeout(resolve, ms);\n t.unref?.();\n });\n}\n\nasync function postWithRetry(options: {\n name: string;\n request: HttpDrainRequest;\n timeoutMs: number;\n retries: number;\n}): Promise<void> {\n const { name, request, timeoutMs, retries } = options;\n const attempts = Math.max(1, retries);\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= attempts; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n timeout.unref?.();\n try {\n const response = await fetch(request.url, {\n method: 'POST',\n headers: request.headers,\n body: request.body,\n signal: controller.signal,\n });\n if (!response.ok) {\n throw new Error(\n `[autotel/${name}] HTTP ${response.status} draining ${request.url}`,\n );\n }\n return;\n } catch (error) {\n lastError = error;\n if (attempt < attempts) {\n await delay(100 * attempt);\n }\n } finally {\n clearTimeout(timeout);\n }\n }\n\n throw lastError;\n}\n\nexport function defineDrain<TContext, TConfig, TPayload = TContext>(\n options: DrainOptions<TContext, TConfig, TPayload>,\n): (ctx: TContext | TContext[]) => Promise<void> {\n return async (ctx: TContext | TContext[]) => {\n const contexts = Array.isArray(ctx) ? ctx : [ctx];\n if (contexts.length === 0) return;\n\n const config = await options.resolve();\n if (!config) return;\n\n const payloads = options.transform\n ? options.transform(contexts)\n : (contexts as unknown as TPayload[]);\n\n if (payloads.length === 0) return;\n\n try {\n await options.send(payloads, config);\n } catch (error) {\n console.error(`[autotel/${options.name}] drain failed:`, error);\n }\n };\n}\n\nexport function defineHttpDrain<TContext, TConfig, TPayload = TContext>(\n options: HttpDrainOptions<TContext, TConfig, TPayload>,\n): (ctx: TContext | TContext[]) => Promise<void> {\n return defineDrain<TContext, TConfig, TPayload>({\n name: options.name,\n resolve: options.resolve,\n transform: options.transform,\n send: async (payloads, config) => {\n const request = options.encode(payloads, config);\n if (!request) return;\n const timeoutMs =\n options.resolveTimeoutMs?.(config) ??\n options.timeoutMs ??\n DEFAULT_TIMEOUT_MS;\n const retries =\n options.resolveRetries?.(config) ?? options.retries ?? DEFAULT_RETRIES;\n\n await postWithRetry({\n name: options.name,\n request,\n timeoutMs,\n retries,\n });\n },\n });\n}\n","export interface EnrichContext<TEvent extends Record<string, unknown>> {\n event: TEvent;\n request?: {\n method?: string;\n path?: string;\n requestId?: string;\n };\n response?: {\n status?: number;\n };\n headers?: Record<string, string>;\n}\n\nexport interface EnricherDefinition<\n TEvent extends Record<string, unknown>,\n TValue extends object,\n> {\n /** Stable identifier used in error logs. */\n name: string;\n /** Top-level field to merge computed values into. */\n field: keyof TEvent & string;\n /** Return undefined to skip enrichment. */\n compute: (ctx: EnrichContext<TEvent>) => TValue | undefined;\n}\n\nexport interface EnricherOptions {\n /** Replace existing field value instead of merge. Default false. */\n overwrite?: boolean;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\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 (isPlainObject(sourceVal) && isPlainObject(targetVal)) {\n mergeInto(targetVal, sourceVal);\n } else {\n target[key] = sourceVal;\n }\n }\n}\n\nexport function defineEnricher<\n TEvent extends Record<string, unknown>,\n TValue extends object,\n>(\n def: EnricherDefinition<TEvent, TValue>,\n options: EnricherOptions = {},\n): (ctx: EnrichContext<TEvent>) => void {\n return (ctx: EnrichContext<TEvent>) => {\n let computed: TValue | undefined;\n try {\n computed = def.compute(ctx);\n } catch (error) {\n console.error(`[autotel/${def.name}] enrich failed:`, error);\n return;\n }\n\n if (!computed) return;\n\n if (options.overwrite || !isPlainObject(ctx.event[def.field])) {\n (ctx.event as Record<string, unknown>)[def.field] = computed;\n return;\n }\n\n mergeInto(\n ctx.event[def.field] as unknown as Record<string, unknown>,\n computed as unknown as Record<string, unknown>,\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';\nimport { emitCorrelatedEvent } from './correlated-events';\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 emitCorrelatedEvent(ctx, '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 emitCorrelatedEvent(\n ctx,\n 'gen_ai.response.received',\n buildResponseAttrs(event),\n );\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 emitCorrelatedEvent(ctx, '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 emitCorrelatedEvent(ctx, '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 emitCorrelatedEvent(\n ctx,\n 'gen_ai.stream.first_token',\n buildStreamFirstTokenAttrs(event),\n );\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"]}
1
+ {"version":3,"sources":["../src/trace-hybrid.ts","../src/define-event.ts","../src/shutdown.ts","../src/request-logger.ts","../src/error-catalog.ts","../src/drain-toolkit.ts","../src/enricher-toolkit.ts","../src/gen-ai-metrics.ts","../src/gen-ai-events.ts","../src/gen-ai-cost.ts"],"names":["otelTraceApi","trace","track","createHash","getEventQueue","getSdk","getLogger","_closeEmbeddedDevtools","resetEvents","resetMetrics","resetEventQueue","AsyncLocalStorage","ctx","span","otelTrace","createTraceContext","attrs","flattenToAttributes","emitCorrelatedEvent","recordStructuredError","createStructuredError","request","mergeInto","AggregationType"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Hybrid `trace` export: callable like autotel's `trace(fn)`, AND exposes the\n * full `@opentelemetry/api` `TraceAPI` surface (`trace.getActiveSpan()`,\n * `trace.getTracer()`, …) so existing OTel code \"just works\" when imported\n * from `autotel`.\n *\n * Implementation: `Object.assign` mutates the autotel `trace` function to\n * attach the OTel TraceAPI methods. Because every reference to `trace` across\n * autotel resolves to the same function instance, this is a one-time, global\n * augmentation.\n */\n\nimport { trace as otelTraceApi } from '@opentelemetry/api';\nimport { trace as autotelTraceFn } from './functional';\n\nconst otelMethods = {\n // Class methods on TraceAPI — bind to the singleton.\n setGlobalTracerProvider:\n otelTraceApi.setGlobalTracerProvider.bind(otelTraceApi),\n getTracerProvider: otelTraceApi.getTracerProvider.bind(otelTraceApi),\n getTracer: otelTraceApi.getTracer.bind(otelTraceApi),\n disable: otelTraceApi.disable.bind(otelTraceApi),\n // Instance fields on TraceAPI — already standalone, copy by reference.\n wrapSpanContext: otelTraceApi.wrapSpanContext,\n isSpanContextValid: otelTraceApi.isSpanContextValid,\n deleteSpan: otelTraceApi.deleteSpan,\n getSpan: otelTraceApi.getSpan,\n getActiveSpan: otelTraceApi.getActiveSpan,\n getSpanContext: otelTraceApi.getSpanContext,\n setSpan: otelTraceApi.setSpan,\n setSpanContext: otelTraceApi.setSpanContext,\n};\n\nexport const trace: typeof autotelTraceFn & typeof otelTraceApi = Object.assign(\n autotelTraceFn,\n otelMethods,\n) as typeof autotelTraceFn & typeof otelTraceApi;\n","import { createHash } from 'node:crypto';\nimport { track } from './track';\nimport type { EventSchemaMetadata } from './event-subscriber';\n\ntype SafeParseResult<T> =\n | { success: true; data: T }\n | { success: false; error: unknown };\n\nexport interface SchemaLike<T> {\n safeParse(input: unknown): SafeParseResult<T>;\n}\n\nexport interface DefineEventOptions<S> {\n toJsonSchema?: (schema: S) => unknown;\n}\n\nexport interface DefinedEvent<Name extends string, Payload> {\n readonly name: Name;\n readonly schemaMetadata?: EventSchemaMetadata;\n track(payload: Payload): void;\n}\n\nexport function defineEvent<\n Name extends string,\n Payload,\n S extends SchemaLike<Payload>,\n>(\n name: Name,\n schema: S,\n options: DefineEventOptions<S> = {},\n): DefinedEvent<Name, Payload> {\n const jsonSchema = options.toJsonSchema?.(schema);\n const schemaMetadata = jsonSchema\n ? {\n source: 'zod' as const,\n jsonSchema,\n hash: hashSchema(jsonSchema),\n }\n : undefined;\n\n return {\n name,\n schemaMetadata,\n track(payload: Payload) {\n const parsed = schema.safeParse(payload);\n if (!parsed.success) {\n throw new Error(\n `Invalid payload for event \"${name}\". Schema validation failed.`,\n );\n }\n track(\n name,\n parsed.data,\n schemaMetadata ? { schema: schemaMetadata } : undefined,\n );\n },\n };\n}\n\nfunction hashSchema(schema: unknown): string {\n return createHash('sha256').update(stableStringify(schema)).digest('hex');\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === null || value === undefined || typeof value !== 'object') {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n return '[' + value.map((v) => stableStringify(v)).join(',') + ']';\n }\n const obj = value as Record<string, unknown>;\n const body = Object.keys(obj)\n .sort()\n .map((k) => JSON.stringify(k) + ':' + stableStringify(obj[k]))\n .join(',');\n return '{' + body + '}';\n}\n","/**\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 { 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';\nimport { emitCorrelatedEvent } from './correlated-events';\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(\n label: string,\n fn: () => void | Promise<void>,\n options?: ForkOptions,\n ): 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\n/**\n * Optional lifecycle hooks for adapters that need to track child loggers\n * spawned by `log.fork()` (e.g. active logger maps in framework integrations).\n */\nexport interface ForkLifecycle {\n /** Called after the child logger is created, before `fn` runs. */\n onChildEnter?: (child: RequestLogger) => void;\n /** Called after the child has finished (emit + drain), success or failure. */\n onChildExit?: (child: RequestLogger) => void;\n}\n\nexport interface ForkOptions {\n lifecycle?: ForkLifecycle;\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 emitCorrelatedEvent(activeContext, `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 emitCorrelatedEvent(activeContext, '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(\n label: string,\n fn: () => void | Promise<void>,\n forkOptions?: ForkOptions,\n ): 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 const lifecycle = forkOptions?.lifecycle;\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 lifecycle?.onChildEnter?.(childLog);\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 try {\n lifecycle?.onChildExit?.(childLog);\n } catch (hookError) {\n console.warn(\n '[autotel] fork onChildExit hook threw:',\n hookError,\n );\n }\n childSpan.end();\n });\n });\n });\n },\n };\n}\n","/**\n * Typed error and audit catalogs.\n *\n * Group related errors into one catalog and get a refactor-safe builder per\n * code, with autocomplete at every call site and typed message parameters.\n *\n * @example\n * ```typescript\n * import { defineErrorCatalog } from 'autotel';\n *\n * export const billing = defineErrorCatalog('billing', {\n * PAYMENT_DECLINED: {\n * status: 402,\n * message: 'Card declined',\n * why: 'The issuer rejected the charge',\n * fix: 'Try a different payment method',\n * },\n * INSUFFICIENT_FUNDS: {\n * status: 402,\n * message: ({ available, required }: { available: number; required: number }) =>\n * `Insufficient funds: $${available} of $${required}`,\n * },\n * });\n *\n * throw billing.PAYMENT_DECLINED({ cause: stripeError });\n * throw billing.INSUFFICIENT_FUNDS({ available: 5, required: 100 });\n *\n * // In a catch block — refactor-safe, no magic strings:\n * if (billing.PAYMENT_DECLINED.match(err)) { ... }\n * ```\n */\n\nimport { createStructuredError, type StructuredError } from './structured-error';\n\nconst catalogCodeKey = Symbol.for('autotel.catalog.code');\n\n/** Definition of a single error in a catalog. */\nexport interface ErrorCatalogEntry {\n /**\n * Human-readable message. Use a function to interpolate typed parameters;\n * the parameter type flows through to the call site.\n */\n message: string | ((params: never) => string);\n /** HTTP status to surface to clients. */\n status?: number;\n /** Stable error code. Defaults to `${namespace}.${KEY}`. */\n code?: string | number;\n /** Why it happened. A function receives the same params as `message`. */\n why?: string | ((params: never) => string);\n /** What the caller should do next. */\n fix?: string;\n /** Docs or runbook link. */\n link?: string;\n /** Error name. Defaults to the catalog key. */\n name?: string;\n}\n\n/** Per-call options passed alongside (or instead of) typed params. */\nexport interface ErrorBuildOptions {\n cause?: unknown;\n details?: Record<string, unknown>;\n /** Backend-only context. Never serialized to clients. */\n internal?: Record<string, unknown>;\n}\n\ntype ParamsOf<E> = E extends { message: (params: infer P) => string }\n ? P\n : E extends { why: (params: infer P) => string }\n ? P\n : void;\n\ntype BuilderArgs<E extends ErrorCatalogEntry> = ParamsOf<E> extends void\n ? [options?: ErrorBuildOptions]\n : [params: ParamsOf<E>, options?: ErrorBuildOptions];\n\n/** A callable error factory produced by {@link defineErrorCatalog}. */\nexport interface ErrorBuilder<E extends ErrorCatalogEntry> {\n (...args: BuilderArgs<E>): StructuredError;\n /** Stable code assigned to every error from this entry. */\n readonly code: string | number;\n /** True when `error` was produced by this catalog entry. */\n match(error: unknown): boolean;\n}\n\nexport type ErrorCatalog<T extends Record<string, ErrorCatalogEntry>> = {\n readonly [K in keyof T]: ErrorBuilder<T[K]>;\n};\n\nfunction readCatalogCode(error: unknown): string | number | undefined {\n if (error === null || typeof error !== 'object') return undefined;\n return (error as Record<symbol, unknown>)[catalogCodeKey] as\n | string\n | number\n | undefined;\n}\n\n/** True when `error` was produced by any autotel error catalog. */\nexport function isCatalogError(error: unknown): error is StructuredError {\n return readCatalogCode(error) !== undefined;\n}\n\n/** Returns the catalog code of `error`, or `undefined` if it has none. */\nexport function getCatalogCode(error: unknown): string | number | undefined {\n return readCatalogCode(error);\n}\n\n/**\n * Define a typed error catalog. Returns an object whose keys are error\n * builders. Each builder produces a {@link StructuredError} carrying the\n * entry's message, status, code, why, fix, and link.\n */\nexport function defineErrorCatalog<\n const T extends Record<string, ErrorCatalogEntry>,\n>(namespace: string, entries: T): ErrorCatalog<T> {\n const catalog: Record<string, ErrorBuilder<ErrorCatalogEntry>> = {};\n\n for (const [key, entry] of Object.entries(entries) as [\n string,\n ErrorCatalogEntry,\n ][]) {\n const code = entry.code ?? `${namespace}.${key}`;\n const usesParams =\n typeof entry.message === 'function' || typeof entry.why === 'function';\n\n const builder = ((\n paramsOrOptions?: unknown,\n maybeOptions?: ErrorBuildOptions,\n ): StructuredError => {\n const params = usesParams ? paramsOrOptions : undefined;\n const options = (\n usesParams ? maybeOptions : paramsOrOptions\n ) as ErrorBuildOptions | undefined;\n\n const message =\n typeof entry.message === 'function'\n ? (entry.message as (p: unknown) => string)(params)\n : entry.message;\n const why =\n typeof entry.why === 'function'\n ? (entry.why as (p: unknown) => string)(params)\n : entry.why;\n\n const error = createStructuredError({\n message,\n name: entry.name ?? key,\n code,\n ...(entry.status === undefined ? {} : { status: entry.status }),\n ...(why === undefined ? {} : { why }),\n ...(entry.fix === undefined ? {} : { fix: entry.fix }),\n ...(entry.link === undefined ? {} : { link: entry.link }),\n ...(options?.cause === undefined ? {} : { cause: options.cause }),\n ...(options?.details === undefined ? {} : { details: options.details }),\n ...(options?.internal === undefined\n ? {}\n : { internal: options.internal }),\n });\n\n Object.defineProperty(error, catalogCodeKey, {\n value: code,\n enumerable: false,\n writable: false,\n configurable: true,\n });\n\n return error;\n }) as ErrorBuilder<ErrorCatalogEntry>;\n\n Object.defineProperty(builder, 'code', {\n value: code,\n enumerable: true,\n });\n Object.defineProperty(builder, 'match', {\n value: (error: unknown): boolean => readCatalogCode(error) === code,\n enumerable: false,\n });\n\n catalog[key] = builder;\n }\n\n return Object.freeze(catalog) as ErrorCatalog<T>;\n}\n\n/** Severity of an audit action. */\nexport type AuditSeverity = 'info' | 'warn' | 'critical';\n\n/** Definition of a single action in an audit catalog. */\nexport interface AuditCatalogEntry {\n /** Human-readable description. Use a function for typed params. */\n message?: string | ((params: never) => string);\n /** Stable action name. Defaults to `${namespace}.${KEY}`. */\n action?: string;\n /** Severity of the action. Defaults to `'info'`. */\n severity?: AuditSeverity;\n}\n\n/** A resolved audit action descriptor produced by an audit catalog. */\nexport interface AuditAction {\n readonly action: string;\n readonly severity: AuditSeverity;\n readonly message?: string;\n}\n\ntype AuditDescriptorArgs<E extends AuditCatalogEntry> = ParamsOf<E> extends void\n ? []\n : [params: ParamsOf<E>];\n\n/** A callable audit-action descriptor produced by {@link defineAuditCatalog}. */\nexport interface AuditDescriptor<E extends AuditCatalogEntry> {\n (...args: AuditDescriptorArgs<E>): AuditAction;\n readonly action: string;\n readonly severity: AuditSeverity;\n}\n\nexport type AuditCatalog<T extends Record<string, AuditCatalogEntry>> = {\n readonly [K in keyof T]: AuditDescriptor<T[K]>;\n};\n\n/**\n * Define a typed audit catalog. Returns typed action descriptors you can pass\n * to `track()` or audit helpers without scattering magic strings.\n */\nexport function defineAuditCatalog<\n const T extends Record<string, AuditCatalogEntry>,\n>(namespace: string, entries: T): AuditCatalog<T> {\n const catalog: Record<string, AuditDescriptor<AuditCatalogEntry>> = {};\n\n for (const [key, entry] of Object.entries(entries) as [\n string,\n AuditCatalogEntry,\n ][]) {\n const action = entry.action ?? `${namespace}.${key}`;\n const severity: AuditSeverity = entry.severity ?? 'info';\n\n const descriptor = ((params?: unknown): AuditAction => {\n const message =\n typeof entry.message === 'function'\n ? (entry.message as (p: unknown) => string)(params)\n : entry.message;\n return Object.freeze({\n action,\n severity,\n ...(message === undefined ? {} : { message }),\n });\n }) as AuditDescriptor<AuditCatalogEntry>;\n\n Object.defineProperty(descriptor, 'action', {\n value: action,\n enumerable: true,\n });\n Object.defineProperty(descriptor, 'severity', {\n value: severity,\n enumerable: true,\n });\n\n catalog[key] = descriptor;\n }\n\n return Object.freeze(catalog) as AuditCatalog<T>;\n}\n","export interface DrainOptions<TContext, TConfig, TPayload = TContext> {\n /** Stable identifier used in error logs. */\n name: string;\n /** Return null to skip draining (e.g. missing API key in dev). */\n resolve: () => TConfig | null | Promise<TConfig | null>;\n /** Transform contexts into payloads. Defaults to identity. */\n transform?: (contexts: TContext[]) => TPayload[];\n /** Transport implementation. */\n send: (payloads: TPayload[], config: TConfig) => Promise<void>;\n}\n\nexport interface HttpDrainRequest {\n url: string;\n headers: Record<string, string>;\n body: string;\n}\n\nexport interface HttpDrainOptions<\n TContext,\n TConfig,\n TPayload = TContext,\n> extends Omit<DrainOptions<TContext, TConfig, TPayload>, 'send'> {\n encode: (payloads: TPayload[], config: TConfig) => HttpDrainRequest | null;\n timeoutMs?: number;\n retries?: number;\n resolveTimeoutMs?: (config: TConfig) => number | undefined;\n resolveRetries?: (config: TConfig) => number | undefined;\n}\n\nconst DEFAULT_TIMEOUT_MS = 5000;\nconst DEFAULT_RETRIES = 2;\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const t = setTimeout(resolve, ms);\n t.unref?.();\n });\n}\n\nasync function postWithRetry(options: {\n name: string;\n request: HttpDrainRequest;\n timeoutMs: number;\n retries: number;\n}): Promise<void> {\n const { name, request, timeoutMs, retries } = options;\n const attempts = Math.max(1, retries);\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= attempts; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n timeout.unref?.();\n try {\n const response = await fetch(request.url, {\n method: 'POST',\n headers: request.headers,\n body: request.body,\n signal: controller.signal,\n });\n if (!response.ok) {\n throw new Error(\n `[autotel/${name}] HTTP ${response.status} draining ${request.url}`,\n );\n }\n return;\n } catch (error) {\n lastError = error;\n if (attempt < attempts) {\n await delay(100 * attempt);\n }\n } finally {\n clearTimeout(timeout);\n }\n }\n\n throw lastError;\n}\n\nexport function defineDrain<TContext, TConfig, TPayload = TContext>(\n options: DrainOptions<TContext, TConfig, TPayload>,\n): (ctx: TContext | TContext[]) => Promise<void> {\n return async (ctx: TContext | TContext[]) => {\n const contexts = Array.isArray(ctx) ? ctx : [ctx];\n if (contexts.length === 0) return;\n\n const config = await options.resolve();\n if (!config) return;\n\n const payloads = options.transform\n ? options.transform(contexts)\n : (contexts as unknown as TPayload[]);\n\n if (payloads.length === 0) return;\n\n try {\n await options.send(payloads, config);\n } catch (error) {\n console.error(`[autotel/${options.name}] drain failed:`, error);\n }\n };\n}\n\nexport function defineHttpDrain<TContext, TConfig, TPayload = TContext>(\n options: HttpDrainOptions<TContext, TConfig, TPayload>,\n): (ctx: TContext | TContext[]) => Promise<void> {\n return defineDrain<TContext, TConfig, TPayload>({\n name: options.name,\n resolve: options.resolve,\n transform: options.transform,\n send: async (payloads, config) => {\n const request = options.encode(payloads, config);\n if (!request) return;\n const timeoutMs =\n options.resolveTimeoutMs?.(config) ??\n options.timeoutMs ??\n DEFAULT_TIMEOUT_MS;\n const retries =\n options.resolveRetries?.(config) ?? options.retries ?? DEFAULT_RETRIES;\n\n await postWithRetry({\n name: options.name,\n request,\n timeoutMs,\n retries,\n });\n },\n });\n}\n","export interface EnrichContext<TEvent extends Record<string, unknown>> {\n event: TEvent;\n request?: {\n method?: string;\n path?: string;\n requestId?: string;\n };\n response?: {\n status?: number;\n };\n headers?: Record<string, string>;\n}\n\nexport interface EnricherDefinition<\n TEvent extends Record<string, unknown>,\n TValue extends object,\n> {\n /** Stable identifier used in error logs. */\n name: string;\n /** Top-level field to merge computed values into. */\n field: keyof TEvent & string;\n /** Return undefined to skip enrichment. */\n compute: (ctx: EnrichContext<TEvent>) => TValue | undefined;\n}\n\nexport interface EnricherOptions {\n /** Replace existing field value instead of merge. Default false. */\n overwrite?: boolean;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\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 (isPlainObject(sourceVal) && isPlainObject(targetVal)) {\n mergeInto(targetVal, sourceVal);\n } else {\n target[key] = sourceVal;\n }\n }\n}\n\nexport function defineEnricher<\n TEvent extends Record<string, unknown>,\n TValue extends object,\n>(\n def: EnricherDefinition<TEvent, TValue>,\n options: EnricherOptions = {},\n): (ctx: EnrichContext<TEvent>) => void {\n return (ctx: EnrichContext<TEvent>) => {\n let computed: TValue | undefined;\n try {\n computed = def.compute(ctx);\n } catch (error) {\n console.error(`[autotel/${def.name}] enrich failed:`, error);\n return;\n }\n\n if (!computed) return;\n\n if (options.overwrite || !isPlainObject(ctx.event[def.field])) {\n (ctx.event as Record<string, unknown>)[def.field] = computed;\n return;\n }\n\n mergeInto(\n ctx.event[def.field] as unknown as Record<string, unknown>,\n computed as unknown as Record<string, unknown>,\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';\nimport { emitCorrelatedEvent } from './correlated-events';\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 emitCorrelatedEvent(ctx, '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 emitCorrelatedEvent(\n ctx,\n 'gen_ai.response.received',\n buildResponseAttrs(event),\n );\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 emitCorrelatedEvent(ctx, '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 emitCorrelatedEvent(ctx, '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 emitCorrelatedEvent(\n ctx,\n 'gen_ai.stream.first_token',\n buildStreamFirstTokenAttrs(event),\n );\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","/**\n * Per-model LLM cost estimation.\n *\n * Estimate the USD cost of an LLM call from its token usage and record it as a\n * span attribute (`gen_ai.usage.cost.usd`). Pair with the\n * `gen_ai.client.cost.usd` metric bucket advice in `gen-ai-metrics`.\n *\n * @example\n * ```typescript\n * import { trace, recordLLMCost } from 'autotel';\n *\n * export const chat = trace((ctx) => async (prompt: string) => {\n * const res = await client.messages.create({ model, ... });\n * recordLLMCost(ctx, model, {\n * inputTokens: res.usage.input_tokens,\n * outputTokens: res.usage.output_tokens,\n * });\n * return res;\n * });\n * ```\n */\n\nimport type { TraceContext } from './trace-context';\n\n/** Span attribute key autotel sets for an estimated call cost. */\nexport const GEN_AI_COST_ATTRIBUTE = 'gen_ai.usage.cost.usd';\n\n/** Pricing for a single model, in USD per 1,000,000 tokens. */\nexport interface ModelPricing {\n /** USD per 1M input (prompt) tokens. */\n inputPer1M: number;\n /** USD per 1M output (completion) tokens. */\n outputPer1M: number;\n /** USD per 1M cached input tokens. Defaults to {@link ModelPricing.inputPer1M}. */\n cachedInputPer1M?: number;\n}\n\n/** Token counts for a single LLM call. */\nexport interface TokenUsage {\n inputTokens?: number;\n outputTokens?: number;\n /** Cached input tokens, billed at {@link ModelPricing.cachedInputPer1M}. */\n cachedInputTokens?: number;\n}\n\nexport interface EstimateCostOptions {\n /** Override or extend {@link MODEL_PRICING}. Keys are matched first. */\n pricing?: Record<string, ModelPricing>;\n}\n\n/**\n * Approximate public list prices (USD per 1M tokens) at the time of writing.\n * Prices change; treat these as convenience defaults, not a billing source of\n * truth. Override per call via `options.pricing` or mutate this table at init.\n * Matching is exact first, then by longest key prefix, so versioned model ids\n * (`claude-sonnet-4-6-20251101`) resolve to a base entry (`claude-sonnet-4-6`).\n */\nexport const MODEL_PRICING: Record<string, ModelPricing> = {\n // OpenAI\n 'gpt-4o': { inputPer1M: 2.5, outputPer1M: 10 },\n 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.6 },\n 'gpt-4.1': { inputPer1M: 2, outputPer1M: 8 },\n 'gpt-4.1-mini': { inputPer1M: 0.4, outputPer1M: 1.6 },\n 'gpt-4.1-nano': { inputPer1M: 0.1, outputPer1M: 0.4 },\n 'o3-mini': { inputPer1M: 1.1, outputPer1M: 4.4 },\n // Anthropic Claude\n 'claude-opus-4': { inputPer1M: 15, outputPer1M: 75 },\n 'claude-sonnet-4': { inputPer1M: 3, outputPer1M: 15 },\n 'claude-3-5-sonnet': { inputPer1M: 3, outputPer1M: 15 },\n 'claude-3-5-haiku': { inputPer1M: 0.8, outputPer1M: 4 },\n 'claude-3-opus': { inputPer1M: 15, outputPer1M: 75 },\n 'claude-3-haiku': { inputPer1M: 0.25, outputPer1M: 1.25 },\n // Google Gemini\n 'gemini-1.5-pro': { inputPer1M: 1.25, outputPer1M: 5 },\n 'gemini-1.5-flash': { inputPer1M: 0.075, outputPer1M: 0.3 },\n 'gemini-2.0-flash': { inputPer1M: 0.1, outputPer1M: 0.4 },\n};\n\nfunction resolvePricing(\n table: Record<string, ModelPricing>,\n model: string,\n): ModelPricing | undefined {\n const exact = table[model];\n if (exact) return exact;\n\n let best: ModelPricing | undefined;\n let bestLength = 0;\n for (const key of Object.keys(table)) {\n if (model.startsWith(key) && key.length > bestLength) {\n best = table[key];\n bestLength = key.length;\n }\n }\n return best;\n}\n\nfunction round(value: number): number {\n return Math.round(value * 1e6) / 1e6;\n}\n\n/**\n * Estimate the USD cost of an LLM call. Returns `undefined` when the model has\n * no known pricing (supply one via `options.pricing`).\n */\nexport function estimateLLMCost(\n model: string,\n usage: TokenUsage,\n options?: EstimateCostOptions,\n): number | undefined {\n const table = options?.pricing\n ? { ...MODEL_PRICING, ...options.pricing }\n : MODEL_PRICING;\n const price = resolvePricing(table, model);\n if (!price) return undefined;\n\n const cachedInput = usage.cachedInputTokens ?? 0;\n const billedInput = Math.max(0, (usage.inputTokens ?? 0) - cachedInput);\n const output = usage.outputTokens ?? 0;\n const cachedRate = price.cachedInputPer1M ?? price.inputPer1M;\n\n const cost =\n (billedInput / 1_000_000) * price.inputPer1M +\n (cachedInput / 1_000_000) * cachedRate +\n (output / 1_000_000) * price.outputPer1M;\n\n return round(cost);\n}\n\n/**\n * Estimate cost and record it on `ctx` as the `gen_ai.usage.cost.usd` span\n * attribute. Returns the estimated cost, or `undefined` when the model is\n * unknown (in which case no attribute is set).\n */\nexport function recordLLMCost(\n ctx: Pick<TraceContext, 'setAttribute'>,\n model: string,\n usage: TokenUsage,\n options?: EstimateCostOptions,\n): number | undefined {\n const cost = estimateLLMCost(model, usage, options);\n if (cost !== undefined) {\n ctx.setAttribute(GEN_AI_COST_ATTRIBUTE, cost);\n }\n return cost;\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AutotelConfig, i as init, a as isLoggerLocked, l as lockLogger } from './init-D9Bxx39e.cjs';
1
+ export { A as AutotelConfig, i as init, a as isLoggerLocked, l as lockLogger } from './init-gyesUMwz.cjs';
2
2
  import { Span, Context, trace as trace$2 } from '@opentelemetry/api';
3
3
  export { AttributeValue, Attributes, Baggage, BaggageEntry, Context, Exception, HrTime, Link, ROOT_CONTEXT, Span, SpanAttributes, SpanContext, SpanKind, Link as SpanLink, SpanStatusCode, TextMapGetter, TextMapSetter, TimeInput, TraceFlags, TraceState, Tracer, TracerProvider, context, trace as otelTrace, propagation } from '@opentelemetry/api';
4
4
  import { SpanProcessor, ReadableSpan } from '@opentelemetry/sdk-trace-base';
@@ -8,7 +8,7 @@ import { AttributeRedactorConfig, AttributeRedactorPreset } from './attribute-re
8
8
  export { AttributeRedactingProcessor, AttributeRedactingProcessorOptions, AttributeRedactorFn, BuiltinPatternName, MaskFn, REDACTOR_PATTERNS, REDACTOR_PRESETS, ValuePatternConfig, builtinPatterns, createAttributeRedactor, createRedactedSpan, normalizeAttributeRedactorConfig } from './attribute-redacting-processor.cjs';
9
9
  import { trace as trace$1 } from './functional.cjs';
10
10
  export { InstrumentOptions, SpanOptions, WithBaggageOptions, WithNewContextOptions, ctx, instrument, markAsImmediate, span, withBaggage, withNewContext, withTracing } from './functional.cjs';
11
- import { EventSubscriber, EventAttributes, AutotelEventContext } from './event-subscriber.cjs';
11
+ import { EventSubscriber, EventAttributes, AutotelEventContext, EventSchemaMetadata, EventTrackingOptions } from './event-subscriber.cjs';
12
12
  export { FunnelStatus, OutcomeStatus } from './event-subscriber.cjs';
13
13
  export { CORRELATION_ID_BAGGAGE_KEY, generateCorrelationId, getCorrelationId, getOrCreateCorrelationId, runWithCorrelationId, setCorrelationId, setCorrelationIdInBaggage } from './correlation-id.cjs';
14
14
  import { T as TraceContext, A as AttributeValue } from './trace-context-DbGKd1Rn.cjs';
@@ -202,6 +202,8 @@ interface EventData {
202
202
  _traceId?: string;
203
203
  /** Autotel context for trace correlation (passed to subscribers) */
204
204
  autotel?: AutotelEventContext;
205
+ /** Optional schema metadata for contract-aware subscribers. */
206
+ schema?: EventSchemaMetadata;
205
207
  }
206
208
  interface QueueConfig {
207
209
  maxSize: number;
@@ -368,13 +370,33 @@ declare class EventQueue {
368
370
  * }
369
371
  * ```
370
372
  */
371
- declare function track<Events extends Record<string, any> = Record<string, any>>(event: keyof Events & string, data?: Events[typeof event]): void;
373
+ declare function track<Events extends Record<string, any> = Record<string, any>>(event: keyof Events & string, data?: Events[typeof event], options?: EventTrackingOptions): void;
372
374
  /**
373
375
  * Get events queue (for flush/shutdown)
374
376
  * @internal
375
377
  */
376
378
  declare function getEventQueue(): EventQueue | null;
377
379
 
380
+ type SafeParseResult<T> = {
381
+ success: true;
382
+ data: T;
383
+ } | {
384
+ success: false;
385
+ error: unknown;
386
+ };
387
+ interface SchemaLike<T> {
388
+ safeParse(input: unknown): SafeParseResult<T>;
389
+ }
390
+ interface DefineEventOptions<S> {
391
+ toJsonSchema?: (schema: S) => unknown;
392
+ }
393
+ interface DefinedEvent<Name extends string, Payload> {
394
+ readonly name: Name;
395
+ readonly schemaMetadata?: EventSchemaMetadata;
396
+ track(payload: Payload): void;
397
+ }
398
+ declare function defineEvent<Name extends string, Payload, S extends SchemaLike<Payload>>(name: Name, schema: S, options?: DefineEventOptions<S>): DefinedEvent<Name, Payload>;
399
+
378
400
  /**
379
401
  * Graceful shutdown with flush and cleanup
380
402
  */
@@ -499,6 +521,125 @@ declare function structuredErrorToJSON(error: StructuredError): Record<string, u
499
521
  declare function getStructuredErrorAttributes(error: Error): Record<string, AttributeValue>;
500
522
  declare function recordStructuredError(ctx: Pick<TraceContext, 'setAttributes' | 'setStatus'>, error: Error): void;
501
523
 
524
+ /**
525
+ * Typed error and audit catalogs.
526
+ *
527
+ * Group related errors into one catalog and get a refactor-safe builder per
528
+ * code, with autocomplete at every call site and typed message parameters.
529
+ *
530
+ * @example
531
+ * ```typescript
532
+ * import { defineErrorCatalog } from 'autotel';
533
+ *
534
+ * export const billing = defineErrorCatalog('billing', {
535
+ * PAYMENT_DECLINED: {
536
+ * status: 402,
537
+ * message: 'Card declined',
538
+ * why: 'The issuer rejected the charge',
539
+ * fix: 'Try a different payment method',
540
+ * },
541
+ * INSUFFICIENT_FUNDS: {
542
+ * status: 402,
543
+ * message: ({ available, required }: { available: number; required: number }) =>
544
+ * `Insufficient funds: $${available} of $${required}`,
545
+ * },
546
+ * });
547
+ *
548
+ * throw billing.PAYMENT_DECLINED({ cause: stripeError });
549
+ * throw billing.INSUFFICIENT_FUNDS({ available: 5, required: 100 });
550
+ *
551
+ * // In a catch block — refactor-safe, no magic strings:
552
+ * if (billing.PAYMENT_DECLINED.match(err)) { ... }
553
+ * ```
554
+ */
555
+
556
+ /** Definition of a single error in a catalog. */
557
+ interface ErrorCatalogEntry {
558
+ /**
559
+ * Human-readable message. Use a function to interpolate typed parameters;
560
+ * the parameter type flows through to the call site.
561
+ */
562
+ message: string | ((params: never) => string);
563
+ /** HTTP status to surface to clients. */
564
+ status?: number;
565
+ /** Stable error code. Defaults to `${namespace}.${KEY}`. */
566
+ code?: string | number;
567
+ /** Why it happened. A function receives the same params as `message`. */
568
+ why?: string | ((params: never) => string);
569
+ /** What the caller should do next. */
570
+ fix?: string;
571
+ /** Docs or runbook link. */
572
+ link?: string;
573
+ /** Error name. Defaults to the catalog key. */
574
+ name?: string;
575
+ }
576
+ /** Per-call options passed alongside (or instead of) typed params. */
577
+ interface ErrorBuildOptions {
578
+ cause?: unknown;
579
+ details?: Record<string, unknown>;
580
+ /** Backend-only context. Never serialized to clients. */
581
+ internal?: Record<string, unknown>;
582
+ }
583
+ type ParamsOf<E> = E extends {
584
+ message: (params: infer P) => string;
585
+ } ? P : E extends {
586
+ why: (params: infer P) => string;
587
+ } ? P : void;
588
+ type BuilderArgs<E extends ErrorCatalogEntry> = ParamsOf<E> extends void ? [options?: ErrorBuildOptions] : [params: ParamsOf<E>, options?: ErrorBuildOptions];
589
+ /** A callable error factory produced by {@link defineErrorCatalog}. */
590
+ interface ErrorBuilder<E extends ErrorCatalogEntry> {
591
+ (...args: BuilderArgs<E>): StructuredError;
592
+ /** Stable code assigned to every error from this entry. */
593
+ readonly code: string | number;
594
+ /** True when `error` was produced by this catalog entry. */
595
+ match(error: unknown): boolean;
596
+ }
597
+ type ErrorCatalog<T extends Record<string, ErrorCatalogEntry>> = {
598
+ readonly [K in keyof T]: ErrorBuilder<T[K]>;
599
+ };
600
+ /** True when `error` was produced by any autotel error catalog. */
601
+ declare function isCatalogError(error: unknown): error is StructuredError;
602
+ /** Returns the catalog code of `error`, or `undefined` if it has none. */
603
+ declare function getCatalogCode(error: unknown): string | number | undefined;
604
+ /**
605
+ * Define a typed error catalog. Returns an object whose keys are error
606
+ * builders. Each builder produces a {@link StructuredError} carrying the
607
+ * entry's message, status, code, why, fix, and link.
608
+ */
609
+ declare function defineErrorCatalog<const T extends Record<string, ErrorCatalogEntry>>(namespace: string, entries: T): ErrorCatalog<T>;
610
+ /** Severity of an audit action. */
611
+ type AuditSeverity = 'info' | 'warn' | 'critical';
612
+ /** Definition of a single action in an audit catalog. */
613
+ interface AuditCatalogEntry {
614
+ /** Human-readable description. Use a function for typed params. */
615
+ message?: string | ((params: never) => string);
616
+ /** Stable action name. Defaults to `${namespace}.${KEY}`. */
617
+ action?: string;
618
+ /** Severity of the action. Defaults to `'info'`. */
619
+ severity?: AuditSeverity;
620
+ }
621
+ /** A resolved audit action descriptor produced by an audit catalog. */
622
+ interface AuditAction {
623
+ readonly action: string;
624
+ readonly severity: AuditSeverity;
625
+ readonly message?: string;
626
+ }
627
+ type AuditDescriptorArgs<E extends AuditCatalogEntry> = ParamsOf<E> extends void ? [] : [params: ParamsOf<E>];
628
+ /** A callable audit-action descriptor produced by {@link defineAuditCatalog}. */
629
+ interface AuditDescriptor<E extends AuditCatalogEntry> {
630
+ (...args: AuditDescriptorArgs<E>): AuditAction;
631
+ readonly action: string;
632
+ readonly severity: AuditSeverity;
633
+ }
634
+ type AuditCatalog<T extends Record<string, AuditCatalogEntry>> = {
635
+ readonly [K in keyof T]: AuditDescriptor<T[K]>;
636
+ };
637
+ /**
638
+ * Define a typed audit catalog. Returns typed action descriptors you can pass
639
+ * to `track()` or audit helpers without scattering magic strings.
640
+ */
641
+ declare function defineAuditCatalog<const T extends Record<string, AuditCatalogEntry>>(namespace: string, entries: T): AuditCatalog<T>;
642
+
502
643
  /**
503
644
  * Convert an unknown value to an OTel-compatible AttributeValue.
504
645
  * Returns undefined when the value cannot be represented.
@@ -767,4 +908,68 @@ declare function recordToolCall(ctx: TraceContext, event: ToolCallEvent): void;
767
908
  */
768
909
  declare function recordStreamFirstToken(ctx: TraceContext, event?: StreamFirstTokenEvent): void;
769
910
 
770
- export { AttributeRedactorConfig, AttributeRedactorPreset, BaggageSpanProcessor, type BaggageSpanProcessorOptions, type DrainOptions, type EnrichContext, type EnricherDefinition, type EnricherOptions, EventAttributes, EventSubscriber, type ForkLifecycle, type ForkOptions, GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_TOKEN_USAGE_BUCKETS, type HttpDrainOptions, type HttpDrainRequest, type OperationContext, type PromptSentEvent, type RequestLogSnapshot, type RequestLogger, type RequestLoggerOptions, type ResponseReceivedEvent, type RetryEvent, type StreamFirstTokenEvent, type StringRedactor, type StructuredError, type StructuredErrorInput, type ToolCallEvent, TraceContext, createStringRedactor, createStructuredError, defineDrain, defineEnricher, defineHttpDrain, flattenToAttributes, flush, formatDuration, genAiMetricViews, getEventQueue, getOperationContext, getRequestLogger, getStructuredErrorAttributes, llmHistogramAdvice, recordPromptSent, recordResponseReceived, recordRetry, recordStreamFirstToken, recordStructuredError, recordToolCall, runInOperationContext, runWithRequestContext, shutdown, structuredErrorToJSON, toAttributeValue, trace, track };
911
+ /**
912
+ * Per-model LLM cost estimation.
913
+ *
914
+ * Estimate the USD cost of an LLM call from its token usage and record it as a
915
+ * span attribute (`gen_ai.usage.cost.usd`). Pair with the
916
+ * `gen_ai.client.cost.usd` metric bucket advice in `gen-ai-metrics`.
917
+ *
918
+ * @example
919
+ * ```typescript
920
+ * import { trace, recordLLMCost } from 'autotel';
921
+ *
922
+ * export const chat = trace((ctx) => async (prompt: string) => {
923
+ * const res = await client.messages.create({ model, ... });
924
+ * recordLLMCost(ctx, model, {
925
+ * inputTokens: res.usage.input_tokens,
926
+ * outputTokens: res.usage.output_tokens,
927
+ * });
928
+ * return res;
929
+ * });
930
+ * ```
931
+ */
932
+
933
+ /** Span attribute key autotel sets for an estimated call cost. */
934
+ declare const GEN_AI_COST_ATTRIBUTE = "gen_ai.usage.cost.usd";
935
+ /** Pricing for a single model, in USD per 1,000,000 tokens. */
936
+ interface ModelPricing {
937
+ /** USD per 1M input (prompt) tokens. */
938
+ inputPer1M: number;
939
+ /** USD per 1M output (completion) tokens. */
940
+ outputPer1M: number;
941
+ /** USD per 1M cached input tokens. Defaults to {@link ModelPricing.inputPer1M}. */
942
+ cachedInputPer1M?: number;
943
+ }
944
+ /** Token counts for a single LLM call. */
945
+ interface TokenUsage {
946
+ inputTokens?: number;
947
+ outputTokens?: number;
948
+ /** Cached input tokens, billed at {@link ModelPricing.cachedInputPer1M}. */
949
+ cachedInputTokens?: number;
950
+ }
951
+ interface EstimateCostOptions {
952
+ /** Override or extend {@link MODEL_PRICING}. Keys are matched first. */
953
+ pricing?: Record<string, ModelPricing>;
954
+ }
955
+ /**
956
+ * Approximate public list prices (USD per 1M tokens) at the time of writing.
957
+ * Prices change; treat these as convenience defaults, not a billing source of
958
+ * truth. Override per call via `options.pricing` or mutate this table at init.
959
+ * Matching is exact first, then by longest key prefix, so versioned model ids
960
+ * (`claude-sonnet-4-6-20251101`) resolve to a base entry (`claude-sonnet-4-6`).
961
+ */
962
+ declare const MODEL_PRICING: Record<string, ModelPricing>;
963
+ /**
964
+ * Estimate the USD cost of an LLM call. Returns `undefined` when the model has
965
+ * no known pricing (supply one via `options.pricing`).
966
+ */
967
+ declare function estimateLLMCost(model: string, usage: TokenUsage, options?: EstimateCostOptions): number | undefined;
968
+ /**
969
+ * Estimate cost and record it on `ctx` as the `gen_ai.usage.cost.usd` span
970
+ * attribute. Returns the estimated cost, or `undefined` when the model is
971
+ * unknown (in which case no attribute is set).
972
+ */
973
+ declare function recordLLMCost(ctx: Pick<TraceContext, 'setAttribute'>, model: string, usage: TokenUsage, options?: EstimateCostOptions): number | undefined;
974
+
975
+ export { AttributeRedactorConfig, AttributeRedactorPreset, type AuditAction, type AuditCatalog, type AuditCatalogEntry, type AuditDescriptor, type AuditSeverity, BaggageSpanProcessor, type BaggageSpanProcessorOptions, type DefineEventOptions, type DefinedEvent, type DrainOptions, type EnrichContext, type EnricherDefinition, type EnricherOptions, type ErrorBuildOptions, type ErrorBuilder, type ErrorCatalog, type ErrorCatalogEntry, type EstimateCostOptions, EventAttributes, EventSubscriber, type ForkLifecycle, type ForkOptions, GEN_AI_COST_ATTRIBUTE, GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_TOKEN_USAGE_BUCKETS, type HttpDrainOptions, type HttpDrainRequest, MODEL_PRICING, type ModelPricing, type OperationContext, type PromptSentEvent, type RequestLogSnapshot, type RequestLogger, type RequestLoggerOptions, type ResponseReceivedEvent, type RetryEvent, type SchemaLike, type StreamFirstTokenEvent, type StringRedactor, type StructuredError, type StructuredErrorInput, type TokenUsage, type ToolCallEvent, TraceContext, createStringRedactor, createStructuredError, defineAuditCatalog, defineDrain, defineEnricher, defineErrorCatalog, defineEvent, defineHttpDrain, estimateLLMCost, flattenToAttributes, flush, formatDuration, genAiMetricViews, getCatalogCode, getEventQueue, getOperationContext, getRequestLogger, getStructuredErrorAttributes, isCatalogError, llmHistogramAdvice, recordLLMCost, recordPromptSent, recordResponseReceived, recordRetry, recordStreamFirstToken, recordStructuredError, recordToolCall, runInOperationContext, runWithRequestContext, shutdown, structuredErrorToJSON, toAttributeValue, trace, track };