@backendkit-labs/auto-learning 0.1.1 → 0.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/nestjs/index.ts","../../src/nestjs/auto-learning.module.ts","../../src/core/pattern-registry/pattern-registry.ts","../../src/core/errors.ts","../../src/core/anomaly-detector/types.ts","../../src/core/anomaly-detector/anomaly-detector.ts","../../src/core/config-tuner/types.ts","../../src/core/config-tuner/config-tuner.ts","../../src/core/feedback-loop/types.ts","../../src/core/feedback-loop/feedback-loop.ts","../../src/core/persistence/in-memory-storage.ts","../../src/core/observability/noop-observability-adapter.ts","../../src/core/auto-learning-core.ts","../../src/nestjs/auto-learning.interceptor.ts","../../src/nestjs/auto-learning.constants.ts","../../src/nestjs/backend-kit-observability-adapter.ts","../../src/nestjs/auto-learning.decorator.ts"],"sourcesContent":["export { AutoLearningModule } from './auto-learning.module.js';\nexport type { AutoLearningModuleOptions } from './auto-learning.module.js';\nexport { AutoLearn } from './auto-learning.decorator.js';\nexport type { AutoLearnOptions } from './auto-learning.decorator.js';\nexport { AUTO_LEARNING_INSTANCE, AUTO_LEARNING_OPTIONS, AUTO_LEARN_METADATA } from './auto-learning.constants.js';\n","import { DynamicModule, Module, Provider, LoggerService } from '@nestjs/common';\nimport { APP_INTERCEPTOR } from '@nestjs/core';\nimport { AutoLearningCore, AutoLearningCoreOptions } from '../core/auto-learning-core.js';\nimport { AutoLearningInterceptor } from './auto-learning.interceptor.js';\nimport { AUTO_LEARNING_OPTIONS, AUTO_LEARNING_INSTANCE } from './auto-learning.constants.js';\nimport { BackendKitObservabilityAdapter } from './backend-kit-observability-adapter.js';\nimport { ObservabilityAdapter } from '../core/observability/observability-adapter.js';\n\nexport type AutoLearningModuleOptions = {\n intervalMs?: number;\n storage?: 'memory' | 'redis' | 'sql';\n redisUrl?: string;\n observability?: {\n logger?: LoggerService;\n metrics?: {\n increment?: (name: string, value?: number, tags?: Record<string, string>) => void;\n gauge?: (name: string, value: number, tags?: Record<string, string>) => void;\n histogram?: (name: string, value: number, tags?: Record<string, string>) => void;\n };\n };\n coreOptions?: Omit<AutoLearningCoreOptions, 'storage' | 'observability'>;\n};\n\n@Module({})\nexport class AutoLearningModule {\n static forRoot(options: AutoLearningModuleOptions = {}): DynamicModule {\n const providers: Provider[] = [\n {\n provide: AUTO_LEARNING_OPTIONS,\n useValue: options,\n },\n {\n provide: AUTO_LEARNING_INSTANCE,\n useFactory: (opts: AutoLearningModuleOptions) => {\n let observability: ObservabilityAdapter | undefined;\n\n if (opts.observability?.logger) {\n observability = new BackendKitObservabilityAdapter(\n opts.observability.logger,\n opts.observability.metrics,\n );\n }\n\n return AutoLearningCore.create({\n ...opts.coreOptions,\n observability,\n });\n },\n inject: [AUTO_LEARNING_OPTIONS],\n },\n {\n provide: APP_INTERCEPTOR,\n useClass: AutoLearningInterceptor,\n },\n ];\n\n return {\n module: AutoLearningModule,\n providers,\n exports: [AUTO_LEARNING_INSTANCE],\n global: true,\n };\n }\n}\n","import { ok, fail } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { IPatternRegistry, RegistryStats } from './types.js';\nimport { EndpointPattern, AggregatePattern } from '../types.js';\nimport { LearningError, storageError } from '../errors.js';\nimport { StorageAdapter } from '../persistence/storage-adapter.js';\nimport { ObservabilityAdapter } from '../observability/observability-adapter.js';\n\nexport class PatternRegistry implements IPatternRegistry {\n constructor(\n private readonly storage: StorageAdapter,\n private readonly observability: ObservabilityAdapter,\n ) {}\n\n record(pattern: EndpointPattern): Result<void, LearningError> {\n const result = this.storage.savePattern(pattern);\n if (!result.ok) {\n this.observability.error('Failed to record pattern', {\n error: result.error,\n pattern: { method: pattern.method, path: pattern.path },\n });\n return fail(storageError('Failed to save pattern', result.error));\n }\n\n this.observability.incrementMetric('patterns.recorded', 1, {\n method: pattern.method,\n path: pattern.path,\n });\n\n this.observability.histogramMetric('patterns.duration_ms', pattern.durationMs, {\n method: pattern.method,\n path: pattern.path,\n });\n\n return ok(undefined);\n }\n\n getAggregates(windowMinutes: number): Result<AggregatePattern[], LearningError> {\n const result = this.storage.getAggregates(windowMinutes);\n if (!result.ok) {\n this.observability.error('Failed to get aggregates', { error: result.error });\n return fail(storageError('Failed to get aggregates', result.error));\n }\n return ok(result.value);\n }\n\n getHistory(\n endpoint: string,\n method: string,\n limit: number,\n ): Result<EndpointPattern[], LearningError> {\n const now = new Date();\n const past = new Date(now.getTime() - 24 * 60 * 60 * 1000);\n const patterns = this.storage.getPatterns(past, now);\n\n if (!patterns.ok) {\n return fail(storageError('Failed to get history', patterns.error));\n }\n\n const filtered = patterns.value\n .filter((p: EndpointPattern) => p.path === endpoint && p.method === method)\n .slice(-limit);\n\n return ok(filtered);\n }\n\n getStats(): Result<RegistryStats, LearningError> {\n const now = new Date();\n const past = new Date(0);\n const patterns = this.storage.getPatterns(past, now);\n\n if (!patterns.ok) {\n return fail(storageError('Failed to get stats', patterns.error));\n }\n\n const all = patterns.value;\n if (all.length === 0) {\n return ok({\n totalPatterns: 0,\n uniqueEndpoints: 0,\n oldestPattern: now,\n newestPattern: now,\n });\n }\n\n const uniqueEndpoints = new Set(all.map((p: EndpointPattern) => `${p.method}:${p.path}`));\n const timestamps = all.map((p: EndpointPattern) => p.timestamp.getTime());\n\n return ok({\n totalPatterns: all.length,\n uniqueEndpoints: uniqueEndpoints.size,\n oldestPattern: new Date(Math.min(...timestamps)),\n newestPattern: new Date(Math.max(...timestamps)),\n });\n }\n}\n","import { fail } from '@backendkit-labs/result';\n\nexport type LearningErrorTag =\n | 'STORAGE_ERROR'\n | 'INSUFFICIENT_DATA'\n | 'INVALID_CONFIG'\n | 'ANOMALY_DETECTION_FAILED'\n | 'FEEDBACK_LOOP_ALREADY_RUNNING'\n | 'FEEDBACK_LOOP_NOT_RUNNING';\n\nexport type LearningError = {\n readonly tag: LearningErrorTag;\n readonly message: string;\n readonly cause?: unknown;\n readonly required?: number;\n readonly actual?: number;\n readonly key?: string;\n readonly value?: unknown;\n};\n\nexport const storageError = (message: string, cause?: unknown): LearningError =>\n ({ tag: 'STORAGE_ERROR', message, cause });\n\nexport const insufficientData = (required: number, actual: number): LearningError =>\n ({ tag: 'INSUFFICIENT_DATA', message: `Insufficient data: required ${required}, got ${actual}`, required, actual });\n\nexport const invalidConfig = (key: string, value: unknown): LearningError =>\n ({ tag: 'INVALID_CONFIG', message: `Invalid config for key: ${key}`, key, value });\n\nexport const anomalyDetectionFailed = (message: string): LearningError =>\n ({ tag: 'ANOMALY_DETECTION_FAILED', message });\n\nexport const feedbackLoopAlreadyRunning = (): LearningError =>\n ({ tag: 'FEEDBACK_LOOP_ALREADY_RUNNING', message: 'Feedback loop is already running' });\n\nexport const feedbackLoopNotRunning = (): LearningError =>\n ({ tag: 'FEEDBACK_LOOP_NOT_RUNNING', message: 'Feedback loop is not running' });\n","import type { Result } from '@backendkit-labs/result';\nimport { EndpointPattern, AggregatePattern, AnomalySeverity } from '../types.js';\nimport { LearningError } from '../errors.js';\n\nexport interface IAnomalyDetector {\n analyze(\n current: EndpointPattern,\n baseline: AggregatePattern,\n ): Result<AnomalyReport | null, LearningError>;\n\n batchAnalyze(\n windowPatterns: EndpointPattern[],\n baselines: AggregatePattern[],\n ): Result<AnomalyReport[], LearningError>;\n}\n\nexport type AnomalyReport = {\n id: string;\n endpoint: string;\n method: string;\n severity: AnomalySeverity;\n metric: 'latency' | 'error_rate' | 'frequency' | 'unknown_endpoint';\n expectedValue: number;\n actualValue: number;\n deviation: number;\n detectedAt: Date;\n};\n\nexport type AnomalyDetectorConfig = {\n latencyStdDevThreshold: number;\n errorRateThreshold: number;\n frequencyDeviationThreshold: number;\n enableUnknownEndpointDetection: boolean;\n};\n\nexport const DEFAULT_ANOMALY_CONFIG: AnomalyDetectorConfig = {\n latencyStdDevThreshold: 2.5,\n errorRateThreshold: 0.05,\n frequencyDeviationThreshold: 3.0,\n enableUnknownEndpointDetection: true,\n};\n","import { ok, fail } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { v4 as uuid } from 'uuid';\nimport { IAnomalyDetector, AnomalyReport, AnomalyDetectorConfig, DEFAULT_ANOMALY_CONFIG } from './types.js';\nimport { EndpointPattern, AggregatePattern } from '../types.js';\nimport { LearningError, anomalyDetectionFailed } from '../errors.js';\n\nexport class AnomalyDetector implements IAnomalyDetector {\n private readonly config: AnomalyDetectorConfig;\n\n constructor(config?: Partial<AnomalyDetectorConfig>) {\n this.config = { ...DEFAULT_ANOMALY_CONFIG, ...config };\n }\n\n analyze(\n current: EndpointPattern,\n baseline: AggregatePattern,\n ): Result<AnomalyReport | null, LearningError> {\n try {\n const reports: AnomalyReport[] = [];\n\n // Latency anomaly: check if duration deviates from baseline\n if (baseline.count > 0) {\n const latencyDeviation =\n Math.abs(current.durationMs - baseline.avgDurationMs) /\n Math.max(this.stdDev(baseline), 1);\n\n if (latencyDeviation > this.config.latencyStdDevThreshold) {\n reports.push({\n id: uuid(),\n endpoint: current.path,\n method: current.method,\n severity: this.calculateSeverity(latencyDeviation),\n metric: 'latency',\n expectedValue: baseline.avgDurationMs,\n actualValue: current.durationMs,\n deviation: latencyDeviation,\n detectedAt: new Date(),\n });\n }\n }\n\n // Error rate anomaly: require at least 3 errors in the window\n // to avoid false positives from individual 500s\n if (current.statusCode >= 500 && baseline.errorCount >= 3) {\n const currentErrorRate = 1.0;\n if (currentErrorRate > baseline.errorRate * 2 && currentErrorRate > this.config.errorRateThreshold) {\n reports.push({\n id: uuid(),\n endpoint: current.path,\n method: current.method,\n severity: 'high',\n metric: 'error_rate',\n expectedValue: baseline.errorRate,\n actualValue: currentErrorRate,\n deviation: currentErrorRate / Math.max(baseline.errorRate, 0.001),\n detectedAt: new Date(),\n });\n }\n }\n\n return ok(reports.length > 0 ? reports[0] : null);\n } catch (e) {\n return fail(\n anomalyDetectionFailed(\n e instanceof Error ? e.message : 'Unknown anomaly detection error',\n ),\n );\n }\n }\n\n batchAnalyze(\n windowPatterns: EndpointPattern[],\n baselines: AggregatePattern[],\n ): Result<AnomalyReport[], LearningError> {\n try {\n const baselineMap = new Map<string, AggregatePattern>();\n for (const b of baselines) {\n baselineMap.set(`${b.method}:${b.path}`, b);\n }\n\n const reports: AnomalyReport[] = [];\n\n for (const pattern of windowPatterns) {\n const key = `${pattern.method}:${pattern.path}`;\n const baseline = baselineMap.get(key);\n\n if (!baseline) {\n if (this.config.enableUnknownEndpointDetection) {\n reports.push({\n id: uuid(),\n endpoint: pattern.path,\n method: pattern.method,\n severity: 'low',\n metric: 'unknown_endpoint',\n expectedValue: 0,\n actualValue: 1,\n deviation: 1,\n detectedAt: new Date(),\n });\n }\n continue;\n }\n\n const result = this.analyze(pattern, baseline);\n if (result.ok && result.value) {\n reports.push(result.value);\n }\n }\n\n return ok(reports);\n } catch (e) {\n return fail(\n anomalyDetectionFailed(\n e instanceof Error ? e.message : 'Unknown batch analysis error',\n ),\n );\n }\n }\n\n private calculateSeverity(deviation: number): 'low' | 'medium' | 'high' | 'critical' {\n if (deviation > 5) return 'critical';\n if (deviation > 4) return 'high';\n if (deviation > 3) return 'medium';\n return 'low';\n }\n\n private stdDev(baseline: AggregatePattern): number {\n return (baseline.p95Ms - baseline.p50Ms) / 2;\n }\n}\n","import type { Result } from '@backendkit-labs/result';\nimport { TunableConfig, AggregatePattern, AnomalyReport } from '../types.js';\nimport { LearningError } from '../errors.js';\n\nexport interface IConfigTuner {\n getCurrentConfig(): TunableConfig;\n tune(\n aggregates: AggregatePattern[],\n anomalies: AnomalyReport[],\n ): Result<TunableConfig, LearningError>;\n reset(): Result<TunableConfig, LearningError>;\n onConfigChange(callback: (config: TunableConfig) => void): void;\n}\n\nexport type ConfigTunerConfig = {\n minTimeoutMs: number;\n maxTimeoutMs: number;\n smoothingFactor: number;\n adjustmentStepMs: number;\n};\n\nexport const DEFAULT_TUNER_CONFIG: ConfigTunerConfig = {\n minTimeoutMs: 1000,\n maxTimeoutMs: 30000,\n smoothingFactor: 0.3,\n adjustmentStepMs: 500,\n};\n","import { ok, fail } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { IConfigTuner, ConfigTunerConfig, DEFAULT_TUNER_CONFIG } from './types.js';\nimport { TunableConfig, AggregatePattern, AnomalyReport } from '../types.js';\nimport { LearningError, storageError } from '../errors.js';\nimport { StorageAdapter } from '../persistence/storage-adapter.js';\nimport { ObservabilityAdapter } from '../observability/observability-adapter.js';\n\nconst DEFAULT_CONFIG: TunableConfig = {\n timeoutMs: 10000,\n maxRetries: 3,\n circuitBreakerThreshold: 0.5,\n circuitBreakerHalfOpenAfterMs: 30000,\n bulkheadMaxConcurrent: 10,\n};\n\nexport class ConfigTuner implements IConfigTuner {\n private currentConfig: TunableConfig;\n private readonly config: ConfigTunerConfig;\n private listeners: Array<(config: TunableConfig) => void> = [];\n private lastChangeAt: number = 0;\n\n constructor(\n private readonly storage: StorageAdapter,\n private readonly observability: ObservabilityAdapter,\n tunerConfig?: Partial<ConfigTunerConfig>,\n ) {\n this.config = { ...DEFAULT_TUNER_CONFIG, ...tunerConfig };\n\n const loaded = this.storage.loadConfig();\n this.currentConfig = loaded.ok && loaded.value\n ? loaded.value\n : { ...DEFAULT_CONFIG };\n }\n\n getCurrentConfig(): TunableConfig {\n return { ...this.currentConfig };\n }\n\n tune(\n aggregates: AggregatePattern[],\n anomalies: AnomalyReport[],\n ): Result<TunableConfig, LearningError> {\n if (aggregates.length === 0) {\n return ok(this.getCurrentConfig());\n }\n\n const newConfig = { ...this.currentConfig };\n const changes: Partial<Record<string, unknown>> = {};\n\n // Tune timeout based on p95 latency\n const maxP95 = Math.max(...aggregates.map((a) => a.p95Ms));\n const targetTimeout = Math.min(\n Math.max(maxP95 * 2, this.config.minTimeoutMs),\n this.config.maxTimeoutMs,\n );\n\n if (Math.abs(targetTimeout - newConfig.timeoutMs) > this.config.adjustmentStepMs) {\n newConfig.timeoutMs = this.smoothValue(\n newConfig.timeoutMs,\n targetTimeout,\n );\n changes.timeoutMs = newConfig.timeoutMs;\n }\n\n // Tune maxRetries based on error rate\n const avgErrorRate =\n aggregates.reduce((sum, a) => sum + a.errorRate, 0) / aggregates.length;\n\n if (avgErrorRate > 0.1) {\n newConfig.maxRetries = Math.min(newConfig.maxRetries + 1, 5);\n changes.maxRetries = newConfig.maxRetries;\n } else if (avgErrorRate < 0.01 && newConfig.maxRetries > 1) {\n newConfig.maxRetries = Math.max(newConfig.maxRetries - 1, 0);\n changes.maxRetries = newConfig.maxRetries;\n }\n\n // Tune circuit breaker threshold based on anomalies\n const criticalAnomalies = anomalies.filter(\n (a) => a.severity === 'critical' || a.severity === 'high',\n ).length;\n\n if (criticalAnomalies > 0) {\n newConfig.circuitBreakerThreshold = Math.max(\n this.currentConfig.circuitBreakerThreshold - 0.1 * criticalAnomalies,\n 0.1,\n );\n changes.circuitBreakerThreshold = newConfig.circuitBreakerThreshold;\n } else if (anomalies.length === 0) {\n newConfig.circuitBreakerThreshold = Math.min(\n this.currentConfig.circuitBreakerThreshold + 0.05,\n 0.8,\n );\n changes.circuitBreakerThreshold = newConfig.circuitBreakerThreshold;\n }\n\n // Apply changes if any\n if (Object.keys(changes).length > 0) {\n const now = Date.now();\n if (now - this.lastChangeAt > 60_000) {\n this.currentConfig = newConfig;\n this.lastChangeAt = now;\n\n const saveResult = this.storage.saveConfig(newConfig);\n if (!saveResult.ok) {\n return fail(storageError('Failed to save config', saveResult.error));\n }\n\n this.observability.info('Config tuned', { changes });\n this.observability.incrementMetric('config.changes', 1);\n\n for (const listener of this.listeners) {\n listener(this.getCurrentConfig());\n }\n }\n }\n\n return ok(this.getCurrentConfig());\n }\n\n reset(): Result<TunableConfig, LearningError> {\n this.currentConfig = { ...DEFAULT_CONFIG };\n const saveResult = this.storage.saveConfig(this.currentConfig);\n if (!saveResult.ok) {\n return fail(storageError('Failed to reset config', saveResult.error));\n }\n\n this.observability.info('Config reset to defaults');\n for (const listener of this.listeners) {\n listener(this.getCurrentConfig());\n }\n\n return ok(this.getCurrentConfig());\n }\n\n onConfigChange(callback: (config: TunableConfig) => void): void {\n this.listeners.push(callback);\n }\n\n private smoothValue(current: number, target: number): number {\n return current + (target - current) * this.config.smoothingFactor;\n }\n}\n","import type { Result } from '@backendkit-labs/result';\nimport { LearningCycleEvent } from '../types.js';\nimport { LearningError } from '../errors.js';\n\nexport interface IFeedbackLoop {\n start(intervalMs?: number): void;\n stop(): void;\n isRunning(): boolean;\n runOnce(): Promise<Result<LearningCycleEvent, LearningError>>;\n onCycle(callback: (event: LearningCycleEvent) => void): void;\n}\n\nexport type FeedbackLoopConfig = {\n defaultIntervalMs: number;\n windowSizeMinutes: number;\n minSamplesBeforeTuning: number;\n cooldownBetweenChangesMs: number;\n};\n\nexport const DEFAULT_LOOP_CONFIG: FeedbackLoopConfig = {\n defaultIntervalMs: 60_000,\n windowSizeMinutes: 5,\n minSamplesBeforeTuning: 10,\n cooldownBetweenChangesMs: 120_000,\n};\n","import { ok, fail } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { v4 as uuid } from 'uuid';\nimport { IFeedbackLoop, FeedbackLoopConfig, DEFAULT_LOOP_CONFIG } from './types.js';\nimport { LearningCycleEvent } from '../types.js';\nimport { LearningError, storageError } from '../errors.js';\nimport { IPatternRegistry } from '../pattern-registry/types.js';\nimport { IAnomalyDetector } from '../anomaly-detector/types.js';\nimport { IConfigTuner } from '../config-tuner/types.js';\nimport { StorageAdapter } from '../persistence/storage-adapter.js';\nimport { ObservabilityAdapter } from '../observability/observability-adapter.js';\n\nexport class FeedbackLoop implements IFeedbackLoop {\n private timerId: ReturnType<typeof setInterval> | null = null;\n private readonly config: FeedbackLoopConfig;\n private cycleListeners: Array<(event: LearningCycleEvent) => void> = [];\n\n constructor(\n private readonly patternRegistry: IPatternRegistry,\n private readonly anomalyDetector: IAnomalyDetector,\n private readonly configTuner: IConfigTuner,\n private readonly storage: StorageAdapter,\n private readonly observability: ObservabilityAdapter,\n loopConfig?: Partial<FeedbackLoopConfig>,\n ) {\n this.config = { ...DEFAULT_LOOP_CONFIG, ...loopConfig };\n }\n\n start(intervalMs?: number): void {\n if (this.timerId !== null) {\n this.observability.warn('Feedback loop already running, ignoring start');\n return;\n }\n\n const interval = intervalMs ?? this.config.defaultIntervalMs;\n this.observability.info('Feedback loop started', { intervalMs: interval });\n\n this.timerId = setInterval(() => {\n this.runOnce().then((result) => {\n if (!result.ok) {\n this.observability.error('Feedback loop cycle failed', {\n error: result.error,\n });\n }\n });\n }, interval);\n }\n\n stop(): void {\n if (this.timerId === null) {\n this.observability.warn('Feedback loop not running, ignoring stop');\n return;\n }\n\n clearInterval(this.timerId);\n this.timerId = null;\n this.observability.info('Feedback loop stopped');\n }\n\n isRunning(): boolean {\n return this.timerId !== null;\n }\n\n async runOnce(): Promise<Result<LearningCycleEvent, LearningError>> {\n const cycleId = uuid();\n const startTime = Date.now();\n\n this.observability.debug('Feedback cycle started', { cycleId });\n\n // Step 1: Collect patterns from the window\n const patternsResult = this.storage.getPatterns(\n new Date(Date.now() - this.config.windowSizeMinutes * 60_000),\n new Date(),\n );\n\n if (!patternsResult.ok) {\n return fail(storageError('Failed to collect patterns', patternsResult.error));\n }\n\n const patterns = patternsResult.value;\n if (patterns.length < this.config.minSamplesBeforeTuning) {\n this.observability.debug('Skipping cycle: insufficient samples', {\n actual: patterns.length,\n required: this.config.minSamplesBeforeTuning,\n });\n\n const skippedEvent: LearningCycleEvent = {\n cycleId,\n timestamp: new Date(),\n patternsProcessed: patterns.length,\n anomaliesFound: 0,\n configChanges: {},\n durationMs: Date.now() - startTime,\n };\n\n return ok(skippedEvent);\n }\n\n // Step 2: Get aggregates\n const aggregatesResult = this.patternRegistry.getAggregates(\n this.config.windowSizeMinutes,\n );\n\n if (!aggregatesResult.ok) {\n return fail(aggregatesResult.error);\n }\n\n const aggregates = aggregatesResult.value;\n\n // Step 3: Detect anomalies\n const anomaliesResult = this.anomalyDetector.batchAnalyze(patterns, aggregates);\n\n if (!anomaliesResult.ok) {\n return fail(anomaliesResult.error);\n }\n\n const anomalies = anomaliesResult.value;\n\n // Persist anomalies\n for (const anomaly of anomalies) {\n this.storage.saveAnomaly(anomaly);\n }\n\n // Log anomalies\n if (anomalies.length > 0) {\n this.observability.warn('Anomalies detected', {\n count: anomalies.length,\n severities: anomalies.map((a) => a.severity),\n });\n this.observability.incrementMetric('anomalies.detected', anomalies.length);\n }\n\n // Step 4: Tune config\n const tuneResult = this.configTuner.tune(aggregates, anomalies);\n\n if (!tuneResult.ok) {\n return fail(tuneResult.error);\n }\n\n const newConfig = tuneResult.value;\n const previousConfig = this.configTuner.getCurrentConfig();\n\n // Compute config changes\n const configChanges: Record<string, unknown> = {};\n const configKeys = Object.keys(newConfig) as Array<keyof typeof newConfig>;\n for (const key of configKeys) {\n if (newConfig[key] !== previousConfig[key]) {\n configChanges[key] = newConfig[key];\n }\n }\n\n // Step 5: Build and persist cycle event\n const cycleEvent: LearningCycleEvent = {\n cycleId,\n timestamp: new Date(),\n patternsProcessed: patterns.length,\n anomaliesFound: anomalies.length,\n configChanges,\n durationMs: Date.now() - startTime,\n };\n\n const saveResult = this.storage.saveCycleEvent(cycleEvent);\n if (!saveResult.ok) {\n this.observability.error('Failed to save cycle event', { error: saveResult.error });\n return fail(saveResult.error);\n }\n\n // Emit to listeners\n for (const listener of this.cycleListeners) {\n listener(cycleEvent);\n }\n\n this.observability.info('Feedback cycle completed', {\n cycleId,\n patternsProcessed: cycleEvent.patternsProcessed,\n anomaliesFound: cycleEvent.anomaliesFound,\n durationMs: cycleEvent.durationMs,\n });\n\n this.observability.histogramMetric('cycle.duration_ms', cycleEvent.durationMs);\n this.observability.gaugeMetric('cycle.patterns_count', cycleEvent.patternsProcessed);\n\n return ok(cycleEvent);\n }\n\n onCycle(callback: (event: LearningCycleEvent) => void): void {\n this.cycleListeners.push(callback);\n }\n}\n","import { ok, fail } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { StorageAdapter } from './storage-adapter.js';\nimport {\n EndpointPattern,\n AggregatePattern,\n AnomalyReport,\n LearningCycleEvent,\n TunableConfig,\n} from '../types.js';\nimport { LearningError, storageError } from '../errors.js';\n\nconst DEFAULT_CONFIG: TunableConfig = {\n timeoutMs: 10000,\n maxRetries: 3,\n circuitBreakerThreshold: 0.5,\n circuitBreakerHalfOpenAfterMs: 30000,\n bulkheadMaxConcurrent: 10,\n};\n\nfunction percentile(sorted: number[], p: number): number {\n if (sorted.length === 0) return 0;\n const index = Math.ceil((p / 100) * sorted.length) - 1;\n return sorted[Math.max(0, index)];\n}\n\nexport class InMemoryStorage implements StorageAdapter {\n private patterns: EndpointPattern[] = [];\n private anomalies: AnomalyReport[] = [];\n private config: TunableConfig = { ...DEFAULT_CONFIG };\n private cycles: LearningCycleEvent[] = [];\n\n savePattern(pattern: EndpointPattern): Result<void, LearningError> {\n try {\n this.patterns.push(pattern);\n return ok(undefined);\n } catch (e) {\n return fail(storageError('Failed to save pattern', e));\n }\n }\n\n getPatterns(windowStart: Date, windowEnd: Date): Result<EndpointPattern[], LearningError> {\n try {\n return ok(\n this.patterns.filter(\n (p) => p.timestamp >= windowStart && p.timestamp <= windowEnd,\n ),\n );\n } catch (e) {\n return fail(storageError('Failed to get patterns', e));\n }\n }\n\n getAggregates(windowMinutes: number): Result<AggregatePattern[], LearningError> {\n try {\n const cutoff = new Date(Date.now() - windowMinutes * 60_000);\n const recent = this.patterns.filter((p) => p.timestamp >= cutoff);\n\n const groups = new Map<string, EndpointPattern[]>();\n for (const p of recent) {\n const key = `${p.method}:${p.path}`;\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(p);\n }\n\n const aggregates: AggregatePattern[] = [];\n for (const [key, items] of groups) {\n const [method, path] = key.split(':');\n const durations = items.map((i) => i.durationMs).sort((a, b) => a - b);\n const errors = items.filter((i) => i.statusCode >= 500).length;\n\n aggregates.push({\n method,\n path,\n windowStart: cutoff,\n windowEnd: new Date(),\n count: items.length,\n avgDurationMs:\n durations.reduce((a, b) => a + b, 0) / durations.length,\n p50Ms: percentile(durations, 50),\n p95Ms: percentile(durations, 95),\n p99Ms: percentile(durations, 99),\n errorCount: errors,\n errorRate: errors / items.length,\n });\n }\n\n return ok(aggregates);\n } catch (e) {\n return fail(storageError('Failed to get aggregates', e));\n }\n }\n\n saveAnomaly(report: AnomalyReport): Result<void, LearningError> {\n try {\n this.anomalies.push(report);\n return ok(undefined);\n } catch (e) {\n return fail(storageError('Failed to save anomaly', e));\n }\n }\n\n getRecentAnomalies(limit: number): Result<AnomalyReport[], LearningError> {\n try {\n return ok(this.anomalies.slice(-limit).reverse());\n } catch (e) {\n return fail(storageError('Failed to get recent anomalies', e));\n }\n }\n\n saveConfig(config: TunableConfig): Result<void, LearningError> {\n try {\n this.config = { ...config };\n return ok(undefined);\n } catch (e) {\n return fail(storageError('Failed to save config', e));\n }\n }\n\n loadConfig(): Result<TunableConfig | null, LearningError> {\n try {\n return ok(this.config);\n } catch (e) {\n return fail(storageError('Failed to load config', e));\n }\n }\n\n saveCycleEvent(event: LearningCycleEvent): Result<void, LearningError> {\n try {\n this.cycles.push(event);\n return ok(undefined);\n } catch (e) {\n return fail(storageError('Failed to save cycle event', e));\n }\n }\n\n getLastCycleTime(): Result<Date | null, LearningError> {\n try {\n if (this.cycles.length === 0) return ok(null);\n return ok(this.cycles[this.cycles.length - 1].timestamp);\n } catch (e) {\n return fail(storageError('Failed to get last cycle time', e));\n }\n }\n\n prune(before: Date): Result<number, LearningError> {\n try {\n const beforeLen = this.patterns.length + this.anomalies.length;\n this.patterns = this.patterns.filter((p) => p.timestamp >= before);\n this.anomalies = this.anomalies.filter((a) => a.detectedAt >= before);\n const pruned = beforeLen - (this.patterns.length + this.anomalies.length);\n return ok(pruned);\n } catch (e) {\n return fail(storageError('Failed to prune', e));\n }\n }\n}\n","import { ObservabilityAdapter } from './observability-adapter.js';\n\nexport class NoopObservabilityAdapter implements ObservabilityAdapter {\n info(_msg: string, _meta?: Record<string, unknown>): void {}\n warn(_msg: string, _meta?: Record<string, unknown>): void {}\n error(_msg: string, _meta?: Record<string, unknown>): void {}\n debug(_msg: string, _meta?: Record<string, unknown>): void {}\n\n incrementMetric(_name: string, _value?: number, _tags?: Record<string, string>): void {}\n gaugeMetric(_name: string, _value: number, _tags?: Record<string, string>): void {}\n histogramMetric(_name: string, _value: number, _tags?: Record<string, string>): void {}\n}\n","import { ok } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { EndpointPattern, TunableConfig, LearningCycleEvent } from './types.js';\nimport { LearningError } from './errors.js';\nimport { IPatternRegistry, PatternRegistry } from './pattern-registry/index.js';\nimport { IAnomalyDetector, AnomalyDetector, AnomalyDetectorConfig } from './anomaly-detector/index.js';\nimport { IConfigTuner, ConfigTuner, ConfigTunerConfig } from './config-tuner/index.js';\nimport { IFeedbackLoop, FeedbackLoop, FeedbackLoopConfig } from './feedback-loop/index.js';\nimport { StorageAdapter, InMemoryStorage } from './persistence/index.js';\nimport { ObservabilityAdapter, NoopObservabilityAdapter } from './observability/index.js';\n\nexport type AutoLearningCoreOptions = {\n storage?: StorageAdapter;\n observability?: ObservabilityAdapter;\n anomalyConfig?: Partial<AnomalyDetectorConfig>;\n tunerConfig?: Partial<ConfigTunerConfig>;\n loopConfig?: Partial<FeedbackLoopConfig>;\n};\n\nexport class AutoLearningCore {\n private constructor(\n public readonly patternRegistry: IPatternRegistry,\n public readonly anomalyDetector: IAnomalyDetector,\n public readonly configTuner: IConfigTuner,\n public readonly feedbackLoop: IFeedbackLoop,\n public readonly storage: StorageAdapter,\n public readonly observability: ObservabilityAdapter,\n ) {}\n\n static create(options?: AutoLearningCoreOptions): AutoLearningCore {\n const storage = options?.storage ?? new InMemoryStorage();\n const obs = options?.observability ?? new NoopObservabilityAdapter();\n const registry = new PatternRegistry(storage, obs);\n const detector = new AnomalyDetector(options?.anomalyConfig);\n const tuner = new ConfigTuner(storage, obs, options?.tunerConfig);\n const loop = new FeedbackLoop(registry, detector, tuner, storage, obs, options?.loopConfig);\n\n return new AutoLearningCore(registry, detector, tuner, loop, storage, obs);\n }\n\n recordPattern(pattern: EndpointPattern): Result<void, LearningError> {\n return this.patternRegistry.record(pattern);\n }\n\n getCurrentConfig(): TunableConfig {\n return this.configTuner.getCurrentConfig();\n }\n\n startFeedbackLoop(intervalMs?: number): void {\n this.feedbackLoop.start(intervalMs);\n }\n\n stopFeedbackLoop(): void {\n this.feedbackLoop.stop();\n }\n\n isFeedbackLoopRunning(): boolean {\n return this.feedbackLoop.isRunning();\n }\n\n async runOnce(): Promise<Result<LearningCycleEvent, LearningError>> {\n return this.feedbackLoop.runOnce();\n }\n\n onConfigChange(callback: (config: TunableConfig) => void): void {\n this.configTuner.onConfigChange(callback);\n }\n\n onCycle(callback: (event: LearningCycleEvent) => void): void {\n this.feedbackLoop.onCycle(callback);\n }\n}\n","import {\n Injectable,\n NestInterceptor,\n ExecutionContext,\n CallHandler,\n Inject,\n} from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { Observable, tap } from 'rxjs';\nimport { AUTO_LEARN_METADATA, AUTO_LEARNING_INSTANCE } from './auto-learning.constants.js';\nimport { AutoLearnOptions } from './auto-learning.decorator.js';\nimport { AutoLearningCore } from '../core/auto-learning-core.js';\n\n@Injectable()\nexport class AutoLearningInterceptor implements NestInterceptor {\n constructor(\n private readonly reflector: Reflector,\n @Inject(AUTO_LEARNING_INSTANCE)\n private readonly core: AutoLearningCore,\n ) {}\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<any> {\n const options = this.reflector.get<AutoLearnOptions>(\n AUTO_LEARN_METADATA,\n context.getHandler(),\n );\n\n if (!options) {\n return next.handle();\n }\n\n const start = Date.now();\n const req = context.switchToHttp().getRequest();\n const { method, path } = this.extractRequestInfo(req);\n\n return next.handle().pipe(\n tap(() => {\n const duration = Date.now() - start;\n const status = context.switchToHttp().getResponse().statusCode;\n\n this.core.recordPattern({\n method,\n path,\n statusCode: status,\n durationMs: duration,\n timestamp: new Date(),\n metadata: options.customMetadata ? options.customMetadata(req) : undefined,\n });\n }),\n );\n }\n\n private extractRequestInfo(req: any): { method: string; path: string } {\n const method = req.method ?? 'UNKNOWN';\n const path = req.route?.path ?? req.path ?? req.url ?? '/';\n return { method, path };\n }\n}\n","export const AUTO_LEARNING_OPTIONS = Symbol('AUTO_LEARNING_OPTIONS');\nexport const AUTO_LEARNING_INSTANCE = Symbol('AUTO_LEARNING_INSTANCE');\nexport const AUTO_LEARN_METADATA = 'auto_learn_metadata';\n","import { LoggerService } from '@nestjs/common';\nimport { ObservabilityAdapter } from '../core/observability/observability-adapter.js';\n\nexport class BackendKitObservabilityAdapter implements ObservabilityAdapter {\n private readonly prefix = 'auto_learning';\n\n constructor(\n private readonly logger: LoggerService,\n private readonly metrics?: {\n increment?: (name: string, value?: number, tags?: Record<string, string>) => void;\n gauge?: (name: string, value: number, tags?: Record<string, string>) => void;\n histogram?: (name: string, value: number, tags?: Record<string, string>) => void;\n },\n ) {}\n\n info(msg: string, meta?: Record<string, unknown>): void {\n this.logger.log?.(`[AutoLearn] ${msg}`, meta);\n }\n\n warn(msg: string, meta?: Record<string, unknown>): void {\n this.logger.warn?.(`[AutoLearn] ${msg}`, meta);\n }\n\n error(msg: string, meta?: Record<string, unknown>): void {\n this.logger.error?.(`[AutoLearn] ${msg}`, meta);\n }\n\n debug(msg: string, meta?: Record<string, unknown>): void {\n this.logger.debug?.(`[AutoLearn] ${msg}`, meta);\n }\n\n incrementMetric(name: string, value = 1, tags?: Record<string, string>): void {\n this.metrics?.increment?.(`${this.prefix}.${name}`, value, tags);\n }\n\n gaugeMetric(name: string, value: number, tags?: Record<string, string>): void {\n this.metrics?.gauge?.(`${this.prefix}.${name}`, value, tags);\n }\n\n histogramMetric(name: string, value: number, tags?: Record<string, string>): void {\n this.metrics?.histogram?.(`${this.prefix}.${name}`, value, tags);\n }\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { AUTO_LEARN_METADATA } from './auto-learning.constants.js';\n\nexport type AutoLearnOptions = {\n trackParams?: boolean;\n trackBody?: boolean;\n customMetadata?: (req: any) => Record<string, unknown>;\n};\n\nexport const AutoLearn = (options?: AutoLearnOptions): MethodDecorator =>\n SetMetadata(AUTO_LEARN_METADATA, options ?? {});\n"],"mappings":"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","names":["import_common","import_result","uuid","import_result","import_result","import_uuid","uuid","import_result","DEFAULT_CONFIG","import_common"]}
1
+ {"version":3,"sources":["../../src/nestjs/index.ts","../../src/nestjs/auto-learning.module.ts","../../src/core/pattern-registry/pattern-registry.ts","../../src/core/errors.ts","../../src/core/anomaly-detector/types.ts","../../src/core/anomaly-detector/anomaly-detector.ts","../../src/core/config-tuner/types.ts","../../src/core/config-tuner/config-tuner.ts","../../src/core/feedback-loop/types.ts","../../src/core/feedback-loop/feedback-loop.ts","../../src/core/persistence/in-memory-storage.ts","../../src/core/observability/noop-observability-adapter.ts","../../src/core/auto-learning-core.ts","../../src/nestjs/auto-learning.interceptor.ts","../../src/nestjs/auto-learning.constants.ts","../../src/nestjs/auto-learning-adapters.service.ts","../../src/nestjs/backend-kit-observability-adapter.ts","../../src/nestjs/auto-learning.decorator.ts"],"sourcesContent":["export { AutoLearningModule } from './auto-learning.module.js';\nexport type { AutoLearningModuleOptions } from './auto-learning.module.js';\nexport { AutoLearn } from './auto-learning.decorator.js';\nexport type { AutoLearnOptions } from './auto-learning.decorator.js';\nexport { AUTO_LEARNING_INSTANCE, AUTO_LEARNING_OPTIONS, AUTO_LEARN_METADATA } from './auto-learning.constants.js';\n","import { DynamicModule, Module, Provider, LoggerService } from '@nestjs/common';\nimport { APP_INTERCEPTOR } from '@nestjs/core';\nimport { AutoLearningCore, AutoLearningCoreOptions } from '../core/auto-learning-core.js';\nimport { AutoLearningInterceptor } from './auto-learning.interceptor.js';\nimport { AutoLearningAdaptersService } from './auto-learning-adapters.service.js';\nimport { AUTO_LEARNING_OPTIONS, AUTO_LEARNING_INSTANCE } from './auto-learning.constants.js';\nimport { BackendKitObservabilityAdapter } from './backend-kit-observability-adapter.js';\nimport { ObservabilityAdapter } from '../core/observability/observability-adapter.js';\n\nexport type AutoLearningModuleOptions = {\n intervalMs?: number;\n storage?: 'memory' | 'redis' | 'sql';\n redisUrl?: string;\n observability?: {\n logger?: LoggerService;\n metrics?: {\n increment?: (name: string, value?: number, tags?: Record<string, string>) => void;\n gauge?: (name: string, value: number, tags?: Record<string, string>) => void;\n histogram?: (name: string, value: number, tags?: Record<string, string>) => void;\n };\n };\n coreOptions?: Omit<AutoLearningCoreOptions, 'storage' | 'observability'>;\n adapters?: {\n circuitBreaker?: boolean;\n bulkhead?: boolean;\n };\n};\n\n@Module({})\nexport class AutoLearningModule {\n static forRoot(options: AutoLearningModuleOptions = {}): DynamicModule {\n const providers: Provider[] = [\n {\n provide: AUTO_LEARNING_OPTIONS,\n useValue: options,\n },\n {\n provide: AUTO_LEARNING_INSTANCE,\n useFactory: (opts: AutoLearningModuleOptions) => {\n let observability: ObservabilityAdapter | undefined;\n\n if (opts.observability?.logger) {\n observability = new BackendKitObservabilityAdapter(\n opts.observability.logger,\n opts.observability.metrics,\n );\n }\n\n return AutoLearningCore.create({\n ...opts.coreOptions,\n observability,\n });\n },\n inject: [AUTO_LEARNING_OPTIONS],\n },\n {\n provide: APP_INTERCEPTOR,\n useClass: AutoLearningInterceptor,\n },\n AutoLearningAdaptersService,\n ];\n\n return {\n module: AutoLearningModule,\n providers,\n exports: [AUTO_LEARNING_INSTANCE],\n global: true,\n };\n }\n}\n","import { ok, fail } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { IPatternRegistry, RegistryStats } from './types.js';\nimport { EndpointPattern, AggregatePattern } from '../types.js';\nimport { LearningError, storageError } from '../errors.js';\nimport { StorageAdapter } from '../persistence/storage-adapter.js';\nimport { ObservabilityAdapter } from '../observability/observability-adapter.js';\n\nexport class PatternRegistry implements IPatternRegistry {\n constructor(\n private readonly storage: StorageAdapter,\n private readonly observability: ObservabilityAdapter,\n ) {}\n\n record(pattern: EndpointPattern): Result<void, LearningError> {\n const result = this.storage.savePattern(pattern);\n if (!result.ok) {\n this.observability.error('Failed to record pattern', {\n error: result.error,\n pattern: { method: pattern.method, path: pattern.path },\n });\n return fail(storageError('Failed to save pattern', result.error));\n }\n\n this.observability.incrementMetric('patterns.recorded', 1, {\n method: pattern.method,\n path: pattern.path,\n });\n\n this.observability.histogramMetric('patterns.duration_ms', pattern.durationMs, {\n method: pattern.method,\n path: pattern.path,\n });\n\n return ok(undefined);\n }\n\n getAggregates(windowMinutes: number): Result<AggregatePattern[], LearningError> {\n const result = this.storage.getAggregates(windowMinutes);\n if (!result.ok) {\n this.observability.error('Failed to get aggregates', { error: result.error });\n return fail(storageError('Failed to get aggregates', result.error));\n }\n return ok(result.value);\n }\n\n getHistory(\n endpoint: string,\n method: string,\n limit: number,\n ): Result<EndpointPattern[], LearningError> {\n const now = new Date();\n const past = new Date(now.getTime() - 24 * 60 * 60 * 1000);\n const patterns = this.storage.getPatterns(past, now);\n\n if (!patterns.ok) {\n return fail(storageError('Failed to get history', patterns.error));\n }\n\n const filtered = patterns.value\n .filter((p: EndpointPattern) => p.path === endpoint && p.method === method)\n .slice(-limit);\n\n return ok(filtered);\n }\n\n getStats(): Result<RegistryStats, LearningError> {\n const now = new Date();\n const past = new Date(0);\n const patterns = this.storage.getPatterns(past, now);\n\n if (!patterns.ok) {\n return fail(storageError('Failed to get stats', patterns.error));\n }\n\n const all = patterns.value;\n if (all.length === 0) {\n return ok({\n totalPatterns: 0,\n uniqueEndpoints: 0,\n oldestPattern: now,\n newestPattern: now,\n });\n }\n\n const uniqueEndpoints = new Set(all.map((p: EndpointPattern) => `${p.method}:${p.path}`));\n const timestamps = all.map((p: EndpointPattern) => p.timestamp.getTime());\n\n return ok({\n totalPatterns: all.length,\n uniqueEndpoints: uniqueEndpoints.size,\n oldestPattern: new Date(Math.min(...timestamps)),\n newestPattern: new Date(Math.max(...timestamps)),\n });\n }\n}\n","import { fail } from '@backendkit-labs/result';\n\nexport type LearningErrorTag =\n | 'STORAGE_ERROR'\n | 'INSUFFICIENT_DATA'\n | 'INVALID_CONFIG'\n | 'ANOMALY_DETECTION_FAILED'\n | 'FEEDBACK_LOOP_ALREADY_RUNNING'\n | 'FEEDBACK_LOOP_NOT_RUNNING';\n\nexport type LearningError = {\n readonly tag: LearningErrorTag;\n readonly message: string;\n readonly cause?: unknown;\n readonly required?: number;\n readonly actual?: number;\n readonly key?: string;\n readonly value?: unknown;\n};\n\nexport const storageError = (message: string, cause?: unknown): LearningError =>\n ({ tag: 'STORAGE_ERROR', message, cause });\n\nexport const insufficientData = (required: number, actual: number): LearningError =>\n ({ tag: 'INSUFFICIENT_DATA', message: `Insufficient data: required ${required}, got ${actual}`, required, actual });\n\nexport const invalidConfig = (key: string, value: unknown): LearningError =>\n ({ tag: 'INVALID_CONFIG', message: `Invalid config for key: ${key}`, key, value });\n\nexport const anomalyDetectionFailed = (message: string): LearningError =>\n ({ tag: 'ANOMALY_DETECTION_FAILED', message });\n\nexport const feedbackLoopAlreadyRunning = (): LearningError =>\n ({ tag: 'FEEDBACK_LOOP_ALREADY_RUNNING', message: 'Feedback loop is already running' });\n\nexport const feedbackLoopNotRunning = (): LearningError =>\n ({ tag: 'FEEDBACK_LOOP_NOT_RUNNING', message: 'Feedback loop is not running' });\n","import type { Result } from '@backendkit-labs/result';\nimport { EndpointPattern, AggregatePattern, AnomalySeverity } from '../types.js';\nimport { LearningError } from '../errors.js';\n\nexport interface IAnomalyDetector {\n analyze(\n current: EndpointPattern,\n baseline: AggregatePattern,\n ): Result<AnomalyReport | null, LearningError>;\n\n batchAnalyze(\n windowPatterns: EndpointPattern[],\n baselines: AggregatePattern[],\n ): Result<AnomalyReport[], LearningError>;\n}\n\nexport type AnomalyReport = {\n id: string;\n endpoint: string;\n method: string;\n severity: AnomalySeverity;\n metric: 'latency' | 'error_rate' | 'frequency' | 'unknown_endpoint';\n expectedValue: number;\n actualValue: number;\n deviation: number;\n detectedAt: Date;\n};\n\nexport type AnomalyDetectorConfig = {\n latencyStdDevThreshold: number;\n errorRateThreshold: number;\n frequencyDeviationThreshold: number;\n enableUnknownEndpointDetection: boolean;\n};\n\nexport const DEFAULT_ANOMALY_CONFIG: AnomalyDetectorConfig = {\n latencyStdDevThreshold: 2.5,\n errorRateThreshold: 0.05,\n frequencyDeviationThreshold: 3.0,\n enableUnknownEndpointDetection: true,\n};\n","import { ok, fail } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { v4 as uuid } from 'uuid';\nimport { IAnomalyDetector, AnomalyReport, AnomalyDetectorConfig, DEFAULT_ANOMALY_CONFIG } from './types.js';\nimport { EndpointPattern, AggregatePattern } from '../types.js';\nimport { LearningError, anomalyDetectionFailed } from '../errors.js';\n\nexport class AnomalyDetector implements IAnomalyDetector {\n private readonly config: AnomalyDetectorConfig;\n\n constructor(config?: Partial<AnomalyDetectorConfig>) {\n this.config = { ...DEFAULT_ANOMALY_CONFIG, ...config };\n }\n\n analyze(\n current: EndpointPattern,\n baseline: AggregatePattern,\n ): Result<AnomalyReport | null, LearningError> {\n try {\n const reports: AnomalyReport[] = [];\n\n // Latency anomaly: check if duration deviates from baseline\n if (baseline.count > 0) {\n const latencyDeviation =\n Math.abs(current.durationMs - baseline.avgDurationMs) /\n Math.max(this.stdDev(baseline), 1);\n\n if (latencyDeviation > this.config.latencyStdDevThreshold) {\n reports.push({\n id: uuid(),\n endpoint: current.path,\n method: current.method,\n severity: this.calculateSeverity(latencyDeviation),\n metric: 'latency',\n expectedValue: baseline.avgDurationMs,\n actualValue: current.durationMs,\n deviation: latencyDeviation,\n detectedAt: new Date(),\n });\n }\n }\n\n // Error rate anomaly: require at least 3 errors in the window\n // to avoid false positives from individual 500s\n if (current.statusCode >= 500 && baseline.errorCount >= 3) {\n const currentErrorRate = 1.0;\n if (currentErrorRate > baseline.errorRate * 2 && currentErrorRate > this.config.errorRateThreshold) {\n reports.push({\n id: uuid(),\n endpoint: current.path,\n method: current.method,\n severity: 'high',\n metric: 'error_rate',\n expectedValue: baseline.errorRate,\n actualValue: currentErrorRate,\n deviation: currentErrorRate / Math.max(baseline.errorRate, 0.001),\n detectedAt: new Date(),\n });\n }\n }\n\n return ok(reports.length > 0 ? reports[0] : null);\n } catch (e) {\n return fail(\n anomalyDetectionFailed(\n e instanceof Error ? e.message : 'Unknown anomaly detection error',\n ),\n );\n }\n }\n\n batchAnalyze(\n windowPatterns: EndpointPattern[],\n baselines: AggregatePattern[],\n ): Result<AnomalyReport[], LearningError> {\n try {\n const baselineMap = new Map<string, AggregatePattern>();\n for (const b of baselines) {\n baselineMap.set(`${b.method}:${b.path}`, b);\n }\n\n const reports: AnomalyReport[] = [];\n\n for (const pattern of windowPatterns) {\n const key = `${pattern.method}:${pattern.path}`;\n const baseline = baselineMap.get(key);\n\n if (!baseline) {\n if (this.config.enableUnknownEndpointDetection) {\n reports.push({\n id: uuid(),\n endpoint: pattern.path,\n method: pattern.method,\n severity: 'low',\n metric: 'unknown_endpoint',\n expectedValue: 0,\n actualValue: 1,\n deviation: 1,\n detectedAt: new Date(),\n });\n }\n continue;\n }\n\n const result = this.analyze(pattern, baseline);\n if (result.ok && result.value) {\n reports.push(result.value);\n }\n }\n\n return ok(reports);\n } catch (e) {\n return fail(\n anomalyDetectionFailed(\n e instanceof Error ? e.message : 'Unknown batch analysis error',\n ),\n );\n }\n }\n\n private calculateSeverity(deviation: number): 'low' | 'medium' | 'high' | 'critical' {\n if (deviation > 5) return 'critical';\n if (deviation > 4) return 'high';\n if (deviation > 3) return 'medium';\n return 'low';\n }\n\n private stdDev(baseline: AggregatePattern): number {\n return (baseline.p95Ms - baseline.p50Ms) / 2;\n }\n}\n","import type { Result } from '@backendkit-labs/result';\nimport { TunableConfig, AggregatePattern, AnomalyReport } from '../types.js';\nimport { LearningError } from '../errors.js';\n\nexport interface IConfigTuner {\n getCurrentConfig(): TunableConfig;\n tune(\n aggregates: AggregatePattern[],\n anomalies: AnomalyReport[],\n ): Result<TunableConfig, LearningError>;\n reset(): Result<TunableConfig, LearningError>;\n onConfigChange(callback: (config: TunableConfig) => void): void;\n}\n\nexport type ConfigTunerConfig = {\n minTimeoutMs: number;\n maxTimeoutMs: number;\n smoothingFactor: number;\n adjustmentStepMs: number;\n};\n\nexport const DEFAULT_TUNER_CONFIG: ConfigTunerConfig = {\n minTimeoutMs: 1000,\n maxTimeoutMs: 30000,\n smoothingFactor: 0.3,\n adjustmentStepMs: 500,\n};\n","import { ok, fail } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { IConfigTuner, ConfigTunerConfig, DEFAULT_TUNER_CONFIG } from './types.js';\nimport { TunableConfig, AggregatePattern, AnomalyReport } from '../types.js';\nimport { LearningError, storageError } from '../errors.js';\nimport { StorageAdapter } from '../persistence/storage-adapter.js';\nimport { ObservabilityAdapter } from '../observability/observability-adapter.js';\n\nconst DEFAULT_CONFIG: TunableConfig = {\n circuitBreaker: { failureThreshold: 50, openTimeoutMs: 30000 },\n bulkhead: { maxConcurrentCalls: 10 },\n httpClient: { timeoutMs: 10000, maxRetries: 3 },\n};\n\nexport class ConfigTuner implements IConfigTuner {\n private currentConfig: TunableConfig;\n private readonly config: ConfigTunerConfig;\n private listeners: Array<(config: TunableConfig) => void> = [];\n private lastChangeAt: number = 0;\n\n constructor(\n private readonly storage: StorageAdapter,\n private readonly observability: ObservabilityAdapter,\n tunerConfig?: Partial<ConfigTunerConfig>,\n ) {\n this.config = { ...DEFAULT_TUNER_CONFIG, ...tunerConfig };\n\n const loaded = this.storage.loadConfig();\n this.currentConfig = loaded.ok && loaded.value\n ? loaded.value\n : { ...DEFAULT_CONFIG };\n }\n\n getCurrentConfig(): TunableConfig {\n return {\n circuitBreaker: { ...this.currentConfig.circuitBreaker },\n bulkhead: { ...this.currentConfig.bulkhead },\n httpClient: { ...this.currentConfig.httpClient },\n };\n }\n\n tune(\n aggregates: AggregatePattern[],\n anomalies: AnomalyReport[],\n ): Result<TunableConfig, LearningError> {\n if (aggregates.length === 0) {\n return ok(this.getCurrentConfig());\n }\n\n const newConfig: TunableConfig = {\n circuitBreaker: { ...this.currentConfig.circuitBreaker },\n bulkhead: { ...this.currentConfig.bulkhead },\n httpClient: { ...this.currentConfig.httpClient },\n };\n const changedSections = new Set<keyof TunableConfig>();\n\n // Tune httpClient.timeoutMs based on p95 latency\n const maxP95 = Math.max(...aggregates.map((a) => a.p95Ms));\n const targetTimeout = Math.min(\n Math.max(maxP95 * 2, this.config.minTimeoutMs),\n this.config.maxTimeoutMs,\n );\n\n if (Math.abs(targetTimeout - newConfig.httpClient.timeoutMs) > this.config.adjustmentStepMs) {\n newConfig.httpClient.timeoutMs = this.smoothValue(newConfig.httpClient.timeoutMs, targetTimeout);\n changedSections.add('httpClient');\n }\n\n // Tune httpClient.maxRetries based on error rate\n const avgErrorRate =\n aggregates.reduce((sum, a) => sum + a.errorRate, 0) / aggregates.length;\n\n if (avgErrorRate > 0.1) {\n newConfig.httpClient.maxRetries = Math.min(newConfig.httpClient.maxRetries + 1, 5);\n changedSections.add('httpClient');\n } else if (avgErrorRate < 0.01 && newConfig.httpClient.maxRetries > 1) {\n newConfig.httpClient.maxRetries = Math.max(newConfig.httpClient.maxRetries - 1, 0);\n changedSections.add('httpClient');\n }\n\n // Tune circuitBreaker.failureThreshold based on anomalies (0–100 scale)\n const criticalAnomalies = anomalies.filter(\n (a) => a.severity === 'critical' || a.severity === 'high',\n ).length;\n\n if (criticalAnomalies > 0) {\n newConfig.circuitBreaker.failureThreshold = Math.max(\n this.currentConfig.circuitBreaker.failureThreshold - 10 * criticalAnomalies,\n 10,\n );\n changedSections.add('circuitBreaker');\n } else if (anomalies.length === 0) {\n newConfig.circuitBreaker.failureThreshold = Math.min(\n this.currentConfig.circuitBreaker.failureThreshold + 5,\n 80,\n );\n changedSections.add('circuitBreaker');\n }\n\n // Apply changes if any\n if (changedSections.size > 0) {\n const now = Date.now();\n if (now - this.lastChangeAt > 60_000) {\n this.currentConfig = newConfig;\n this.lastChangeAt = now;\n\n const saveResult = this.storage.saveConfig(newConfig);\n if (!saveResult.ok) {\n return fail(storageError('Failed to save config', saveResult.error));\n }\n\n const changes = Object.fromEntries(\n [...changedSections].map((s) => [s, newConfig[s]]),\n );\n this.observability.info('Config tuned', { changes });\n this.observability.incrementMetric('config.changes', 1);\n\n for (const listener of this.listeners) {\n listener(this.getCurrentConfig());\n }\n }\n }\n\n return ok(this.getCurrentConfig());\n }\n\n reset(): Result<TunableConfig, LearningError> {\n this.currentConfig = {\n circuitBreaker: { ...DEFAULT_CONFIG.circuitBreaker },\n bulkhead: { ...DEFAULT_CONFIG.bulkhead },\n httpClient: { ...DEFAULT_CONFIG.httpClient },\n };\n const saveResult = this.storage.saveConfig(this.currentConfig);\n if (!saveResult.ok) {\n return fail(storageError('Failed to reset config', saveResult.error));\n }\n\n this.observability.info('Config reset to defaults');\n for (const listener of this.listeners) {\n listener(this.getCurrentConfig());\n }\n\n return ok(this.getCurrentConfig());\n }\n\n onConfigChange(callback: (config: TunableConfig) => void): void {\n this.listeners.push(callback);\n }\n\n private smoothValue(current: number, target: number): number {\n return current + (target - current) * this.config.smoothingFactor;\n }\n}\n","import type { Result } from '@backendkit-labs/result';\nimport { LearningCycleEvent } from '../types.js';\nimport { LearningError } from '../errors.js';\n\nexport interface IFeedbackLoop {\n start(intervalMs?: number): void;\n stop(): void;\n isRunning(): boolean;\n runOnce(): Promise<Result<LearningCycleEvent, LearningError>>;\n onCycle(callback: (event: LearningCycleEvent) => void): void;\n}\n\nexport type FeedbackLoopConfig = {\n defaultIntervalMs: number;\n windowSizeMinutes: number;\n minSamplesBeforeTuning: number;\n cooldownBetweenChangesMs: number;\n};\n\nexport const DEFAULT_LOOP_CONFIG: FeedbackLoopConfig = {\n defaultIntervalMs: 60_000,\n windowSizeMinutes: 5,\n minSamplesBeforeTuning: 10,\n cooldownBetweenChangesMs: 120_000,\n};\n","import { ok, fail } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { v4 as uuid } from 'uuid';\nimport { IFeedbackLoop, FeedbackLoopConfig, DEFAULT_LOOP_CONFIG } from './types.js';\nimport { LearningCycleEvent, TunableConfig } from '../types.js';\nimport { LearningError, storageError } from '../errors.js';\nimport { IPatternRegistry } from '../pattern-registry/types.js';\nimport { IAnomalyDetector } from '../anomaly-detector/types.js';\nimport { IConfigTuner } from '../config-tuner/types.js';\nimport { StorageAdapter } from '../persistence/storage-adapter.js';\nimport { ObservabilityAdapter } from '../observability/observability-adapter.js';\n\nexport class FeedbackLoop implements IFeedbackLoop {\n private timerId: ReturnType<typeof setInterval> | null = null;\n private readonly config: FeedbackLoopConfig;\n private cycleListeners: Array<(event: LearningCycleEvent) => void> = [];\n\n constructor(\n private readonly patternRegistry: IPatternRegistry,\n private readonly anomalyDetector: IAnomalyDetector,\n private readonly configTuner: IConfigTuner,\n private readonly storage: StorageAdapter,\n private readonly observability: ObservabilityAdapter,\n loopConfig?: Partial<FeedbackLoopConfig>,\n ) {\n this.config = { ...DEFAULT_LOOP_CONFIG, ...loopConfig };\n }\n\n start(intervalMs?: number): void {\n if (this.timerId !== null) {\n this.observability.warn('Feedback loop already running, ignoring start');\n return;\n }\n\n const interval = intervalMs ?? this.config.defaultIntervalMs;\n this.observability.info('Feedback loop started', { intervalMs: interval });\n\n this.timerId = setInterval(() => {\n this.runOnce().then((result) => {\n if (!result.ok) {\n this.observability.error('Feedback loop cycle failed', {\n error: result.error,\n });\n }\n });\n }, interval);\n }\n\n stop(): void {\n if (this.timerId === null) {\n this.observability.warn('Feedback loop not running, ignoring stop');\n return;\n }\n\n clearInterval(this.timerId);\n this.timerId = null;\n this.observability.info('Feedback loop stopped');\n }\n\n isRunning(): boolean {\n return this.timerId !== null;\n }\n\n async runOnce(): Promise<Result<LearningCycleEvent, LearningError>> {\n const cycleId = uuid();\n const startTime = Date.now();\n\n this.observability.debug('Feedback cycle started', { cycleId });\n\n // Step 1: Collect patterns from the window\n const patternsResult = this.storage.getPatterns(\n new Date(Date.now() - this.config.windowSizeMinutes * 60_000),\n new Date(),\n );\n\n if (!patternsResult.ok) {\n return fail(storageError('Failed to collect patterns', patternsResult.error));\n }\n\n const patterns = patternsResult.value;\n if (patterns.length < this.config.minSamplesBeforeTuning) {\n this.observability.debug('Skipping cycle: insufficient samples', {\n actual: patterns.length,\n required: this.config.minSamplesBeforeTuning,\n });\n\n const skippedEvent: LearningCycleEvent = {\n cycleId,\n timestamp: new Date(),\n patternsProcessed: patterns.length,\n anomaliesFound: 0,\n configChanges: {},\n durationMs: Date.now() - startTime,\n };\n\n return ok(skippedEvent);\n }\n\n // Step 2: Get aggregates\n const aggregatesResult = this.patternRegistry.getAggregates(\n this.config.windowSizeMinutes,\n );\n\n if (!aggregatesResult.ok) {\n return fail(aggregatesResult.error);\n }\n\n const aggregates = aggregatesResult.value;\n\n // Step 3: Detect anomalies\n const anomaliesResult = this.anomalyDetector.batchAnalyze(patterns, aggregates);\n\n if (!anomaliesResult.ok) {\n return fail(anomaliesResult.error);\n }\n\n const anomalies = anomaliesResult.value;\n\n // Persist anomalies\n for (const anomaly of anomalies) {\n this.storage.saveAnomaly(anomaly);\n }\n\n // Log anomalies\n if (anomalies.length > 0) {\n this.observability.warn('Anomalies detected', {\n count: anomalies.length,\n severities: anomalies.map((a) => a.severity),\n });\n this.observability.incrementMetric('anomalies.detected', anomalies.length);\n }\n\n // Step 4: Tune config\n const tuneResult = this.configTuner.tune(aggregates, anomalies);\n\n if (!tuneResult.ok) {\n return fail(tuneResult.error);\n }\n\n const newConfig = tuneResult.value;\n const previousConfig = this.configTuner.getCurrentConfig();\n\n // Compute config changes (section-level comparison)\n const configChanges: Partial<TunableConfig> = {};\n for (const key of Object.keys(newConfig) as Array<keyof TunableConfig>) {\n if (JSON.stringify(newConfig[key]) !== JSON.stringify(previousConfig[key])) {\n (configChanges as Record<keyof TunableConfig, unknown>)[key] = newConfig[key];\n }\n }\n\n // Step 5: Build and persist cycle event\n const cycleEvent: LearningCycleEvent = {\n cycleId,\n timestamp: new Date(),\n patternsProcessed: patterns.length,\n anomaliesFound: anomalies.length,\n configChanges,\n durationMs: Date.now() - startTime,\n };\n\n const saveResult = this.storage.saveCycleEvent(cycleEvent);\n if (!saveResult.ok) {\n this.observability.error('Failed to save cycle event', { error: saveResult.error });\n return fail(saveResult.error);\n }\n\n // Emit to listeners\n for (const listener of this.cycleListeners) {\n listener(cycleEvent);\n }\n\n this.observability.info('Feedback cycle completed', {\n cycleId,\n patternsProcessed: cycleEvent.patternsProcessed,\n anomaliesFound: cycleEvent.anomaliesFound,\n durationMs: cycleEvent.durationMs,\n });\n\n this.observability.histogramMetric('cycle.duration_ms', cycleEvent.durationMs);\n this.observability.gaugeMetric('cycle.patterns_count', cycleEvent.patternsProcessed);\n\n return ok(cycleEvent);\n }\n\n onCycle(callback: (event: LearningCycleEvent) => void): void {\n this.cycleListeners.push(callback);\n }\n}\n","import { ok, fail } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { StorageAdapter } from './storage-adapter.js';\nimport {\n EndpointPattern,\n AggregatePattern,\n AnomalyReport,\n LearningCycleEvent,\n TunableConfig,\n} from '../types.js';\nimport { LearningError, storageError } from '../errors.js';\n\nconst DEFAULT_CONFIG: TunableConfig = {\n circuitBreaker: { failureThreshold: 50, openTimeoutMs: 30000 },\n bulkhead: { maxConcurrentCalls: 10 },\n httpClient: { timeoutMs: 10000, maxRetries: 3 },\n};\n\nfunction percentile(sorted: number[], p: number): number {\n if (sorted.length === 0) return 0;\n const index = Math.ceil((p / 100) * sorted.length) - 1;\n return sorted[Math.max(0, index)];\n}\n\nexport class InMemoryStorage implements StorageAdapter {\n private patterns: EndpointPattern[] = [];\n private anomalies: AnomalyReport[] = [];\n private config: TunableConfig = { ...DEFAULT_CONFIG };\n private cycles: LearningCycleEvent[] = [];\n\n savePattern(pattern: EndpointPattern): Result<void, LearningError> {\n try {\n this.patterns.push(pattern);\n return ok(undefined);\n } catch (e) {\n return fail(storageError('Failed to save pattern', e));\n }\n }\n\n getPatterns(windowStart: Date, windowEnd: Date): Result<EndpointPattern[], LearningError> {\n try {\n return ok(\n this.patterns.filter(\n (p) => p.timestamp >= windowStart && p.timestamp <= windowEnd,\n ),\n );\n } catch (e) {\n return fail(storageError('Failed to get patterns', e));\n }\n }\n\n getAggregates(windowMinutes: number): Result<AggregatePattern[], LearningError> {\n try {\n const cutoff = new Date(Date.now() - windowMinutes * 60_000);\n const recent = this.patterns.filter((p) => p.timestamp >= cutoff);\n\n const groups = new Map<string, EndpointPattern[]>();\n for (const p of recent) {\n const key = `${p.method}:${p.path}`;\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(p);\n }\n\n const aggregates: AggregatePattern[] = [];\n for (const [key, items] of groups) {\n const [method, path] = key.split(':');\n const durations = items.map((i) => i.durationMs).sort((a, b) => a - b);\n const errors = items.filter((i) => i.statusCode >= 500).length;\n\n aggregates.push({\n method,\n path,\n windowStart: cutoff,\n windowEnd: new Date(),\n count: items.length,\n avgDurationMs:\n durations.reduce((a, b) => a + b, 0) / durations.length,\n p50Ms: percentile(durations, 50),\n p95Ms: percentile(durations, 95),\n p99Ms: percentile(durations, 99),\n errorCount: errors,\n errorRate: errors / items.length,\n });\n }\n\n return ok(aggregates);\n } catch (e) {\n return fail(storageError('Failed to get aggregates', e));\n }\n }\n\n saveAnomaly(report: AnomalyReport): Result<void, LearningError> {\n try {\n this.anomalies.push(report);\n return ok(undefined);\n } catch (e) {\n return fail(storageError('Failed to save anomaly', e));\n }\n }\n\n getRecentAnomalies(limit: number): Result<AnomalyReport[], LearningError> {\n try {\n return ok(this.anomalies.slice(-limit).reverse());\n } catch (e) {\n return fail(storageError('Failed to get recent anomalies', e));\n }\n }\n\n saveConfig(config: TunableConfig): Result<void, LearningError> {\n try {\n this.config = {\n circuitBreaker: { ...config.circuitBreaker },\n bulkhead: { ...config.bulkhead },\n httpClient: { ...config.httpClient },\n };\n return ok(undefined);\n } catch (e) {\n return fail(storageError('Failed to save config', e));\n }\n }\n\n loadConfig(): Result<TunableConfig | null, LearningError> {\n try {\n return ok({\n circuitBreaker: { ...this.config.circuitBreaker },\n bulkhead: { ...this.config.bulkhead },\n httpClient: { ...this.config.httpClient },\n });\n } catch (e) {\n return fail(storageError('Failed to load config', e));\n }\n }\n\n saveCycleEvent(event: LearningCycleEvent): Result<void, LearningError> {\n try {\n this.cycles.push(event);\n return ok(undefined);\n } catch (e) {\n return fail(storageError('Failed to save cycle event', e));\n }\n }\n\n getLastCycleTime(): Result<Date | null, LearningError> {\n try {\n if (this.cycles.length === 0) return ok(null);\n return ok(this.cycles[this.cycles.length - 1].timestamp);\n } catch (e) {\n return fail(storageError('Failed to get last cycle time', e));\n }\n }\n\n prune(before: Date): Result<number, LearningError> {\n try {\n const beforeLen = this.patterns.length + this.anomalies.length;\n this.patterns = this.patterns.filter((p) => p.timestamp >= before);\n this.anomalies = this.anomalies.filter((a) => a.detectedAt >= before);\n const pruned = beforeLen - (this.patterns.length + this.anomalies.length);\n return ok(pruned);\n } catch (e) {\n return fail(storageError('Failed to prune', e));\n }\n }\n}\n","import { ObservabilityAdapter } from './observability-adapter.js';\n\nexport class NoopObservabilityAdapter implements ObservabilityAdapter {\n info(_msg: string, _meta?: Record<string, unknown>): void {}\n warn(_msg: string, _meta?: Record<string, unknown>): void {}\n error(_msg: string, _meta?: Record<string, unknown>): void {}\n debug(_msg: string, _meta?: Record<string, unknown>): void {}\n\n incrementMetric(_name: string, _value?: number, _tags?: Record<string, string>): void {}\n gaugeMetric(_name: string, _value: number, _tags?: Record<string, string>): void {}\n histogramMetric(_name: string, _value: number, _tags?: Record<string, string>): void {}\n}\n","import { ok } from '@backendkit-labs/result';\nimport type { Result } from '@backendkit-labs/result';\nimport { EndpointPattern, TunableConfig, LearningCycleEvent } from './types.js';\nimport { LearningError } from './errors.js';\nimport { IPatternRegistry, PatternRegistry } from './pattern-registry/index.js';\nimport { IAnomalyDetector, AnomalyDetector, AnomalyDetectorConfig } from './anomaly-detector/index.js';\nimport { IConfigTuner, ConfigTuner, ConfigTunerConfig } from './config-tuner/index.js';\nimport { IFeedbackLoop, FeedbackLoop, FeedbackLoopConfig } from './feedback-loop/index.js';\nimport { StorageAdapter, InMemoryStorage } from './persistence/index.js';\nimport { ObservabilityAdapter, NoopObservabilityAdapter } from './observability/index.js';\n\nexport type AutoLearningCoreOptions = {\n storage?: StorageAdapter;\n observability?: ObservabilityAdapter;\n anomalyConfig?: Partial<AnomalyDetectorConfig>;\n tunerConfig?: Partial<ConfigTunerConfig>;\n loopConfig?: Partial<FeedbackLoopConfig>;\n};\n\nexport class AutoLearningCore {\n private constructor(\n public readonly patternRegistry: IPatternRegistry,\n public readonly anomalyDetector: IAnomalyDetector,\n public readonly configTuner: IConfigTuner,\n public readonly feedbackLoop: IFeedbackLoop,\n public readonly storage: StorageAdapter,\n public readonly observability: ObservabilityAdapter,\n ) {}\n\n static create(options?: AutoLearningCoreOptions): AutoLearningCore {\n const storage = options?.storage ?? new InMemoryStorage();\n const obs = options?.observability ?? new NoopObservabilityAdapter();\n const registry = new PatternRegistry(storage, obs);\n const detector = new AnomalyDetector(options?.anomalyConfig);\n const tuner = new ConfigTuner(storage, obs, options?.tunerConfig);\n const loop = new FeedbackLoop(registry, detector, tuner, storage, obs, options?.loopConfig);\n\n return new AutoLearningCore(registry, detector, tuner, loop, storage, obs);\n }\n\n recordPattern(pattern: EndpointPattern): Result<void, LearningError> {\n return this.patternRegistry.record(pattern);\n }\n\n getCurrentConfig(): TunableConfig {\n return this.configTuner.getCurrentConfig();\n }\n\n startFeedbackLoop(intervalMs?: number): void {\n this.feedbackLoop.start(intervalMs);\n }\n\n stopFeedbackLoop(): void {\n this.feedbackLoop.stop();\n }\n\n isFeedbackLoopRunning(): boolean {\n return this.feedbackLoop.isRunning();\n }\n\n async runOnce(): Promise<Result<LearningCycleEvent, LearningError>> {\n return this.feedbackLoop.runOnce();\n }\n\n onConfigChange(callback: (config: TunableConfig) => void): void {\n this.configTuner.onConfigChange(callback);\n }\n\n onCycle(callback: (event: LearningCycleEvent) => void): void {\n this.feedbackLoop.onCycle(callback);\n }\n}\n","import {\n Injectable,\n NestInterceptor,\n ExecutionContext,\n CallHandler,\n Inject,\n} from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { Observable, tap } from 'rxjs';\nimport { AUTO_LEARN_METADATA, AUTO_LEARNING_INSTANCE } from './auto-learning.constants.js';\nimport { AutoLearnOptions } from './auto-learning.decorator.js';\nimport { AutoLearningCore } from '../core/auto-learning-core.js';\n\n@Injectable()\nexport class AutoLearningInterceptor implements NestInterceptor {\n constructor(\n private readonly reflector: Reflector,\n @Inject(AUTO_LEARNING_INSTANCE)\n private readonly core: AutoLearningCore,\n ) {}\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<any> {\n const options = this.reflector.get<AutoLearnOptions>(\n AUTO_LEARN_METADATA,\n context.getHandler(),\n );\n\n if (!options) {\n return next.handle();\n }\n\n const start = Date.now();\n const req = context.switchToHttp().getRequest();\n const { method, path } = this.extractRequestInfo(req);\n\n return next.handle().pipe(\n tap(() => {\n const duration = Date.now() - start;\n const status = context.switchToHttp().getResponse().statusCode;\n\n this.core.recordPattern({\n method,\n path,\n statusCode: status,\n durationMs: duration,\n timestamp: new Date(),\n metadata: options.customMetadata ? options.customMetadata(req) : undefined,\n });\n }),\n );\n }\n\n private extractRequestInfo(req: any): { method: string; path: string } {\n const method = req.method ?? 'UNKNOWN';\n const path = req.route?.path ?? req.path ?? req.url ?? '/';\n return { method, path };\n }\n}\n","export const AUTO_LEARNING_OPTIONS = Symbol('AUTO_LEARNING_OPTIONS');\nexport const AUTO_LEARNING_INSTANCE = Symbol('AUTO_LEARNING_INSTANCE');\nexport const AUTO_LEARN_METADATA = 'auto_learn_metadata';\n","import { Injectable, OnModuleInit, Inject } from '@nestjs/common';\nimport { ModuleRef } from '@nestjs/core';\nimport type { CircuitBreakerRegistry } from '@backendkit-labs/circuit-breaker';\nimport type { BulkheadRegistry } from '@backendkit-labs/bulkhead';\nimport { AutoLearningCore } from '../core/auto-learning-core.js';\nimport { TunableConfig } from '../core/types.js';\nimport { AUTO_LEARNING_INSTANCE, AUTO_LEARNING_OPTIONS } from './auto-learning.constants.js';\nimport type { AutoLearningModuleOptions } from './auto-learning.module.js';\n\n@Injectable()\nexport class AutoLearningAdaptersService implements OnModuleInit {\n private cbRegistry: CircuitBreakerRegistry | null = null;\n private bhRegistry: BulkheadRegistry | null = null;\n\n constructor(\n @Inject(AUTO_LEARNING_INSTANCE) private readonly core: AutoLearningCore,\n @Inject(AUTO_LEARNING_OPTIONS) private readonly options: AutoLearningModuleOptions,\n private readonly moduleRef: ModuleRef,\n ) {}\n\n async onModuleInit(): Promise<void> {\n await this.resolveRegistries();\n\n if (this.cbRegistry || this.bhRegistry) {\n this.core.onConfigChange((config) => this.applyConfig(config));\n }\n }\n\n private async resolveRegistries(): Promise<void> {\n if (this.options.adapters?.circuitBreaker) {\n try {\n const mod = await import('@backendkit-labs/circuit-breaker');\n this.cbRegistry = this.moduleRef.get(mod.CircuitBreakerRegistry, { strict: false });\n this.core.observability.info('CircuitBreakerRegistry adapter connected');\n } catch {\n this.core.observability.warn(\n 'adapters.circuitBreaker=true but CircuitBreakerModule is not imported — adapter skipped',\n );\n }\n }\n\n if (this.options.adapters?.bulkhead) {\n try {\n const mod = await import('@backendkit-labs/bulkhead');\n this.bhRegistry = this.moduleRef.get(mod.BulkheadRegistry, { strict: false });\n this.core.observability.info('BulkheadRegistry adapter connected');\n } catch {\n this.core.observability.warn(\n 'adapters.bulkhead=true but BulkheadModule is not imported — adapter skipped',\n );\n }\n }\n }\n\n private applyConfig(config: TunableConfig): void {\n if (this.cbRegistry) {\n const allMetrics = this.cbRegistry.getAllMetrics();\n for (const name of Object.keys(allMetrics)) {\n const cb = this.cbRegistry.getOrCreate({ name });\n cb.updateConfig({\n failureThreshold: config.circuitBreaker.failureThreshold,\n openTimeoutMs: config.circuitBreaker.openTimeoutMs,\n });\n }\n this.core.observability.debug('Circuit breaker config updated', {\n ...config.circuitBreaker,\n affected: Object.keys(allMetrics).length,\n });\n }\n\n if (this.bhRegistry) {\n const allMetrics = this.bhRegistry.getAllMetrics();\n for (const name of Object.keys(allMetrics)) {\n const bh = this.bhRegistry.getOrCreate({ name });\n bh.updateConfig({ maxConcurrentCalls: config.bulkhead.maxConcurrentCalls });\n }\n this.core.observability.debug('Bulkhead config updated', {\n ...config.bulkhead,\n affected: Object.keys(allMetrics).length,\n });\n }\n }\n}\n","import { LoggerService } from '@nestjs/common';\nimport { ObservabilityAdapter } from '../core/observability/observability-adapter.js';\n\nexport class BackendKitObservabilityAdapter implements ObservabilityAdapter {\n private readonly prefix = 'auto_learning';\n\n constructor(\n private readonly logger: LoggerService,\n private readonly metrics?: {\n increment?: (name: string, value?: number, tags?: Record<string, string>) => void;\n gauge?: (name: string, value: number, tags?: Record<string, string>) => void;\n histogram?: (name: string, value: number, tags?: Record<string, string>) => void;\n },\n ) {}\n\n info(msg: string, meta?: Record<string, unknown>): void {\n this.logger.log?.(`[AutoLearn] ${msg}`, meta);\n }\n\n warn(msg: string, meta?: Record<string, unknown>): void {\n this.logger.warn?.(`[AutoLearn] ${msg}`, meta);\n }\n\n error(msg: string, meta?: Record<string, unknown>): void {\n this.logger.error?.(`[AutoLearn] ${msg}`, meta);\n }\n\n debug(msg: string, meta?: Record<string, unknown>): void {\n this.logger.debug?.(`[AutoLearn] ${msg}`, meta);\n }\n\n incrementMetric(name: string, value = 1, tags?: Record<string, string>): void {\n this.metrics?.increment?.(`${this.prefix}.${name}`, value, tags);\n }\n\n gaugeMetric(name: string, value: number, tags?: Record<string, string>): void {\n this.metrics?.gauge?.(`${this.prefix}.${name}`, value, tags);\n }\n\n histogramMetric(name: string, value: number, tags?: Record<string, string>): void {\n this.metrics?.histogram?.(`${this.prefix}.${name}`, value, tags);\n }\n}\n","import { SetMetadata } from '@nestjs/common';\nimport { AUTO_LEARN_METADATA } from './auto-learning.constants.js';\n\nexport type AutoLearnOptions = {\n trackParams?: boolean;\n trackBody?: boolean;\n customMetadata?: (req: any) => Record<string, unknown>;\n};\n\nexport const AutoLearn = (options?: AutoLearnOptions): MethodDecorator =>\n SetMetadata(AUTO_LEARN_METADATA, options ?? {});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,iBAA+D;AAC/D,kBAAgC;;;ACDhC,oBAAyB;;;ACoBlB,IAAM,eAAe,CAAC,SAAiB,WAC3C,EAAE,KAAK,iBAAiB,SAAS,MAAM;AAQnC,IAAM,yBAAyB,CAAC,aACpC,EAAE,KAAK,4BAA4B,QAAQ;;;ADtBvC,IAAM,kBAAN,MAAkD;AAAA,EACvD,YACmB,SACA,eACjB;AAFiB;AACA;AAAA,EAChB;AAAA,EAFgB;AAAA,EACA;AAAA,EAGnB,OAAO,SAAuD;AAC5D,UAAM,SAAS,KAAK,QAAQ,YAAY,OAAO;AAC/C,QAAI,CAAC,OAAO,IAAI;AACd,WAAK,cAAc,MAAM,4BAA4B;AAAA,QACnD,OAAO,OAAO;AAAA,QACd,SAAS,EAAE,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,KAAK;AAAA,MACxD,CAAC;AACD,iBAAO,oBAAK,aAAa,0BAA0B,OAAO,KAAK,CAAC;AAAA,IAClE;AAEA,SAAK,cAAc,gBAAgB,qBAAqB,GAAG;AAAA,MACzD,QAAQ,QAAQ;AAAA,MAChB,MAAM,QAAQ;AAAA,IAChB,CAAC;AAED,SAAK,cAAc,gBAAgB,wBAAwB,QAAQ,YAAY;AAAA,MAC7E,QAAQ,QAAQ;AAAA,MAChB,MAAM,QAAQ;AAAA,IAChB,CAAC;AAED,eAAO,kBAAG,MAAS;AAAA,EACrB;AAAA,EAEA,cAAc,eAAkE;AAC9E,UAAM,SAAS,KAAK,QAAQ,cAAc,aAAa;AACvD,QAAI,CAAC,OAAO,IAAI;AACd,WAAK,cAAc,MAAM,4BAA4B,EAAE,OAAO,OAAO,MAAM,CAAC;AAC5E,iBAAO,oBAAK,aAAa,4BAA4B,OAAO,KAAK,CAAC;AAAA,IACpE;AACA,eAAO,kBAAG,OAAO,KAAK;AAAA,EACxB;AAAA,EAEA,WACE,UACA,QACA,OAC0C;AAC1C,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,OAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,KAAK,KAAK,GAAI;AACzD,UAAM,WAAW,KAAK,QAAQ,YAAY,MAAM,GAAG;AAEnD,QAAI,CAAC,SAAS,IAAI;AAChB,iBAAO,oBAAK,aAAa,yBAAyB,SAAS,KAAK,CAAC;AAAA,IACnE;AAEA,UAAM,WAAW,SAAS,MACvB,OAAO,CAAC,MAAuB,EAAE,SAAS,YAAY,EAAE,WAAW,MAAM,EACzE,MAAM,CAAC,KAAK;AAEf,eAAO,kBAAG,QAAQ;AAAA,EACpB;AAAA,EAEA,WAAiD;AAC/C,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,OAAO,oBAAI,KAAK,CAAC;AACvB,UAAM,WAAW,KAAK,QAAQ,YAAY,MAAM,GAAG;AAEnD,QAAI,CAAC,SAAS,IAAI;AAChB,iBAAO,oBAAK,aAAa,uBAAuB,SAAS,KAAK,CAAC;AAAA,IACjE;AAEA,UAAM,MAAM,SAAS;AACrB,QAAI,IAAI,WAAW,GAAG;AACpB,iBAAO,kBAAG;AAAA,QACR,eAAe;AAAA,QACf,iBAAiB;AAAA,QACjB,eAAe;AAAA,QACf,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,UAAM,kBAAkB,IAAI,IAAI,IAAI,IAAI,CAAC,MAAuB,GAAG,EAAE,MAAM,IAAI,EAAE,IAAI,EAAE,CAAC;AACxF,UAAM,aAAa,IAAI,IAAI,CAAC,MAAuB,EAAE,UAAU,QAAQ,CAAC;AAExE,eAAO,kBAAG;AAAA,MACR,eAAe,IAAI;AAAA,MACnB,iBAAiB,gBAAgB;AAAA,MACjC,eAAe,IAAI,KAAK,KAAK,IAAI,GAAG,UAAU,CAAC;AAAA,MAC/C,eAAe,IAAI,KAAK,KAAK,IAAI,GAAG,UAAU,CAAC;AAAA,IACjD,CAAC;AAAA,EACH;AACF;;;AE5DO,IAAM,yBAAgD;AAAA,EAC3D,wBAAwB;AAAA,EACxB,oBAAoB;AAAA,EACpB,6BAA6B;AAAA,EAC7B,gCAAgC;AAClC;;;ACxCA,IAAAC,iBAAyB;AAEzB,kBAA2B;AAKpB,IAAM,kBAAN,MAAkD;AAAA,EACtC;AAAA,EAEjB,YAAY,QAAyC;AACnD,SAAK,SAAS,EAAE,GAAG,wBAAwB,GAAG,OAAO;AAAA,EACvD;AAAA,EAEA,QACE,SACA,UAC6C;AAC7C,QAAI;AACF,YAAM,UAA2B,CAAC;AAGlC,UAAI,SAAS,QAAQ,GAAG;AACtB,cAAM,mBACJ,KAAK,IAAI,QAAQ,aAAa,SAAS,aAAa,IACpD,KAAK,IAAI,KAAK,OAAO,QAAQ,GAAG,CAAC;AAEnC,YAAI,mBAAmB,KAAK,OAAO,wBAAwB;AACzD,kBAAQ,KAAK;AAAA,YACX,QAAI,YAAAC,IAAK;AAAA,YACT,UAAU,QAAQ;AAAA,YAClB,QAAQ,QAAQ;AAAA,YAChB,UAAU,KAAK,kBAAkB,gBAAgB;AAAA,YACjD,QAAQ;AAAA,YACR,eAAe,SAAS;AAAA,YACxB,aAAa,QAAQ;AAAA,YACrB,WAAW;AAAA,YACX,YAAY,oBAAI,KAAK;AAAA,UACvB,CAAC;AAAA,QACH;AAAA,MACF;AAIA,UAAI,QAAQ,cAAc,OAAO,SAAS,cAAc,GAAG;AACzD,cAAM,mBAAmB;AACzB,YAAI,mBAAmB,SAAS,YAAY,KAAK,mBAAmB,KAAK,OAAO,oBAAoB;AAClG,kBAAQ,KAAK;AAAA,YACX,QAAI,YAAAA,IAAK;AAAA,YACT,UAAU,QAAQ;AAAA,YAClB,QAAQ,QAAQ;AAAA,YAChB,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,eAAe,SAAS;AAAA,YACxB,aAAa;AAAA,YACb,WAAW,mBAAmB,KAAK,IAAI,SAAS,WAAW,IAAK;AAAA,YAChE,YAAY,oBAAI,KAAK;AAAA,UACvB,CAAC;AAAA,QACH;AAAA,MACF;AAEA,iBAAO,mBAAG,QAAQ,SAAS,IAAI,QAAQ,CAAC,IAAI,IAAI;AAAA,IAClD,SAAS,GAAG;AACV,iBAAO;AAAA,QACL;AAAA,UACE,aAAa,QAAQ,EAAE,UAAU;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,aACE,gBACA,WACwC;AACxC,QAAI;AACF,YAAM,cAAc,oBAAI,IAA8B;AACtD,iBAAW,KAAK,WAAW;AACzB,oBAAY,IAAI,GAAG,EAAE,MAAM,IAAI,EAAE,IAAI,IAAI,CAAC;AAAA,MAC5C;AAEA,YAAM,UAA2B,CAAC;AAElC,iBAAW,WAAW,gBAAgB;AACpC,cAAM,MAAM,GAAG,QAAQ,MAAM,IAAI,QAAQ,IAAI;AAC7C,cAAM,WAAW,YAAY,IAAI,GAAG;AAEpC,YAAI,CAAC,UAAU;AACb,cAAI,KAAK,OAAO,gCAAgC;AAC9C,oBAAQ,KAAK;AAAA,cACX,QAAI,YAAAA,IAAK;AAAA,cACT,UAAU,QAAQ;AAAA,cAClB,QAAQ,QAAQ;AAAA,cAChB,UAAU;AAAA,cACV,QAAQ;AAAA,cACR,eAAe;AAAA,cACf,aAAa;AAAA,cACb,WAAW;AAAA,cACX,YAAY,oBAAI,KAAK;AAAA,YACvB,CAAC;AAAA,UACH;AACA;AAAA,QACF;AAEA,cAAM,SAAS,KAAK,QAAQ,SAAS,QAAQ;AAC7C,YAAI,OAAO,MAAM,OAAO,OAAO;AAC7B,kBAAQ,KAAK,OAAO,KAAK;AAAA,QAC3B;AAAA,MACF;AAEA,iBAAO,mBAAG,OAAO;AAAA,IACnB,SAAS,GAAG;AACV,iBAAO;AAAA,QACL;AAAA,UACE,aAAa,QAAQ,EAAE,UAAU;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,kBAAkB,WAA2D;AACnF,QAAI,YAAY,EAAG,QAAO;AAC1B,QAAI,YAAY,EAAG,QAAO;AAC1B,QAAI,YAAY,EAAG,QAAO;AAC1B,WAAO;AAAA,EACT;AAAA,EAEQ,OAAO,UAAoC;AACjD,YAAQ,SAAS,QAAQ,SAAS,SAAS;AAAA,EAC7C;AACF;;;AC7GO,IAAM,uBAA0C;AAAA,EACrD,cAAc;AAAA,EACd,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,kBAAkB;AACpB;;;AC1BA,IAAAC,iBAAyB;AAQzB,IAAM,iBAAgC;AAAA,EACpC,gBAAgB,EAAE,kBAAkB,IAAI,eAAe,IAAM;AAAA,EAC7D,UAAU,EAAE,oBAAoB,GAAG;AAAA,EACnC,YAAY,EAAE,WAAW,KAAO,YAAY,EAAE;AAChD;AAEO,IAAM,cAAN,MAA0C;AAAA,EAM/C,YACmB,SACA,eACjB,aACA;AAHiB;AACA;AAGjB,SAAK,SAAS,EAAE,GAAG,sBAAsB,GAAG,YAAY;AAExD,UAAM,SAAS,KAAK,QAAQ,WAAW;AACvC,SAAK,gBAAgB,OAAO,MAAM,OAAO,QACrC,OAAO,QACP,EAAE,GAAG,eAAe;AAAA,EAC1B;AAAA,EAVmB;AAAA,EACA;AAAA,EAPX;AAAA,EACS;AAAA,EACT,YAAoD,CAAC;AAAA,EACrD,eAAuB;AAAA,EAe/B,mBAAkC;AAChC,WAAO;AAAA,MACL,gBAAgB,EAAE,GAAG,KAAK,cAAc,eAAe;AAAA,MACvD,UAAU,EAAE,GAAG,KAAK,cAAc,SAAS;AAAA,MAC3C,YAAY,EAAE,GAAG,KAAK,cAAc,WAAW;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,KACE,YACA,WACsC;AACtC,QAAI,WAAW,WAAW,GAAG;AAC3B,iBAAO,mBAAG,KAAK,iBAAiB,CAAC;AAAA,IACnC;AAEA,UAAM,YAA2B;AAAA,MAC/B,gBAAgB,EAAE,GAAG,KAAK,cAAc,eAAe;AAAA,MACvD,UAAU,EAAE,GAAG,KAAK,cAAc,SAAS;AAAA,MAC3C,YAAY,EAAE,GAAG,KAAK,cAAc,WAAW;AAAA,IACjD;AACA,UAAM,kBAAkB,oBAAI,IAAyB;AAGrD,UAAM,SAAS,KAAK,IAAI,GAAG,WAAW,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACzD,UAAM,gBAAgB,KAAK;AAAA,MACzB,KAAK,IAAI,SAAS,GAAG,KAAK,OAAO,YAAY;AAAA,MAC7C,KAAK,OAAO;AAAA,IACd;AAEA,QAAI,KAAK,IAAI,gBAAgB,UAAU,WAAW,SAAS,IAAI,KAAK,OAAO,kBAAkB;AAC3F,gBAAU,WAAW,YAAY,KAAK,YAAY,UAAU,WAAW,WAAW,aAAa;AAC/F,sBAAgB,IAAI,YAAY;AAAA,IAClC;AAGA,UAAM,eACJ,WAAW,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,WAAW,CAAC,IAAI,WAAW;AAEnE,QAAI,eAAe,KAAK;AACtB,gBAAU,WAAW,aAAa,KAAK,IAAI,UAAU,WAAW,aAAa,GAAG,CAAC;AACjF,sBAAgB,IAAI,YAAY;AAAA,IAClC,WAAW,eAAe,QAAQ,UAAU,WAAW,aAAa,GAAG;AACrE,gBAAU,WAAW,aAAa,KAAK,IAAI,UAAU,WAAW,aAAa,GAAG,CAAC;AACjF,sBAAgB,IAAI,YAAY;AAAA,IAClC;AAGA,UAAM,oBAAoB,UAAU;AAAA,MAClC,CAAC,MAAM,EAAE,aAAa,cAAc,EAAE,aAAa;AAAA,IACrD,EAAE;AAEF,QAAI,oBAAoB,GAAG;AACzB,gBAAU,eAAe,mBAAmB,KAAK;AAAA,QAC/C,KAAK,cAAc,eAAe,mBAAmB,KAAK;AAAA,QAC1D;AAAA,MACF;AACA,sBAAgB,IAAI,gBAAgB;AAAA,IACtC,WAAW,UAAU,WAAW,GAAG;AACjC,gBAAU,eAAe,mBAAmB,KAAK;AAAA,QAC/C,KAAK,cAAc,eAAe,mBAAmB;AAAA,QACrD;AAAA,MACF;AACA,sBAAgB,IAAI,gBAAgB;AAAA,IACtC;AAGA,QAAI,gBAAgB,OAAO,GAAG;AAC5B,YAAM,MAAM,KAAK,IAAI;AACrB,UAAI,MAAM,KAAK,eAAe,KAAQ;AACpC,aAAK,gBAAgB;AACrB,aAAK,eAAe;AAEpB,cAAM,aAAa,KAAK,QAAQ,WAAW,SAAS;AACpD,YAAI,CAAC,WAAW,IAAI;AAClB,qBAAO,qBAAK,aAAa,yBAAyB,WAAW,KAAK,CAAC;AAAA,QACrE;AAEA,cAAM,UAAU,OAAO;AAAA,UACrB,CAAC,GAAG,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;AAAA,QACnD;AACA,aAAK,cAAc,KAAK,gBAAgB,EAAE,QAAQ,CAAC;AACnD,aAAK,cAAc,gBAAgB,kBAAkB,CAAC;AAEtD,mBAAW,YAAY,KAAK,WAAW;AACrC,mBAAS,KAAK,iBAAiB,CAAC;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAEA,eAAO,mBAAG,KAAK,iBAAiB,CAAC;AAAA,EACnC;AAAA,EAEA,QAA8C;AAC5C,SAAK,gBAAgB;AAAA,MACnB,gBAAgB,EAAE,GAAG,eAAe,eAAe;AAAA,MACnD,UAAU,EAAE,GAAG,eAAe,SAAS;AAAA,MACvC,YAAY,EAAE,GAAG,eAAe,WAAW;AAAA,IAC7C;AACA,UAAM,aAAa,KAAK,QAAQ,WAAW,KAAK,aAAa;AAC7D,QAAI,CAAC,WAAW,IAAI;AAClB,iBAAO,qBAAK,aAAa,0BAA0B,WAAW,KAAK,CAAC;AAAA,IACtE;AAEA,SAAK,cAAc,KAAK,0BAA0B;AAClD,eAAW,YAAY,KAAK,WAAW;AACrC,eAAS,KAAK,iBAAiB,CAAC;AAAA,IAClC;AAEA,eAAO,mBAAG,KAAK,iBAAiB,CAAC;AAAA,EACnC;AAAA,EAEA,eAAe,UAAiD;AAC9D,SAAK,UAAU,KAAK,QAAQ;AAAA,EAC9B;AAAA,EAEQ,YAAY,SAAiB,QAAwB;AAC3D,WAAO,WAAW,SAAS,WAAW,KAAK,OAAO;AAAA,EACpD;AACF;;;ACrIO,IAAM,sBAA0C;AAAA,EACrD,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EACxB,0BAA0B;AAC5B;;;ACxBA,IAAAC,iBAAyB;AAEzB,IAAAC,eAA2B;AAUpB,IAAM,eAAN,MAA4C;AAAA,EAKjD,YACmB,iBACA,iBACA,aACA,SACA,eACjB,YACA;AANiB;AACA;AACA;AACA;AACA;AAGjB,SAAK,SAAS,EAAE,GAAG,qBAAqB,GAAG,WAAW;AAAA,EACxD;AAAA,EARmB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EATX,UAAiD;AAAA,EACxC;AAAA,EACT,iBAA6D,CAAC;AAAA,EAatE,MAAM,YAA2B;AAC/B,QAAI,KAAK,YAAY,MAAM;AACzB,WAAK,cAAc,KAAK,+CAA+C;AACvE;AAAA,IACF;AAEA,UAAM,WAAW,cAAc,KAAK,OAAO;AAC3C,SAAK,cAAc,KAAK,yBAAyB,EAAE,YAAY,SAAS,CAAC;AAEzE,SAAK,UAAU,YAAY,MAAM;AAC/B,WAAK,QAAQ,EAAE,KAAK,CAAC,WAAW;AAC9B,YAAI,CAAC,OAAO,IAAI;AACd,eAAK,cAAc,MAAM,8BAA8B;AAAA,YACrD,OAAO,OAAO;AAAA,UAChB,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH,GAAG,QAAQ;AAAA,EACb;AAAA,EAEA,OAAa;AACX,QAAI,KAAK,YAAY,MAAM;AACzB,WAAK,cAAc,KAAK,0CAA0C;AAClE;AAAA,IACF;AAEA,kBAAc,KAAK,OAAO;AAC1B,SAAK,UAAU;AACf,SAAK,cAAc,KAAK,uBAAuB;AAAA,EACjD;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK,YAAY;AAAA,EAC1B;AAAA,EAEA,MAAM,UAA8D;AAClE,UAAM,cAAU,aAAAC,IAAK;AACrB,UAAM,YAAY,KAAK,IAAI;AAE3B,SAAK,cAAc,MAAM,0BAA0B,EAAE,QAAQ,CAAC;AAG9D,UAAM,iBAAiB,KAAK,QAAQ;AAAA,MAClC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,OAAO,oBAAoB,GAAM;AAAA,MAC5D,oBAAI,KAAK;AAAA,IACX;AAEA,QAAI,CAAC,eAAe,IAAI;AACtB,iBAAO,qBAAK,aAAa,8BAA8B,eAAe,KAAK,CAAC;AAAA,IAC9E;AAEA,UAAM,WAAW,eAAe;AAChC,QAAI,SAAS,SAAS,KAAK,OAAO,wBAAwB;AACxD,WAAK,cAAc,MAAM,wCAAwC;AAAA,QAC/D,QAAQ,SAAS;AAAA,QACjB,UAAU,KAAK,OAAO;AAAA,MACxB,CAAC;AAED,YAAM,eAAmC;AAAA,QACvC;AAAA,QACA,WAAW,oBAAI,KAAK;AAAA,QACpB,mBAAmB,SAAS;AAAA,QAC5B,gBAAgB;AAAA,QAChB,eAAe,CAAC;AAAA,QAChB,YAAY,KAAK,IAAI,IAAI;AAAA,MAC3B;AAEA,iBAAO,mBAAG,YAAY;AAAA,IACxB;AAGA,UAAM,mBAAmB,KAAK,gBAAgB;AAAA,MAC5C,KAAK,OAAO;AAAA,IACd;AAEA,QAAI,CAAC,iBAAiB,IAAI;AACxB,iBAAO,qBAAK,iBAAiB,KAAK;AAAA,IACpC;AAEA,UAAM,aAAa,iBAAiB;AAGpC,UAAM,kBAAkB,KAAK,gBAAgB,aAAa,UAAU,UAAU;AAE9E,QAAI,CAAC,gBAAgB,IAAI;AACvB,iBAAO,qBAAK,gBAAgB,KAAK;AAAA,IACnC;AAEA,UAAM,YAAY,gBAAgB;AAGlC,eAAW,WAAW,WAAW;AAC/B,WAAK,QAAQ,YAAY,OAAO;AAAA,IAClC;AAGA,QAAI,UAAU,SAAS,GAAG;AACxB,WAAK,cAAc,KAAK,sBAAsB;AAAA,QAC5C,OAAO,UAAU;AAAA,QACjB,YAAY,UAAU,IAAI,CAAC,MAAM,EAAE,QAAQ;AAAA,MAC7C,CAAC;AACD,WAAK,cAAc,gBAAgB,sBAAsB,UAAU,MAAM;AAAA,IAC3E;AAGA,UAAM,aAAa,KAAK,YAAY,KAAK,YAAY,SAAS;AAE9D,QAAI,CAAC,WAAW,IAAI;AAClB,iBAAO,qBAAK,WAAW,KAAK;AAAA,IAC9B;AAEA,UAAM,YAAY,WAAW;AAC7B,UAAM,iBAAiB,KAAK,YAAY,iBAAiB;AAGzD,UAAM,gBAAwC,CAAC;AAC/C,eAAW,OAAO,OAAO,KAAK,SAAS,GAAiC;AACtE,UAAI,KAAK,UAAU,UAAU,GAAG,CAAC,MAAM,KAAK,UAAU,eAAe,GAAG,CAAC,GAAG;AAC1E,QAAC,cAAuD,GAAG,IAAI,UAAU,GAAG;AAAA,MAC9E;AAAA,IACF;AAGA,UAAM,aAAiC;AAAA,MACrC;AAAA,MACA,WAAW,oBAAI,KAAK;AAAA,MACpB,mBAAmB,SAAS;AAAA,MAC5B,gBAAgB,UAAU;AAAA,MAC1B;AAAA,MACA,YAAY,KAAK,IAAI,IAAI;AAAA,IAC3B;AAEA,UAAM,aAAa,KAAK,QAAQ,eAAe,UAAU;AACzD,QAAI,CAAC,WAAW,IAAI;AAClB,WAAK,cAAc,MAAM,8BAA8B,EAAE,OAAO,WAAW,MAAM,CAAC;AAClF,iBAAO,qBAAK,WAAW,KAAK;AAAA,IAC9B;AAGA,eAAW,YAAY,KAAK,gBAAgB;AAC1C,eAAS,UAAU;AAAA,IACrB;AAEA,SAAK,cAAc,KAAK,4BAA4B;AAAA,MAClD;AAAA,MACA,mBAAmB,WAAW;AAAA,MAC9B,gBAAgB,WAAW;AAAA,MAC3B,YAAY,WAAW;AAAA,IACzB,CAAC;AAED,SAAK,cAAc,gBAAgB,qBAAqB,WAAW,UAAU;AAC7E,SAAK,cAAc,YAAY,wBAAwB,WAAW,iBAAiB;AAEnF,eAAO,mBAAG,UAAU;AAAA,EACtB;AAAA,EAEA,QAAQ,UAAqD;AAC3D,SAAK,eAAe,KAAK,QAAQ;AAAA,EACnC;AACF;;;AC3LA,IAAAC,iBAAyB;AAYzB,IAAMC,kBAAgC;AAAA,EACpC,gBAAgB,EAAE,kBAAkB,IAAI,eAAe,IAAM;AAAA,EAC7D,UAAU,EAAE,oBAAoB,GAAG;AAAA,EACnC,YAAY,EAAE,WAAW,KAAO,YAAY,EAAE;AAChD;AAEA,SAAS,WAAW,QAAkB,GAAmB;AACvD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,QAAQ,KAAK,KAAM,IAAI,MAAO,OAAO,MAAM,IAAI;AACrD,SAAO,OAAO,KAAK,IAAI,GAAG,KAAK,CAAC;AAClC;AAEO,IAAM,kBAAN,MAAgD;AAAA,EAC7C,WAA8B,CAAC;AAAA,EAC/B,YAA6B,CAAC;AAAA,EAC9B,SAAwB,EAAE,GAAGA,gBAAe;AAAA,EAC5C,SAA+B,CAAC;AAAA,EAExC,YAAY,SAAuD;AACjE,QAAI;AACF,WAAK,SAAS,KAAK,OAAO;AAC1B,iBAAO,mBAAG,MAAS;AAAA,IACrB,SAAS,GAAG;AACV,iBAAO,qBAAK,aAAa,0BAA0B,CAAC,CAAC;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,YAAY,aAAmB,WAA2D;AACxF,QAAI;AACF,iBAAO;AAAA,QACL,KAAK,SAAS;AAAA,UACZ,CAAC,MAAM,EAAE,aAAa,eAAe,EAAE,aAAa;AAAA,QACtD;AAAA,MACF;AAAA,IACF,SAAS,GAAG;AACV,iBAAO,qBAAK,aAAa,0BAA0B,CAAC,CAAC;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,cAAc,eAAkE;AAC9E,QAAI;AACF,YAAM,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,gBAAgB,GAAM;AAC3D,YAAM,SAAS,KAAK,SAAS,OAAO,CAAC,MAAM,EAAE,aAAa,MAAM;AAEhE,YAAM,SAAS,oBAAI,IAA+B;AAClD,iBAAW,KAAK,QAAQ;AACtB,cAAM,MAAM,GAAG,EAAE,MAAM,IAAI,EAAE,IAAI;AACjC,YAAI,CAAC,OAAO,IAAI,GAAG,EAAG,QAAO,IAAI,KAAK,CAAC,CAAC;AACxC,eAAO,IAAI,GAAG,EAAG,KAAK,CAAC;AAAA,MACzB;AAEA,YAAM,aAAiC,CAAC;AACxC,iBAAW,CAAC,KAAK,KAAK,KAAK,QAAQ;AACjC,cAAM,CAAC,QAAQ,IAAI,IAAI,IAAI,MAAM,GAAG;AACpC,cAAM,YAAY,MAAM,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACrE,cAAM,SAAS,MAAM,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,EAAE;AAExD,mBAAW,KAAK;AAAA,UACd;AAAA,UACA;AAAA,UACA,aAAa;AAAA,UACb,WAAW,oBAAI,KAAK;AAAA,UACpB,OAAO,MAAM;AAAA,UACb,eACE,UAAU,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,UAAU;AAAA,UACnD,OAAO,WAAW,WAAW,EAAE;AAAA,UAC/B,OAAO,WAAW,WAAW,EAAE;AAAA,UAC/B,OAAO,WAAW,WAAW,EAAE;AAAA,UAC/B,YAAY;AAAA,UACZ,WAAW,SAAS,MAAM;AAAA,QAC5B,CAAC;AAAA,MACH;AAEA,iBAAO,mBAAG,UAAU;AAAA,IACtB,SAAS,GAAG;AACV,iBAAO,qBAAK,aAAa,4BAA4B,CAAC,CAAC;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,YAAY,QAAoD;AAC9D,QAAI;AACF,WAAK,UAAU,KAAK,MAAM;AAC1B,iBAAO,mBAAG,MAAS;AAAA,IACrB,SAAS,GAAG;AACV,iBAAO,qBAAK,aAAa,0BAA0B,CAAC,CAAC;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,mBAAmB,OAAuD;AACxE,QAAI;AACF,iBAAO,mBAAG,KAAK,UAAU,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC;AAAA,IAClD,SAAS,GAAG;AACV,iBAAO,qBAAK,aAAa,kCAAkC,CAAC,CAAC;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,WAAW,QAAoD;AAC7D,QAAI;AACF,WAAK,SAAS;AAAA,QACZ,gBAAgB,EAAE,GAAG,OAAO,eAAe;AAAA,QAC3C,UAAU,EAAE,GAAG,OAAO,SAAS;AAAA,QAC/B,YAAY,EAAE,GAAG,OAAO,WAAW;AAAA,MACrC;AACA,iBAAO,mBAAG,MAAS;AAAA,IACrB,SAAS,GAAG;AACV,iBAAO,qBAAK,aAAa,yBAAyB,CAAC,CAAC;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,aAA0D;AACxD,QAAI;AACF,iBAAO,mBAAG;AAAA,QACR,gBAAgB,EAAE,GAAG,KAAK,OAAO,eAAe;AAAA,QAChD,UAAU,EAAE,GAAG,KAAK,OAAO,SAAS;AAAA,QACpC,YAAY,EAAE,GAAG,KAAK,OAAO,WAAW;AAAA,MAC1C,CAAC;AAAA,IACH,SAAS,GAAG;AACV,iBAAO,qBAAK,aAAa,yBAAyB,CAAC,CAAC;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,eAAe,OAAwD;AACrE,QAAI;AACF,WAAK,OAAO,KAAK,KAAK;AACtB,iBAAO,mBAAG,MAAS;AAAA,IACrB,SAAS,GAAG;AACV,iBAAO,qBAAK,aAAa,8BAA8B,CAAC,CAAC;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,mBAAuD;AACrD,QAAI;AACF,UAAI,KAAK,OAAO,WAAW,EAAG,YAAO,mBAAG,IAAI;AAC5C,iBAAO,mBAAG,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC,EAAE,SAAS;AAAA,IACzD,SAAS,GAAG;AACV,iBAAO,qBAAK,aAAa,iCAAiC,CAAC,CAAC;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,MAAM,QAA6C;AACjD,QAAI;AACF,YAAM,YAAY,KAAK,SAAS,SAAS,KAAK,UAAU;AACxD,WAAK,WAAW,KAAK,SAAS,OAAO,CAAC,MAAM,EAAE,aAAa,MAAM;AACjE,WAAK,YAAY,KAAK,UAAU,OAAO,CAAC,MAAM,EAAE,cAAc,MAAM;AACpE,YAAM,SAAS,aAAa,KAAK,SAAS,SAAS,KAAK,UAAU;AAClE,iBAAO,mBAAG,MAAM;AAAA,IAClB,SAAS,GAAG;AACV,iBAAO,qBAAK,aAAa,mBAAmB,CAAC,CAAC;AAAA,IAChD;AAAA,EACF;AACF;;;AChKO,IAAM,2BAAN,MAA+D;AAAA,EACpE,KAAK,MAAc,OAAuC;AAAA,EAAC;AAAA,EAC3D,KAAK,MAAc,OAAuC;AAAA,EAAC;AAAA,EAC3D,MAAM,MAAc,OAAuC;AAAA,EAAC;AAAA,EAC5D,MAAM,MAAc,OAAuC;AAAA,EAAC;AAAA,EAE5D,gBAAgB,OAAe,QAAiB,OAAsC;AAAA,EAAC;AAAA,EACvF,YAAY,OAAe,QAAgB,OAAsC;AAAA,EAAC;AAAA,EAClF,gBAAgB,OAAe,QAAgB,OAAsC;AAAA,EAAC;AACxF;;;ACQO,IAAM,mBAAN,MAAM,kBAAiB;AAAA,EACpB,YACU,iBACA,iBACA,aACA,cACA,SACA,eAChB;AANgB;AACA;AACA;AACA;AACA;AACA;AAAA,EACf;AAAA,EANe;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGlB,OAAO,OAAO,SAAqD;AACjE,UAAM,UAAU,SAAS,WAAW,IAAI,gBAAgB;AACxD,UAAM,MAAM,SAAS,iBAAiB,IAAI,yBAAyB;AACnE,UAAM,WAAW,IAAI,gBAAgB,SAAS,GAAG;AACjD,UAAM,WAAW,IAAI,gBAAgB,SAAS,aAAa;AAC3D,UAAM,QAAQ,IAAI,YAAY,SAAS,KAAK,SAAS,WAAW;AAChE,UAAM,OAAO,IAAI,aAAa,UAAU,UAAU,OAAO,SAAS,KAAK,SAAS,UAAU;AAE1F,WAAO,IAAI,kBAAiB,UAAU,UAAU,OAAO,MAAM,SAAS,GAAG;AAAA,EAC3E;AAAA,EAEA,cAAc,SAAuD;AACnE,WAAO,KAAK,gBAAgB,OAAO,OAAO;AAAA,EAC5C;AAAA,EAEA,mBAAkC;AAChC,WAAO,KAAK,YAAY,iBAAiB;AAAA,EAC3C;AAAA,EAEA,kBAAkB,YAA2B;AAC3C,SAAK,aAAa,MAAM,UAAU;AAAA,EACpC;AAAA,EAEA,mBAAyB;AACvB,SAAK,aAAa,KAAK;AAAA,EACzB;AAAA,EAEA,wBAAiC;AAC/B,WAAO,KAAK,aAAa,UAAU;AAAA,EACrC;AAAA,EAEA,MAAM,UAA8D;AAClE,WAAO,KAAK,aAAa,QAAQ;AAAA,EACnC;AAAA,EAEA,eAAe,UAAiD;AAC9D,SAAK,YAAY,eAAe,QAAQ;AAAA,EAC1C;AAAA,EAEA,QAAQ,UAAqD;AAC3D,SAAK,aAAa,QAAQ,QAAQ;AAAA,EACpC;AACF;;;ACvEA,oBAMO;AAEP,kBAAgC;;;ACRzB,IAAM,wBAAwB,uBAAO,uBAAuB;AAC5D,IAAM,yBAAyB,uBAAO,wBAAwB;AAC9D,IAAM,sBAAsB;;;ADY5B,IAAM,0BAAN,MAAyD;AAAA,EAC9D,YACmB,WAEA,MACjB;AAHiB;AAEA;AAAA,EAChB;AAAA,EAHgB;AAAA,EAEA;AAAA,EAGnB,UAAU,SAA2B,MAAoC;AACvE,UAAM,UAAU,KAAK,UAAU;AAAA,MAC7B;AAAA,MACA,QAAQ,WAAW;AAAA,IACrB;AAEA,QAAI,CAAC,SAAS;AACZ,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,UAAM,QAAQ,KAAK,IAAI;AACvB,UAAM,MAAM,QAAQ,aAAa,EAAE,WAAW;AAC9C,UAAM,EAAE,QAAQ,KAAK,IAAI,KAAK,mBAAmB,GAAG;AAEpD,WAAO,KAAK,OAAO,EAAE;AAAA,UACnB,iBAAI,MAAM;AACR,cAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,cAAM,SAAS,QAAQ,aAAa,EAAE,YAAY,EAAE;AAEpD,aAAK,KAAK,cAAc;AAAA,UACtB;AAAA,UACA;AAAA,UACA,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ,WAAW,oBAAI,KAAK;AAAA,UACpB,UAAU,QAAQ,iBAAiB,QAAQ,eAAe,GAAG,IAAI;AAAA,QACnE,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,mBAAmB,KAA4C;AACrE,UAAM,SAAS,IAAI,UAAU;AAC7B,UAAM,OAAO,IAAI,OAAO,QAAQ,IAAI,QAAQ,IAAI,OAAO;AACvD,WAAO,EAAE,QAAQ,KAAK;AAAA,EACxB;AACF;AA3Ca,0BAAN;AAAA,MADN,0BAAW;AAAA,EAIP,6CAAO,sBAAsB;AAAA,GAHrB;;;AEdb,IAAAC,iBAAiD;AAU1C,IAAM,8BAAN,MAA0D;AAAA,EAI/D,YACmD,MACD,SAC/B,WACjB;AAHiD;AACD;AAC/B;AAAA,EAChB;AAAA,EAHgD;AAAA,EACD;AAAA,EAC/B;AAAA,EANX,aAA4C;AAAA,EAC5C,aAAsC;AAAA,EAQ9C,MAAM,eAA8B;AAClC,UAAM,KAAK,kBAAkB;AAE7B,QAAI,KAAK,cAAc,KAAK,YAAY;AACtC,WAAK,KAAK,eAAe,CAAC,WAAW,KAAK,YAAY,MAAM,CAAC;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,MAAc,oBAAmC;AAC/C,QAAI,KAAK,QAAQ,UAAU,gBAAgB;AACzC,UAAI;AACF,cAAM,MAAM,MAAM,OAAO,kCAAkC;AAC3D,aAAK,aAAa,KAAK,UAAU,IAAI,IAAI,wBAAwB,EAAE,QAAQ,MAAM,CAAC;AAClF,aAAK,KAAK,cAAc,KAAK,0CAA0C;AAAA,MACzE,QAAQ;AACN,aAAK,KAAK,cAAc;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,QAAQ,UAAU,UAAU;AACnC,UAAI;AACF,cAAM,MAAM,MAAM,OAAO,2BAA2B;AACpD,aAAK,aAAa,KAAK,UAAU,IAAI,IAAI,kBAAkB,EAAE,QAAQ,MAAM,CAAC;AAC5E,aAAK,KAAK,cAAc,KAAK,oCAAoC;AAAA,MACnE,QAAQ;AACN,aAAK,KAAK,cAAc;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,YAAY,QAA6B;AAC/C,QAAI,KAAK,YAAY;AACnB,YAAM,aAAa,KAAK,WAAW,cAAc;AACjD,iBAAW,QAAQ,OAAO,KAAK,UAAU,GAAG;AAC1C,cAAM,KAAK,KAAK,WAAW,YAAY,EAAE,KAAK,CAAC;AAC/C,WAAG,aAAa;AAAA,UACd,kBAAkB,OAAO,eAAe;AAAA,UACxC,eAAe,OAAO,eAAe;AAAA,QACvC,CAAC;AAAA,MACH;AACA,WAAK,KAAK,cAAc,MAAM,kCAAkC;AAAA,QAC9D,GAAG,OAAO;AAAA,QACV,UAAU,OAAO,KAAK,UAAU,EAAE;AAAA,MACpC,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,YAAY;AACnB,YAAM,aAAa,KAAK,WAAW,cAAc;AACjD,iBAAW,QAAQ,OAAO,KAAK,UAAU,GAAG;AAC1C,cAAM,KAAK,KAAK,WAAW,YAAY,EAAE,KAAK,CAAC;AAC/C,WAAG,aAAa,EAAE,oBAAoB,OAAO,SAAS,mBAAmB,CAAC;AAAA,MAC5E;AACA,WAAK,KAAK,cAAc,MAAM,2BAA2B;AAAA,QACvD,GAAG,OAAO;AAAA,QACV,UAAU,OAAO,KAAK,UAAU,EAAE;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAxEa,8BAAN;AAAA,MADN,2BAAW;AAAA,EAMP,8CAAO,sBAAsB;AAAA,EAC7B,8CAAO,qBAAqB;AAAA,GANpB;;;ACPN,IAAM,iCAAN,MAAqE;AAAA,EAG1E,YACmB,QACA,SAKjB;AANiB;AACA;AAAA,EAKhB;AAAA,EANgB;AAAA,EACA;AAAA,EAJF,SAAS;AAAA,EAW1B,KAAK,KAAa,MAAsC;AACtD,SAAK,OAAO,MAAM,eAAe,GAAG,IAAI,IAAI;AAAA,EAC9C;AAAA,EAEA,KAAK,KAAa,MAAsC;AACtD,SAAK,OAAO,OAAO,eAAe,GAAG,IAAI,IAAI;AAAA,EAC/C;AAAA,EAEA,MAAM,KAAa,MAAsC;AACvD,SAAK,OAAO,QAAQ,eAAe,GAAG,IAAI,IAAI;AAAA,EAChD;AAAA,EAEA,MAAM,KAAa,MAAsC;AACvD,SAAK,OAAO,QAAQ,eAAe,GAAG,IAAI,IAAI;AAAA,EAChD;AAAA,EAEA,gBAAgB,MAAc,QAAQ,GAAG,MAAqC;AAC5E,SAAK,SAAS,YAAY,GAAG,KAAK,MAAM,IAAI,IAAI,IAAI,OAAO,IAAI;AAAA,EACjE;AAAA,EAEA,YAAY,MAAc,OAAe,MAAqC;AAC5E,SAAK,SAAS,QAAQ,GAAG,KAAK,MAAM,IAAI,IAAI,IAAI,OAAO,IAAI;AAAA,EAC7D;AAAA,EAEA,gBAAgB,MAAc,OAAe,MAAqC;AAChF,SAAK,SAAS,YAAY,GAAG,KAAK,MAAM,IAAI,IAAI,IAAI,OAAO,IAAI;AAAA,EACjE;AACF;;;AfbO,IAAM,qBAAN,MAAyB;AAAA,EAC9B,OAAO,QAAQ,UAAqC,CAAC,GAAkB;AACrE,UAAM,YAAwB;AAAA,MAC5B;AAAA,QACE,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,YAAY,CAAC,SAAoC;AAC/C,cAAI;AAEJ,cAAI,KAAK,eAAe,QAAQ;AAC9B,4BAAgB,IAAI;AAAA,cAClB,KAAK,cAAc;AAAA,cACnB,KAAK,cAAc;AAAA,YACrB;AAAA,UACF;AAEA,iBAAO,iBAAiB,OAAO;AAAA,YAC7B,GAAG,KAAK;AAAA,YACR;AAAA,UACF,CAAC;AAAA,QACH;AAAA,QACA,QAAQ,CAAC,qBAAqB;AAAA,MAChC;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA,SAAS,CAAC,sBAAsB;AAAA,MAChC,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAxCa,qBAAN;AAAA,MADN,uBAAO,CAAC,CAAC;AAAA,GACG;;;AgB7Bb,IAAAC,iBAA4B;AASrB,IAAM,YAAY,CAAC,gBACxB,4BAAY,qBAAqB,WAAW,CAAC,CAAC;","names":["import_common","import_result","uuid","import_result","import_result","import_uuid","uuid","import_result","DEFAULT_CONFIG","import_common","import_common"]}
@@ -1,3 +1,3 @@
1
- export { h as AUTO_LEARNING_INSTANCE, i as AUTO_LEARNING_OPTIONS, j as AUTO_LEARN_METADATA, l as AutoLearn, m as AutoLearnOptions, p as AutoLearningModule, q as AutoLearningModuleOptions } from '../index-DnQ9xssn.cjs';
1
+ export { h as AUTO_LEARNING_INSTANCE, i as AUTO_LEARNING_OPTIONS, j as AUTO_LEARN_METADATA, l as AutoLearn, m as AutoLearnOptions, p as AutoLearningModule, q as AutoLearningModuleOptions } from '../index-CtdA-dkB.cjs';
2
2
  import '@nestjs/common';
3
3
  import '@backendkit-labs/result';
@@ -1,3 +1,3 @@
1
- export { h as AUTO_LEARNING_INSTANCE, i as AUTO_LEARNING_OPTIONS, j as AUTO_LEARN_METADATA, l as AutoLearn, m as AutoLearnOptions, p as AutoLearningModule, q as AutoLearningModuleOptions } from '../index-DnQ9xssn.js';
1
+ export { h as AUTO_LEARNING_INSTANCE, i as AUTO_LEARNING_OPTIONS, j as AUTO_LEARN_METADATA, l as AutoLearn, m as AutoLearnOptions, p as AutoLearningModule, q as AutoLearningModuleOptions } from '../index-CtdA-dkB.js';
2
2
  import '@nestjs/common';
3
3
  import '@backendkit-labs/result';
@@ -215,11 +215,9 @@ var DEFAULT_TUNER_CONFIG = {
215
215
  // src/core/config-tuner/config-tuner.ts
216
216
  import { ok as ok3, fail as fail3 } from "@backendkit-labs/result";
217
217
  var DEFAULT_CONFIG = {
218
- timeoutMs: 1e4,
219
- maxRetries: 3,
220
- circuitBreakerThreshold: 0.5,
221
- circuitBreakerHalfOpenAfterMs: 3e4,
222
- bulkheadMaxConcurrent: 10
218
+ circuitBreaker: { failureThreshold: 50, openTimeoutMs: 3e4 },
219
+ bulkhead: { maxConcurrentCalls: 10 },
220
+ httpClient: { timeoutMs: 1e4, maxRetries: 3 }
223
221
  };
224
222
  var ConfigTuner = class {
225
223
  constructor(storage, observability, tunerConfig) {
@@ -236,51 +234,56 @@ var ConfigTuner = class {
236
234
  listeners = [];
237
235
  lastChangeAt = 0;
238
236
  getCurrentConfig() {
239
- return { ...this.currentConfig };
237
+ return {
238
+ circuitBreaker: { ...this.currentConfig.circuitBreaker },
239
+ bulkhead: { ...this.currentConfig.bulkhead },
240
+ httpClient: { ...this.currentConfig.httpClient }
241
+ };
240
242
  }
241
243
  tune(aggregates, anomalies) {
242
244
  if (aggregates.length === 0) {
243
245
  return ok3(this.getCurrentConfig());
244
246
  }
245
- const newConfig = { ...this.currentConfig };
246
- const changes = {};
247
+ const newConfig = {
248
+ circuitBreaker: { ...this.currentConfig.circuitBreaker },
249
+ bulkhead: { ...this.currentConfig.bulkhead },
250
+ httpClient: { ...this.currentConfig.httpClient }
251
+ };
252
+ const changedSections = /* @__PURE__ */ new Set();
247
253
  const maxP95 = Math.max(...aggregates.map((a) => a.p95Ms));
248
254
  const targetTimeout = Math.min(
249
255
  Math.max(maxP95 * 2, this.config.minTimeoutMs),
250
256
  this.config.maxTimeoutMs
251
257
  );
252
- if (Math.abs(targetTimeout - newConfig.timeoutMs) > this.config.adjustmentStepMs) {
253
- newConfig.timeoutMs = this.smoothValue(
254
- newConfig.timeoutMs,
255
- targetTimeout
256
- );
257
- changes.timeoutMs = newConfig.timeoutMs;
258
+ if (Math.abs(targetTimeout - newConfig.httpClient.timeoutMs) > this.config.adjustmentStepMs) {
259
+ newConfig.httpClient.timeoutMs = this.smoothValue(newConfig.httpClient.timeoutMs, targetTimeout);
260
+ changedSections.add("httpClient");
258
261
  }
259
262
  const avgErrorRate = aggregates.reduce((sum, a) => sum + a.errorRate, 0) / aggregates.length;
260
263
  if (avgErrorRate > 0.1) {
261
- newConfig.maxRetries = Math.min(newConfig.maxRetries + 1, 5);
262
- changes.maxRetries = newConfig.maxRetries;
263
- } else if (avgErrorRate < 0.01 && newConfig.maxRetries > 1) {
264
- newConfig.maxRetries = Math.max(newConfig.maxRetries - 1, 0);
265
- changes.maxRetries = newConfig.maxRetries;
264
+ newConfig.httpClient.maxRetries = Math.min(newConfig.httpClient.maxRetries + 1, 5);
265
+ changedSections.add("httpClient");
266
+ } else if (avgErrorRate < 0.01 && newConfig.httpClient.maxRetries > 1) {
267
+ newConfig.httpClient.maxRetries = Math.max(newConfig.httpClient.maxRetries - 1, 0);
268
+ changedSections.add("httpClient");
266
269
  }
267
270
  const criticalAnomalies = anomalies.filter(
268
271
  (a) => a.severity === "critical" || a.severity === "high"
269
272
  ).length;
270
273
  if (criticalAnomalies > 0) {
271
- newConfig.circuitBreakerThreshold = Math.max(
272
- this.currentConfig.circuitBreakerThreshold - 0.1 * criticalAnomalies,
273
- 0.1
274
+ newConfig.circuitBreaker.failureThreshold = Math.max(
275
+ this.currentConfig.circuitBreaker.failureThreshold - 10 * criticalAnomalies,
276
+ 10
274
277
  );
275
- changes.circuitBreakerThreshold = newConfig.circuitBreakerThreshold;
278
+ changedSections.add("circuitBreaker");
276
279
  } else if (anomalies.length === 0) {
277
- newConfig.circuitBreakerThreshold = Math.min(
278
- this.currentConfig.circuitBreakerThreshold + 0.05,
279
- 0.8
280
+ newConfig.circuitBreaker.failureThreshold = Math.min(
281
+ this.currentConfig.circuitBreaker.failureThreshold + 5,
282
+ 80
280
283
  );
281
- changes.circuitBreakerThreshold = newConfig.circuitBreakerThreshold;
284
+ changedSections.add("circuitBreaker");
282
285
  }
283
- if (Object.keys(changes).length > 0) {
286
+ if (changedSections.size > 0) {
284
287
  const now = Date.now();
285
288
  if (now - this.lastChangeAt > 6e4) {
286
289
  this.currentConfig = newConfig;
@@ -289,6 +292,9 @@ var ConfigTuner = class {
289
292
  if (!saveResult.ok) {
290
293
  return fail3(storageError("Failed to save config", saveResult.error));
291
294
  }
295
+ const changes = Object.fromEntries(
296
+ [...changedSections].map((s) => [s, newConfig[s]])
297
+ );
292
298
  this.observability.info("Config tuned", { changes });
293
299
  this.observability.incrementMetric("config.changes", 1);
294
300
  for (const listener of this.listeners) {
@@ -299,7 +305,11 @@ var ConfigTuner = class {
299
305
  return ok3(this.getCurrentConfig());
300
306
  }
301
307
  reset() {
302
- this.currentConfig = { ...DEFAULT_CONFIG };
308
+ this.currentConfig = {
309
+ circuitBreaker: { ...DEFAULT_CONFIG.circuitBreaker },
310
+ bulkhead: { ...DEFAULT_CONFIG.bulkhead },
311
+ httpClient: { ...DEFAULT_CONFIG.httpClient }
312
+ };
303
313
  const saveResult = this.storage.saveConfig(this.currentConfig);
304
314
  if (!saveResult.ok) {
305
315
  return fail3(storageError("Failed to reset config", saveResult.error));
@@ -431,9 +441,8 @@ var FeedbackLoop = class {
431
441
  const newConfig = tuneResult.value;
432
442
  const previousConfig = this.configTuner.getCurrentConfig();
433
443
  const configChanges = {};
434
- const configKeys = Object.keys(newConfig);
435
- for (const key of configKeys) {
436
- if (newConfig[key] !== previousConfig[key]) {
444
+ for (const key of Object.keys(newConfig)) {
445
+ if (JSON.stringify(newConfig[key]) !== JSON.stringify(previousConfig[key])) {
437
446
  configChanges[key] = newConfig[key];
438
447
  }
439
448
  }
@@ -471,11 +480,9 @@ var FeedbackLoop = class {
471
480
  // src/core/persistence/in-memory-storage.ts
472
481
  import { ok as ok5, fail as fail5 } from "@backendkit-labs/result";
473
482
  var DEFAULT_CONFIG2 = {
474
- timeoutMs: 1e4,
475
- maxRetries: 3,
476
- circuitBreakerThreshold: 0.5,
477
- circuitBreakerHalfOpenAfterMs: 3e4,
478
- bulkheadMaxConcurrent: 10
483
+ circuitBreaker: { failureThreshold: 50, openTimeoutMs: 3e4 },
484
+ bulkhead: { maxConcurrentCalls: 10 },
485
+ httpClient: { timeoutMs: 1e4, maxRetries: 3 }
479
486
  };
480
487
  function percentile(sorted, p) {
481
488
  if (sorted.length === 0) return 0;
@@ -557,7 +564,11 @@ var InMemoryStorage = class {
557
564
  }
558
565
  saveConfig(config) {
559
566
  try {
560
- this.config = { ...config };
567
+ this.config = {
568
+ circuitBreaker: { ...config.circuitBreaker },
569
+ bulkhead: { ...config.bulkhead },
570
+ httpClient: { ...config.httpClient }
571
+ };
561
572
  return ok5(void 0);
562
573
  } catch (e) {
563
574
  return fail5(storageError("Failed to save config", e));
@@ -565,7 +576,11 @@ var InMemoryStorage = class {
565
576
  }
566
577
  loadConfig() {
567
578
  try {
568
- return ok5(this.config);
579
+ return ok5({
580
+ circuitBreaker: { ...this.config.circuitBreaker },
581
+ bulkhead: { ...this.config.bulkhead },
582
+ httpClient: { ...this.config.httpClient }
583
+ });
569
584
  } catch (e) {
570
585
  return fail5(storageError("Failed to load config", e));
571
586
  }
@@ -725,6 +740,83 @@ AutoLearningInterceptor = __decorateClass([
725
740
  __decorateParam(1, Inject(AUTO_LEARNING_INSTANCE))
726
741
  ], AutoLearningInterceptor);
727
742
 
743
+ // src/nestjs/auto-learning-adapters.service.ts
744
+ import { Injectable as Injectable2, Inject as Inject2 } from "@nestjs/common";
745
+ var AutoLearningAdaptersService = class {
746
+ constructor(core, options, moduleRef) {
747
+ this.core = core;
748
+ this.options = options;
749
+ this.moduleRef = moduleRef;
750
+ }
751
+ core;
752
+ options;
753
+ moduleRef;
754
+ cbRegistry = null;
755
+ bhRegistry = null;
756
+ async onModuleInit() {
757
+ await this.resolveRegistries();
758
+ if (this.cbRegistry || this.bhRegistry) {
759
+ this.core.onConfigChange((config) => this.applyConfig(config));
760
+ }
761
+ }
762
+ async resolveRegistries() {
763
+ if (this.options.adapters?.circuitBreaker) {
764
+ try {
765
+ const mod = await import("@backendkit-labs/circuit-breaker");
766
+ this.cbRegistry = this.moduleRef.get(mod.CircuitBreakerRegistry, { strict: false });
767
+ this.core.observability.info("CircuitBreakerRegistry adapter connected");
768
+ } catch {
769
+ this.core.observability.warn(
770
+ "adapters.circuitBreaker=true but CircuitBreakerModule is not imported \u2014 adapter skipped"
771
+ );
772
+ }
773
+ }
774
+ if (this.options.adapters?.bulkhead) {
775
+ try {
776
+ const mod = await import("@backendkit-labs/bulkhead");
777
+ this.bhRegistry = this.moduleRef.get(mod.BulkheadRegistry, { strict: false });
778
+ this.core.observability.info("BulkheadRegistry adapter connected");
779
+ } catch {
780
+ this.core.observability.warn(
781
+ "adapters.bulkhead=true but BulkheadModule is not imported \u2014 adapter skipped"
782
+ );
783
+ }
784
+ }
785
+ }
786
+ applyConfig(config) {
787
+ if (this.cbRegistry) {
788
+ const allMetrics = this.cbRegistry.getAllMetrics();
789
+ for (const name of Object.keys(allMetrics)) {
790
+ const cb = this.cbRegistry.getOrCreate({ name });
791
+ cb.updateConfig({
792
+ failureThreshold: config.circuitBreaker.failureThreshold,
793
+ openTimeoutMs: config.circuitBreaker.openTimeoutMs
794
+ });
795
+ }
796
+ this.core.observability.debug("Circuit breaker config updated", {
797
+ ...config.circuitBreaker,
798
+ affected: Object.keys(allMetrics).length
799
+ });
800
+ }
801
+ if (this.bhRegistry) {
802
+ const allMetrics = this.bhRegistry.getAllMetrics();
803
+ for (const name of Object.keys(allMetrics)) {
804
+ const bh = this.bhRegistry.getOrCreate({ name });
805
+ bh.updateConfig({ maxConcurrentCalls: config.bulkhead.maxConcurrentCalls });
806
+ }
807
+ this.core.observability.debug("Bulkhead config updated", {
808
+ ...config.bulkhead,
809
+ affected: Object.keys(allMetrics).length
810
+ });
811
+ }
812
+ }
813
+ };
814
+ AutoLearningAdaptersService = __decorateClass([
815
+ Injectable2(),
816
+ __decorateParam(0, Inject2(AUTO_LEARNING_INSTANCE)),
817
+ __decorateParam(1, Inject2(AUTO_LEARNING_OPTIONS))
818
+ ], AutoLearningAdaptersService);
819
+
728
820
  // src/nestjs/backend-kit-observability-adapter.ts
729
821
  var BackendKitObservabilityAdapter = class {
730
822
  constructor(logger, metrics) {
@@ -785,7 +877,8 @@ var AutoLearningModule = class {
785
877
  {
786
878
  provide: APP_INTERCEPTOR,
787
879
  useClass: AutoLearningInterceptor
788
- }
880
+ },
881
+ AutoLearningAdaptersService
789
882
  ];
790
883
  return {
791
884
  module: AutoLearningModule,