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
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AutotelConfig, i as init, a as isLoggerLocked, l as lockLogger } from './init-BSyIyDs5.js';
1
+ export { A as AutotelConfig, i as init, a as isLoggerLocked, l as lockLogger } from './init-DyE43paw.js';
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.js';
9
9
  import { trace as trace$1 } from './functional.js';
10
10
  export { InstrumentOptions, SpanOptions, WithBaggageOptions, WithNewContextOptions, ctx, instrument, markAsImmediate, span, withBaggage, withNewContext, withTracing } from './functional.js';
11
- import { EventSubscriber, EventAttributes, AutotelEventContext } from './event-subscriber.js';
11
+ import { EventSubscriber, EventAttributes, AutotelEventContext, EventSchemaMetadata, EventTrackingOptions } from './event-subscriber.js';
12
12
  export { FunnelStatus, OutcomeStatus } from './event-subscriber.js';
13
13
  export { CORRELATION_ID_BAGGAGE_KEY, generateCorrelationId, getCorrelationId, getOrCreateCorrelationId, runWithCorrelationId, setCorrelationId, setCorrelationIdInBaggage } from './correlation-id.js';
14
14
  import { T as TraceContext, A as AttributeValue } from './trace-context-DbGKd1Rn.js';
@@ -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 };
package/dist/index.js CHANGED
@@ -1,34 +1,34 @@
1
1
  export { createDrainPipeline } from './chunk-KFOHQK7X.js';
2
- export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-PEEUMQ3R.js';
3
- export { attrs, autoRedactPII, dbClient, httpClient, httpServer, identify, mergeAttrs, mergeServiceResource, request, safeSetAttributes, setDevice, setError, setException, setSession, setUser, validateAttribute } from './chunk-DDXIUZEG.js';
2
+ export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-FZROHTZZ.js';
3
+ export { attrs, autoRedactPII, dbClient, httpClient, httpServer, identify, mergeAttrs, mergeServiceResource, request, safeSetAttributes, setDevice, setError, setException, setSession, setUser, validateAttribute } from './chunk-454CH4OV.js';
4
4
  export { httpRequestHeaderAttribute, httpResponseHeaderAttribute } from './chunk-7552UTQW.js';
5
5
  export { HTTPAttributes, ServiceAttributes, URLAttributes } from './chunk-4A53YIAX.js';
6
6
  export { parseError } from './chunk-J7VGRIAJ.js';
7
- export { traceConsumer, traceProducer } from './chunk-6TFJF7SS.js';
7
+ export { traceConsumer, traceProducer } from './chunk-4TAQQZDU.js';
8
8
  import { emitCorrelatedEvent } from './chunk-KIL5CUN6.js';
9
9
  export { BusinessBaggage, createSafeBaggageSchema } from './chunk-4IFSYQVX.js';
10
10
  import { resetMetrics } from './chunk-7SAWIN74.js';
11
11
  export { Metric, getMetrics, resetMetrics } from './chunk-7SAWIN74.js';
12
12
  import './chunk-5ZN622AO.js';
13
13
  export { createCounter, createHistogram, createObservableGauge, createUpDownCounter, getMeter } from './chunk-TQ5UWA7S.js';
14
- export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-52ALHU7T.js';
15
- import { trace as trace$1 } from './chunk-T7CPAGOI.js';
16
- export { ctx, instrument, markAsImmediate, span, withBaggage, withNewContext, withTracing } from './chunk-T7CPAGOI.js';
14
+ export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-OPCTN527.js';
15
+ import { trace as trace$1 } from './chunk-U4D5IBSB.js';
16
+ export { ctx, instrument, markAsImmediate, span, withBaggage, withNewContext, withTracing } from './chunk-U4D5IBSB.js';
17
17
  export { createDeterministicTraceId, enrichWithTraceContext, finalizeSpan, flattenMetadata, getActiveContext, getActiveSpan, getTraceContext, getTracer, isTracing, resolveTraceUrl, runWithSpan } from './chunk-HLZ7H3VZ.js';
18
- import { resetEvents } from './chunk-MHPYLMQS.js';
19
- export { Event, getEvents, resetEvents } from './chunk-MHPYLMQS.js';
18
+ import { resetEvents } from './chunk-OACAWYLR.js';
19
+ export { Event, getEvents, resetEvents } from './chunk-OACAWYLR.js';
20
20
  import './chunk-LITNXTTT.js';
21
21
  import './chunk-BZHG5IZ4.js';
22
22
  export { getOperationContext, runInOperationContext } from './chunk-SEO6NAQT.js';
