olympus-ai 2.5.3 → 2.6.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/__tests__/learning/agent-evaluator.test.d.ts +2 -0
- package/dist/__tests__/learning/agent-evaluator.test.d.ts.map +1 -0
- package/dist/__tests__/learning/agent-evaluator.test.js +29 -0
- package/dist/__tests__/learning/agent-evaluator.test.js.map +1 -0
- package/dist/__tests__/learning/discovery.test.d.ts +2 -0
- package/dist/__tests__/learning/discovery.test.d.ts.map +1 -0
- package/dist/__tests__/learning/discovery.test.js +70 -0
- package/dist/__tests__/learning/discovery.test.js.map +1 -0
- package/dist/__tests__/learning/fixtures/mock-feedback.d.ts +14 -0
- package/dist/__tests__/learning/fixtures/mock-feedback.d.ts.map +1 -0
- package/dist/__tests__/learning/fixtures/mock-feedback.js +146 -0
- package/dist/__tests__/learning/fixtures/mock-feedback.js.map +1 -0
- package/dist/__tests__/learning/pattern-extractor.test.d.ts +2 -0
- package/dist/__tests__/learning/pattern-extractor.test.d.ts.map +1 -0
- package/dist/__tests__/learning/pattern-extractor.test.js +30 -0
- package/dist/__tests__/learning/pattern-extractor.test.js.map +1 -0
- package/dist/__tests__/learning/revision-detector.test.d.ts +2 -0
- package/dist/__tests__/learning/revision-detector.test.d.ts.map +1 -0
- package/dist/__tests__/learning/revision-detector.test.js +54 -0
- package/dist/__tests__/learning/revision-detector.test.js.map +1 -0
- package/dist/cli/index.js +264 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/hooks/agent-usage-reminder/index.d.ts +1 -0
- package/dist/hooks/agent-usage-reminder/index.d.ts.map +1 -1
- package/dist/hooks/agent-usage-reminder/index.js +107 -0
- package/dist/hooks/agent-usage-reminder/index.js.map +1 -1
- package/dist/hooks/agent-usage-reminder/index.test.d.ts +5 -0
- package/dist/hooks/agent-usage-reminder/index.test.d.ts.map +1 -0
- package/dist/hooks/agent-usage-reminder/index.test.js +141 -0
- package/dist/hooks/agent-usage-reminder/index.test.js.map +1 -0
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +14 -2
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/keyword-detector/index.d.ts +1 -1
- package/dist/hooks/keyword-detector/index.d.ts.map +1 -1
- package/dist/hooks/keyword-detector/index.js +2 -1
- package/dist/hooks/keyword-detector/index.js.map +1 -1
- package/dist/hooks/olympus-hooks.cjs +162 -67
- package/dist/hooks/olympus-state/index.d.ts +69 -0
- package/dist/hooks/olympus-state/index.d.ts.map +1 -0
- package/dist/hooks/olympus-state/index.js +226 -0
- package/dist/hooks/olympus-state/index.js.map +1 -0
- package/dist/hooks/persistent-mode/index.d.ts +7 -6
- package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/index.js +94 -5
- package/dist/hooks/persistent-mode/index.js.map +1 -1
- package/dist/hooks/registrations/session-start.d.ts.map +1 -1
- package/dist/hooks/registrations/session-start.js +26 -0
- package/dist/hooks/registrations/session-start.js.map +1 -1
- package/dist/hooks/registrations/stop.d.ts.map +1 -1
- package/dist/hooks/registrations/stop.js +25 -0
- package/dist/hooks/registrations/stop.js.map +1 -1
- package/dist/hooks/registrations/user-prompt-submit.d.ts.map +1 -1
- package/dist/hooks/registrations/user-prompt-submit.js +34 -0
- package/dist/hooks/registrations/user-prompt-submit.js.map +1 -1
- package/dist/installer/hooks.d.ts +7 -1
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +61 -2
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts +1 -1
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +40 -14
- package/dist/installer/index.js.map +1 -1
- package/dist/learning/agent-evaluator.d.ts +6 -0
- package/dist/learning/agent-evaluator.d.ts.map +1 -0
- package/dist/learning/agent-evaluator.js +116 -0
- package/dist/learning/agent-evaluator.js.map +1 -0
- package/dist/learning/discovery-validator.d.ts +21 -0
- package/dist/learning/discovery-validator.d.ts.map +1 -0
- package/dist/learning/discovery-validator.js +75 -0
- package/dist/learning/discovery-validator.js.map +1 -0
- package/dist/learning/discovery.d.ts +20 -0
- package/dist/learning/discovery.d.ts.map +1 -0
- package/dist/learning/discovery.js +141 -0
- package/dist/learning/discovery.js.map +1 -0
- package/dist/learning/hooks/cancellation-detector.d.ts +8 -0
- package/dist/learning/hooks/cancellation-detector.d.ts.map +1 -0
- package/dist/learning/hooks/cancellation-detector.js +64 -0
- package/dist/learning/hooks/cancellation-detector.js.map +1 -0
- package/dist/learning/hooks/learned-context.d.ts +6 -0
- package/dist/learning/hooks/learned-context.d.ts.map +1 -0
- package/dist/learning/hooks/learned-context.js +104 -0
- package/dist/learning/hooks/learned-context.js.map +1 -0
- package/dist/learning/hooks/revision-detector.d.ts +9 -0
- package/dist/learning/hooks/revision-detector.d.ts.map +1 -0
- package/dist/learning/hooks/revision-detector.js +92 -0
- package/dist/learning/hooks/revision-detector.js.map +1 -0
- package/dist/learning/hooks/success-detector.d.ts +4 -0
- package/dist/learning/hooks/success-detector.d.ts.map +1 -0
- package/dist/learning/hooks/success-detector.js +58 -0
- package/dist/learning/hooks/success-detector.js.map +1 -0
- package/dist/learning/index.d.ts +10 -0
- package/dist/learning/index.d.ts.map +1 -0
- package/dist/learning/index.js +17 -0
- package/dist/learning/index.js.map +1 -0
- package/dist/learning/migrate-notepads.d.ts +6 -0
- package/dist/learning/migrate-notepads.d.ts.map +1 -0
- package/dist/learning/migrate-notepads.js +77 -0
- package/dist/learning/migrate-notepads.js.map +1 -0
- package/dist/learning/pattern-extractor.d.ts +6 -0
- package/dist/learning/pattern-extractor.d.ts.map +1 -0
- package/dist/learning/pattern-extractor.js +106 -0
- package/dist/learning/pattern-extractor.js.map +1 -0
- package/dist/learning/preference-learner.d.ts +6 -0
- package/dist/learning/preference-learner.d.ts.map +1 -0
- package/dist/learning/preference-learner.js +96 -0
- package/dist/learning/preference-learner.js.map +1 -0
- package/dist/learning/prompt-patcher.d.ts +24 -0
- package/dist/learning/prompt-patcher.d.ts.map +1 -0
- package/dist/learning/prompt-patcher.js +120 -0
- package/dist/learning/prompt-patcher.js.map +1 -0
- package/dist/learning/session-state.d.ts +18 -0
- package/dist/learning/session-state.d.ts.map +1 -0
- package/dist/learning/session-state.js +78 -0
- package/dist/learning/session-state.js.map +1 -0
- package/dist/learning/storage.d.ts +18 -0
- package/dist/learning/storage.d.ts.map +1 -0
- package/dist/learning/storage.js +74 -0
- package/dist/learning/storage.js.map +1 -0
- package/dist/learning/types.d.ts +138 -0
- package/dist/learning/types.d.ts.map +1 -0
- package/dist/learning/types.js +6 -0
- package/dist/learning/types.js.map +1 -0
- package/dist/shared/types.d.ts +12 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { recordDiscovery } from './discovery.js';
|
|
4
|
+
/**
|
|
5
|
+
* Migrate existing notepad content to discoveries.
|
|
6
|
+
* This is a one-time migration utility.
|
|
7
|
+
*/
|
|
8
|
+
export async function migrateNotepads(projectPath) {
|
|
9
|
+
const notepadsDir = join(projectPath, '.olympus', 'notepads');
|
|
10
|
+
if (!existsSync(notepadsDir)) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
let migratedCount = 0;
|
|
14
|
+
// Recursively find all .md files
|
|
15
|
+
const planDirs = readdirSync(notepadsDir, { withFileTypes: true })
|
|
16
|
+
.filter(d => d.isDirectory())
|
|
17
|
+
.map(d => d.name);
|
|
18
|
+
for (const planDir of planDirs) {
|
|
19
|
+
const planPath = join(notepadsDir, planDir);
|
|
20
|
+
const files = readdirSync(planPath).filter(f => f.endsWith('.md'));
|
|
21
|
+
for (const file of files) {
|
|
22
|
+
const content = readFileSync(join(planPath, file), 'utf-8');
|
|
23
|
+
// Parse markdown sections into discoveries
|
|
24
|
+
const discoveries = parseNotepadContent(content, planDir);
|
|
25
|
+
for (const d of discoveries) {
|
|
26
|
+
recordDiscovery({
|
|
27
|
+
...d,
|
|
28
|
+
session_id: 'migration',
|
|
29
|
+
project_path: projectPath,
|
|
30
|
+
agent_name: 'migration',
|
|
31
|
+
confidence: 0.7, // Lower confidence for migrated content
|
|
32
|
+
scope: 'project',
|
|
33
|
+
});
|
|
34
|
+
migratedCount++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return migratedCount;
|
|
39
|
+
}
|
|
40
|
+
function parseNotepadContent(content, taskContext) {
|
|
41
|
+
// Simple parsing: each H3 (###) becomes a discovery
|
|
42
|
+
const sections = content.split(/^### /m).slice(1);
|
|
43
|
+
return sections.map(section => {
|
|
44
|
+
const lines = section.split('\n');
|
|
45
|
+
const summary = lines[0].trim().slice(0, 100);
|
|
46
|
+
const details = lines.slice(1).join('\n').trim();
|
|
47
|
+
return {
|
|
48
|
+
category: inferCategory(summary, details),
|
|
49
|
+
summary,
|
|
50
|
+
details: details || summary,
|
|
51
|
+
task_context: taskContext,
|
|
52
|
+
};
|
|
53
|
+
}).filter(d => d.summary.length >= 10 && d.details.length >= 20);
|
|
54
|
+
}
|
|
55
|
+
function inferCategory(summary, details) {
|
|
56
|
+
const text = (summary + ' ' + details).toLowerCase();
|
|
57
|
+
if (text.includes('performance') || text.includes('slow') || text.includes('optimize')) {
|
|
58
|
+
return 'performance';
|
|
59
|
+
}
|
|
60
|
+
if (text.includes('workaround') || text.includes('hack') || text.includes('fix')) {
|
|
61
|
+
return 'workaround';
|
|
62
|
+
}
|
|
63
|
+
if (text.includes('pattern') || text.includes('convention') || text.includes('style')) {
|
|
64
|
+
return 'pattern';
|
|
65
|
+
}
|
|
66
|
+
if (text.includes('gotcha') || text.includes('careful') || text.includes('warning')) {
|
|
67
|
+
return 'gotcha';
|
|
68
|
+
}
|
|
69
|
+
if (text.includes('dependency') || text.includes('package') || text.includes('install')) {
|
|
70
|
+
return 'dependency';
|
|
71
|
+
}
|
|
72
|
+
if (text.includes('config') || text.includes('environment') || text.includes('setting')) {
|
|
73
|
+
return 'configuration';
|
|
74
|
+
}
|
|
75
|
+
return 'technical_insight';
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=migrate-notepads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate-notepads.js","sourceRoot":"","sources":["../../src/learning/migrate-notepads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAmB;IACvD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IAE9D,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,aAAa,GAAG,CAAC,CAAC;IAEtB,iCAAiC;IACjC,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAC/D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEpB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAEnE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YAE5D,2CAA2C;YAC3C,MAAM,WAAW,GAAG,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAE1D,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;gBAC5B,eAAe,CAAC;oBACd,GAAG,CAAC;oBACJ,UAAU,EAAE,WAAW;oBACvB,YAAY,EAAE,WAAW;oBACzB,UAAU,EAAE,WAAW;oBACvB,UAAU,EAAE,GAAG,EAAE,wCAAwC;oBACzD,KAAK,EAAE,SAAS;iBACjB,CAAC,CAAC;gBACH,aAAa,EAAE,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AASD,SAAS,mBAAmB,CAAC,OAAe,EAAE,WAAmB;IAC/D,oDAAoD;IACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAElD,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;QAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAEjD,OAAO;YACL,QAAQ,EAAE,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC;YACzC,OAAO;YACP,OAAO,EAAE,OAAO,IAAI,OAAO;YAC3B,YAAY,EAAE,WAAW;SAC1B,CAAC;IACJ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,aAAa,CAAC,OAAe,EAAE,OAAe;IACrD,MAAM,IAAI,GAAG,CAAC,OAAO,GAAG,GAAG,GAAG,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IAErD,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACvF,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACjF,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACpF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACxF,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACxF,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,OAAO,mBAAmB,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FeedbackEntry, ExtractedPattern } from './types.js';
|
|
2
|
+
/** Calculate Jaccard similarity between two texts (exported for reuse) */
|
|
3
|
+
export declare function jaccardSimilarity(text1: string, text2: string): number;
|
|
4
|
+
/** Extract patterns from feedback log */
|
|
5
|
+
export declare function extractPatterns(feedbackLog: FeedbackEntry[], minOccurrences?: number): ExtractedPattern[];
|
|
6
|
+
//# sourceMappingURL=pattern-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-extractor.d.ts","sourceRoot":"","sources":["../../src/learning/pattern-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAkBlE,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQtE;AAgCD,yCAAyC;AACzC,wBAAgB,eAAe,CAC7B,WAAW,EAAE,aAAa,EAAE,EAC5B,cAAc,GAAE,MAAU,GACzB,gBAAgB,EAAE,CAqCpB"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/** Extract n-grams from text for similarity comparison */
|
|
2
|
+
function extractNgrams(text, n = 3) {
|
|
3
|
+
const normalized = text.toLowerCase().replace(/[^\w\s]/g, '');
|
|
4
|
+
const words = normalized.split(/\s+/).filter(w => w.length > 0);
|
|
5
|
+
if (words.length < n) {
|
|
6
|
+
return new Set([normalized]);
|
|
7
|
+
}
|
|
8
|
+
const ngrams = new Set();
|
|
9
|
+
for (let i = 0; i <= words.length - n; i++) {
|
|
10
|
+
ngrams.add(words.slice(i, i + n).join(' '));
|
|
11
|
+
}
|
|
12
|
+
return ngrams;
|
|
13
|
+
}
|
|
14
|
+
/** Calculate Jaccard similarity between two texts (exported for reuse) */
|
|
15
|
+
export function jaccardSimilarity(text1, text2) {
|
|
16
|
+
const ngrams1 = extractNgrams(text1);
|
|
17
|
+
const ngrams2 = extractNgrams(text2);
|
|
18
|
+
const intersection = new Set([...ngrams1].filter(x => ngrams2.has(x)));
|
|
19
|
+
const union = new Set([...ngrams1, ...ngrams2]);
|
|
20
|
+
return union.size > 0 ? intersection.size / union.size : 0;
|
|
21
|
+
}
|
|
22
|
+
/** Group similar feedback entries */
|
|
23
|
+
function clusterFeedback(entries, similarityThreshold = 0.3) {
|
|
24
|
+
const clusters = [];
|
|
25
|
+
const assigned = new Set();
|
|
26
|
+
for (const entry of entries) {
|
|
27
|
+
if (assigned.has(entry.id))
|
|
28
|
+
continue;
|
|
29
|
+
const cluster = [entry];
|
|
30
|
+
assigned.add(entry.id);
|
|
31
|
+
for (const other of entries) {
|
|
32
|
+
if (assigned.has(other.id))
|
|
33
|
+
continue;
|
|
34
|
+
const similarity = jaccardSimilarity(entry.user_message, other.user_message);
|
|
35
|
+
if (similarity >= similarityThreshold) {
|
|
36
|
+
cluster.push(other);
|
|
37
|
+
assigned.add(other.id);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
clusters.push(cluster);
|
|
41
|
+
}
|
|
42
|
+
return clusters;
|
|
43
|
+
}
|
|
44
|
+
/** Extract patterns from feedback log */
|
|
45
|
+
export function extractPatterns(feedbackLog, minOccurrences = 3) {
|
|
46
|
+
// Only analyze corrections and clarifications
|
|
47
|
+
const relevantFeedback = feedbackLog.filter(e => e.feedback_category === 'correction' ||
|
|
48
|
+
e.feedback_category === 'clarification' ||
|
|
49
|
+
e.feedback_category === 'explicit_preference');
|
|
50
|
+
const clusters = clusterFeedback(relevantFeedback);
|
|
51
|
+
return clusters
|
|
52
|
+
.filter(cluster => cluster.length >= minOccurrences)
|
|
53
|
+
.map(cluster => {
|
|
54
|
+
// Use the most recent entry as the pattern description
|
|
55
|
+
const mostRecent = cluster.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())[0];
|
|
56
|
+
// Calculate average confidence
|
|
57
|
+
const avgConfidence = cluster.reduce((sum, e) => sum + e.confidence, 0) / cluster.length;
|
|
58
|
+
// Determine scope
|
|
59
|
+
const projectPaths = new Set(cluster.map(e => e.project_path));
|
|
60
|
+
const scope = projectPaths.size === 1 ? 'project' : 'global';
|
|
61
|
+
// Categorize
|
|
62
|
+
const category = categorizePattern(cluster);
|
|
63
|
+
return {
|
|
64
|
+
pattern: generatePatternDescription(cluster),
|
|
65
|
+
confidence: avgConfidence,
|
|
66
|
+
evidence_count: cluster.length,
|
|
67
|
+
evidence_examples: cluster.slice(0, 3).map(e => e.user_message),
|
|
68
|
+
scope,
|
|
69
|
+
category,
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/** Generate human-readable pattern description */
|
|
74
|
+
function generatePatternDescription(cluster) {
|
|
75
|
+
// Find common keywords in the cluster
|
|
76
|
+
const allWords = new Map();
|
|
77
|
+
for (const entry of cluster) {
|
|
78
|
+
const words = entry.user_message.toLowerCase()
|
|
79
|
+
.replace(/[^\w\s]/g, '')
|
|
80
|
+
.split(/\s+/)
|
|
81
|
+
.filter(w => w.length > 3);
|
|
82
|
+
for (const word of words) {
|
|
83
|
+
allWords.set(word, (allWords.get(word) || 0) + 1);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Get top 3 most common words
|
|
87
|
+
const topWords = [...allWords.entries()]
|
|
88
|
+
.sort((a, b) => b[1] - a[1])
|
|
89
|
+
.slice(0, 3)
|
|
90
|
+
.map(([word]) => word);
|
|
91
|
+
// Return most recent message as base, with common themes noted
|
|
92
|
+
const mostRecent = cluster[0].user_message.substring(0, 100);
|
|
93
|
+
return mostRecent + (topWords.length > 0 ? ` [themes: ${topWords.join(', ')}]` : '');
|
|
94
|
+
}
|
|
95
|
+
/** Categorize pattern based on content */
|
|
96
|
+
function categorizePattern(cluster) {
|
|
97
|
+
const text = cluster.map(e => e.user_message).join(' ').toLowerCase();
|
|
98
|
+
if (/typescript|eslint|prettier|format|indent|naming/i.test(text))
|
|
99
|
+
return 'style';
|
|
100
|
+
if (/test|build|npm|yarn|run|command|install/i.test(text))
|
|
101
|
+
return 'tooling';
|
|
102
|
+
if (/verbose|brief|explain|detail|ask|confirm/i.test(text))
|
|
103
|
+
return 'communication';
|
|
104
|
+
return 'behavior';
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=pattern-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-extractor.js","sourceRoot":"","sources":["../../src/learning/pattern-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FeedbackEntry, UserPreferences, ExtractedPattern } from './types.js';
|
|
2
|
+
/** Update preferences based on new feedback */
|
|
3
|
+
export declare function updatePreferences(currentPrefs: UserPreferences, newFeedback: FeedbackEntry[], extractedPatterns: ExtractedPattern[]): UserPreferences;
|
|
4
|
+
/** Create default preferences object */
|
|
5
|
+
export declare function createDefaultPreferences(): UserPreferences;
|
|
6
|
+
//# sourceMappingURL=preference-learner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preference-learner.d.ts","sourceRoot":"","sources":["../../src/learning/preference-learner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAgEnF,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,eAAe,EAC7B,WAAW,EAAE,aAAa,EAAE,EAC5B,iBAAiB,EAAE,gBAAgB,EAAE,GACpC,eAAe,CAgDjB;AAED,wCAAwC;AACxC,wBAAgB,wBAAwB,IAAI,eAAe,CAE1D"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { jaccardSimilarity } from './pattern-extractor.js';
|
|
2
|
+
const DEFAULT_PREFERENCES = {
|
|
3
|
+
verbosity: 'unknown',
|
|
4
|
+
autonomy: 'unknown',
|
|
5
|
+
explanation_depth: 'unknown',
|
|
6
|
+
explicit_rules: [],
|
|
7
|
+
inferred_preferences: [],
|
|
8
|
+
recurring_corrections: [],
|
|
9
|
+
last_updated: new Date().toISOString(),
|
|
10
|
+
};
|
|
11
|
+
/** Preference decay factor - old preferences lose weight over time */
|
|
12
|
+
const DECAY_DAYS = 30;
|
|
13
|
+
/** Extract explicit preferences from "always/never" statements */
|
|
14
|
+
function extractExplicitPreferences(feedback) {
|
|
15
|
+
const explicit = feedback.filter(e => e.feedback_category === 'explicit_preference');
|
|
16
|
+
const rules = [];
|
|
17
|
+
for (const entry of explicit) {
|
|
18
|
+
// Extract the rule from statements like "always use TypeScript"
|
|
19
|
+
const alwaysMatch = entry.user_message.match(/always\s+(.+?)(?:\.|$)/i);
|
|
20
|
+
const neverMatch = entry.user_message.match(/never\s+(.+?)(?:\.|$)/i);
|
|
21
|
+
if (alwaysMatch)
|
|
22
|
+
rules.push(`Always: ${alwaysMatch[1].trim()}`);
|
|
23
|
+
if (neverMatch)
|
|
24
|
+
rules.push(`Never: ${neverMatch[1].trim()}`);
|
|
25
|
+
}
|
|
26
|
+
return [...new Set(rules)]; // Deduplicate
|
|
27
|
+
}
|
|
28
|
+
/** Infer verbosity preference from feedback patterns */
|
|
29
|
+
function inferVerbosity(feedback) {
|
|
30
|
+
const verboseComplaints = feedback.filter(e => /too (long|verbose|much|wordy)/i.test(e.user_message)).length;
|
|
31
|
+
const briefComplaints = feedback.filter(e => /more (detail|info|explanation)|too (brief|short)/i.test(e.user_message)).length;
|
|
32
|
+
if (verboseComplaints >= 3 && verboseComplaints > briefComplaints)
|
|
33
|
+
return 'concise';
|
|
34
|
+
if (briefComplaints >= 3 && briefComplaints > verboseComplaints)
|
|
35
|
+
return 'detailed';
|
|
36
|
+
return 'unknown';
|
|
37
|
+
}
|
|
38
|
+
/** Infer autonomy preference from feedback patterns */
|
|
39
|
+
function inferAutonomy(feedback) {
|
|
40
|
+
const askFirst = feedback.filter(e => /ask (me )?(first|before)|don't assume|confirm/i.test(e.user_message)).length;
|
|
41
|
+
const justDoIt = feedback.filter(e => /just (do|make|fix)|don't ask|stop asking/i.test(e.user_message)).length;
|
|
42
|
+
if (askFirst >= 3 && askFirst > justDoIt)
|
|
43
|
+
return 'ask_first';
|
|
44
|
+
if (justDoIt >= 3 && justDoIt > askFirst)
|
|
45
|
+
return 'just_do_it';
|
|
46
|
+
if (askFirst >= 2 && justDoIt >= 2)
|
|
47
|
+
return 'balanced';
|
|
48
|
+
return 'unknown';
|
|
49
|
+
}
|
|
50
|
+
/** Update preferences based on new feedback */
|
|
51
|
+
export function updatePreferences(currentPrefs, newFeedback, extractedPatterns) {
|
|
52
|
+
// Start with current preferences
|
|
53
|
+
const updated = { ...currentPrefs };
|
|
54
|
+
// Add new explicit rules
|
|
55
|
+
const newRules = extractExplicitPreferences(newFeedback);
|
|
56
|
+
updated.explicit_rules = [...new Set([...updated.explicit_rules, ...newRules])];
|
|
57
|
+
// Update verbosity if we have enough signal
|
|
58
|
+
const newVerbosity = inferVerbosity(newFeedback);
|
|
59
|
+
if (newVerbosity !== 'unknown') {
|
|
60
|
+
updated.verbosity = newVerbosity;
|
|
61
|
+
}
|
|
62
|
+
// Update autonomy if we have enough signal
|
|
63
|
+
const newAutonomy = inferAutonomy(newFeedback);
|
|
64
|
+
if (newAutonomy !== 'unknown') {
|
|
65
|
+
updated.autonomy = newAutonomy;
|
|
66
|
+
}
|
|
67
|
+
// Add inferred preferences from patterns
|
|
68
|
+
const inferred = extractedPatterns
|
|
69
|
+
.filter(p => p.confidence > 0.7 && p.scope === 'global')
|
|
70
|
+
.map(p => p.pattern);
|
|
71
|
+
updated.inferred_preferences = [...new Set([...updated.inferred_preferences, ...inferred])];
|
|
72
|
+
// Update recurring corrections
|
|
73
|
+
for (const pattern of extractedPatterns) {
|
|
74
|
+
const existing = updated.recurring_corrections.find(c => jaccardSimilarity(c.pattern, pattern.pattern) > 0.5);
|
|
75
|
+
if (existing) {
|
|
76
|
+
existing.count = pattern.evidence_count;
|
|
77
|
+
existing.last_seen = new Date().toISOString();
|
|
78
|
+
existing.examples = pattern.evidence_examples;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
updated.recurring_corrections.push({
|
|
82
|
+
pattern: pattern.pattern,
|
|
83
|
+
count: pattern.evidence_count,
|
|
84
|
+
last_seen: new Date().toISOString(),
|
|
85
|
+
examples: pattern.evidence_examples,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
updated.last_updated = new Date().toISOString();
|
|
90
|
+
return updated;
|
|
91
|
+
}
|
|
92
|
+
/** Create default preferences object */
|
|
93
|
+
export function createDefaultPreferences() {
|
|
94
|
+
return { ...DEFAULT_PREFERENCES, last_updated: new Date().toISOString() };
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=preference-learner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preference-learner.js","sourceRoot":"","sources":["../../src/learning/preference-learner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AgentPerformance, UserPreferences } from './types.js';
|
|
2
|
+
export interface PromptPatch {
|
|
3
|
+
agent_name: string;
|
|
4
|
+
patch_type: 'append' | 'prepend';
|
|
5
|
+
content: string;
|
|
6
|
+
reason: string;
|
|
7
|
+
confidence: number;
|
|
8
|
+
evidence_count: number;
|
|
9
|
+
}
|
|
10
|
+
export interface PatchResult {
|
|
11
|
+
agent_name: string;
|
|
12
|
+
success: boolean;
|
|
13
|
+
backup_path?: string;
|
|
14
|
+
error?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Generate prompt patches based on learnings */
|
|
17
|
+
export declare function generatePromptPatches(agentPerformance: Map<string, AgentPerformance>, userPreferences: UserPreferences): PromptPatch[];
|
|
18
|
+
/** Preview patches (dry run) */
|
|
19
|
+
export declare function previewPatches(patches: PromptPatch[]): string;
|
|
20
|
+
/** Apply patches to agent prompt files */
|
|
21
|
+
export declare function applyPromptPatches(patches: PromptPatch[], agentsDir?: string): PatchResult[];
|
|
22
|
+
/** Revert a patch using backup file */
|
|
23
|
+
export declare function revertPatch(backupPath: string): boolean;
|
|
24
|
+
//# sourceMappingURL=prompt-patcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-patcher.d.ts","sourceRoot":"","sources":["../../src/learning/prompt-patcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKpE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,QAAQ,GAAG,SAAS,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,iDAAiD;AACjD,wBAAgB,qBAAqB,CACnC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAC/C,eAAe,EAAE,eAAe,GAC/B,WAAW,EAAE,CA2Cf;AAED,gCAAgC;AAChC,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAa7D;AAED,0CAA0C;AAC1C,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,WAAW,EAAE,EACtB,SAAS,GAAE,MAA6C,GACvD,WAAW,EAAE,CAiDf;AAED,uCAAuC;AACvC,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAQvD"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, copyFileSync, readdirSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
/** Generate prompt patches based on learnings */
|
|
5
|
+
export function generatePromptPatches(agentPerformance, userPreferences) {
|
|
6
|
+
const patches = [];
|
|
7
|
+
// Generate patches from agent failure patterns
|
|
8
|
+
for (const [agent, perf] of agentPerformance) {
|
|
9
|
+
for (const failure of perf.failure_patterns) {
|
|
10
|
+
if (failure.count >= 3) {
|
|
11
|
+
patches.push({
|
|
12
|
+
agent_name: agent,
|
|
13
|
+
patch_type: 'append',
|
|
14
|
+
content: `\n\n## Learned: ${failure.pattern}\nBe extra careful with: ${failure.pattern}. This has been flagged ${failure.count} times.`,
|
|
15
|
+
reason: `Agent failed on "${failure.pattern}" ${failure.count} times`,
|
|
16
|
+
confidence: Math.min(0.5 + failure.count * 0.1, 0.95),
|
|
17
|
+
evidence_count: failure.count,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Generate patches from user preferences
|
|
23
|
+
if (userPreferences.verbosity === 'concise') {
|
|
24
|
+
patches.push({
|
|
25
|
+
agent_name: '*', // All agents
|
|
26
|
+
patch_type: 'append',
|
|
27
|
+
content: '\n\n## User Preference\nKeep responses concise. Avoid unnecessary verbosity.',
|
|
28
|
+
reason: 'User prefers concise responses',
|
|
29
|
+
confidence: 0.85,
|
|
30
|
+
evidence_count: 3,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
for (const rule of userPreferences.explicit_rules) {
|
|
34
|
+
patches.push({
|
|
35
|
+
agent_name: '*',
|
|
36
|
+
patch_type: 'append',
|
|
37
|
+
content: `\n\n## User Rule\n${rule}`,
|
|
38
|
+
reason: 'Explicit user preference',
|
|
39
|
+
confidence: 0.95,
|
|
40
|
+
evidence_count: 1,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return patches;
|
|
44
|
+
}
|
|
45
|
+
/** Preview patches (dry run) */
|
|
46
|
+
export function previewPatches(patches) {
|
|
47
|
+
const lines = ['Suggested Prompt Patches:', ''];
|
|
48
|
+
for (const patch of patches) {
|
|
49
|
+
lines.push(`Agent: ${patch.agent_name}`);
|
|
50
|
+
lines.push(`Type: ${patch.patch_type}`);
|
|
51
|
+
lines.push(`Reason: ${patch.reason}`);
|
|
52
|
+
lines.push(`Confidence: ${(patch.confidence * 100).toFixed(0)}%`);
|
|
53
|
+
lines.push(`Content: ${patch.content.substring(0, 100)}...`);
|
|
54
|
+
lines.push('---');
|
|
55
|
+
}
|
|
56
|
+
return lines.join('\n');
|
|
57
|
+
}
|
|
58
|
+
/** Apply patches to agent prompt files */
|
|
59
|
+
export function applyPromptPatches(patches, agentsDir = join(homedir(), '.claude', 'agents')) {
|
|
60
|
+
const results = [];
|
|
61
|
+
for (const patch of patches) {
|
|
62
|
+
const agentFiles = patch.agent_name === '*'
|
|
63
|
+
? getAllAgentFiles(agentsDir)
|
|
64
|
+
: [join(agentsDir, `${patch.agent_name}.md`)];
|
|
65
|
+
for (const filePath of agentFiles) {
|
|
66
|
+
if (!existsSync(filePath)) {
|
|
67
|
+
results.push({
|
|
68
|
+
agent_name: patch.agent_name,
|
|
69
|
+
success: false,
|
|
70
|
+
error: `File not found: ${filePath}`,
|
|
71
|
+
});
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
// Create backup
|
|
76
|
+
const backupPath = `${filePath}.backup.${Date.now()}`;
|
|
77
|
+
copyFileSync(filePath, backupPath);
|
|
78
|
+
// Read current content
|
|
79
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
80
|
+
// Apply patch
|
|
81
|
+
const newContent = patch.patch_type === 'prepend'
|
|
82
|
+
? patch.content + '\n\n' + content
|
|
83
|
+
: content + '\n' + patch.content;
|
|
84
|
+
writeFileSync(filePath, newContent, 'utf-8');
|
|
85
|
+
results.push({
|
|
86
|
+
agent_name: patch.agent_name,
|
|
87
|
+
success: true,
|
|
88
|
+
backup_path: backupPath,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
results.push({
|
|
93
|
+
agent_name: patch.agent_name,
|
|
94
|
+
success: false,
|
|
95
|
+
error: error instanceof Error ? error.message : String(error),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return results;
|
|
101
|
+
}
|
|
102
|
+
/** Revert a patch using backup file */
|
|
103
|
+
export function revertPatch(backupPath) {
|
|
104
|
+
const originalPath = backupPath.replace(/\.backup\.\d+$/, '');
|
|
105
|
+
try {
|
|
106
|
+
copyFileSync(backupPath, originalPath);
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function getAllAgentFiles(agentsDir) {
|
|
114
|
+
if (!existsSync(agentsDir))
|
|
115
|
+
return [];
|
|
116
|
+
return readdirSync(agentsDir)
|
|
117
|
+
.filter((f) => f.endsWith('.md'))
|
|
118
|
+
.map((f) => join(agentsDir, f));
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=prompt-patcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-patcher.js","sourceRoot":"","sources":["../../src/learning/prompt-patcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SessionState, FeedbackCategory } from './types.js';
|
|
2
|
+
/** Get session state file path */
|
|
3
|
+
export declare function getSessionStatePath(directory: string): string;
|
|
4
|
+
/** Create fresh session state */
|
|
5
|
+
export declare function createSessionState(sessionId?: string): SessionState;
|
|
6
|
+
/** Load or create session state */
|
|
7
|
+
export declare function loadSessionState(directory: string, sessionId?: string): SessionState;
|
|
8
|
+
/** Save session state */
|
|
9
|
+
export declare function saveSessionState(directory: string, state: SessionState): void;
|
|
10
|
+
/** Add prompt to session state */
|
|
11
|
+
export declare function addPromptToSession(state: SessionState, prompt: string, detectedFeedback?: FeedbackCategory): SessionState;
|
|
12
|
+
/** Mark a completion claim */
|
|
13
|
+
export declare function markCompletionClaim(state: SessionState, taskDescription: string, agentUsed?: string): SessionState;
|
|
14
|
+
/** Clear completion claim (on success or explicit reset) */
|
|
15
|
+
export declare function clearCompletionClaim(state: SessionState): SessionState;
|
|
16
|
+
/** Check if there's a pending completion claim */
|
|
17
|
+
export declare function hasPendingCompletion(state: SessionState): boolean;
|
|
18
|
+
//# sourceMappingURL=session-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../src/learning/session-state.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAO5D,kCAAkC;AAClC,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,iCAAiC;AACjC,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CASnE;AAED,mCAAmC;AACnC,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAgBpF;AAED,yBAAyB;AACzB,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAI7E;AAED,kCAAkC;AAClC,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,EACd,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,YAAY,CAWd;AAED,8BAA8B;AAC9B,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EACnB,eAAe,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,GACjB,YAAY,CAQd;AAED,4DAA4D;AAC5D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CAItE;AAED,kDAAkD;AAClD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAOjE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import { readJsonFile, writeJsonFile } from './storage.js';
|
|
3
|
+
import { randomUUID } from 'crypto';
|
|
4
|
+
const MAX_RECENT_PROMPTS = 10;
|
|
5
|
+
const SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
|
|
6
|
+
/** Get session state file path */
|
|
7
|
+
export function getSessionStatePath(directory) {
|
|
8
|
+
return join(directory, '.olympus', 'session-state.json');
|
|
9
|
+
}
|
|
10
|
+
/** Create fresh session state */
|
|
11
|
+
export function createSessionState(sessionId) {
|
|
12
|
+
return {
|
|
13
|
+
session_id: sessionId || randomUUID(),
|
|
14
|
+
started_at: new Date().toISOString(),
|
|
15
|
+
last_updated: new Date().toISOString(),
|
|
16
|
+
recent_prompts: [],
|
|
17
|
+
pending_completion: null,
|
|
18
|
+
todo_snapshot: null,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Load or create session state */
|
|
22
|
+
export function loadSessionState(directory, sessionId) {
|
|
23
|
+
const path = getSessionStatePath(directory);
|
|
24
|
+
const state = readJsonFile(path, null);
|
|
25
|
+
if (!state) {
|
|
26
|
+
return createSessionState(sessionId);
|
|
27
|
+
}
|
|
28
|
+
// Check for session timeout
|
|
29
|
+
const lastUpdate = new Date(state.last_updated).getTime();
|
|
30
|
+
const now = Date.now();
|
|
31
|
+
if (now - lastUpdate > SESSION_TIMEOUT_MS) {
|
|
32
|
+
return createSessionState(sessionId);
|
|
33
|
+
}
|
|
34
|
+
return state;
|
|
35
|
+
}
|
|
36
|
+
/** Save session state */
|
|
37
|
+
export function saveSessionState(directory, state) {
|
|
38
|
+
const path = getSessionStatePath(directory);
|
|
39
|
+
state.last_updated = new Date().toISOString();
|
|
40
|
+
writeJsonFile(path, state);
|
|
41
|
+
}
|
|
42
|
+
/** Add prompt to session state */
|
|
43
|
+
export function addPromptToSession(state, prompt, detectedFeedback) {
|
|
44
|
+
const entry = {
|
|
45
|
+
prompt,
|
|
46
|
+
timestamp: new Date().toISOString(),
|
|
47
|
+
detected_feedback: detectedFeedback,
|
|
48
|
+
};
|
|
49
|
+
state.recent_prompts = [entry, ...state.recent_prompts].slice(0, MAX_RECENT_PROMPTS);
|
|
50
|
+
state.last_updated = new Date().toISOString();
|
|
51
|
+
return state;
|
|
52
|
+
}
|
|
53
|
+
/** Mark a completion claim */
|
|
54
|
+
export function markCompletionClaim(state, taskDescription, agentUsed) {
|
|
55
|
+
state.pending_completion = {
|
|
56
|
+
claimed_at: new Date().toISOString(),
|
|
57
|
+
task_description: taskDescription,
|
|
58
|
+
agent_used: agentUsed,
|
|
59
|
+
};
|
|
60
|
+
state.last_updated = new Date().toISOString();
|
|
61
|
+
return state;
|
|
62
|
+
}
|
|
63
|
+
/** Clear completion claim (on success or explicit reset) */
|
|
64
|
+
export function clearCompletionClaim(state) {
|
|
65
|
+
state.pending_completion = null;
|
|
66
|
+
state.last_updated = new Date().toISOString();
|
|
67
|
+
return state;
|
|
68
|
+
}
|
|
69
|
+
/** Check if there's a pending completion claim */
|
|
70
|
+
export function hasPendingCompletion(state) {
|
|
71
|
+
if (!state.pending_completion?.claimed_at)
|
|
72
|
+
return false;
|
|
73
|
+
// Consider completion stale after 5 minutes
|
|
74
|
+
const claimedAt = new Date(state.pending_completion.claimed_at).getTime();
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
return now - claimedAt < 5 * 60 * 1000;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=session-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-state.js","sourceRoot":"","sources":["../../src/learning/session-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FeedbackEntry } from './types.js';
|
|
2
|
+
/** Get learning storage directory (cross-platform) */
|
|
3
|
+
export declare function getLearningDir(): string;
|
|
4
|
+
/** Get project-specific learning directory */
|
|
5
|
+
export declare function getProjectLearningDir(projectPath: string): string;
|
|
6
|
+
/** Generate deterministic hash for project path */
|
|
7
|
+
export declare function getProjectHash(projectPath: string): string;
|
|
8
|
+
/** Ensure learning directories exist */
|
|
9
|
+
export declare function ensureLearningDirs(projectPath?: string): void;
|
|
10
|
+
/** Append feedback entry to JSONL log */
|
|
11
|
+
export declare function appendFeedback(entry: FeedbackEntry): void;
|
|
12
|
+
/** Read feedback log */
|
|
13
|
+
export declare function readFeedbackLog(): FeedbackEntry[];
|
|
14
|
+
/** Read JSON file with type safety and error handling */
|
|
15
|
+
export declare function readJsonFile<T>(path: string, defaultValue: T): T;
|
|
16
|
+
/** Write JSON file with error handling */
|
|
17
|
+
export declare function writeJsonFile<T>(filePath: string, data: T): void;
|
|
18
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/learning/storage.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,sDAAsD;AACtD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,8CAA8C;AAC9C,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,mDAAmD;AACnD,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAY7D;AAED,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAIzD;AAED,wBAAwB;AACxB,wBAAgB,eAAe,IAAI,aAAa,EAAE,CASjD;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAQhE;AAED,0CAA0C;AAC1C,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAWhE"}
|