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