23
- import { getEventQueue, resetEventQueue, createTraceContext, flattenToAttributes, recordStructuredError } from './chunk-FTBBBPT6.js';
24
- export { CORRELATION_ID_BAGGAGE_KEY, createStructuredError, defineBaggageSchema, flattenToAttributes, generateCorrelationId, getCorrelationId, getEventQueue, getOrCreateCorrelationId, getStructuredErrorAttributes, recordStructuredError, runWithCorrelationId, setCorrelationId, setCorrelationIdInBaggage, structuredErrorToJSON, toAttributeValue, track } from './chunk-FTBBBPT6.js';
25
- import { getLogger, getSdk, _closeEmbeddedDevtools } from './chunk-MYWQELNY.js';
26
- export { BaggageSpanProcessor, createStringRedactor, init, isLoggerLocked, lockLogger } from './chunk-MYWQELNY.js';
23
+ import { getEventQueue, resetEventQueue, track, createTraceContext, flattenToAttributes, recordStructuredError, createStructuredError } from './chunk-TGV2XF57.js';
24
+ export { CORRELATION_ID_BAGGAGE_KEY, createStructuredError, defineBaggageSchema, flattenToAttributes, generateCorrelationId, getCorrelationId, getEventQueue, getOrCreateCorrelationId, getStructuredErrorAttributes, recordStructuredError, runWithCorrelationId, setCorrelationId, setCorrelationIdInBaggage, structuredErrorToJSON, toAttributeValue, track } from './chunk-TGV2XF57.js';
25
+ import { getLogger, getSdk, _closeEmbeddedDevtools } from './chunk-32AXF4MA.js';
26
+ export { BaggageSpanProcessor, createStringRedactor, init, isLoggerLocked, lockLogger } from './chunk-32AXF4MA.js';
27
27
  import './chunk-643PQG3Y.js';
28
28
  import './chunk-A4E5AQFK.js';
29
29
  export { FilteringSpanProcessor } from './chunk-WGWSHJ2N.js';
30
30
  export { NORMALIZER_PATTERNS, NORMALIZER_PRESETS, SpanNameNormalizingProcessor } from './chunk-GYR5K654.js';
31
- export { AttributeRedactingProcessor, REDACTOR_PATTERNS, REDACTOR_PRESETS, builtinPatterns, createAttributeRedactor, createRedactedSpan, normalizeAttributeRedactorConfig } from './chunk-JVWJDHDB.js';
31
+ export { AttributeRedactingProcessor, REDACTOR_PATTERNS, REDACTOR_PRESETS, builtinPatterns, createAttributeRedactor, createRedactedSpan, normalizeAttributeRedactorConfig } from './chunk-RUPKBKUF.js';
32
32
  import './chunk-6UQRVUN3.js';
33
33
  export { formatDuration } from './chunk-3QXBFGKP.js';
34
34
  import './chunk-KVDA4HX2.js';
@@ -38,6 +38,7 @@ import './chunk-J5QENANM.js';
38
38
  export { getAutotelTracer, getAutotelTracerProvider, setAutotelTracerProvider } from './chunk-HA2WBOGQ.js';
39
39
  import { trace } from '@opentelemetry/api';
40
40
  export { ROOT_CONTEXT, SpanKind, SpanStatusCode, context, trace as otelTrace, propagation } from '@opentelemetry/api';
41
+ import { createHash } from 'crypto';
41
42
  import { AsyncLocalStorage } from 'async_hooks';
42
43
  import { AggregationType } from '@opentelemetry/sdk-metrics';
43
44
 
@@ -61,6 +62,45 @@ var trace2 = Object.assign(
61
62
  trace$1,
62
63
  otelMethods
63
64
  );
65
+ function defineEvent(name, schema, options = {}) {
66
+ const jsonSchema = options.toJsonSchema?.(schema);
67
+ const schemaMetadata = jsonSchema ? {
68
+ source: "zod",
69
+ jsonSchema,
70
+ hash: hashSchema(jsonSchema)
71
+ } : void 0;
72
+ return {
73
+ name,
74
+ schemaMetadata,
75
+ track(payload) {
76
+ const parsed = schema.safeParse(payload);
77
+ if (!parsed.success) {
78
+ throw new Error(
79
+ `Invalid payload for event "${name}". Schema validation failed.`
80
+ );
81
+ }
82
+ track(
83
+ name,
84
+ parsed.data,
85
+ schemaMetadata ? { schema: schemaMetadata } : void 0
86
+ );
87
+ }
88
+ };
89
+ }
90
+ function hashSchema(schema) {
91
+ return createHash("sha256").update(stableStringify(schema)).digest("hex");
92
+ }
93
+ function stableStringify(value) {
94
+ if (value === null || value === void 0 || typeof value !== "object") {
95
+ return JSON.stringify(value);
96
+ }
97
+ if (Array.isArray(value)) {
98
+ return "[" + value.map((v) => stableStringify(v)).join(",") + "]";
99
+ }
100
+ const obj = value;
101
+ const body = Object.keys(obj).sort().map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",");
102
+ return "{" + body + "}";
103
+ }
64
104
 
