@azumag/opencode-rate-limit-fallback 1.58.0 → 1.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +27 -0
- package/dist/src/config/Validator.js +0 -8
- package/dist/src/config/defaults.d.ts +14 -3
- package/dist/src/config/defaults.js +15 -4
- package/dist/src/diagnostics/Reporter.d.ts +4 -1
- package/dist/src/diagnostics/Reporter.js +16 -0
- package/dist/src/errors/ConfidenceScorer.d.ts +37 -27
- package/dist/src/errors/ConfidenceScorer.js +80 -90
- package/dist/src/errors/PatternExtractor.d.ts +21 -14
- package/dist/src/errors/PatternExtractor.js +176 -114
- package/dist/src/errors/PatternLearner.d.ts +29 -60
- package/dist/src/errors/PatternLearner.js +139 -210
- package/dist/src/errors/PatternRegistry.d.ts +35 -58
- package/dist/src/errors/PatternRegistry.js +90 -192
- package/dist/src/errors/PatternStorage.d.ts +24 -25
- package/dist/src/errors/PatternStorage.js +133 -188
- package/dist/src/main/ConfigReloader.d.ts +6 -0
- package/dist/src/main/ConfigReloader.js +17 -0
- package/dist/src/types/index.d.ts +26 -26
- package/dist/src/utils/config.js +9 -4
- package/package.json +1 -1
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pattern
|
|
2
|
+
* Pattern Learner for orchestrating error pattern learning
|
|
3
3
|
*/
|
|
4
|
+
import { PatternExtractor } from './PatternExtractor.js';
|
|
5
|
+
import { ConfidenceScorer } from './ConfidenceScorer.js';
|
|
6
|
+
import { PatternStorage } from './PatternStorage.js';
|
|
4
7
|
/**
|
|
5
|
-
*
|
|
8
|
+
* Pattern Learner class
|
|
9
|
+
* Orchestrates the learning process
|
|
6
10
|
*/
|
|
7
11
|
export class PatternLearner {
|
|
8
12
|
extractor;
|
|
@@ -10,253 +14,178 @@ export class PatternLearner {
|
|
|
10
14
|
storage;
|
|
11
15
|
config;
|
|
12
16
|
logger;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
// Track patterns being learned
|
|
18
|
+
patternTracking;
|
|
19
|
+
// Statistics
|
|
20
|
+
stats = {
|
|
21
|
+
totalErrorsProcessed: 0,
|
|
22
|
+
patternsLearned: 0,
|
|
23
|
+
patternsRejected: 0,
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Constructor
|
|
27
|
+
*/
|
|
28
|
+
constructor(config, logger) {
|
|
19
29
|
this.config = config;
|
|
20
|
-
this.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
try {
|
|
31
|
-
// Extract pattern candidates
|
|
32
|
-
const candidates = this.extractor.extractPatterns(error);
|
|
33
|
-
for (const candidate of candidates) {
|
|
34
|
-
this.trackPattern(candidate);
|
|
35
|
-
}
|
|
36
|
-
// Process and potentially save patterns
|
|
37
|
-
// Fire-and-forget with proper error handling
|
|
38
|
-
this.processPatterns().catch((error) => {
|
|
39
|
-
this.logger.error('[PatternLearner] Failed to process patterns', {
|
|
40
|
-
error: error instanceof Error ? error.message : String(error),
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
this.logger.error('[PatternLearner] Failed to learn from error', {
|
|
46
|
-
error: error instanceof Error ? error.message : String(error),
|
|
47
|
-
});
|
|
48
|
-
}
|
|
30
|
+
this.extractor = new PatternExtractor();
|
|
31
|
+
this.scorer = new ConfidenceScorer(config);
|
|
32
|
+
this.storage = new PatternStorage(config);
|
|
33
|
+
this.patternTracking = new Map();
|
|
34
|
+
this.logger = logger || {
|
|
35
|
+
debug: () => { },
|
|
36
|
+
info: () => { },
|
|
37
|
+
warn: () => { },
|
|
38
|
+
error: () => { },
|
|
39
|
+
};
|
|
49
40
|
}
|
|
50
41
|
/**
|
|
51
|
-
*
|
|
42
|
+
* Update configuration
|
|
52
43
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (existing) {
|
|
58
|
-
// Update existing tracker
|
|
59
|
-
existing.lastSeen = Date.now();
|
|
60
|
-
existing.count++;
|
|
61
|
-
existing.samples.push(candidate.sourceError);
|
|
62
|
-
// Keep only last 10 samples
|
|
63
|
-
if (existing.samples.length > 10) {
|
|
64
|
-
existing.samples.shift();
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
// Create new tracker
|
|
69
|
-
this.patternTracker.set(key, {
|
|
70
|
-
pattern: candidate,
|
|
71
|
-
firstSeen: Date.now(),
|
|
72
|
-
lastSeen: Date.now(),
|
|
73
|
-
count: 1,
|
|
74
|
-
samples: [candidate.sourceError],
|
|
75
|
-
});
|
|
76
|
-
}
|
|
44
|
+
updateConfig(config) {
|
|
45
|
+
this.config = config;
|
|
46
|
+
this.scorer.updateConfig(config);
|
|
47
|
+
this.storage.updateConfig(config);
|
|
77
48
|
}
|
|
78
49
|
/**
|
|
79
|
-
*
|
|
50
|
+
* Set the config file path for storage
|
|
80
51
|
*/
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// Check if pattern meets frequency threshold
|
|
84
|
-
if (tracker.count < this.config.minErrorFrequency) {
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
// Check if pattern already exists in learned patterns
|
|
88
|
-
if (this.learnedPatterns.has(key)) {
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
// Calculate confidence score
|
|
92
|
-
const confidence = this.scorer.calculateScore(tracker.pattern, tracker.count, tracker.firstSeen);
|
|
93
|
-
// Check if pattern meets auto-approve threshold
|
|
94
|
-
if (!this.scorer.shouldAutoApprove(confidence)) {
|
|
95
|
-
this.logger.debug(`[PatternLearner] Pattern confidence ${confidence.toFixed(2)} below threshold ${this.config.autoApproveThreshold}, not auto-approving`);
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
// Create learned pattern
|
|
99
|
-
const learnedPattern = {
|
|
100
|
-
name: this.generatePatternName(tracker.pattern),
|
|
101
|
-
provider: tracker.pattern.provider,
|
|
102
|
-
patterns: tracker.pattern.patterns,
|
|
103
|
-
priority: this.calculatePriority(tracker.pattern, confidence),
|
|
104
|
-
confidence,
|
|
105
|
-
learnedAt: new Date(tracker.firstSeen).toISOString(),
|
|
106
|
-
sampleCount: tracker.count,
|
|
107
|
-
lastUsed: undefined,
|
|
108
|
-
};
|
|
109
|
-
// Save to storage
|
|
110
|
-
await this.storage.savePattern(learnedPattern);
|
|
111
|
-
// Add to learned patterns
|
|
112
|
-
this.learnedPatterns.set(key, learnedPattern);
|
|
113
|
-
// Remove from tracker
|
|
114
|
-
this.patternTracker.delete(key);
|
|
115
|
-
this.logger.info(`[PatternLearner] Learned new pattern: ${learnedPattern.name} (confidence: ${confidence.toFixed(2)})`);
|
|
116
|
-
}
|
|
52
|
+
setConfigFilePath(path) {
|
|
53
|
+
this.storage.setConfigFilePath(path);
|
|
117
54
|
}
|
|
118
55
|
/**
|
|
119
|
-
*
|
|
56
|
+
* Process an error and learn from it
|
|
120
57
|
*/
|
|
121
|
-
|
|
122
|
-
if (
|
|
58
|
+
async processError(error) {
|
|
59
|
+
if (!this.config.enabled) {
|
|
60
|
+
this.logger.debug('Pattern learning is disabled, skipping');
|
|
123
61
|
return null;
|
|
124
62
|
}
|
|
125
|
-
|
|
126
|
-
|
|
63
|
+
this.stats.totalErrorsProcessed++;
|
|
64
|
+
// Extract pattern from error
|
|
65
|
+
const candidate = this.extractor.extractPattern(error);
|
|
66
|
+
if (!candidate) {
|
|
67
|
+
return null;
|
|
127
68
|
}
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
provider
|
|
131
|
-
|
|
132
|
-
sourceError: patterns.map(p => p.sourceError).join('; '),
|
|
133
|
-
extractedAt: Math.max(...patterns.map(p => p.extractedAt)),
|
|
134
|
-
};
|
|
135
|
-
// Deduplicate patterns
|
|
136
|
-
mergedPattern.patterns = [...new Set(mergedPattern.patterns)];
|
|
137
|
-
return mergedPattern;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Load learned patterns from storage
|
|
141
|
-
*/
|
|
142
|
-
async loadLearnedPatterns() {
|
|
143
|
-
try {
|
|
144
|
-
const patterns = await this.storage.loadPatterns();
|
|
145
|
-
for (const pattern of patterns) {
|
|
146
|
-
const key = this.generatePatternKeyFromLearned(pattern);
|
|
147
|
-
this.learnedPatterns.set(key, pattern);
|
|
148
|
-
}
|
|
149
|
-
this.logger.info(`[PatternLearner] Loaded ${patterns.length} learned patterns`);
|
|
69
|
+
// Check if provider is present (required for meaningful patterns)
|
|
70
|
+
if (!candidate.provider) {
|
|
71
|
+
this.logger.debug('No provider found in error, skipping pattern learning');
|
|
72
|
+
return null;
|
|
150
73
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
74
|
+
// Create a pattern key for tracking
|
|
75
|
+
const patternKey = this.createPatternKey(candidate);
|
|
76
|
+
// Update pattern tracking
|
|
77
|
+
const tracking = this.getOrCreateTracking(candidate, patternKey);
|
|
78
|
+
tracking.frequency++;
|
|
79
|
+
tracking.samples.push(candidate.rawText);
|
|
80
|
+
// Check if we should learn this pattern
|
|
81
|
+
if (tracking.frequency < this.config.minErrorFrequency) {
|
|
82
|
+
return null; // Not enough samples yet
|
|
155
83
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Get learned patterns for a specific provider
|
|
165
|
-
*/
|
|
166
|
-
getLearnedPatternsForProvider(provider) {
|
|
167
|
-
return this.getLearnedPatterns().filter(p => !p.provider || p.provider === provider);
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Add a learned pattern manually
|
|
171
|
-
*/
|
|
172
|
-
async addLearnedPattern(pattern) {
|
|
173
|
-
const key = this.generatePatternKeyFromLearned(pattern);
|
|
174
|
-
this.learnedPatterns.set(key, pattern);
|
|
175
|
-
await this.storage.savePattern(pattern);
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Remove a learned pattern
|
|
179
|
-
*/
|
|
180
|
-
async removeLearnedPattern(name) {
|
|
181
|
-
const pattern = this.getLearnedPatternByName(name);
|
|
182
|
-
if (pattern) {
|
|
183
|
-
const key = this.generatePatternKeyFromLearned(pattern);
|
|
184
|
-
this.learnedPatterns.delete(key);
|
|
185
|
-
await this.storage.deletePattern(name);
|
|
186
|
-
return true;
|
|
84
|
+
// Calculate confidence
|
|
85
|
+
const confidence = this.scorer.calculateConfidence(tracking.pattern, tracking.frequency, tracking.firstSeen, []);
|
|
86
|
+
// Check if we should learn and save this pattern
|
|
87
|
+
if (!this.scorer.shouldAutoApprove(confidence)) {
|
|
88
|
+
this.stats.patternsRejected++;
|
|
89
|
+
this.logger.debug(`Pattern confidence ${confidence} below threshold ${this.config.autoApproveThreshold}`);
|
|
90
|
+
return null;
|
|
187
91
|
}
|
|
188
|
-
|
|
92
|
+
// Create learned pattern
|
|
93
|
+
const learnedPattern = this.storage.createLearnedPattern(tracking.pattern, confidence, tracking.frequency);
|
|
94
|
+
// Save to storage
|
|
95
|
+
await this.saveLearnedPattern(learnedPattern);
|
|
96
|
+
// Clear tracking for this pattern
|
|
97
|
+
this.patternTracking.delete(patternKey);
|
|
98
|
+
this.stats.patternsLearned++;
|
|
99
|
+
this.logger.info(`Learned new pattern: ${learnedPattern.name} with confidence ${confidence}`);
|
|
100
|
+
return learnedPattern;
|
|
189
101
|
}
|
|
190
102
|
/**
|
|
191
|
-
*
|
|
192
|
-
*/
|
|
193
|
-
getLearnedPatternByName(name) {
|
|
194
|
-
return this.getLearnedPatterns().find(p => p.name === name);
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Generate a unique key for a pattern candidate
|
|
103
|
+
* Load learned patterns from storage
|
|
198
104
|
*/
|
|
199
|
-
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
return
|
|
105
|
+
async loadLearnedPatterns() {
|
|
106
|
+
const patterns = await this.storage.loadLearnedPatterns();
|
|
107
|
+
this.logger.debug(`Loaded ${patterns.length} learned patterns`);
|
|
108
|
+
return patterns;
|
|
203
109
|
}
|
|
204
110
|
/**
|
|
205
|
-
*
|
|
111
|
+
* Save learned patterns
|
|
206
112
|
*/
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
const
|
|
210
|
-
|
|
113
|
+
async saveLearnedPatterns(patterns) {
|
|
114
|
+
const merged = this.storage.mergeSimilarPatterns(patterns);
|
|
115
|
+
const cleaned = this.storage.cleanupPatterns(merged);
|
|
116
|
+
await this.storage.saveLearnedPatterns(cleaned);
|
|
117
|
+
this.logger.debug(`Saved ${cleaned.length} learned patterns`);
|
|
211
118
|
}
|
|
212
119
|
/**
|
|
213
|
-
*
|
|
120
|
+
* Get statistics
|
|
214
121
|
*/
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const timestamp = Date.now();
|
|
218
|
-
return `learned-${provider}-${timestamp}`;
|
|
122
|
+
getStats() {
|
|
123
|
+
return { ...this.stats };
|
|
219
124
|
}
|
|
220
125
|
/**
|
|
221
|
-
*
|
|
126
|
+
* Reset statistics
|
|
222
127
|
*/
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const patternCountBonus = Math.min(pattern.patterns.length * 2, 10);
|
|
230
|
-
return Math.max(1, Math.min(100, basePriority + providerBonus + patternCountBonus));
|
|
128
|
+
resetStats() {
|
|
129
|
+
this.stats = {
|
|
130
|
+
totalErrorsProcessed: 0,
|
|
131
|
+
patternsLearned: 0,
|
|
132
|
+
patternsRejected: 0,
|
|
133
|
+
};
|
|
231
134
|
}
|
|
232
135
|
/**
|
|
233
|
-
*
|
|
136
|
+
* Clear all pattern tracking
|
|
234
137
|
*/
|
|
235
|
-
|
|
236
|
-
|
|
138
|
+
clearTracking() {
|
|
139
|
+
this.patternTracking.clear();
|
|
237
140
|
}
|
|
238
141
|
/**
|
|
239
|
-
*
|
|
142
|
+
* Create a pattern key for tracking
|
|
240
143
|
*/
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
|
|
144
|
+
createPatternKey(candidate) {
|
|
145
|
+
const parts = [
|
|
146
|
+
candidate.provider || 'unknown',
|
|
147
|
+
candidate.statusCode || 'no-status',
|
|
148
|
+
...candidate.phrases.slice(0, 3), // Use first 3 phrases for key
|
|
149
|
+
].join('|');
|
|
150
|
+
return parts;
|
|
244
151
|
}
|
|
245
152
|
/**
|
|
246
|
-
*
|
|
153
|
+
* Get or create pattern tracking
|
|
247
154
|
*/
|
|
248
|
-
|
|
249
|
-
this.
|
|
155
|
+
getOrCreateTracking(candidate, patternKey) {
|
|
156
|
+
if (this.patternTracking.has(patternKey)) {
|
|
157
|
+
return this.patternTracking.get(patternKey);
|
|
158
|
+
}
|
|
159
|
+
// Create pattern from candidate
|
|
160
|
+
const allPatterns = [
|
|
161
|
+
...candidate.phrases,
|
|
162
|
+
...candidate.errorCodes,
|
|
163
|
+
...(candidate.statusCode ? [candidate.statusCode] : []),
|
|
164
|
+
];
|
|
165
|
+
const pattern = {
|
|
166
|
+
name: `learned-${candidate.provider}-${Date.now()}`,
|
|
167
|
+
provider: candidate.provider || undefined,
|
|
168
|
+
patterns: allPatterns,
|
|
169
|
+
priority: 70, // Medium priority for learned patterns
|
|
170
|
+
};
|
|
171
|
+
const tracking = {
|
|
172
|
+
pattern,
|
|
173
|
+
frequency: 0,
|
|
174
|
+
firstSeen: Date.now(),
|
|
175
|
+
samples: [],
|
|
176
|
+
};
|
|
177
|
+
this.patternTracking.set(patternKey, tracking);
|
|
178
|
+
return tracking;
|
|
250
179
|
}
|
|
251
180
|
/**
|
|
252
|
-
*
|
|
181
|
+
* Save a single learned pattern
|
|
253
182
|
*/
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
183
|
+
async saveLearnedPattern(pattern) {
|
|
184
|
+
// Load existing patterns
|
|
185
|
+
const existing = await this.storage.loadLearnedPatterns();
|
|
186
|
+
// Add new pattern
|
|
187
|
+
existing.push(pattern);
|
|
188
|
+
// Merge and clean up
|
|
189
|
+
await this.saveLearnedPatterns(existing);
|
|
261
190
|
}
|
|
262
191
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Error Pattern Registry for rate limit error detection
|
|
3
3
|
*/
|
|
4
|
-
import type { ErrorPattern,
|
|
4
|
+
import type { ErrorPattern, LearnedPattern, PatternLearningConfig } from '../types/index.js';
|
|
5
5
|
import { Logger } from '../../logger.js';
|
|
6
|
+
import { PatternLearner } from './PatternLearner.js';
|
|
6
7
|
/**
|
|
7
8
|
* Error Pattern Registry class
|
|
8
9
|
* Manages and matches error patterns for rate limit detection
|
|
@@ -10,51 +11,61 @@ import { Logger } from '../../logger.js';
|
|
|
10
11
|
export declare class ErrorPatternRegistry {
|
|
11
12
|
private patterns;
|
|
12
13
|
private learnedPatterns;
|
|
13
|
-
private patternLearner
|
|
14
|
-
private
|
|
15
|
-
private
|
|
16
|
-
constructor(logger?: Logger
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
private patternLearner;
|
|
15
|
+
private learningConfig;
|
|
16
|
+
private _logger;
|
|
17
|
+
constructor(logger?: Logger);
|
|
18
|
+
/**
|
|
19
|
+
* Register default rate limit error patterns
|
|
20
|
+
*/
|
|
21
|
+
registerDefaultPatterns(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Register a new error pattern
|
|
24
|
+
*/
|
|
25
|
+
register(pattern: ErrorPattern): void;
|
|
26
|
+
/**
|
|
27
|
+
* Register multiple error patterns
|
|
28
|
+
*/
|
|
29
|
+
registerMany(patterns: ErrorPattern[]): void;
|
|
20
30
|
/**
|
|
21
31
|
* Initialize pattern learning
|
|
22
32
|
*/
|
|
23
|
-
|
|
33
|
+
initializePatternLearning(config: PatternLearningConfig, configFilePath: string): void;
|
|
24
34
|
/**
|
|
25
|
-
*
|
|
35
|
+
* Check if pattern learning is enabled
|
|
26
36
|
*/
|
|
27
|
-
|
|
37
|
+
isLearningEnabled(): boolean;
|
|
28
38
|
/**
|
|
29
|
-
*
|
|
39
|
+
* Get the pattern learner instance
|
|
30
40
|
*/
|
|
31
|
-
|
|
41
|
+
getPatternLearner(): PatternLearner | null;
|
|
32
42
|
/**
|
|
33
|
-
*
|
|
43
|
+
* Add a learned pattern
|
|
34
44
|
*/
|
|
35
|
-
|
|
45
|
+
addLearnedPattern(pattern: LearnedPattern): void;
|
|
36
46
|
/**
|
|
37
|
-
*
|
|
47
|
+
* Get all learned patterns
|
|
38
48
|
*/
|
|
39
|
-
|
|
49
|
+
getLearnedPatterns(): LearnedPattern[];
|
|
40
50
|
/**
|
|
41
|
-
*
|
|
51
|
+
* Clear all learned patterns
|
|
42
52
|
*/
|
|
43
|
-
|
|
53
|
+
clearLearnedPatterns(): void;
|
|
44
54
|
/**
|
|
45
|
-
*
|
|
55
|
+
* Update learned patterns
|
|
46
56
|
*/
|
|
47
|
-
|
|
57
|
+
updateLearnedPatterns(patterns: LearnedPattern[]): void;
|
|
48
58
|
/**
|
|
49
59
|
* Check if an error matches any registered rate limit pattern
|
|
50
60
|
*/
|
|
51
61
|
isRateLimitError(error: unknown): boolean;
|
|
52
62
|
/**
|
|
53
63
|
* Get the matched pattern for an error, or null if no match
|
|
64
|
+
* Checks default patterns first, then learned patterns
|
|
54
65
|
*/
|
|
55
66
|
getMatchedPattern(error: unknown): ErrorPattern | null;
|
|
56
67
|
/**
|
|
57
|
-
* Get all registered patterns
|
|
68
|
+
* Get all registered patterns (including learned patterns)
|
|
58
69
|
*/
|
|
59
70
|
getAllPatterns(): ErrorPattern[];
|
|
60
71
|
/**
|
|
@@ -77,47 +88,13 @@ export declare class ErrorPatternRegistry {
|
|
|
77
88
|
* Reset to default patterns only
|
|
78
89
|
*/
|
|
79
90
|
resetToDefaults(): void;
|
|
80
|
-
/**
|
|
81
|
-
* Learn a new pattern from an error
|
|
82
|
-
*/
|
|
83
|
-
addLearnedPattern(error: unknown): void;
|
|
84
|
-
/**
|
|
85
|
-
* Learn a new pattern from an error (async version)
|
|
86
|
-
*/
|
|
87
|
-
addLearnedPatternAsync(error: unknown): Promise<void>;
|
|
88
|
-
/**
|
|
89
|
-
* Get all learned patterns
|
|
90
|
-
*/
|
|
91
|
-
getLearnedPatterns(): LearnedPattern[];
|
|
92
|
-
/**
|
|
93
|
-
* Get a learned pattern by name
|
|
94
|
-
*/
|
|
95
|
-
getLearnedPatternByName(name: string): LearnedPattern | undefined;
|
|
96
|
-
/**
|
|
97
|
-
* Remove a learned pattern by name
|
|
98
|
-
*/
|
|
99
|
-
removeLearnedPattern(name: string): Promise<boolean>;
|
|
100
|
-
/**
|
|
101
|
-
* Merge duplicate learned patterns
|
|
102
|
-
*/
|
|
103
|
-
mergeDuplicatePatterns(): Promise<number>;
|
|
104
|
-
/**
|
|
105
|
-
* Cleanup old learned patterns
|
|
106
|
-
*/
|
|
107
|
-
cleanupOldPatterns(): Promise<number>;
|
|
108
|
-
/**
|
|
109
|
-
* Get learning statistics
|
|
110
|
-
*/
|
|
111
|
-
getLearningStats(): {
|
|
112
|
-
trackedPatterns: number;
|
|
113
|
-
learnedPatterns: number;
|
|
114
|
-
pendingPatterns: number;
|
|
115
|
-
} | null;
|
|
116
91
|
/**
|
|
117
92
|
* Get statistics about registered patterns
|
|
118
93
|
*/
|
|
119
94
|
getStats(): {
|
|
120
95
|
total: number;
|
|
96
|
+
default: number;
|
|
97
|
+
learned: number;
|
|
121
98
|
byProvider: Record<string, number>;
|
|
122
99
|
byPriority: Record<string, number>;
|
|
123
100
|
};
|