agentic-qe 3.7.21 → 3.7.22
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/.claude/helpers/brain-checkpoint.cjs +4 -1
- package/.claude/helpers/statusline-v3.cjs +3 -1
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +14 -0
- package/README.md +0 -12
- package/assets/helpers/statusline-v3.cjs +3 -1
- package/dist/cli/brain-commands.js +6 -10
- package/dist/cli/bundle.js +2049 -3380
- package/dist/cli/commands/hooks.js +29 -6
- package/dist/cli/commands/init.js +1 -73
- package/dist/cli/commands/learning.js +164 -12
- package/dist/cli/handlers/init-handler.d.ts +0 -1
- package/dist/cli/handlers/init-handler.js +0 -6
- package/dist/cli/index.js +0 -2
- package/dist/context/sources/defect-source.js +2 -2
- package/dist/context/sources/memory-source.js +2 -2
- package/dist/context/sources/requirements-source.js +2 -2
- package/dist/init/index.d.ts +0 -2
- package/dist/init/index.js +0 -1
- package/dist/init/init-wizard-steps.d.ts +10 -0
- package/dist/init/init-wizard-steps.js +87 -1
- package/dist/init/init-wizard.d.ts +1 -9
- package/dist/init/init-wizard.js +3 -69
- package/dist/init/orchestrator.js +0 -1
- package/dist/init/phases/01-detection.js +0 -27
- package/dist/init/phases/07-hooks.js +6 -4
- package/dist/init/phases/phase-interface.d.ts +0 -1
- package/dist/init/settings-merge.js +1 -1
- package/dist/kernel/unified-memory.js +5 -6
- package/dist/learning/experience-capture-middleware.js +20 -0
- package/dist/learning/index.d.ts +0 -2
- package/dist/learning/index.js +0 -4
- package/dist/learning/metrics-tracker.js +15 -13
- package/dist/learning/pattern-lifecycle.d.ts +1 -1
- package/dist/learning/pattern-lifecycle.js +18 -20
- package/dist/learning/qe-unified-memory.js +1 -28
- package/dist/mcp/bundle.js +180 -175
- package/package.json +1 -1
- package/dist/cli/commands/migrate.d.ts +0 -9
- package/dist/cli/commands/migrate.js +0 -566
- package/dist/init/init-wizard-migration.d.ts +0 -52
- package/dist/init/init-wizard-migration.js +0 -345
- package/dist/init/migration/config-migrator.d.ts +0 -31
- package/dist/init/migration/config-migrator.js +0 -149
- package/dist/init/migration/data-migrator.d.ts +0 -72
- package/dist/init/migration/data-migrator.js +0 -232
- package/dist/init/migration/detector.d.ts +0 -44
- package/dist/init/migration/detector.js +0 -105
- package/dist/init/migration/index.d.ts +0 -8
- package/dist/init/migration/index.js +0 -8
- package/dist/learning/v2-to-v3-migration.d.ts +0 -86
- package/dist/learning/v2-to-v3-migration.js +0 -529
|
@@ -6,11 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* This is a facade module. Implementation details are extracted to:
|
|
8
8
|
* - init-wizard-hooks.ts (hook configuration, MCP, CLAUDE.md generation)
|
|
9
|
-
* - init-wizard-
|
|
10
|
-
* - init-wizard-steps.ts (persistence, learning, workers, skills, agents, config)
|
|
9
|
+
* - init-wizard-steps.ts (persistence, learning, workers, skills, agents, config, version)
|
|
11
10
|
*/
|
|
12
11
|
import type { InitResult, WizardStep, PretrainedLibrary } from './types.js';
|
|
13
|
-
export type { V2DetectionResult } from './init-wizard-migration.js';
|
|
14
12
|
export interface InitOrchestratorOptions {
|
|
15
13
|
/** Project root directory */
|
|
16
14
|
projectRoot: string;
|
|
@@ -31,8 +29,6 @@ export interface InitOrchestratorOptions {
|
|
|
31
29
|
baseUrl?: string;
|
|
32
30
|
apiKey?: string;
|
|
33
31
|
};
|
|
34
|
-
/** Automatically migrate from v2 if detected */
|
|
35
|
-
autoMigrate?: boolean;
|
|
36
32
|
}
|
|
37
33
|
export declare class InitOrchestrator {
|
|
38
34
|
private projectRoot;
|
|
@@ -49,10 +45,6 @@ export declare class InitOrchestrator {
|
|
|
49
45
|
* Get wizard steps
|
|
50
46
|
*/
|
|
51
47
|
getWizardSteps(): WizardStep[];
|
|
52
|
-
/**
|
|
53
|
-
* Handle V2 detection - returns early result if migration not auto, null otherwise.
|
|
54
|
-
*/
|
|
55
|
-
private handleV2Detection;
|
|
56
48
|
/**
|
|
57
49
|
* Run a single initialization step with timing and status tracking
|
|
58
50
|
*/
|
package/dist/init/init-wizard.js
CHANGED
|
@@ -6,16 +6,15 @@
|
|
|
6
6
|
*
|
|
7
7
|
* This is a facade module. Implementation details are extracted to:
|
|
8
8
|
* - init-wizard-hooks.ts (hook configuration, MCP, CLAUDE.md generation)
|
|
9
|
-
* - init-wizard-
|
|
10
|
-
* - init-wizard-steps.ts (persistence, learning, workers, skills, agents, config)
|
|
9
|
+
* - init-wizard-steps.ts (persistence, learning, workers, skills, agents, config, version)
|
|
11
10
|
*/
|
|
12
11
|
import { createDefaultConfig } from './types.js';
|
|
13
12
|
import { createProjectAnalyzer } from './project-analyzer.js';
|
|
14
13
|
import { createSelfConfigurator } from './self-configurator.js';
|
|
15
|
-
|
|
14
|
+
// Import from extracted modules
|
|
16
15
|
import { configureHooks, configureMCP, generateCLAUDEmd, } from './init-wizard-hooks.js';
|
|
17
16
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
18
|
-
import { initializePersistenceDatabase, checkCodeIntelligenceIndex, runCodeIntelligenceScan, getKGEntryCount, initializeLearningSystem, startWorkers, installSkills, installAgents, installN8n, saveConfig, } from './init-wizard-steps.js';
|
|
17
|
+
import { initializePersistenceDatabase, checkCodeIntelligenceIndex, runCodeIntelligenceScan, getKGEntryCount, initializeLearningSystem, startWorkers, installSkills, installAgents, installN8n, saveConfig, writeVersionToDb, } from './init-wizard-steps.js';
|
|
19
18
|
// ============================================================================
|
|
20
19
|
// Wizard Step Definitions
|
|
21
20
|
// ============================================================================
|
|
@@ -105,13 +104,6 @@ export class InitOrchestrator {
|
|
|
105
104
|
async initialize() {
|
|
106
105
|
const startTime = Date.now();
|
|
107
106
|
try {
|
|
108
|
-
// Step 0: Check for existing v2 installation
|
|
109
|
-
const v2Detection = await detectV2Installation(this.projectRoot);
|
|
110
|
-
if (v2Detection.detected) {
|
|
111
|
-
const earlyResult = this.handleV2Detection(v2Detection, startTime);
|
|
112
|
-
if (earlyResult)
|
|
113
|
-
return earlyResult;
|
|
114
|
-
}
|
|
115
107
|
// Step 1: Analyze project
|
|
116
108
|
const analysis = await this.runStep('Project Analysis', async () => {
|
|
117
109
|
return await this.analyzer.analyze();
|
|
@@ -251,64 +243,6 @@ export class InitOrchestrator {
|
|
|
251
243
|
getWizardSteps() {
|
|
252
244
|
return WIZARD_STEPS;
|
|
253
245
|
}
|
|
254
|
-
/**
|
|
255
|
-
* Handle V2 detection - returns early result if migration not auto, null otherwise.
|
|
256
|
-
*/
|
|
257
|
-
handleV2Detection(v2Detection, startTime) {
|
|
258
|
-
console.log('\n' + '='.repeat(60));
|
|
259
|
-
console.log(' EXISTING V2 INSTALLATION DETECTED');
|
|
260
|
-
console.log('='.repeat(60) + '\n');
|
|
261
|
-
console.log('Found v2 installation at:');
|
|
262
|
-
if (v2Detection.hasMemoryDb) {
|
|
263
|
-
console.log(` - Memory DB: .agentic-qe/memory.db`);
|
|
264
|
-
}
|
|
265
|
-
if (v2Detection.hasConfig) {
|
|
266
|
-
console.log(` - Config: .agentic-qe/config/`);
|
|
267
|
-
}
|
|
268
|
-
if (v2Detection.hasAgents) {
|
|
269
|
-
console.log(` - Agents: .claude/agents/`);
|
|
270
|
-
}
|
|
271
|
-
console.log('');
|
|
272
|
-
if (this.options.autoMigrate) {
|
|
273
|
-
console.log('Auto-migrate mode enabled. Running migration...\n');
|
|
274
|
-
// Fire and forget - the caller will await initialize() which runs migration inline
|
|
275
|
-
runV2Migration(this.projectRoot, v2Detection).catch((e) => { console.warn('[InitWizard] V2 migration failed:', e instanceof Error ? e.message : e); });
|
|
276
|
-
return null;
|
|
277
|
-
}
|
|
278
|
-
// Warn and suggest migration
|
|
279
|
-
console.log('RECOMMENDED: Run migration before init:\n');
|
|
280
|
-
console.log(' npx aqe migrate status # Check what needs migration');
|
|
281
|
-
console.log(' npx aqe migrate run --dry-run # Preview changes');
|
|
282
|
-
console.log(' npx aqe migrate run # Execute migration\n');
|
|
283
|
-
console.log('Or continue with:');
|
|
284
|
-
console.log(' aqe init --auto-migrate # Auto-migrate during init\n');
|
|
285
|
-
console.log('='.repeat(60) + '\n');
|
|
286
|
-
return {
|
|
287
|
-
success: false,
|
|
288
|
-
config: createDefaultConfig('unknown', this.projectRoot),
|
|
289
|
-
steps: [{
|
|
290
|
-
step: 'V2 Detection',
|
|
291
|
-
status: 'error',
|
|
292
|
-
message: 'Existing v2 installation detected. Run migration first.',
|
|
293
|
-
durationMs: Date.now() - startTime,
|
|
294
|
-
}],
|
|
295
|
-
summary: {
|
|
296
|
-
projectAnalyzed: false,
|
|
297
|
-
configGenerated: false,
|
|
298
|
-
codeIntelligenceIndexed: 0,
|
|
299
|
-
patternsLoaded: 0,
|
|
300
|
-
skillsInstalled: 0,
|
|
301
|
-
agentsInstalled: 0,
|
|
302
|
-
hooksConfigured: false,
|
|
303
|
-
mcpConfigured: false,
|
|
304
|
-
claudeMdGenerated: false,
|
|
305
|
-
workersStarted: 0,
|
|
306
|
-
},
|
|
307
|
-
totalDurationMs: Date.now() - startTime,
|
|
308
|
-
timestamp: new Date(),
|
|
309
|
-
v2Detected: true,
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
246
|
/**
|
|
313
247
|
* Run a single initialization step with timing and status tracking
|
|
314
248
|
*/
|
|
@@ -32,7 +32,6 @@ export class ModularInitOrchestrator {
|
|
|
32
32
|
upgrade: options.upgrade,
|
|
33
33
|
skipPatterns: options.skipPatterns,
|
|
34
34
|
minimal: options.minimal,
|
|
35
|
-
autoMigrate: options.autoMigrate,
|
|
36
35
|
withN8n: options.withN8n,
|
|
37
36
|
withOpenCode: options.withOpenCode,
|
|
38
37
|
withKiro: options.withKiro,
|
|
@@ -27,33 +27,6 @@ export class DetectionPhase extends BasePhase {
|
|
|
27
27
|
const freshInstall = !v2Detected && !v3Detected;
|
|
28
28
|
// Store v2 detection in context for other phases
|
|
29
29
|
context.v2Detection = v2Detection;
|
|
30
|
-
if (v2Detected && !context.options.autoMigrate) {
|
|
31
|
-
context.services.log('');
|
|
32
|
-
context.services.log('═'.repeat(60));
|
|
33
|
-
context.services.log('⚠️ EXISTING V2 INSTALLATION DETECTED');
|
|
34
|
-
context.services.log('═'.repeat(60));
|
|
35
|
-
context.services.log('');
|
|
36
|
-
context.services.log('Found v2 installation at:');
|
|
37
|
-
if (v2Detection.hasMemoryDb) {
|
|
38
|
-
context.services.log(' • Memory DB: .agentic-qe/memory.db');
|
|
39
|
-
}
|
|
40
|
-
if (v2Detection.hasConfig) {
|
|
41
|
-
context.services.log(' • Config: .agentic-qe/config/');
|
|
42
|
-
}
|
|
43
|
-
if (v2Detection.hasAgents) {
|
|
44
|
-
context.services.log(' • Agents: .claude/agents/');
|
|
45
|
-
}
|
|
46
|
-
context.services.log('');
|
|
47
|
-
context.services.log('📋 RECOMMENDED: Run with --auto-migrate:');
|
|
48
|
-
context.services.log(' aqe init --auto-migrate');
|
|
49
|
-
context.services.log('');
|
|
50
|
-
return {
|
|
51
|
-
v2Detected: true,
|
|
52
|
-
v3Detected,
|
|
53
|
-
freshInstall: false,
|
|
54
|
-
v2Detection,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
30
|
return {
|
|
58
31
|
v2Detected,
|
|
59
32
|
v3Detected,
|
|
@@ -289,13 +289,14 @@ const { execFileSync } = require('child_process');
|
|
|
289
289
|
|
|
290
290
|
function q(bin, args, d) { try { return execFileSync(bin, args, { encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] }).trim(); } catch { return d || ''; } }
|
|
291
291
|
|
|
292
|
-
const dir =
|
|
292
|
+
const dir = path.resolve(__dirname, '..', '..');
|
|
293
293
|
const dbPath = path.join(dir, '.agentic-qe', 'memory.db');
|
|
294
294
|
let patterns = 0;
|
|
295
295
|
try {
|
|
296
296
|
if (fs.existsSync(dbPath)) {
|
|
297
297
|
const Database = require('better-sqlite3');
|
|
298
298
|
const db = new Database(dbPath, { readonly: true, fileMustExist: true });
|
|
299
|
+
db.pragma('busy_timeout = 5000');
|
|
299
300
|
patterns = db.prepare('SELECT COUNT(*) AS c FROM qe_patterns').get()?.c || 0;
|
|
300
301
|
db.close();
|
|
301
302
|
}
|
|
@@ -325,7 +326,8 @@ const { execFileSync } = require('child_process');
|
|
|
325
326
|
const fs = require('fs');
|
|
326
327
|
const path = require('path');
|
|
327
328
|
|
|
328
|
-
const
|
|
329
|
+
const PROJECT_ROOT = path.resolve(__dirname, '..', '..');
|
|
330
|
+
const AQE_DIR = path.join(PROJECT_ROOT, '.agentic-qe');
|
|
329
331
|
const RVF_PATH = path.join(AQE_DIR, 'aqe.rvf');
|
|
330
332
|
const DB_PATH = path.join(AQE_DIR, 'memory.db');
|
|
331
333
|
const MAX_AGE_HOURS = 24;
|
|
@@ -496,7 +498,7 @@ if (process.argv.includes('--json')) process.stdout.write(JSON.stringify(result)
|
|
|
496
498
|
hooks: [
|
|
497
499
|
{
|
|
498
500
|
type: 'command',
|
|
499
|
-
command: 'node
|
|
501
|
+
command: 'node "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.claude/helpers/brain-checkpoint.cjs" verify --json',
|
|
500
502
|
timeout: 5000,
|
|
501
503
|
continueOnError: true,
|
|
502
504
|
},
|
|
@@ -518,7 +520,7 @@ if (process.argv.includes('--json')) process.stdout.write(JSON.stringify(result)
|
|
|
518
520
|
hooks: [
|
|
519
521
|
{
|
|
520
522
|
type: 'command',
|
|
521
|
-
command: 'node
|
|
523
|
+
command: 'node "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.claude/helpers/brain-checkpoint.cjs" export --json',
|
|
522
524
|
timeout: 60000,
|
|
523
525
|
continueOnError: true,
|
|
524
526
|
},
|
|
@@ -73,7 +73,6 @@ export interface InitOptions {
|
|
|
73
73
|
/** Minimal configuration (no skills, patterns, workers) */
|
|
74
74
|
minimal?: boolean;
|
|
75
75
|
/** Automatically migrate from v2 if detected */
|
|
76
|
-
autoMigrate?: boolean;
|
|
77
76
|
/** Install n8n workflow testing platform */
|
|
78
77
|
withN8n?: boolean;
|
|
79
78
|
/** N8n API configuration */
|
|
@@ -97,7 +97,7 @@ export function generateV3SettingsSections(config) {
|
|
|
97
97
|
},
|
|
98
98
|
statusLine: {
|
|
99
99
|
type: 'command',
|
|
100
|
-
command: 'node
|
|
100
|
+
command: 'node "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.claude/helpers/statusline-v3.cjs" 2>/dev/null || echo "▊ Agentic QE v3"',
|
|
101
101
|
refreshMs: 5000,
|
|
102
102
|
enabled: true,
|
|
103
103
|
},
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* - unified-memory-hnsw.ts: HNSW index + BinaryHeap
|
|
22
22
|
* - unified-memory.ts: UnifiedMemoryManager class (this file, facade)
|
|
23
23
|
*/
|
|
24
|
-
import
|
|
24
|
+
import { openDatabase as openSafeDatabase } from '../shared/safe-db.js';
|
|
25
25
|
import { safeJsonParse } from '../shared/safe-json.js';
|
|
26
26
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
27
27
|
import * as fs from 'fs';
|
|
@@ -278,13 +278,12 @@ export class UnifiedMemoryManager {
|
|
|
278
278
|
dbSizeBefore = newest.size;
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
|
-
this.db =
|
|
282
|
-
|
|
283
|
-
this.
|
|
284
|
-
}
|
|
281
|
+
this.db = openSafeDatabase(this.config.dbPath, {
|
|
282
|
+
walMode: this.config.walMode,
|
|
283
|
+
busyTimeout: this.config.busyTimeout,
|
|
284
|
+
});
|
|
285
285
|
this.db.pragma(`mmap_size = ${this.config.mmapSize}`);
|
|
286
286
|
this.db.pragma(`cache_size = ${this.config.cacheSize}`);
|
|
287
|
-
this.db.pragma(`busy_timeout = ${this.config.busyTimeout}`);
|
|
288
287
|
this.db.pragma('foreign_keys = ON');
|
|
289
288
|
await this.runMigrations();
|
|
290
289
|
// DATA LOSS PREVENTION: After migration, if the DB existed before and was
|
|
@@ -170,6 +170,26 @@ async function doInitialize() {
|
|
|
170
170
|
CREATE INDEX IF NOT EXISTS idx_captured_exp_agent ON captured_experiences(agent);
|
|
171
171
|
CREATE INDEX IF NOT EXISTS idx_captured_exp_completed ON captured_experiences(completed_at DESC);
|
|
172
172
|
`);
|
|
173
|
+
// Add consolidation columns if missing (needed by ExperienceConsolidator)
|
|
174
|
+
const colNames = new Set(db.prepare('PRAGMA table_info(captured_experiences)').all().map(c => c.name));
|
|
175
|
+
const consolidationCols = [
|
|
176
|
+
['application_count', 'INTEGER DEFAULT 0'],
|
|
177
|
+
['avg_token_savings', 'REAL DEFAULT 0'],
|
|
178
|
+
['embedding', 'BLOB'],
|
|
179
|
+
['embedding_dimension', 'INTEGER'],
|
|
180
|
+
['tags', 'TEXT'],
|
|
181
|
+
['last_applied_at', 'TEXT'],
|
|
182
|
+
['consolidated_into', 'TEXT DEFAULT NULL'],
|
|
183
|
+
['consolidation_count', 'INTEGER DEFAULT 1'],
|
|
184
|
+
['quality_updated_at', 'TEXT DEFAULT NULL'],
|
|
185
|
+
['reuse_success_count', 'INTEGER DEFAULT 0'],
|
|
186
|
+
['reuse_failure_count', 'INTEGER DEFAULT 0'],
|
|
187
|
+
];
|
|
188
|
+
for (const [col, def] of consolidationCols) {
|
|
189
|
+
if (!colNames.has(col)) {
|
|
190
|
+
db.exec(`ALTER TABLE captured_experiences ADD COLUMN ${col} ${def}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
173
193
|
}
|
|
174
194
|
// Start periodic cleanup of stale experiences
|
|
175
195
|
startCleanupTimer();
|
package/dist/learning/index.d.ts
CHANGED
|
@@ -57,8 +57,6 @@ export { SQLitePatternStore, createSQLitePatternStore, DEFAULT_SQLITE_CONFIG, }
|
|
|
57
57
|
export type { SQLitePersistenceConfig, } from './sqlite-persistence.js';
|
|
58
58
|
export { QEUnifiedMemory, createQEUnifiedMemory, createDefaultQEUnifiedMemory, QE_MEMORY_DOMAINS, QE_DOMAIN_HNSW_CONFIGS, DEFAULT_QE_UNIFIED_MEMORY_CONFIG, } from './qe-unified-memory.js';
|
|
59
59
|
export type { QEMemoryDomain, QEMemoryMetadata, TestSuiteMetadata, DefectMetadata, QualityMetricsMetadata, LearningPatternMetadata, CoordinationMetadata, QEMemorySearchResult, QEMemorySearchOptions, MigrationConfig, MigrationProgress, MigrationResult, MigrationSource, QEUnifiedMemoryConfig, QEUnifiedMemoryStats, QEMemoryDomainStats, IQEUnifiedMemory, } from './qe-unified-memory.js';
|
|
60
|
-
export { V2ToV3Migrator, migrateV2ToV3, } from './v2-to-v3-migration.js';
|
|
61
|
-
export type { V2MigrationConfig, V2MigrationProgress, V2MigrationResult, } from './v2-to-v3-migration.js';
|
|
62
60
|
export { TokenMetricsCollector, TokenMetricsCollectorImpl, formatCostUsd, estimateTokens, } from './token-tracker.js';
|
|
63
61
|
export type { TokenUsage, TaskTokenMetric, AgentTokenMetrics, SessionTokenSummary, TokenEfficiencyReport, Timeframe, TokenCostConfig, } from './token-tracker.js';
|
|
64
62
|
export { ConceptGraph, createConceptGraph, DEFAULT_CONCEPT_GRAPH_CONFIG, } from './dream/index.js';
|
package/dist/learning/index.js
CHANGED
|
@@ -92,10 +92,6 @@ export { SQLitePatternStore, createSQLitePatternStore, DEFAULT_SQLITE_CONFIG, }
|
|
|
92
92
|
// ============================================================================
|
|
93
93
|
export { QEUnifiedMemory, createQEUnifiedMemory, createDefaultQEUnifiedMemory, QE_MEMORY_DOMAINS, QE_DOMAIN_HNSW_CONFIGS, DEFAULT_QE_UNIFIED_MEMORY_CONFIG, } from './qe-unified-memory.js';
|
|
94
94
|
// ============================================================================
|
|
95
|
-
// V2 to V3 Migration (ADR-038)
|
|
96
|
-
// ============================================================================
|
|
97
|
-
export { V2ToV3Migrator, migrateV2ToV3, } from './v2-to-v3-migration.js';
|
|
98
|
-
// ============================================================================
|
|
99
95
|
// Token Tracking (ADR-042)
|
|
100
96
|
// ============================================================================
|
|
101
97
|
export {
|
|
@@ -87,7 +87,7 @@ export class LearningMetricsTracker {
|
|
|
87
87
|
const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
|
|
88
88
|
// Pattern metrics
|
|
89
89
|
const patternStats = this.getPatternStats(today);
|
|
90
|
-
// Experience metrics (from
|
|
90
|
+
// Experience metrics (from captured_experiences or qe_pattern_usage)
|
|
91
91
|
const experienceStats = this.getExperienceStats(today);
|
|
92
92
|
// Q-value metrics
|
|
93
93
|
const qValueStats = this.getQValueStats();
|
|
@@ -169,16 +169,17 @@ export class LearningMetricsTracker {
|
|
|
169
169
|
if (!this.db) {
|
|
170
170
|
return { total: 0, recordedToday: 0, avgReward: 0, successRate: 0 };
|
|
171
171
|
}
|
|
172
|
-
//
|
|
173
|
-
const
|
|
174
|
-
if (
|
|
172
|
+
// Use captured_experiences table
|
|
173
|
+
const capturedTableExists = this.db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='captured_experiences'`).get();
|
|
174
|
+
if (capturedTableExists) {
|
|
175
175
|
const stats = this.db.prepare(`
|
|
176
176
|
SELECT
|
|
177
177
|
COUNT(*) as total,
|
|
178
|
-
SUM(CASE WHEN date(
|
|
179
|
-
AVG(
|
|
180
|
-
AVG(CASE WHEN
|
|
181
|
-
FROM
|
|
178
|
+
SUM(CASE WHEN date(started_at) = ? THEN 1 ELSE 0 END) as recorded_today,
|
|
179
|
+
AVG(quality) as avg_reward,
|
|
180
|
+
AVG(CASE WHEN success = 1 THEN 1.0 ELSE 0.0 END) as success_rate
|
|
181
|
+
FROM captured_experiences
|
|
182
|
+
WHERE agent != 'cli-hook'
|
|
182
183
|
`).get(today);
|
|
183
184
|
return {
|
|
184
185
|
total: stats.total || 0,
|
|
@@ -252,13 +253,14 @@ export class LearningMetricsTracker {
|
|
|
252
253
|
getHistoricalAvgReward(date) {
|
|
253
254
|
if (!this.db)
|
|
254
255
|
return 0;
|
|
255
|
-
//
|
|
256
|
-
const tableExists = this.db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='
|
|
256
|
+
// Use captured_experiences
|
|
257
|
+
const tableExists = this.db.prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='captured_experiences'`).get();
|
|
257
258
|
if (tableExists) {
|
|
258
259
|
const result = this.db.prepare(`
|
|
259
|
-
SELECT AVG(
|
|
260
|
-
FROM
|
|
261
|
-
WHERE
|
|
260
|
+
SELECT AVG(quality) as avg_reward
|
|
261
|
+
FROM captured_experiences
|
|
262
|
+
WHERE started_at <= datetime(?)
|
|
263
|
+
AND agent != 'cli-hook'
|
|
262
264
|
`).get(date + ' 23:59:59');
|
|
263
265
|
return result?.avg_reward || 0;
|
|
264
266
|
}
|
|
@@ -126,7 +126,7 @@ export declare class PatternLifecycleManager {
|
|
|
126
126
|
*/
|
|
127
127
|
private ensureSchema;
|
|
128
128
|
/**
|
|
129
|
-
* Get recent experiences from
|
|
129
|
+
* Get recent experiences from captured_experiences table.
|
|
130
130
|
*/
|
|
131
131
|
getRecentExperiences(options?: {
|
|
132
132
|
minReward?: number;
|
|
@@ -99,40 +99,38 @@ export class PatternLifecycleManager {
|
|
|
99
99
|
// Experience Extraction
|
|
100
100
|
// ============================================================================
|
|
101
101
|
/**
|
|
102
|
-
* Get recent experiences from
|
|
102
|
+
* Get recent experiences from captured_experiences table.
|
|
103
103
|
*/
|
|
104
104
|
getRecentExperiences(options = {}) {
|
|
105
105
|
const minReward = options.minReward ?? this.config.promotionRewardThreshold;
|
|
106
106
|
const limit = options.limit ?? 100;
|
|
107
107
|
const sinceDays = options.sinceDays ?? 7;
|
|
108
|
-
const
|
|
109
|
-
// Check if learning_experiences table exists
|
|
110
|
-
const tableExists = this.db.prepare(`
|
|
111
|
-
SELECT name FROM sqlite_master
|
|
112
|
-
WHERE type='table' AND name='learning_experiences'
|
|
113
|
-
`).get();
|
|
108
|
+
const tableExists = this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='captured_experiences'").get();
|
|
114
109
|
if (!tableExists) {
|
|
115
|
-
|
|
110
|
+
logger.debug('captured_experiences table not found');
|
|
116
111
|
return [];
|
|
117
112
|
}
|
|
113
|
+
const sinceDate = new Date(Date.now() - sinceDays * 86400000)
|
|
114
|
+
.toISOString().replace('T', ' ').slice(0, 19);
|
|
118
115
|
const aggregates = this.db.prepare(`
|
|
119
116
|
SELECT
|
|
120
|
-
task_type,
|
|
117
|
+
domain as task_type,
|
|
121
118
|
COUNT(*) as count,
|
|
122
|
-
AVG(
|
|
123
|
-
MAX(
|
|
124
|
-
MIN(
|
|
125
|
-
SUM(CASE WHEN
|
|
126
|
-
GROUP_CONCAT(DISTINCT
|
|
127
|
-
MAX(
|
|
128
|
-
FROM
|
|
129
|
-
WHERE
|
|
130
|
-
|
|
119
|
+
AVG(quality) as avg_reward,
|
|
120
|
+
MAX(quality) as max_reward,
|
|
121
|
+
MIN(quality) as min_reward,
|
|
122
|
+
SUM(CASE WHEN quality >= ? THEN 1 ELSE 0 END) as success_count,
|
|
123
|
+
GROUP_CONCAT(DISTINCT agent) as actions,
|
|
124
|
+
MAX(started_at) as latest_at
|
|
125
|
+
FROM captured_experiences
|
|
126
|
+
WHERE started_at >= ?
|
|
127
|
+
AND quality >= ?
|
|
128
|
+
AND agent != 'cli-hook'
|
|
129
|
+
GROUP BY domain
|
|
131
130
|
HAVING COUNT(*) >= ?
|
|
132
131
|
ORDER BY avg_reward DESC
|
|
133
132
|
LIMIT ?
|
|
134
|
-
`).all(minReward,
|
|
135
|
-
this.config.promotionMinOccurrences, limit);
|
|
133
|
+
`).all(minReward, sinceDate, minReward * 0.5, this.config.promotionMinOccurrences, limit);
|
|
136
134
|
return aggregates.map(agg => ({
|
|
137
135
|
taskType: agg.task_type,
|
|
138
136
|
domain: this.taskTypeToQEDomain(agg.task_type),
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
import { LoggerFactory } from '../logging/index.js';
|
|
23
23
|
const logger = LoggerFactory.create('qe-unified-memory');
|
|
24
24
|
import { ok, err } from '../shared/types/index.js';
|
|
25
|
-
import { migrateV2ToV3 } from './v2-to-v3-migration.js';
|
|
26
25
|
import { EMBEDDING_CONFIG } from '../shared/embeddings/types.js';
|
|
27
26
|
import { toErrorMessage } from '../shared/error-utils.js';
|
|
28
27
|
import { HNSWIndex, } from '../domains/coverage-analysis/services/hnsw-index.js';
|
|
@@ -508,33 +507,7 @@ export class QEUnifiedMemory {
|
|
|
508
507
|
// Private Migration Helpers
|
|
509
508
|
// -------------------------------------------------------------------------
|
|
510
509
|
async migrateFromSQLite(config) {
|
|
511
|
-
//
|
|
512
|
-
const sourcePath = config.sourceConfig?.path || '.agentic-qe/memory.db';
|
|
513
|
-
// For V2 to V3 migration, use the dedicated migrator
|
|
514
|
-
if (config.domain === 'learning' || config.migrateAll) {
|
|
515
|
-
logger.info('Starting V2 to V3 migration', { sourcePath });
|
|
516
|
-
const result = await migrateV2ToV3(sourcePath, '.agentic-qe/memory.db', (progress) => {
|
|
517
|
-
logger.info('Migration progress', {
|
|
518
|
-
stage: progress.stage,
|
|
519
|
-
message: progress.message,
|
|
520
|
-
table: progress.table,
|
|
521
|
-
current: progress.current,
|
|
522
|
-
total: progress.total,
|
|
523
|
-
});
|
|
524
|
-
});
|
|
525
|
-
if (result.success) {
|
|
526
|
-
logger.info('V2 migration completed successfully', {
|
|
527
|
-
tablesMigrated: result.tablesMigrated,
|
|
528
|
-
totalRecords: Object.values(result.counts).reduce((a, b) => a + b, 0),
|
|
529
|
-
durationSeconds: Number((result.duration / 1000).toFixed(2)),
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
|
-
else {
|
|
533
|
-
logger.error('V2 migration failed', undefined, { errors: result.errors });
|
|
534
|
-
}
|
|
535
|
-
return Object.values(result.counts).reduce((a, b) => a + b, 0);
|
|
536
|
-
}
|
|
537
|
-
// Generic SQLite migration for other domains
|
|
510
|
+
// Generic SQLite migration
|
|
538
511
|
logger.warn('Generic SQLite migration not yet implemented', { domain: config.domain });
|
|
539
512
|
return 0;
|
|
540
513
|
}
|