@yeaft/webchat-agent 0.1.409 → 0.1.410

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.
@@ -0,0 +1,272 @@
1
+ /**
2
+ * dream-prompt.js — Dream prompt templates for each phase
3
+ *
4
+ * Dream has 5 phases:
5
+ * Phase 1: Orient — assess current memory state
6
+ * Phase 2: Gather — collect recent context
7
+ * Phase 3: Merge — combine duplicates, update outdated
8
+ * Phase 4: Prune — remove stale/low-value entries
9
+ * Phase 5: Promote — extract patterns, update profile
10
+ *
11
+ * Reference: yeaft-unify-core-systems.md §3.3
12
+ */
13
+
14
+ /**
15
+ * Build the Orient phase prompt (Phase 1).
16
+ * The LLM assesses the current memory state and identifies issues.
17
+ *
18
+ * @param {{ memorySummary: string, profileContent: string, entryCount: number }} context
19
+ * @returns {string}
20
+ */
21
+ export function buildOrientPrompt({ memorySummary, profileContent, entryCount }) {
22
+ return `You are in Dream Mode — Phase 1: Orient.
23
+
24
+ Your task is to assess the current state of the memory store and identify what needs attention.
25
+
26
+ ## Current Memory State
27
+
28
+ ${memorySummary}
29
+
30
+ ## MEMORY.md (User Profile)
31
+
32
+ ${profileContent || '(empty)'}
33
+
34
+ ## Assessment Instructions
35
+
36
+ Review the memory state and provide:
37
+ 1. **Redundancies**: Are there entries that overlap or say the same thing?
38
+ 2. **Outdated info**: Are there entries that might be stale or no longer relevant?
39
+ 3. **Gaps**: Is there important context missing from MEMORY.md?
40
+ 4. **Quality**: Are entries well-categorized (kind, scope, tags)?
41
+
42
+ Return your assessment as JSON:
43
+ {
44
+ "redundantGroups": [["entry-a", "entry-b"]],
45
+ "potentiallyStale": ["entry-name-1"],
46
+ "profileGaps": ["missing X context"],
47
+ "qualityIssues": ["entry-y has wrong kind"],
48
+ "overallHealth": "good" | "needs-attention" | "poor",
49
+ "suggestedActions": ["merge entries about X", "prune stale context entries"]
50
+ }
51
+
52
+ Return ONLY valid JSON, no other text.`;
53
+ }
54
+
55
+ /**
56
+ * Build the Gather phase prompt (Phase 2).
57
+ * Collects recent compact summaries and completed task summaries.
58
+ *
59
+ * @param {{ recentCompact: string, completedTasks: object[], orientResult: object }} context
60
+ * @returns {string}
61
+ */
62
+ export function buildGatherPrompt({ recentCompact, completedTasks, orientResult }) {
63
+ const taskSummaries = completedTasks.length > 0
64
+ ? completedTasks.map(t => `- [${t.id}] ${t.description}: ${t.summary || '(no summary)'}`).join('\n')
65
+ : '(no recently completed tasks)';
66
+
67
+ return `You are in Dream Mode — Phase 2: Gather.
68
+
69
+ Your task is to identify what new information should be incorporated into long-term memory.
70
+
71
+ ## Recent Conversation Summary (compact.md)
72
+
73
+ ${recentCompact || '(no recent summaries)'}
74
+
75
+ ## Recently Completed Tasks
76
+
77
+ ${taskSummaries}
78
+
79
+ ## Orient Assessment
80
+
81
+ ${JSON.stringify(orientResult, null, 2)}
82
+
83
+ ## Instructions
84
+
85
+ From the recent conversations and tasks, identify:
86
+ 1. **New facts** worth remembering (project structure, tech decisions)
87
+ 2. **New preferences** expressed by the user
88
+ 3. **New skills/lessons** learned during tasks
89
+ 4. **Context updates** (project progress, status changes)
90
+
91
+ Return as JSON:
92
+ {
93
+ "newEntries": [
94
+ { "name": "slug-name", "kind": "fact|preference|skill|lesson|context|relation", "scope": "path", "tags": ["tag1", "tag2"], "importance": "high|normal|low", "content": "description" }
95
+ ],
96
+ "updatesToExisting": [
97
+ { "entryName": "existing-slug", "updates": { "content": "updated text", "tags": ["new-tag"] } }
98
+ ]
99
+ }
100
+
101
+ Return ONLY valid JSON, no other text.`;
102
+ }
103
+
104
+ /**
105
+ * Build the Merge phase prompt (Phase 3).
106
+ *
107
+ * @param {{ duplicateGroups: object[][], gatherResult: object }} context
108
+ * @returns {string}
109
+ */
110
+ export function buildMergePrompt({ duplicateGroups, gatherResult }) {
111
+ const groupDescriptions = duplicateGroups.map((group, i) => {
112
+ const entries = group.map(e =>
113
+ ` - [${e.name}] kind=${e.kind}, scope=${e.scope}, tags=[${(e.tags || []).join(', ')}]\n ${(e.content || '').slice(0, 200)}`
114
+ ).join('\n');
115
+ return `Group ${i + 1}:\n${entries}`;
116
+ }).join('\n\n');
117
+
118
+ return `You are in Dream Mode — Phase 3: Merge.
119
+
120
+ Your task is to merge duplicate/overlapping entries into single, richer entries.
121
+
122
+ ## Potentially Duplicate Groups
123
+
124
+ ${groupDescriptions || '(no duplicates detected)'}
125
+
126
+ ## New Entries from Gather Phase
127
+
128
+ ${JSON.stringify(gatherResult?.newEntries || [], null, 2)}
129
+
130
+ ## Instructions
131
+
132
+ For each duplicate group:
133
+ 1. Decide if they should be merged (combine info) or kept separate (different enough)
134
+ 2. For merges, create a single entry that preserves all important info from both
135
+ 3. List which old entries should be deleted after merge
136
+
137
+ Also process the new entries from Gather — check if any overlap with existing entries.
138
+
139
+ Return as JSON:
140
+ {
141
+ "merges": [
142
+ {
143
+ "merged": { "name": "new-slug", "kind": "...", "scope": "...", "tags": [], "importance": "...", "content": "..." },
144
+ "deleteOriginals": ["old-entry-1", "old-entry-2"]
145
+ }
146
+ ],
147
+ "newEntries": [
148
+ { "name": "...", "kind": "...", "scope": "...", "tags": [], "importance": "...", "content": "..." }
149
+ ],
150
+ "updates": [
151
+ { "entryName": "existing-slug", "updates": { "content": "updated text" } }
152
+ ]
153
+ }
154
+
155
+ Return ONLY valid JSON, no other text.`;
156
+ }
157
+
158
+ /**
159
+ * Build the Prune phase prompt (Phase 4).
160
+ *
161
+ * @param {{ staleEntries: object[], entryCount: number, maxEntries: number }} context
162
+ * @returns {string}
163
+ */
164
+ export function buildPrunePrompt({ staleEntries, entryCount, maxEntries }) {
165
+ const staleDescriptions = staleEntries.map(e =>
166
+ `- [${e.name}] kind=${e.kind}, scope=${e.scope}, freq=${e.frequency || 1}, days_since_update=${e._daysSinceUpdate}\n ${(e.content || '').slice(0, 150)}`
167
+ ).join('\n');
168
+
169
+ return `You are in Dream Mode — Phase 4: Prune.
170
+
171
+ Your task is to remove stale, low-value, or redundant entries.
172
+
173
+ ## Potentially Stale Entries (${staleEntries.length} found)
174
+
175
+ ${staleDescriptions || '(none detected)'}
176
+
177
+ ## Capacity
178
+
179
+ Current entries: ${entryCount}
180
+ Maximum allowed: ${maxEntries}
181
+ ${entryCount > maxEntries ? `⚠️ OVER CAPACITY by ${entryCount - maxEntries} entries — must prune aggressively` : 'Within capacity'}
182
+
183
+ ## Prune Guidelines
184
+
185
+ Delete entries that are:
186
+ - **Outdated context**: Project status from weeks ago
187
+ - **Never recalled**: frequency=1 and old — nobody needs it
188
+ - **Too vague**: "user mentioned something about X" without useful detail
189
+ - **Redundant with profile**: If MEMORY.md already captures it
190
+ - **Re-derivable**: Info that can be obtained by running a command (e.g., "Node version is 20")
191
+
192
+ KEEP entries that are:
193
+ - High importance or high frequency
194
+ - Recent preferences or lessons
195
+ - Facts about project structure (hard to re-discover)
196
+
197
+ Return as JSON:
198
+ {
199
+ "toDelete": ["entry-name-1", "entry-name-2"],
200
+ "reasoning": {
201
+ "entry-name-1": "outdated context from 45 days ago",
202
+ "entry-name-2": "never recalled, too vague"
203
+ }
204
+ }
205
+
206
+ Return ONLY valid JSON, no other text.`;
207
+ }
208
+
209
+ /**
210
+ * Build the Promote phase prompt (Phase 5).
211
+ *
212
+ * @param {{ entries: object[], profileContent: string, scopesSummary: string }} context
213
+ * @returns {string}
214
+ */
215
+ export function buildPromotePrompt({ entries, profileContent, scopesSummary }) {
216
+ // Find entries that might form patterns
217
+ const highFreq = entries
218
+ .filter(e => (e.frequency || 1) >= 3)
219
+ .map(e => `- [${e.name}] kind=${e.kind}, freq=${e.frequency}, scope=${e.scope}: ${(e.content || '').slice(0, 150)}`)
220
+ .join('\n');
221
+
222
+ const lessons = entries
223
+ .filter(e => e.kind === 'lesson')
224
+ .map(e => `- [${e.name}] scope=${e.scope}: ${(e.content || '').slice(0, 150)}`)
225
+ .join('\n');
226
+
227
+ return `You are in Dream Mode — Phase 5: Promote.
228
+
229
+ Your task is to identify patterns and update the user profile.
230
+
231
+ ## High-Frequency Entries (recalled ≥3 times)
232
+
233
+ ${highFreq || '(none)'}
234
+
235
+ ## All Lessons
236
+
237
+ ${lessons || '(none)'}
238
+
239
+ ## Current MEMORY.md Profile
240
+
241
+ ${profileContent || '(empty)'}
242
+
243
+ ## Scopes
244
+
245
+ ${scopesSummary}
246
+
247
+ ## Instructions
248
+
249
+ 1. **Pattern promotion**: If multiple entries share a pattern, create a higher-level insight
250
+ - Example: 3 entries about "user corrects indentation" → 1 preference: "default to 2-space indent"
251
+ 2. **Profile update**: Update MEMORY.md sections based on accumulated knowledge
252
+ - Keep MEMORY.md under 200 lines
253
+ - Sections: Facts, Preferences, Project Context, Skills, Lessons
254
+ 3. **Scope promotion**: If a lesson applies across projects, promote scope to parent or global
255
+
256
+ Return as JSON:
257
+ {
258
+ "profileUpdates": {
259
+ "Facts": ["- New fact line 1"],
260
+ "Preferences": ["- New preference line"],
261
+ "Project Context": [],
262
+ "Skills": [],
263
+ "Lessons": []
264
+ },
265
+ "promotedEntries": [
266
+ { "name": "...", "kind": "...", "scope": "global", "tags": [], "importance": "high", "content": "..." }
267
+ ],
268
+ "entriesToDelete": ["entry-that-was-promoted-to-profile"]
269
+ }
270
+
271
+ Return ONLY valid JSON, no other text.`;
272
+ }