65
105
  // src/shutdown.ts
66
106
  async function flush(options) {
@@ -369,6 +409,86 @@ function getRequestLogger(ctx2, options) {
369
409
  };
370
410
  }
371
411
 
412
+ // src/error-catalog.ts
413
+ var catalogCodeKey = /* @__PURE__ */ Symbol.for("autotel.catalog.code");
414
+ function readCatalogCode(error) {
415
+ if (error === null || typeof error !== "object") return void 0;
416
+ return error[catalogCodeKey];
417
+ }
418
+ function isCatalogError(error) {
419
+ return readCatalogCode(error) !== void 0;
420
+ }
421
+ function getCatalogCode(error) {
422
+ return readCatalogCode(error);
423
+ }
424
+ function defineErrorCatalog(namespace, entries) {
425
+ const catalog = {};
426
+ for (const [key, entry] of Object.entries(entries)) {
427
+ const code = entry.code ?? `${namespace}.${key}`;
428
+ const usesParams = typeof entry.message === "function" || typeof entry.why === "function";
429
+ const builder = ((paramsOrOptions, maybeOptions) => {
430
+ const params = usesParams ? paramsOrOptions : void 0;
431
+ const options = usesParams ? maybeOptions : paramsOrOptions;
432
+ const message = typeof entry.message === "function" ? entry.message(params) : entry.message;
433
+ const why = typeof entry.why === "function" ? entry.why(params) : entry.why;
434
+ const error = createStructuredError({
435
+ message,
436
+ name: entry.name ?? key,
437
+ code,
438
+ ...entry.status === void 0 ? {} : { status: entry.status },
439
+ ...why === void 0 ? {} : { why },
440
+ ...entry.fix === void 0 ? {} : { fix: entry.fix },
441
+ ...entry.link === void 0 ? {} : { link: entry.link },
442
+ ...options?.cause === void 0 ? {} : { cause: options.cause },
443
+ ...options?.details === void 0 ? {} : { details: options.details },
444
+ ...options?.internal === void 0 ? {} : { internal: options.internal }
445
+ });
446
+ Object.defineProperty(error, catalogCodeKey, {
447
+ value: code,
448
+ enumerable: false,
449
+ writable: false,
450
+ configurable: true
451
+ });
452
+ return error;
453
+ });
454
+ Object.defineProperty(builder, "code", {
455
+ value: code,
456
+ enumerable: true
457
+ });
458
+ Object.defineProperty(builder, "match", {
459
+ value: (error) => readCatalogCode(error) === code,
460
+ enumerable: false
461
+ });
462
+ catalog[key] = builder;
463
+ }
464
+ return Object.freeze(catalog);
465
+ }
466
+ function defineAuditCatalog(namespace, entries) {
467
+ const catalog = {};
468
+ for (const [key, entry] of Object.entries(entries)) {
469
+ const action = entry.action ?? `${namespace}.${key}`;
470
+ const severity = entry.severity ?? "info";
471
+ const descriptor = ((params) => {
472
+ const message = typeof entry.message === "function" ? entry.message(params) : entry.message;
473
+ return Object.freeze({
474
+ action,
475
+ severity,
476
+ ...message === void 0 ? {} : { message }
477
+ });
478
+ });
479
+ Object.defineProperty(descriptor, "action", {
480
+ value: action,
481
+ enumerable: true
482
+ });
483
+ Object.defineProperty(descriptor, "severity", {
484
+ value: severity,
485
+ enumerable: true
486
+ });
487
+ catalog[key] = descriptor;
488
+ }
489
+ return Object.freeze(catalog);
490
+ }
491
+
372
492
  // src/drain-toolkit.ts
373
493
  var DEFAULT_TIMEOUT_MS = 5e3;
374
494
  var DEFAULT_RETRIES = 2;
@@ -605,6 +725,63 @@ function buildStreamFirstTokenAttrs(event) {
605
725
  return attrs2;
606
726
  }
