@backendkit-labs/auto-learning 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../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":["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":"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","names":["ok","fail","ok","fail","ok","fail","ok","fail","ok","fail","uuid","uuid","fail","ok","ok","fail","DEFAULT_CONFIG","ok","fail","Injectable","Inject","Injectable","Inject"]}
1
+ {"version":3,"sources":["../../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":["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 /**\n * Set to false to skip auto-starting the feedback loop on bootstrap.\n * Call core.startFeedbackLoop() manually when ready. Default: true.\n */\n autoStart?: boolean;\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, windowEnd?: Date): Result<AggregatePattern[], LearningError> {\n const result = this.storage.getAggregates(windowMinutes, windowEnd);\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\n // Avoid Math.min/max spread — throws RangeError on large arrays.\n let oldest = all[0].timestamp.getTime();\n let newest = oldest;\n for (const p of all) {\n const t = p.timestamp.getTime();\n if (t < oldest) oldest = t;\n if (t > newest) newest = t;\n }\n\n return ok({\n totalPatterns: all.length,\n uniqueEndpoints: uniqueEndpoints.size,\n oldestPattern: new Date(oldest),\n newestPattern: new Date(newest),\n });\n }\n}\n","export type StorageError = {\n readonly tag: 'STORAGE_ERROR';\n readonly message: string;\n readonly cause?: unknown;\n};\n\nexport type InsufficientDataError = {\n readonly tag: 'INSUFFICIENT_DATA';\n readonly message: string;\n readonly required: number;\n readonly actual: number;\n};\n\nexport type InvalidConfigError = {\n readonly tag: 'INVALID_CONFIG';\n readonly message: string;\n readonly key: string;\n readonly value: unknown;\n};\n\nexport type AnomalyDetectionFailedError = {\n readonly tag: 'ANOMALY_DETECTION_FAILED';\n readonly message: string;\n};\n\nexport type FeedbackLoopAlreadyRunningError = {\n readonly tag: 'FEEDBACK_LOOP_ALREADY_RUNNING';\n readonly message: string;\n};\n\nexport type FeedbackLoopNotRunningError = {\n readonly tag: 'FEEDBACK_LOOP_NOT_RUNNING';\n readonly message: string;\n};\n\nexport type LearningError =\n | StorageError\n | InsufficientDataError\n | InvalidConfigError\n | AnomalyDetectionFailedError\n | FeedbackLoopAlreadyRunningError\n | FeedbackLoopNotRunningError;\n\nexport const storageError = (message: string, cause?: unknown): StorageError =>\n ({ tag: 'STORAGE_ERROR', message, cause });\n\nexport const insufficientData = (required: number, actual: number): InsufficientDataError =>\n ({ tag: 'INSUFFICIENT_DATA', message: `Insufficient data: required ${required}, got ${actual}`, required, actual });\n\nexport const invalidConfig = (key: string, value: unknown): InvalidConfigError =>\n ({ tag: 'INVALID_CONFIG', message: `Invalid config for key: ${key}`, key, value });\n\nexport const anomalyDetectionFailed = (message: string): AnomalyDetectionFailedError =>\n ({ tag: 'ANOMALY_DETECTION_FAILED', message });\n\nexport const feedbackLoopAlreadyRunning = (): FeedbackLoopAlreadyRunningError =>\n ({ tag: 'FEEDBACK_LOOP_ALREADY_RUNNING', message: 'Feedback loop is already running' });\n\nexport const feedbackLoopNotRunning = (): FeedbackLoopNotRunningError =>\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[], 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[], 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: alert when a 5xx arrives at an endpoint that is\n // normally healthy (baseline errorRate below threshold). Avoids noise\n // from already-degraded endpoints.\n if (current.statusCode >= 500 && baseline.errorRate < 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: 1,\n deviation: 1 / Math.max(baseline.errorRate, 0.001),\n detectedAt: new Date(),\n });\n }\n\n return ok(reports);\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 const seenUnknown = new Set<string>();\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 && !seenUnknown.has(key)) {\n seenUnknown.add(key);\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) {\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 /** Minimum milliseconds between successive config applications. Default: 60_000 */\n cooldownMs: number;\n};\n\nexport const DEFAULT_TUNER_CONFIG: ConfigTunerConfig = {\n minTimeoutMs: 1000,\n maxTimeoutMs: 30000,\n smoothingFactor: 0.3,\n adjustmentStepMs: 500,\n cooldownMs: 60_000,\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 = this.computeNext(aggregates, anomalies);\n const changedSections = this.diffSections(this.currentConfig, newConfig);\n\n if (changedSections.size > 0) {\n const now = Date.now();\n if (now - this.lastChangeAt > this.config.cooldownMs) {\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 return () => {\n const idx = this.listeners.indexOf(callback);\n if (idx >= 0) this.listeners.splice(idx, 1);\n };\n }\n\n // Pure computation — derives the next config from aggregates and anomalies\n // without mutating any state or applying cooldown checks.\n private computeNext(\n aggregates: AggregatePattern[],\n anomalies: AnomalyReport[],\n ): TunableConfig {\n const next: TunableConfig = {\n circuitBreaker: { ...this.currentConfig.circuitBreaker },\n bulkhead: { ...this.currentConfig.bulkhead },\n httpClient: { ...this.currentConfig.httpClient },\n };\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 - next.httpClient.timeoutMs) > this.config.adjustmentStepMs) {\n next.httpClient.timeoutMs = this.smoothValue(next.httpClient.timeoutMs, targetTimeout);\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 next.httpClient.maxRetries = Math.min(next.httpClient.maxRetries + 1, 5);\n } else if (avgErrorRate < 0.01 && next.httpClient.maxRetries > 1) {\n next.httpClient.maxRetries = Math.max(next.httpClient.maxRetries - 1, 0);\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 next.circuitBreaker.failureThreshold = Math.max(\n this.currentConfig.circuitBreaker.failureThreshold - 10 * criticalAnomalies,\n 10,\n );\n } else if (anomalies.length === 0) {\n next.circuitBreaker.failureThreshold = Math.min(\n this.currentConfig.circuitBreaker.failureThreshold + 5,\n 80,\n );\n }\n\n return next;\n }\n\n private diffSections(prev: TunableConfig, next: TunableConfig): Set<keyof TunableConfig> {\n const changed = new Set<keyof TunableConfig>();\n for (const key of Object.keys(next) as Array<keyof TunableConfig>) {\n if (JSON.stringify(next[key]) !== JSON.stringify(prev[key])) {\n changed.add(key);\n }\n }\n return changed;\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 /** Hours to retain patterns and anomalies. Records older than this are pruned after each cycle. Default: 24 */\n pruneTtlHours: number;\n};\n\nexport const DEFAULT_LOOP_CONFIG: FeedbackLoopConfig = {\n defaultIntervalMs: 60_000,\n windowSizeMinutes: 5,\n minSamplesBeforeTuning: 10,\n pruneTtlHours: 24,\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 isProcessing = false;\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(async () => {\n if (this.isProcessing) {\n this.observability.warn('Skipping cycle: previous cycle still running');\n return;\n }\n this.isProcessing = true;\n try {\n const result = await this.runOnce();\n if (!result.ok) {\n this.observability.error('Feedback loop cycle failed', { error: result.error });\n }\n } finally {\n this.isProcessing = false;\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 // Capture a single timestamp so both getPatterns and getAggregates use the same window end.\n const windowEnd = new Date();\n const windowStart = new Date(windowEnd.getTime() - this.config.windowSizeMinutes * 60_000);\n\n this.observability.debug('Feedback cycle started', { cycleId });\n\n // Step 1: Collect patterns from the window\n const patternsResult = this.storage.getPatterns(windowStart, windowEnd);\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 (same windowEnd for consistency with step 1)\n const aggregatesResult = this.patternRegistry.getAggregates(\n this.config.windowSizeMinutes,\n windowEnd,\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 const saveAnomalyResult = this.storage.saveAnomaly(anomaly);\n if (!saveAnomalyResult.ok) {\n this.observability.warn('Failed to persist anomaly', { error: saveAnomalyResult.error });\n }\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 previousConfig = this.configTuner.getCurrentConfig();\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\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 // Step 6: Prune records older than the configured TTL\n const pruneCutoff = new Date(Date.now() - this.config.pruneTtlHours * 3_600_000);\n const pruneResult = this.storage.prune(pruneCutoff);\n if (pruneResult.ok && pruneResult.value > 0) {\n this.observability.debug('Pruned old records', { count: pruneResult.value });\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 return () => {\n const idx = this.cycleListeners.indexOf(callback);\n if (idx >= 0) this.cycleListeners.splice(idx, 1);\n };\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\nexport type InMemoryStorageLimits = {\n /** Max patterns kept in memory. Oldest dropped when exceeded (FIFO). Default: 10_000 */\n maxPatterns: number;\n /** Max anomaly reports kept. Oldest dropped when exceeded. Default: 1_000 */\n maxAnomalies: number;\n /** Max cycle events kept. Oldest dropped when exceeded. Default: 1_000 */\n maxCycles: number;\n};\n\nconst DEFAULT_LIMITS: InMemoryStorageLimits = {\n maxPatterns: 10_000,\n maxAnomalies: 1_000,\n maxCycles: 1_000,\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 private readonly limits: InMemoryStorageLimits;\n\n constructor(limits?: Partial<InMemoryStorageLimits>) {\n this.limits = { ...DEFAULT_LIMITS, ...limits };\n }\n\n savePattern(pattern: EndpointPattern): Result<void, LearningError> {\n try {\n this.patterns.push(pattern);\n if (this.patterns.length > this.limits.maxPatterns) {\n this.patterns.shift();\n }\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, windowEnd?: Date): Result<AggregatePattern[], LearningError> {\n try {\n const end = windowEnd ?? new Date();\n const cutoff = new Date(end.getTime() - windowMinutes * 60_000);\n const recent = this.patterns.filter((p) => p.timestamp >= cutoff && p.timestamp <= end);\n\n // Use \\x00 as separator so parameterized paths like /users/:id are preserved.\n type GroupEntry = { method: string; path: string; items: EndpointPattern[] };\n const groups = new Map<string, GroupEntry>();\n for (const p of recent) {\n const key = `${p.method}\\x00${p.path}`;\n let g = groups.get(key);\n if (!g) { g = { method: p.method, path: p.path, items: [] }; groups.set(key, g); }\n g.items.push(p);\n }\n\n const aggregates: AggregatePattern[] = [];\n for (const { method, path, items } of groups.values()) {\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: end,\n count: items.length,\n avgDurationMs: 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 if (this.anomalies.length > this.limits.maxAnomalies) {\n this.anomalies.shift();\n }\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 if (this.cycles.length > this.limits.maxCycles) {\n this.cycles.shift();\n }\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 return this.configTuner.onConfigChange(callback);\n }\n\n onCycle(callback: (event: LearningCycleEvent) => void): () => void {\n return 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 if (context.getType() !== 'http') return next.handle();\n\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 const record = (statusCode: number) => {\n const result = this.core.recordPattern({\n method,\n path,\n statusCode,\n durationMs: Date.now() - start,\n timestamp: new Date(),\n metadata: this.buildMetadata(req, options),\n });\n if (!result.ok) {\n this.core.observability.error('Failed to record pattern', { error: result.error });\n }\n };\n\n return next.handle().pipe(\n tap({\n next: () => record(context.switchToHttp().getResponse().statusCode),\n error: (err: unknown) => {\n const status =\n typeof (err as any)?.getStatus === 'function'\n ? (err as any).getStatus()\n : ((err as any)?.status ?? 500);\n record(status);\n },\n }),\n );\n }\n\n private extractRequestInfo(req: any): { method: string; path: string } {\n const method = req.method ?? 'UNKNOWN';\n const raw = req.route?.path ?? req.path ?? req.url ?? '/';\n const path = raw.split('?')[0];\n return { method, path };\n }\n\n private buildMetadata(req: any, options: AutoLearnOptions): Record<string, unknown> | undefined {\n const meta: Record<string, unknown> = {};\n if (options.trackParams && req.params) meta.params = req.params;\n if (options.trackBody && req.body) meta.body = req.body;\n if (options.customMetadata) Object.assign(meta, options.customMetadata(req));\n return Object.keys(meta).length > 0 ? meta : undefined;\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, OnApplicationBootstrap, OnModuleDestroy, 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\n implements OnModuleInit, OnApplicationBootstrap, OnModuleDestroy\n{\n private cbRegistry: CircuitBreakerRegistry | null = null;\n private bhRegistry: BulkheadRegistry | null = null;\n private unsubConfigChange: (() => void) | 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.unsubConfigChange = this.core.onConfigChange((config) => this.applyConfig(config));\n }\n }\n\n onApplicationBootstrap(): void {\n if (this.options.autoStart !== false) {\n this.core.startFeedbackLoop(this.options.intervalMs);\n }\n }\n\n onModuleDestroy(): void {\n if (this.core.isFeedbackLoopRunning()) {\n this.core.stopFeedbackLoop();\n }\n this.unsubConfigChange?.();\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":"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","names":["ok","fail","ok","fail","ok","fail","ok","fail","ok","fail","uuid","uuid","fail","ok","ok","fail","DEFAULT_CONFIG","ok","fail","Injectable","Inject","Injectable","Inject"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backendkit-labs/auto-learning",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": {
6
6
  "name": "BackendKit Labs",