UNPKG

autotel

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