pi-continuous-learning 0.7.0 → 0.9.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/analysis-event-log.d.ts +50 -0
- package/dist/analysis-event-log.d.ts.map +1 -0
- package/dist/analysis-event-log.js +120 -0
- package/dist/analysis-event-log.js.map +1 -0
- package/dist/analysis-notification.d.ts +20 -0
- package/dist/analysis-notification.d.ts.map +1 -0
- package/dist/analysis-notification.js +63 -0
- package/dist/analysis-notification.js.map +1 -0
- package/dist/cli/analyze-single-shot.d.ts +12 -0
- package/dist/cli/analyze-single-shot.d.ts.map +1 -1
- package/dist/cli/analyze-single-shot.js +84 -2
- package/dist/cli/analyze-single-shot.js.map +1 -1
- package/dist/cli/analyze.js +349 -21
- package/dist/cli/analyze.js.map +1 -1
- package/dist/confidence.d.ts +12 -1
- package/dist/confidence.d.ts.map +1 -1
- package/dist/confidence.js +35 -8
- package/dist/confidence.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -1
- package/dist/consolidation.d.ts +43 -0
- package/dist/consolidation.d.ts.map +1 -0
- package/dist/consolidation.js +104 -0
- package/dist/consolidation.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/instinct-cleanup.d.ts +14 -0
- package/dist/instinct-cleanup.d.ts.map +1 -1
- package/dist/instinct-cleanup.js +59 -3
- package/dist/instinct-cleanup.js.map +1 -1
- package/dist/instinct-contradiction.d.ts +42 -0
- package/dist/instinct-contradiction.d.ts.map +1 -0
- package/dist/instinct-contradiction.js +164 -0
- package/dist/instinct-contradiction.js.map +1 -0
- package/dist/instinct-dream.d.ts +12 -0
- package/dist/instinct-dream.d.ts.map +1 -0
- package/dist/instinct-dream.js +33 -0
- package/dist/instinct-dream.js.map +1 -0
- package/dist/instinct-parser.d.ts.map +1 -1
- package/dist/instinct-parser.js +6 -0
- package/dist/instinct-parser.js.map +1 -1
- package/dist/observation-signal.d.ts +34 -0
- package/dist/observation-signal.d.ts.map +1 -0
- package/dist/observation-signal.js +66 -0
- package/dist/observation-signal.js.map +1 -0
- package/dist/prompts/analyzer-system-single-shot.d.ts.map +1 -1
- package/dist/prompts/analyzer-system-single-shot.js +57 -2
- package/dist/prompts/analyzer-system-single-shot.js.map +1 -1
- package/dist/prompts/analyzer-user-single-shot.d.ts.map +1 -1
- package/dist/prompts/analyzer-user-single-shot.js +5 -3
- package/dist/prompts/analyzer-user-single-shot.js.map +1 -1
- package/dist/prompts/consolidate-system.d.ts +6 -0
- package/dist/prompts/consolidate-system.d.ts.map +1 -0
- package/dist/prompts/consolidate-system.js +102 -0
- package/dist/prompts/consolidate-system.js.map +1 -0
- package/dist/prompts/consolidate-user.d.ts +19 -0
- package/dist/prompts/consolidate-user.d.ts.map +1 -0
- package/dist/prompts/consolidate-user.js +45 -0
- package/dist/prompts/consolidate-user.js.map +1 -0
- package/dist/prompts/dream-prompt.d.ts +7 -0
- package/dist/prompts/dream-prompt.d.ts.map +1 -0
- package/dist/prompts/dream-prompt.js +64 -0
- package/dist/prompts/dream-prompt.js.map +1 -0
- package/dist/prompts/evolve-prompt.d.ts.map +1 -1
- package/dist/prompts/evolve-prompt.js +6 -5
- package/dist/prompts/evolve-prompt.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/analysis-event-log.ts +171 -0
- package/src/analysis-notification.ts +79 -0
- package/src/cli/analyze-single-shot.ts +98 -2
- package/src/cli/analyze.ts +406 -20
- package/src/confidence.ts +33 -7
- package/src/config.ts +10 -0
- package/src/consolidation.ts +162 -0
- package/src/index.ts +17 -0
- package/src/instinct-cleanup.ts +62 -3
- package/src/instinct-contradiction.ts +202 -0
- package/src/instinct-dream.ts +62 -0
- package/src/instinct-parser.ts +6 -0
- package/src/observation-signal.ts +80 -0
- package/src/prompts/analyzer-system-single-shot.ts +57 -2
- package/src/prompts/analyzer-user-single-shot.ts +7 -2
- package/src/prompts/consolidate-system.ts +101 -0
- package/src/prompts/consolidate-user.ts +88 -0
- package/src/prompts/dream-prompt.ts +88 -0
- package/src/prompts/evolve-prompt.ts +6 -5
- package/src/types.ts +5 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidate-system.js","sourceRoot":"","sources":["../../src/prompts/consolidate-system.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EA8FmE,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User prompt builder for the consolidation (dream) pass.
|
|
3
|
+
* Embeds all instincts and optional AGENTS.md context.
|
|
4
|
+
*/
|
|
5
|
+
import type { Instinct, InstalledSkill } from "../types.js";
|
|
6
|
+
export interface ConsolidatePromptOptions {
|
|
7
|
+
agentsMdProject?: string | null;
|
|
8
|
+
agentsMdGlobal?: string | null;
|
|
9
|
+
installedSkills?: InstalledSkill[];
|
|
10
|
+
projectName?: string;
|
|
11
|
+
projectId?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Builds the user prompt for a consolidation pass.
|
|
15
|
+
* Unlike the observation analyzer, this prompt contains only instincts
|
|
16
|
+
* and guidelines - no observations.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildConsolidateUserPrompt(instincts: readonly Instinct[], options?: ConsolidatePromptOptions): string;
|
|
19
|
+
//# sourceMappingURL=consolidate-user.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidate-user.d.ts","sourceRoot":"","sources":["../../src/prompts/consolidate-user.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG5D,MAAM,WAAW,wBAAwB;IACvC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,OAAO,GAAE,wBAA6B,GACrC,MAAM,CA+DR"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User prompt builder for the consolidation (dream) pass.
|
|
3
|
+
* Embeds all instincts and optional AGENTS.md context.
|
|
4
|
+
*/
|
|
5
|
+
import { formatInstinctsCompact } from "../cli/analyze-single-shot.js";
|
|
6
|
+
/**
|
|
7
|
+
* Builds the user prompt for a consolidation pass.
|
|
8
|
+
* Unlike the observation analyzer, this prompt contains only instincts
|
|
9
|
+
* and guidelines - no observations.
|
|
10
|
+
*/
|
|
11
|
+
export function buildConsolidateUserPrompt(instincts, options = {}) {
|
|
12
|
+
const { agentsMdProject = null, agentsMdGlobal = null, installedSkills = [], projectName, projectId, } = options;
|
|
13
|
+
const instinctBlock = instincts.length > 0
|
|
14
|
+
? formatInstinctsCompact([...instincts])
|
|
15
|
+
: "(no instincts)";
|
|
16
|
+
const parts = [];
|
|
17
|
+
if (projectId || projectName) {
|
|
18
|
+
parts.push("## Project Context", "");
|
|
19
|
+
if (projectId)
|
|
20
|
+
parts.push(`project_id: ${projectId}`);
|
|
21
|
+
if (projectName)
|
|
22
|
+
parts.push(`project_name: ${projectName}`);
|
|
23
|
+
parts.push("");
|
|
24
|
+
}
|
|
25
|
+
parts.push("## Full Instinct Corpus", "", instinctBlock, "", `Total instincts: ${instincts.length}`, "");
|
|
26
|
+
if (agentsMdProject != null || agentsMdGlobal != null) {
|
|
27
|
+
parts.push("## Existing Guidelines (AGENTS.md)", "");
|
|
28
|
+
if (agentsMdProject != null) {
|
|
29
|
+
parts.push("### Project AGENTS.md", "", agentsMdProject, "");
|
|
30
|
+
}
|
|
31
|
+
if (agentsMdGlobal != null) {
|
|
32
|
+
parts.push("### Global AGENTS.md", "", agentsMdGlobal, "");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (installedSkills.length > 0) {
|
|
36
|
+
parts.push("## Installed Skills", "");
|
|
37
|
+
for (const skill of installedSkills) {
|
|
38
|
+
parts.push(`- **${skill.name}**: ${skill.description}`);
|
|
39
|
+
}
|
|
40
|
+
parts.push("");
|
|
41
|
+
}
|
|
42
|
+
parts.push("## Instructions", "", "1. Review ALL instincts above as a complete corpus.", "2. Identify merge candidates, contradictions, stale entries, and promotion candidates.", "3. Check for instincts duplicated by AGENTS.md guidelines.", "4. Return a JSON change-set with your proposed modifications.", "5. Prefer conservative changes - only act when the improvement is clear.", "", "Return ONLY the JSON object. No prose, no markdown fences.");
|
|
43
|
+
return parts.join("\n");
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=consolidate-user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidate-user.js","sourceRoot":"","sources":["../../src/prompts/consolidate-user.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAUvE;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,SAA8B,EAC9B,UAAoC,EAAE;IAEtC,MAAM,EACJ,eAAe,GAAG,IAAI,EACtB,cAAc,GAAG,IAAI,EACrB,eAAe,GAAG,EAAE,EACpB,WAAW,EACX,SAAS,GACV,GAAG,OAAO,CAAC;IAEZ,MAAM,aAAa,GACjB,SAAS,CAAC,MAAM,GAAG,CAAC;QAClB,CAAC,CAAC,sBAAsB,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;QACxC,CAAC,CAAC,gBAAgB,CAAC;IAEvB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;QACrC,IAAI,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,SAAS,EAAE,CAAC,CAAC;QACtD,IAAI,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,WAAW,EAAE,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,yBAAyB,EACzB,EAAE,EACF,aAAa,EACb,EAAE,EACF,oBAAoB,SAAS,CAAC,MAAM,EAAE,EACtC,EAAE,CACH,CAAC;IAEF,IAAI,eAAe,IAAI,IAAI,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,oCAAoC,EAAE,EAAE,CAAC,CAAC;QACrD,IAAI,eAAe,IAAI,IAAI,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QACtC,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CACR,iBAAiB,EACjB,EAAE,EACF,qDAAqD,EACrD,wFAAwF,EACxF,4DAA4D,EAC5D,+DAA+D,EAC/D,0EAA0E,EAC1E,EAAE,EACF,4DAA4D,CAC7D,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt builder for the interactive /instinct-dream command.
|
|
3
|
+
* Similar to evolve-prompt but focused on holistic consolidation tasks.
|
|
4
|
+
*/
|
|
5
|
+
import type { Instinct, InstalledSkill } from "../types.js";
|
|
6
|
+
export declare function buildDreamPrompt(instincts: Instinct[], agentsMdProject?: string | null, agentsMdGlobal?: string | null, installedSkills?: InstalledSkill[]): string;
|
|
7
|
+
//# sourceMappingURL=dream-prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dream-prompt.d.ts","sourceRoot":"","sources":["../../src/prompts/dream-prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA8B5D,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,QAAQ,EAAE,EACrB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,EAC9B,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,MAAM,CA+CR"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt builder for the interactive /instinct-dream command.
|
|
3
|
+
* Similar to evolve-prompt but focused on holistic consolidation tasks.
|
|
4
|
+
*/
|
|
5
|
+
function summarizeInstinct(i) {
|
|
6
|
+
return {
|
|
7
|
+
id: i.id,
|
|
8
|
+
title: i.title,
|
|
9
|
+
trigger: i.trigger,
|
|
10
|
+
action: i.action,
|
|
11
|
+
confidence: i.confidence,
|
|
12
|
+
domain: i.domain,
|
|
13
|
+
scope: i.scope,
|
|
14
|
+
confirmed_count: i.confirmed_count,
|
|
15
|
+
contradicted_count: i.contradicted_count,
|
|
16
|
+
inactive_count: i.inactive_count,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function buildDreamPrompt(instincts, agentsMdProject, agentsMdGlobal, installedSkills) {
|
|
20
|
+
const parts = [
|
|
21
|
+
"Perform a holistic consolidation review of my learned instincts.",
|
|
22
|
+
"You have access to instinct tools (instinct_merge, instinct_delete, instinct_write) to act on your findings.",
|
|
23
|
+
"",
|
|
24
|
+
"## Full Instinct Corpus",
|
|
25
|
+
"",
|
|
26
|
+
"```json",
|
|
27
|
+
JSON.stringify(instincts.map(summarizeInstinct), null, 2),
|
|
28
|
+
"```",
|
|
29
|
+
"",
|
|
30
|
+
`Total: ${instincts.length} instincts`,
|
|
31
|
+
"",
|
|
32
|
+
"## Consolidation Tasks",
|
|
33
|
+
"",
|
|
34
|
+
"Review the entire corpus and identify:",
|
|
35
|
+
"",
|
|
36
|
+
"1. **Merge candidates**: Instincts with semantically similar triggers or actions (even if worded differently). Merge into a single, stronger instinct using instinct_merge.",
|
|
37
|
+
"2. **Contradictions**: Instincts with similar triggers but opposing actions. Resolve by keeping the stronger one or merging into a nuanced context-dependent instinct.",
|
|
38
|
+
"3. **Stale instincts**: Entries with zero confirmations, high inactive_count, or references to outdated patterns. Delete them.",
|
|
39
|
+
"4. **AGENTS.md duplicates**: Instincts already covered by the guidelines below. Delete them.",
|
|
40
|
+
"5. **Promotion candidates**: Project-scoped instincts with confidence >= 0.7 and confirmed_count >= 3 that apply universally. Promote to global scope.",
|
|
41
|
+
"6. **Skill shadows**: Instincts whose purpose is already served by an installed skill. Delete them.",
|
|
42
|
+
"7. **Quality cleanup**: Instincts with confidence < 0.2, vague triggers, or flagged_for_removal. Clean up or delete.",
|
|
43
|
+
"",
|
|
44
|
+
"Present your findings conversationally. For each suggestion, explain your reasoning and ask if I'd like you to take action using the instinct tools.",
|
|
45
|
+
"If the corpus looks healthy, say so briefly.",
|
|
46
|
+
];
|
|
47
|
+
if (agentsMdProject || agentsMdGlobal) {
|
|
48
|
+
parts.push("", "## Current Guidelines (AGENTS.md)", "");
|
|
49
|
+
if (agentsMdProject) {
|
|
50
|
+
parts.push("### Project AGENTS.md", "", agentsMdProject, "");
|
|
51
|
+
}
|
|
52
|
+
if (agentsMdGlobal) {
|
|
53
|
+
parts.push("### Global AGENTS.md", "", agentsMdGlobal, "");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (installedSkills && installedSkills.length > 0) {
|
|
57
|
+
parts.push("", "## Installed Skills", "");
|
|
58
|
+
for (const skill of installedSkills) {
|
|
59
|
+
parts.push(`- **${skill.name}**: ${skill.description}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return parts.join("\n");
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=dream-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dream-prompt.js","sourceRoot":"","sources":["../../src/prompts/dream-prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiBH,SAAS,iBAAiB,CAAC,CAAW;IACpC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,eAAe,EAAE,CAAC,CAAC,eAAe;QAClC,kBAAkB,EAAE,CAAC,CAAC,kBAAkB;QACxC,cAAc,EAAE,CAAC,CAAC,cAAc;KACjC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,SAAqB,EACrB,eAA+B,EAC/B,cAA8B,EAC9B,eAAkC;IAElC,MAAM,KAAK,GAAa;QACtB,kEAAkE;QAClE,8GAA8G;QAC9G,EAAE;QACF,yBAAyB;QACzB,EAAE;QACF,SAAS;QACT,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,KAAK;QACL,EAAE;QACF,UAAU,SAAS,CAAC,MAAM,YAAY;QACtC,EAAE;QACF,wBAAwB;QACxB,EAAE;QACF,wCAAwC;QACxC,EAAE;QACF,6KAA6K;QAC7K,wKAAwK;QACxK,gIAAgI;QAChI,8FAA8F;QAC9F,wJAAwJ;QACxJ,qGAAqG;QACrG,sHAAsH;QACtH,EAAE;QACF,sJAAsJ;QACtJ,8CAA8C;KAC/C,CAAC;IAEF,IAAI,eAAe,IAAI,cAAc,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,mCAAmC,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,eAAe,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,cAAc,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evolve-prompt.d.ts","sourceRoot":"","sources":["../../src/prompts/evolve-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAwB5D,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,QAAQ,EAAE,EACrB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,EAC9B,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,MAAM,
|
|
1
|
+
{"version":3,"file":"evolve-prompt.d.ts","sourceRoot":"","sources":["../../src/prompts/evolve-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAwB5D,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,QAAQ,EAAE,EACrB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,EAC9B,eAAe,CAAC,EAAE,cAAc,EAAE,GACjC,MAAM,CA0CR"}
|
|
@@ -22,11 +22,12 @@ export function buildEvolvePrompt(instincts, agentsMdProject, agentsMdGlobal, in
|
|
|
22
22
|
"",
|
|
23
23
|
"## Analysis Tasks",
|
|
24
24
|
"",
|
|
25
|
-
"1. **
|
|
26
|
-
"2. **
|
|
27
|
-
"3. **
|
|
28
|
-
"4. **
|
|
29
|
-
"5. **
|
|
25
|
+
"1. **Contradictions**: Find instincts with similar triggers but opposing actions (e.g., 'prefer X' vs 'avoid X', 'always do Y' vs 'never do Y'). Offer to delete the weaker one, or merge both into a nuanced context-dependent instinct.",
|
|
26
|
+
"2. **Merge candidates**: Find instincts with semantically similar triggers or actions (even if worded differently). Offer to merge them using the instinct_merge tool.",
|
|
27
|
+
"3. **Duplicates of AGENTS.md**: Flag instincts already covered by the guidelines below. Offer to delete them.",
|
|
28
|
+
"4. **Promotion candidates**: Project-scoped instincts with confidence >= 0.7 that could become global.",
|
|
29
|
+
"5. **Skill shadows**: Instincts whose purpose is already served by an installed skill (listed below). Offer to delete them.",
|
|
30
|
+
"6. **Low-confidence cleanup**: Instincts with confidence < 0.3 or flagged_for_removal that should be deleted.",
|
|
30
31
|
"",
|
|
31
32
|
"Present your findings conversationally. For each suggestion, explain your reasoning and ask if I'd like you to take action using the instinct tools.",
|
|
32
33
|
"If there are no issues, say so briefly.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evolve-prompt.js","sourceRoot":"","sources":["../../src/prompts/evolve-prompt.ts"],"names":[],"mappings":"AAYA,SAAS,iBAAiB,CAAC,CAAW;IACpC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,SAAqB,EACrB,eAA+B,EAC/B,cAA8B,EAC9B,eAAkC;IAElC,MAAM,KAAK,GAAa;QACtB,qFAAqF;QACrF,8GAA8G;QAC9G,EAAE;QACF,cAAc;QACd,EAAE;QACF,SAAS;QACT,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,KAAK;QACL,EAAE;QACF,mBAAmB;QACnB,EAAE;QACF,wKAAwK;QACxK,+GAA+G;QAC/G,wGAAwG;QACxG,6HAA6H;QAC7H,+GAA+G;QAC/G,EAAE;QACF,sJAAsJ;QACtJ,yCAAyC;KAC1C,CAAC;IAEF,IAAI,eAAe,IAAI,cAAc,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,mCAAmC,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,eAAe,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,cAAc,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
1
|
+
{"version":3,"file":"evolve-prompt.js","sourceRoot":"","sources":["../../src/prompts/evolve-prompt.ts"],"names":[],"mappings":"AAYA,SAAS,iBAAiB,CAAC,CAAW;IACpC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,SAAqB,EACrB,eAA+B,EAC/B,cAA8B,EAC9B,eAAkC;IAElC,MAAM,KAAK,GAAa;QACtB,qFAAqF;QACrF,8GAA8G;QAC9G,EAAE;QACF,cAAc;QACd,EAAE;QACF,SAAS;QACT,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,KAAK;QACL,EAAE;QACF,mBAAmB;QACnB,EAAE;QACF,2OAA2O;QAC3O,wKAAwK;QACxK,+GAA+G;QAC/G,wGAAwG;QACxG,6HAA6H;QAC7H,+GAA+G;QAC/G,EAAE;QACF,sJAAsJ;QACtJ,yCAAyC;KAC1C,CAAC;IAEF,IAAI,eAAe,IAAI,cAAc,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,mCAAmC,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,eAAe,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,cAAc,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export interface Instinct {
|
|
|
48
48
|
flagged_for_removal?: boolean;
|
|
49
49
|
graduated_to?: GraduationTarget;
|
|
50
50
|
graduated_at?: string;
|
|
51
|
+
last_confirmed_session?: string;
|
|
51
52
|
}
|
|
52
53
|
export type GraduationTarget = "agents-md" | "skill" | "command";
|
|
53
54
|
export interface ProjectEntry {
|
|
@@ -79,5 +80,8 @@ export interface Config {
|
|
|
79
80
|
max_new_instincts_per_run: number;
|
|
80
81
|
flagged_cleanup_days: number;
|
|
81
82
|
instinct_ttl_days: number;
|
|
83
|
+
dreaming_enabled: boolean;
|
|
84
|
+
consolidation_interval_days: number;
|
|
85
|
+
consolidation_min_sessions: number;
|
|
82
86
|
}
|
|
83
87
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,gBAAgB,GACxB,YAAY,GACZ,eAAe,GACf,aAAa,GACb,WAAW,GACX,YAAY,GACZ,UAAU,GACV,WAAW,GACX,iBAAiB,GACjB,cAAc,CAAC;AAEnB,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAMD,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,CAAC;AACjD,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;AAEtD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,gBAAgB,GACxB,YAAY,GACZ,eAAe,GACf,aAAa,GACb,WAAW,GACX,YAAY,GACZ,UAAU,GACV,WAAW,GACX,iBAAiB,GACjB,cAAc,CAAC;AAEnB,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAMD,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,CAAC;AACjD,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;AAEtD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;AAMjE,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,MAAM;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,2BAA2B,EAAE,MAAM,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,+BAA+B,EAAE,MAAM,CAAC;IACxC,0BAA0B,EAAE,MAAM,CAAC;IACnC,yBAAyB,EAAE,MAAM,CAAC;IAClC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAE1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,2BAA2B,EAAE,MAAM,CAAC;IACpC,0BAA0B,EAAE,MAAM,CAAC;CACpC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Append-only analysis event log with atomic rename for safe consumption.
|
|
3
|
+
*
|
|
4
|
+
* The background analyzer appends events to `analysis-events.jsonl`.
|
|
5
|
+
* The extension consumes events by atomically renaming the file to
|
|
6
|
+
* `.consumed`, reading it, then deleting it. On POSIX, rename is atomic -
|
|
7
|
+
* any in-flight appends follow the inode to the renamed file.
|
|
8
|
+
*
|
|
9
|
+
* Multiple analyzer runs can append before the extension reads. No events
|
|
10
|
+
* are lost because each run only appends; the file is never truncated by
|
|
11
|
+
* the analyzer.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
appendFileSync,
|
|
16
|
+
existsSync,
|
|
17
|
+
mkdirSync,
|
|
18
|
+
readFileSync,
|
|
19
|
+
renameSync,
|
|
20
|
+
unlinkSync,
|
|
21
|
+
} from "node:fs";
|
|
22
|
+
import { dirname, join } from "node:path";
|
|
23
|
+
import { getProjectDir } from "./storage.js";
|
|
24
|
+
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Constants
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
const EVENTS_FILENAME = "analysis-events.jsonl";
|
|
30
|
+
const CONSUMED_FILENAME = "analysis-events.consumed";
|
|
31
|
+
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Types
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
export interface InstinctChangeSummary {
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly title: string;
|
|
39
|
+
readonly scope: "project" | "global";
|
|
40
|
+
readonly trigger?: string;
|
|
41
|
+
readonly action?: string;
|
|
42
|
+
readonly confidence_delta?: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface AnalysisEvent {
|
|
46
|
+
readonly timestamp: string;
|
|
47
|
+
readonly project_id: string;
|
|
48
|
+
readonly project_name: string;
|
|
49
|
+
readonly created: readonly InstinctChangeSummary[];
|
|
50
|
+
readonly updated: readonly InstinctChangeSummary[];
|
|
51
|
+
readonly deleted: readonly InstinctChangeSummary[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Paths
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
export function getEventsPath(projectId: string, baseDir?: string): string {
|
|
59
|
+
return join(getProjectDir(projectId, baseDir), EVENTS_FILENAME);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getConsumedPath(projectId: string, baseDir?: string): string {
|
|
63
|
+
return join(getProjectDir(projectId, baseDir), CONSUMED_FILENAME);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Write (analyzer side)
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Appends an analysis event to the project's event log.
|
|
72
|
+
* Skips writing if nothing changed (all arrays empty).
|
|
73
|
+
* Creates the parent directory if needed.
|
|
74
|
+
*/
|
|
75
|
+
export function appendAnalysisEvent(event: AnalysisEvent, baseDir?: string): void {
|
|
76
|
+
if (
|
|
77
|
+
event.created.length === 0 &&
|
|
78
|
+
event.updated.length === 0 &&
|
|
79
|
+
event.deleted.length === 0
|
|
80
|
+
) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const eventsPath = getEventsPath(event.project_id, baseDir);
|
|
85
|
+
mkdirSync(dirname(eventsPath), { recursive: true });
|
|
86
|
+
appendFileSync(eventsPath, JSON.stringify(event) + "\n", "utf-8");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
// Read and clear (extension side)
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Atomically consumes all pending analysis events for a project.
|
|
95
|
+
*
|
|
96
|
+
* Strategy:
|
|
97
|
+
* 1. Check for orphaned `.consumed` file from a prior crash - read it first
|
|
98
|
+
* 2. Rename `analysis-events.jsonl` to `.consumed` (atomic on POSIX)
|
|
99
|
+
* 3. Read and parse all lines from `.consumed`
|
|
100
|
+
* 4. Delete `.consumed`
|
|
101
|
+
*
|
|
102
|
+
* Returns an empty array if no events exist or rename fails (e.g. file
|
|
103
|
+
* doesn't exist, or another consumer raced us).
|
|
104
|
+
*/
|
|
105
|
+
export function consumeAnalysisEvents(
|
|
106
|
+
projectId: string,
|
|
107
|
+
baseDir?: string
|
|
108
|
+
): readonly AnalysisEvent[] {
|
|
109
|
+
const eventsPath = getEventsPath(projectId, baseDir);
|
|
110
|
+
const consumedPath = getConsumedPath(projectId, baseDir);
|
|
111
|
+
|
|
112
|
+
const allEvents: AnalysisEvent[] = [];
|
|
113
|
+
|
|
114
|
+
// Step 1: recover orphaned consumed file from prior crash
|
|
115
|
+
if (existsSync(consumedPath)) {
|
|
116
|
+
allEvents.push(...parseEventsFile(consumedPath));
|
|
117
|
+
safeUnlink(consumedPath);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Step 2: atomically rename the events file
|
|
121
|
+
if (existsSync(eventsPath)) {
|
|
122
|
+
try {
|
|
123
|
+
renameSync(eventsPath, consumedPath);
|
|
124
|
+
} catch {
|
|
125
|
+
// Rename failed (race with another consumer, or OS issue).
|
|
126
|
+
// Return whatever we recovered from step 1.
|
|
127
|
+
return allEvents;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Step 3: read the renamed file
|
|
131
|
+
allEvents.push(...parseEventsFile(consumedPath));
|
|
132
|
+
|
|
133
|
+
// Step 4: delete consumed file
|
|
134
|
+
safeUnlink(consumedPath);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return allEvents;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
// Helpers
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
function parseEventsFile(filePath: string): AnalysisEvent[] {
|
|
145
|
+
const events: AnalysisEvent[] = [];
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const content = readFileSync(filePath, "utf-8");
|
|
149
|
+
const lines = content.split("\n").filter((line) => line.trim().length > 0);
|
|
150
|
+
|
|
151
|
+
for (const line of lines) {
|
|
152
|
+
try {
|
|
153
|
+
events.push(JSON.parse(line) as AnalysisEvent);
|
|
154
|
+
} catch {
|
|
155
|
+
// Skip malformed lines - don't lose other events
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} catch {
|
|
159
|
+
// File read failed - return empty
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return events;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function safeUnlink(filePath: string): void {
|
|
166
|
+
try {
|
|
167
|
+
if (existsSync(filePath)) unlinkSync(filePath);
|
|
168
|
+
} catch {
|
|
169
|
+
// Best effort cleanup
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension-side notification for analysis events.
|
|
3
|
+
*
|
|
4
|
+
* On `before_agent_start`, consumes pending analysis events and shows
|
|
5
|
+
* a brief one-line notification summarizing instinct changes since the
|
|
6
|
+
* last session interaction.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
10
|
+
import {
|
|
11
|
+
consumeAnalysisEvents,
|
|
12
|
+
type AnalysisEvent,
|
|
13
|
+
} from "./analysis-event-log.js";
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Formatting
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Aggregates multiple analysis events into a single summary line.
|
|
21
|
+
* Returns null when no changes occurred.
|
|
22
|
+
*/
|
|
23
|
+
export function formatNotification(events: readonly AnalysisEvent[]): string | null {
|
|
24
|
+
if (events.length === 0) return null;
|
|
25
|
+
|
|
26
|
+
let created = 0;
|
|
27
|
+
let updated = 0;
|
|
28
|
+
let deleted = 0;
|
|
29
|
+
const createdIds: string[] = [];
|
|
30
|
+
|
|
31
|
+
for (const event of events) {
|
|
32
|
+
created += event.created.length;
|
|
33
|
+
updated += event.updated.length;
|
|
34
|
+
deleted += event.deleted.length;
|
|
35
|
+
for (const c of event.created) {
|
|
36
|
+
createdIds.push(c.id);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (created === 0 && updated === 0 && deleted === 0) return null;
|
|
41
|
+
|
|
42
|
+
const parts: string[] = [];
|
|
43
|
+
if (created > 0) {
|
|
44
|
+
const idList = createdIds.slice(0, 3).join(", ");
|
|
45
|
+
const suffix = createdIds.length > 3 ? ", ..." : "";
|
|
46
|
+
parts.push(`+${created} new (${idList}${suffix})`);
|
|
47
|
+
}
|
|
48
|
+
if (updated > 0) {
|
|
49
|
+
parts.push(`${updated} updated`);
|
|
50
|
+
}
|
|
51
|
+
if (deleted > 0) {
|
|
52
|
+
parts.push(`${deleted} deleted`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return `[instincts] Background analysis: ${parts.join(", ")}`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Handler
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Checks for pending analysis events and shows a notification if any exist.
|
|
64
|
+
* Safe to call on every `before_agent_start` - no-ops when there's nothing.
|
|
65
|
+
*/
|
|
66
|
+
export function checkAnalysisNotifications(
|
|
67
|
+
ctx: ExtensionContext,
|
|
68
|
+
projectId: string | null,
|
|
69
|
+
baseDir?: string
|
|
70
|
+
): void {
|
|
71
|
+
if (!projectId) return;
|
|
72
|
+
|
|
73
|
+
const events = consumeAnalysisEvents(projectId, baseDir);
|
|
74
|
+
const message = formatNotification(events);
|
|
75
|
+
|
|
76
|
+
if (message) {
|
|
77
|
+
ctx.ui.notify(message, "info");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -9,7 +9,11 @@ import type { AssistantMessage, Context } from "@mariozechner/pi-ai";
|
|
|
9
9
|
import { complete } from "@mariozechner/pi-ai";
|
|
10
10
|
import type { Instinct } from "../types.js";
|
|
11
11
|
import { serializeInstinct } from "../instinct-parser.js";
|
|
12
|
+
|
|
13
|
+
/** Chars-per-token heuristic for prompt size estimation. */
|
|
14
|
+
const CHARS_PER_TOKEN = 4;
|
|
12
15
|
import { validateInstinct, findSimilarInstinct } from "../instinct-validator.js";
|
|
16
|
+
import { confirmationDelta } from "../confidence.js";
|
|
13
17
|
|
|
14
18
|
export interface InstinctChangePayload {
|
|
15
19
|
id: string;
|
|
@@ -24,6 +28,7 @@ export interface InstinctChangePayload {
|
|
|
24
28
|
contradicted_count?: number;
|
|
25
29
|
inactive_count?: number;
|
|
26
30
|
evidence?: string[];
|
|
31
|
+
last_confirmed_session?: string;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
export interface InstinctChange {
|
|
@@ -117,12 +122,57 @@ export function buildInstinctFromChange(
|
|
|
117
122
|
|
|
118
123
|
const now = new Date().toISOString();
|
|
119
124
|
|
|
125
|
+
// For updates, recompute confidence client-side to enforce:
|
|
126
|
+
// 1. Per-session deduplication: only one confirmation per unique session_id
|
|
127
|
+
// 2. Diminishing returns: each additional confirmation yields a smaller delta
|
|
128
|
+
let resolvedConfidence: number;
|
|
129
|
+
let resolvedConfirmedCount = payload.confirmed_count ?? existing?.confirmed_count ?? 0;
|
|
130
|
+
let resolvedLastConfirmedSession = payload.last_confirmed_session ?? existing?.last_confirmed_session;
|
|
131
|
+
|
|
132
|
+
if (change.action === "update" && existing !== null) {
|
|
133
|
+
const prevConfirmedCount = existing.confirmed_count;
|
|
134
|
+
const newConfirmedCount = payload.confirmed_count ?? prevConfirmedCount;
|
|
135
|
+
const contradictionsAdded = Math.max(
|
|
136
|
+
0,
|
|
137
|
+
(payload.contradicted_count ?? 0) - existing.contradicted_count,
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// Detect whether the LLM intends to add a confirmation
|
|
141
|
+
const wantsToConfirm = newConfirmedCount > prevConfirmedCount;
|
|
142
|
+
|
|
143
|
+
// Session dedup: reject the confirmation if the confirming session is the
|
|
144
|
+
// same as the one that last confirmed this instinct.
|
|
145
|
+
const sessionDuplicate =
|
|
146
|
+
wantsToConfirm &&
|
|
147
|
+
resolvedLastConfirmedSession !== undefined &&
|
|
148
|
+
payload.last_confirmed_session !== undefined &&
|
|
149
|
+
payload.last_confirmed_session === existing.last_confirmed_session;
|
|
150
|
+
|
|
151
|
+
if (sessionDuplicate) {
|
|
152
|
+
// Revert to existing count - this session already confirmed the instinct
|
|
153
|
+
resolvedConfirmedCount = prevConfirmedCount;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Recompute confidence from existing + explicit deltas (don't trust LLM arithmetic)
|
|
157
|
+
resolvedConfidence = existing.confidence;
|
|
158
|
+
if (wantsToConfirm && !sessionDuplicate) {
|
|
159
|
+
resolvedConfidence += confirmationDelta(prevConfirmedCount);
|
|
160
|
+
}
|
|
161
|
+
if (contradictionsAdded > 0) {
|
|
162
|
+
resolvedConfidence -= 0.15 * contradictionsAdded;
|
|
163
|
+
}
|
|
164
|
+
resolvedConfidence = Math.max(0.1, Math.min(0.9, resolvedConfidence));
|
|
165
|
+
} else {
|
|
166
|
+
// For creates, trust the LLM's initial confidence (no prior state to base delta on)
|
|
167
|
+
resolvedConfidence = Math.max(0.1, Math.min(0.9, payload.confidence));
|
|
168
|
+
}
|
|
169
|
+
|
|
120
170
|
return {
|
|
121
171
|
id: payload.id,
|
|
122
172
|
title: payload.title,
|
|
123
173
|
trigger: payload.trigger,
|
|
124
174
|
action: payload.action,
|
|
125
|
-
confidence:
|
|
175
|
+
confidence: resolvedConfidence,
|
|
126
176
|
domain: payload.domain,
|
|
127
177
|
scope: payload.scope,
|
|
128
178
|
source: "personal",
|
|
@@ -130,15 +180,61 @@ export function buildInstinctFromChange(
|
|
|
130
180
|
created_at: existing?.created_at ?? now,
|
|
131
181
|
updated_at: now,
|
|
132
182
|
observation_count: payload.observation_count ?? 1,
|
|
133
|
-
confirmed_count:
|
|
183
|
+
confirmed_count: resolvedConfirmedCount,
|
|
134
184
|
contradicted_count: payload.contradicted_count ?? 0,
|
|
135
185
|
inactive_count: payload.inactive_count ?? 0,
|
|
136
186
|
...(payload.evidence !== undefined ? { evidence: payload.evidence } : {}),
|
|
187
|
+
...(resolvedLastConfirmedSession !== undefined
|
|
188
|
+
? { last_confirmed_session: resolvedLastConfirmedSession }
|
|
189
|
+
: {}),
|
|
137
190
|
};
|
|
138
191
|
}
|
|
139
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Returns days elapsed since the given ISO 8601 date string.
|
|
195
|
+
*/
|
|
196
|
+
function daysSince(dateStr: string): number {
|
|
197
|
+
const ms = Date.now() - new Date(dateStr).getTime();
|
|
198
|
+
return Math.max(0, Math.floor(ms / (1000 * 60 * 60 * 24)));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Formats existing instincts as a compact JSON array for inline context.
|
|
203
|
+
* Reduces token usage by ~70% compared to full YAML+markdown serialization.
|
|
204
|
+
* Includes only the fields the analyzer needs to make decisions.
|
|
205
|
+
*/
|
|
206
|
+
export function formatInstinctsCompact(instincts: Instinct[]): string {
|
|
207
|
+
if (instincts.length === 0) {
|
|
208
|
+
return "[]";
|
|
209
|
+
}
|
|
210
|
+
const summaries = instincts.map((i) => ({
|
|
211
|
+
id: i.id,
|
|
212
|
+
trigger: i.trigger,
|
|
213
|
+
action: i.action,
|
|
214
|
+
confidence: i.confidence,
|
|
215
|
+
domain: i.domain,
|
|
216
|
+
scope: i.scope,
|
|
217
|
+
confirmed: i.confirmed_count,
|
|
218
|
+
contradicted: i.contradicted_count,
|
|
219
|
+
inactive: i.inactive_count,
|
|
220
|
+
age_days: daysSince(i.created_at),
|
|
221
|
+
...(i.last_confirmed_session !== undefined
|
|
222
|
+
? { last_confirmed_session: i.last_confirmed_session }
|
|
223
|
+
: {}),
|
|
224
|
+
}));
|
|
225
|
+
return JSON.stringify(summaries);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Estimates the token count of a text string using a chars/token heuristic.
|
|
230
|
+
*/
|
|
231
|
+
export function estimateTokens(text: string): number {
|
|
232
|
+
return Math.ceil(text.length / CHARS_PER_TOKEN);
|
|
233
|
+
}
|
|
234
|
+
|
|
140
235
|
/**
|
|
141
236
|
* Formats existing instincts as serialized markdown blocks for inline context.
|
|
237
|
+
* @deprecated Use formatInstinctsCompact for lower token usage.
|
|
142
238
|
*/
|
|
143
239
|
export function formatInstinctsForPrompt(instincts: Instinct[]): string {
|
|
144
240
|
if (instincts.length === 0) {
|