607
727
 
608
- export { GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_TOKEN_USAGE_BUCKETS, defineDrain, defineEnricher, defineHttpDrain, flush, genAiMetricViews, getRequestLogger, llmHistogramAdvice, recordPromptSent, recordResponseReceived, recordRetry, recordStreamFirstToken, recordToolCall, runWithRequestContext, shutdown, trace2 as trace };
728
+ // src/gen-ai-cost.ts
729
+ var GEN_AI_COST_ATTRIBUTE = "gen_ai.usage.cost.usd";
730
+ var MODEL_PRICING = {
731
+ // OpenAI
732
+ "gpt-4o": { inputPer1M: 2.5, outputPer1M: 10 },
733
+ "gpt-4o-mini": { inputPer1M: 0.15, outputPer1M: 0.6 },
734
+ "gpt-4.1": { inputPer1M: 2, outputPer1M: 8 },
735
+ "gpt-4.1-mini": { inputPer1M: 0.4, outputPer1M: 1.6 },
736
+ "gpt-4.1-nano": { inputPer1M: 0.1, outputPer1M: 0.4 },
737
+ "o3-mini": { inputPer1M: 1.1, outputPer1M: 4.4 },
738
+ // Anthropic Claude
739
+ "claude-opus-4": { inputPer1M: 15, outputPer1M: 75 },
740
+ "claude-sonnet-4": { inputPer1M: 3, outputPer1M: 15 },
741
+ "claude-3-5-sonnet": { inputPer1M: 3, outputPer1M: 15 },
742
+ "claude-3-5-haiku": { inputPer1M: 0.8, outputPer1M: 4 },
743
+ "claude-3-opus": { inputPer1M: 15, outputPer1M: 75 },
744
+ "claude-3-haiku": { inputPer1M: 0.25, outputPer1M: 1.25 },
745
+ // Google Gemini
746
+ "gemini-1.5-pro": { inputPer1M: 1.25, outputPer1M: 5 },
747
+ "gemini-1.5-flash": { inputPer1M: 0.075, outputPer1M: 0.3 },
748
+ "gemini-2.0-flash": { inputPer1M: 0.1, outputPer1M: 0.4 }
749
+ };
750
+ function resolvePricing(table, model) {
751
+ const exact = table[model];
752
+ if (exact) return exact;
753
+ let best;
754
+ let bestLength = 0;
755
+ for (const key of Object.keys(table)) {
756
+ if (model.startsWith(key) && key.length > bestLength) {
757
+ best = table[key];
758
+ bestLength = key.length;
759
+ }
760
+ }
761
+ return best;
762
+ }
763
+ function round(value) {
764
+ return Math.round(value * 1e6) / 1e6;
765
+ }
766
+ function estimateLLMCost(model, usage, options) {
767
+ const table = options?.pricing ? { ...MODEL_PRICING, ...options.pricing } : MODEL_PRICING;
768
+ const price = resolvePricing(table, model);
769
+ if (!price) return void 0;
770
+ const cachedInput = usage.cachedInputTokens ?? 0;
771
+ const billedInput = Math.max(0, (usage.inputTokens ?? 0) - cachedInput);
772
+ const output = usage.outputTokens ?? 0;
773
+ const cachedRate = price.cachedInputPer1M ?? price.inputPer1M;
774
+ const cost = billedInput / 1e6 * price.inputPer1M + cachedInput / 1e6 * cachedRate + output / 1e6 * price.outputPer1M;
775
+ return round(cost);
776
+ }
777
+ function recordLLMCost(ctx2, model, usage, options) {
778
+ const cost = estimateLLMCost(model, usage, options);
779
+ if (cost !== void 0) {
780
+ ctx2.setAttribute(GEN_AI_COST_ATTRIBUTE, cost);
781
+ }
782
+ return cost;
783
+ }
784
+
785
+ export { GEN_AI_COST_ATTRIBUTE, GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_TOKEN_USAGE_BUCKETS, MODEL_PRICING, defineAuditCatalog, defineDrain, defineEnricher, defineErrorCatalog, defineEvent, defineHttpDrain, estimateLLMCost, flush, genAiMetricViews, getCatalogCode, getRequestLogger, isCatalogError, llmHistogramAdvice, recordLLMCost, recordPromptSent, recordResponseReceived, recordRetry, recordStreamFirstToken, recordToolCall, runWithRequestContext, shutdown, trace2 as trace };
609
786
  //# sourceMappingURL=index.js.map
610
787
  //# sourceMappingURL=index.js.map