@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.
@@ -57,20 +57,40 @@ type LearningCycleEvent = {
57
57
  durationMs: number;
58
58
  };
59
59
 
60
- type LearningErrorTag = 'STORAGE_ERROR' | 'INSUFFICIENT_DATA' | 'INVALID_CONFIG' | 'ANOMALY_DETECTION_FAILED' | 'FEEDBACK_LOOP_ALREADY_RUNNING' | 'FEEDBACK_LOOP_NOT_RUNNING';
61
- type LearningError = {
62
- readonly tag: LearningErrorTag;
60
+ type StorageError = {
61
+ readonly tag: 'STORAGE_ERROR';
63
62
  readonly message: string;
64
63
  readonly cause?: unknown;
65
- readonly required?: number;
66
- readonly actual?: number;
67
- readonly key?: string;
68
- readonly value?: unknown;
69
64
  };
65
+ type InsufficientDataError = {
66
+ readonly tag: 'INSUFFICIENT_DATA';
67
+ readonly message: string;
68
+ readonly required: number;
69
+ readonly actual: number;
70
+ };
71
+ type InvalidConfigError = {
72
+ readonly tag: 'INVALID_CONFIG';
73
+ readonly message: string;
74
+ readonly key: string;
75
+ readonly value: unknown;
76
+ };
77
+ type AnomalyDetectionFailedError = {
78
+ readonly tag: 'ANOMALY_DETECTION_FAILED';
79
+ readonly message: string;
80
+ };
81
+ type FeedbackLoopAlreadyRunningError = {
82
+ readonly tag: 'FEEDBACK_LOOP_ALREADY_RUNNING';
83
+ readonly message: string;
84
+ };
85
+ type FeedbackLoopNotRunningError = {
86
+ readonly tag: 'FEEDBACK_LOOP_NOT_RUNNING';
87
+ readonly message: string;
88
+ };
89
+ type LearningError = StorageError | InsufficientDataError | InvalidConfigError | AnomalyDetectionFailedError | FeedbackLoopAlreadyRunningError | FeedbackLoopNotRunningError;
70
90
 
71
91
  interface IPatternRegistry {
72
92
  record(pattern: EndpointPattern): Result<void, LearningError>;
73
- getAggregates(windowMinutes: number): Result<AggregatePattern[], LearningError>;
93
+ getAggregates(windowMinutes: number, windowEnd?: Date): Result<AggregatePattern[], LearningError>;
74
94
  getHistory(endpoint: string, method: string, limit: number): Result<EndpointPattern[], LearningError>;
75
95
  getStats(): Result<RegistryStats, LearningError>;
76
96
  }
@@ -84,7 +104,7 @@ type RegistryStats = {
84
104
  interface StorageAdapter {
85
105
  savePattern(pattern: EndpointPattern): Result<void, LearningError>;
86
106
  getPatterns(windowStart: Date, windowEnd: Date): Result<EndpointPattern[], LearningError>;
87
- getAggregates(windowMinutes: number): Result<AggregatePattern[], LearningError>;
107
+ getAggregates(windowMinutes: number, windowEnd?: Date): Result<AggregatePattern[], LearningError>;
88
108
  saveAnomaly(report: AnomalyReport$1): Result<void, LearningError>;
89
109
  getRecentAnomalies(limit: number): Result<AnomalyReport$1[], LearningError>;
90
110
  saveConfig(config: TunableConfig): Result<void, LearningError>;
@@ -105,7 +125,7 @@ interface ObservabilityAdapter {
105
125
  }
106
126
 
107
127
  interface IAnomalyDetector {
108
- analyze(current: EndpointPattern, baseline: AggregatePattern): Result<AnomalyReport | null, LearningError>;
128
+ analyze(current: EndpointPattern, baseline: AggregatePattern): Result<AnomalyReport[], LearningError>;
109
129
  batchAnalyze(windowPatterns: EndpointPattern[], baselines: AggregatePattern[]): Result<AnomalyReport[], LearningError>;
110
130
  }
111
131
  type AnomalyReport = {
@@ -131,13 +151,15 @@ interface IConfigTuner {
131
151
  getCurrentConfig(): TunableConfig;
132
152
  tune(aggregates: AggregatePattern[], anomalies: AnomalyReport$1[]): Result<TunableConfig, LearningError>;
133
153
  reset(): Result<TunableConfig, LearningError>;
134
- onConfigChange(callback: (config: TunableConfig) => void): void;
154
+ onConfigChange(callback: (config: TunableConfig) => void): () => void;
135
155
  }
136
156
  type ConfigTunerConfig = {
137
157
  minTimeoutMs: number;
138
158
  maxTimeoutMs: number;
139
159
  smoothingFactor: number;
140
160
  adjustmentStepMs: number;
161
+ /** Minimum milliseconds between successive config applications. Default: 60_000 */
162
+ cooldownMs: number;
141
163
  };
142
164
  declare const DEFAULT_TUNER_CONFIG: ConfigTunerConfig;
143
165
 
@@ -146,13 +168,14 @@ interface IFeedbackLoop {
146
168
  stop(): void;
147
169
  isRunning(): boolean;
148
170
  runOnce(): Promise<Result<LearningCycleEvent, LearningError>>;
149
- onCycle(callback: (event: LearningCycleEvent) => void): void;
171
+ onCycle(callback: (event: LearningCycleEvent) => void): () => void;
150
172
  }
151
173
  type FeedbackLoopConfig = {
152
174
  defaultIntervalMs: number;
153
175
  windowSizeMinutes: number;
154
176
  minSamplesBeforeTuning: number;
155
- cooldownBetweenChangesMs: number;
177
+ /** Hours to retain patterns and anomalies. Records older than this are pruned after each cycle. Default: 24 */
178
+ pruneTtlHours: number;
156
179
  };
157
180
  declare const DEFAULT_LOOP_CONFIG: FeedbackLoopConfig;
158
181
 
@@ -178,14 +201,17 @@ declare class AutoLearningCore {
178
201
  stopFeedbackLoop(): void;
179
202
  isFeedbackLoopRunning(): boolean;
180
203
  runOnce(): Promise<Result<LearningCycleEvent, LearningError>>;
181
- onConfigChange(callback: (config: TunableConfig) => void): void;
182
- onCycle(callback: (event: LearningCycleEvent) => void): void;
204
+ onConfigChange(callback: (config: TunableConfig) => void): () => void;
205
+ onCycle(callback: (event: LearningCycleEvent) => void): () => void;
183
206
  }
184
207
 
185
208
  type AutoLearningModuleOptions = {
186
209
  intervalMs?: number;
187
- storage?: 'memory' | 'redis' | 'sql';
188
- redisUrl?: string;
210
+ /**
211
+ * Set to false to skip auto-starting the feedback loop on bootstrap.
212
+ * Call core.startFeedbackLoop() manually when ready. Default: true.
213
+ */
214
+ autoStart?: boolean;
189
215
  observability?: {
190
216
  logger?: LoggerService;
191
217
  metrics?: {
@@ -215,4 +241,4 @@ declare const AUTO_LEARNING_OPTIONS: unique symbol;
215
241
  declare const AUTO_LEARNING_INSTANCE: unique symbol;
216
242
  declare const AUTO_LEARN_METADATA = "auto_learn_metadata";
217
243
 
218
- export { type AggregatePattern as A, type ConfigTunerConfig as C, DEFAULT_ANOMALY_CONFIG as D, type EndpointPattern as E, type FeedbackLoopConfig as F, type IPatternRegistry as I, type LearningError as L, type ObservabilityAdapter as O, type RegistryStats as R, type StorageAdapter as S, type TunableConfig as T, type IAnomalyDetector as a, type AnomalyDetectorConfig as b, type AnomalyReport as c, type IConfigTuner as d, type AnomalyReport$1 as e, type IFeedbackLoop as f, type LearningCycleEvent as g, AUTO_LEARNING_INSTANCE as h, AUTO_LEARNING_OPTIONS as i, AUTO_LEARN_METADATA as j, type AnomalySeverity as k, AutoLearn as l, type AutoLearnOptions as m, AutoLearningCore as n, type AutoLearningCoreOptions as o, AutoLearningModule as p, type AutoLearningModuleOptions as q, DEFAULT_LOOP_CONFIG as r, DEFAULT_TUNER_CONFIG as s };
244
+ export { type AggregatePattern as A, type ConfigTunerConfig as C, DEFAULT_ANOMALY_CONFIG as D, type EndpointPattern as E, type FeedbackLoopConfig as F, type IPatternRegistry as I, type LearningError as L, type ObservabilityAdapter as O, type RegistryStats as R, type StorageAdapter as S, type TunableConfig as T, type IAnomalyDetector as a, type AnomalyDetectorConfig as b, type AnomalyReport as c, type IConfigTuner as d, type AnomalyReport$1 as e, type IFeedbackLoop as f, type LearningCycleEvent as g, AUTO_LEARNING_INSTANCE as h, AUTO_LEARNING_OPTIONS as i, AUTO_LEARN_METADATA as j, type AnomalyDetectionFailedError as k, type AnomalySeverity as l, AutoLearn as m, type AutoLearnOptions as n, AutoLearningCore as o, type AutoLearningCoreOptions as p, AutoLearningModule as q, type AutoLearningModuleOptions as r, DEFAULT_LOOP_CONFIG as s, DEFAULT_TUNER_CONFIG as t, type FeedbackLoopAlreadyRunningError as u, type FeedbackLoopNotRunningError as v, type InsufficientDataError as w, type InvalidConfigError as x, type StorageError as y };
@@ -57,20 +57,40 @@ type LearningCycleEvent = {
57
57
  durationMs: number;
58
58
  };
59
59
 
60
- type LearningErrorTag = 'STORAGE_ERROR' | 'INSUFFICIENT_DATA' | 'INVALID_CONFIG' | 'ANOMALY_DETECTION_FAILED' | 'FEEDBACK_LOOP_ALREADY_RUNNING' | 'FEEDBACK_LOOP_NOT_RUNNING';
61
- type LearningError = {
62
- readonly tag: LearningErrorTag;
60
+ type StorageError = {
61
+ readonly tag: 'STORAGE_ERROR';
63
62
  readonly message: string;
64
63
  readonly cause?: unknown;
65
- readonly required?: number;
66
- readonly actual?: number;
67
- readonly key?: string;
68
- readonly value?: unknown;
69
64
  };
65
+ type InsufficientDataError = {
66
+ readonly tag: 'INSUFFICIENT_DATA';
67
+ readonly message: string;
68
+ readonly required: number;
69
+ readonly actual: number;
70
+ };
71
+ type InvalidConfigError = {
72
+ readonly tag: 'INVALID_CONFIG';
73
+ readonly message: string;
74
+ readonly key: string;
75
+ readonly value: unknown;
76
+ };
77
+ type AnomalyDetectionFailedError = {
78
+ readonly tag: 'ANOMALY_DETECTION_FAILED';
79
+ readonly message: string;
80
+ };
81
+ type FeedbackLoopAlreadyRunningError = {
82
+ readonly tag: 'FEEDBACK_LOOP_ALREADY_RUNNING';
83
+ readonly message: string;
84
+ };
85
+ type FeedbackLoopNotRunningError = {
86
+ readonly tag: 'FEEDBACK_LOOP_NOT_RUNNING';
87
+ readonly message: string;
88
+ };
89
+ type LearningError = StorageError | InsufficientDataError | InvalidConfigError | AnomalyDetectionFailedError | FeedbackLoopAlreadyRunningError | FeedbackLoopNotRunningError;
70
90
 
71
91
  interface IPatternRegistry {
72
92
  record(pattern: EndpointPattern): Result<void, LearningError>;
73
- getAggregates(windowMinutes: number): Result<AggregatePattern[], LearningError>;
93
+ getAggregates(windowMinutes: number, windowEnd?: Date): Result<AggregatePattern[], LearningError>;
74
94
  getHistory(endpoint: string, method: string, limit: number): Result<EndpointPattern[], LearningError>;
75
95
  getStats(): Result<RegistryStats, LearningError>;
76
96
  }
@@ -84,7 +104,7 @@ type RegistryStats = {
84
104
  interface StorageAdapter {
85
105
  savePattern(pattern: EndpointPattern): Result<void, LearningError>;
86
106
  getPatterns(windowStart: Date, windowEnd: Date): Result<EndpointPattern[], LearningError>;
87
- getAggregates(windowMinutes: number): Result<AggregatePattern[], LearningError>;
107
+ getAggregates(windowMinutes: number, windowEnd?: Date): Result<AggregatePattern[], LearningError>;
88
108
  saveAnomaly(report: AnomalyReport$1): Result<void, LearningError>;
89
109
  getRecentAnomalies(limit: number): Result<AnomalyReport$1[], LearningError>;
90
110
  saveConfig(config: TunableConfig): Result<void, LearningError>;
@@ -105,7 +125,7 @@ interface ObservabilityAdapter {
105
125
  }
106
126
 
107
127
  interface IAnomalyDetector {
108
- analyze(current: EndpointPattern, baseline: AggregatePattern): Result<AnomalyReport | null, LearningError>;
128
+ analyze(current: EndpointPattern, baseline: AggregatePattern): Result<AnomalyReport[], LearningError>;
109
129
  batchAnalyze(windowPatterns: EndpointPattern[], baselines: AggregatePattern[]): Result<AnomalyReport[], LearningError>;
110
130
  }
111
131
  type AnomalyReport = {
@@ -131,13 +151,15 @@ interface IConfigTuner {
131
151
  getCurrentConfig(): TunableConfig;
132
152
  tune(aggregates: AggregatePattern[], anomalies: AnomalyReport$1[]): Result<TunableConfig, LearningError>;
133
153
  reset(): Result<TunableConfig, LearningError>;
134
- onConfigChange(callback: (config: TunableConfig) => void): void;
154
+ onConfigChange(callback: (config: TunableConfig) => void): () => void;
135
155
  }
136
156
  type ConfigTunerConfig = {
137
157
  minTimeoutMs: number;
138
158
  maxTimeoutMs: number;
139
159
  smoothingFactor: number;
140
160
  adjustmentStepMs: number;
161
+ /** Minimum milliseconds between successive config applications. Default: 60_000 */
162
+ cooldownMs: number;
141
163
  };
142
164
  declare const DEFAULT_TUNER_CONFIG: ConfigTunerConfig;
143
165
 
@@ -146,13 +168,14 @@ interface IFeedbackLoop {
146
168
  stop(): void;
147
169
  isRunning(): boolean;
148
170
  runOnce(): Promise<Result<LearningCycleEvent, LearningError>>;
149
- onCycle(callback: (event: LearningCycleEvent) => void): void;
171
+ onCycle(callback: (event: LearningCycleEvent) => void): () => void;
150
172
  }
151
173
  type FeedbackLoopConfig = {
152
174
  defaultIntervalMs: number;
153
175
  windowSizeMinutes: number;
154
176
  minSamplesBeforeTuning: number;
155
- cooldownBetweenChangesMs: number;
177
+ /** Hours to retain patterns and anomalies. Records older than this are pruned after each cycle. Default: 24 */
178
+ pruneTtlHours: number;
156
179
  };
157
180
  declare const DEFAULT_LOOP_CONFIG: FeedbackLoopConfig;
158
181
 
@@ -178,14 +201,17 @@ declare class AutoLearningCore {
178
201
  stopFeedbackLoop(): void;
179
202
  isFeedbackLoopRunning(): boolean;
180
203
  runOnce(): Promise<Result<LearningCycleEvent, LearningError>>;
181
- onConfigChange(callback: (config: TunableConfig) => void): void;
182
- onCycle(callback: (event: LearningCycleEvent) => void): void;
204
+ onConfigChange(callback: (config: TunableConfig) => void): () => void;
205
+ onCycle(callback: (event: LearningCycleEvent) => void): () => void;
183
206
  }
184
207
 
185
208
  type AutoLearningModuleOptions = {
186
209
  intervalMs?: number;
187
- storage?: 'memory' | 'redis' | 'sql';
188
- redisUrl?: string;
210
+ /**
211
+ * Set to false to skip auto-starting the feedback loop on bootstrap.
212
+ * Call core.startFeedbackLoop() manually when ready. Default: true.
213
+ */
214
+ autoStart?: boolean;
189
215
  observability?: {
190
216
  logger?: LoggerService;
191
217
  metrics?: {
@@ -215,4 +241,4 @@ declare const AUTO_LEARNING_OPTIONS: unique symbol;
215
241
  declare const AUTO_LEARNING_INSTANCE: unique symbol;
216
242
  declare const AUTO_LEARN_METADATA = "auto_learn_metadata";
217
243
 
218
- export { type AggregatePattern as A, type ConfigTunerConfig as C, DEFAULT_ANOMALY_CONFIG as D, type EndpointPattern as E, type FeedbackLoopConfig as F, type IPatternRegistry as I, type LearningError as L, type ObservabilityAdapter as O, type RegistryStats as R, type StorageAdapter as S, type TunableConfig as T, type IAnomalyDetector as a, type AnomalyDetectorConfig as b, type AnomalyReport as c, type IConfigTuner as d, type AnomalyReport$1 as e, type IFeedbackLoop as f, type LearningCycleEvent as g, AUTO_LEARNING_INSTANCE as h, AUTO_LEARNING_OPTIONS as i, AUTO_LEARN_METADATA as j, type AnomalySeverity as k, AutoLearn as l, type AutoLearnOptions as m, AutoLearningCore as n, type AutoLearningCoreOptions as o, AutoLearningModule as p, type AutoLearningModuleOptions as q, DEFAULT_LOOP_CONFIG as r, DEFAULT_TUNER_CONFIG as s };
244
+ export { type AggregatePattern as A, type ConfigTunerConfig as C, DEFAULT_ANOMALY_CONFIG as D, type EndpointPattern as E, type FeedbackLoopConfig as F, type IPatternRegistry as I, type LearningError as L, type ObservabilityAdapter as O, type RegistryStats as R, type StorageAdapter as S, type TunableConfig as T, type IAnomalyDetector as a, type AnomalyDetectorConfig as b, type AnomalyReport as c, type IConfigTuner as d, type AnomalyReport$1 as e, type IFeedbackLoop as f, type LearningCycleEvent as g, AUTO_LEARNING_INSTANCE as h, AUTO_LEARNING_OPTIONS as i, AUTO_LEARN_METADATA as j, type AnomalyDetectionFailedError as k, type AnomalySeverity as l, AutoLearn as m, type AutoLearnOptions as n, AutoLearningCore as o, type AutoLearningCoreOptions as p, AutoLearningModule as q, type AutoLearningModuleOptions as r, DEFAULT_LOOP_CONFIG as s, DEFAULT_TUNER_CONFIG as t, type FeedbackLoopAlreadyRunningError as u, type FeedbackLoopNotRunningError as v, type InsufficientDataError as w, type InvalidConfigError as x, type StorageError as y };