@synergenius/flow-weaver-pack-weaver 0.9.159 → 0.9.164
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/ai-chat-provider.d.ts.map +1 -1
- package/dist/ai-chat-provider.js +17 -11
- package/dist/ai-chat-provider.js.map +1 -1
- package/dist/bot/ai-router.js +5 -5
- package/dist/bot/ai-router.js.map +1 -1
- package/dist/bot/assistant-tools.d.ts.map +1 -1
- package/dist/bot/assistant-tools.js +6 -7
- package/dist/bot/assistant-tools.js.map +1 -1
- package/dist/bot/capability-registry.d.ts.map +1 -1
- package/dist/bot/capability-registry.js +37 -14
- package/dist/bot/capability-registry.js.map +1 -1
- package/dist/bot/dashboard.js +1 -1
- package/dist/bot/dashboard.js.map +1 -1
- package/dist/bot/index.d.ts +1 -1
- package/dist/bot/index.d.ts.map +1 -1
- package/dist/bot/index.js.map +1 -1
- package/dist/bot/instance-manager.js +3 -3
- package/dist/bot/instance-manager.js.map +1 -1
- package/dist/bot/profile-store.d.ts.map +1 -1
- package/dist/bot/profile-store.js +11 -9
- package/dist/bot/profile-store.js.map +1 -1
- package/dist/bot/profile-types.d.ts +2 -2
- package/dist/bot/profile-types.d.ts.map +1 -1
- package/dist/bot/runner.d.ts +1 -0
- package/dist/bot/runner.d.ts.map +1 -1
- package/dist/bot/runner.js +6 -2
- package/dist/bot/runner.js.map +1 -1
- package/dist/bot/step-executor.d.ts.map +1 -1
- package/dist/bot/step-executor.js +10 -0
- package/dist/bot/step-executor.js.map +1 -1
- package/dist/bot/swarm-controller.d.ts +3 -5
- package/dist/bot/swarm-controller.d.ts.map +1 -1
- package/dist/bot/swarm-controller.js +157 -74
- package/dist/bot/swarm-controller.js.map +1 -1
- package/dist/bot/task-prompt-builder.d.ts +2 -3
- package/dist/bot/task-prompt-builder.d.ts.map +1 -1
- package/dist/bot/task-prompt-builder.js +81 -67
- package/dist/bot/task-prompt-builder.js.map +1 -1
- package/dist/bot/task-store.d.ts +3 -3
- package/dist/bot/task-store.d.ts.map +1 -1
- package/dist/bot/task-store.js +89 -75
- package/dist/bot/task-store.js.map +1 -1
- package/dist/bot/task-types.d.ts +54 -26
- package/dist/bot/task-types.d.ts.map +1 -1
- package/dist/bot/task-types.js +6 -2
- package/dist/bot/task-types.js.map +1 -1
- package/dist/bot/types.d.ts +2 -0
- package/dist/bot/types.d.ts.map +1 -1
- package/dist/bot/weaver-tools.d.ts.map +1 -1
- package/dist/bot/weaver-tools.js +10 -0
- package/dist/bot/weaver-tools.js.map +1 -1
- package/dist/cli-handlers.d.ts +0 -1
- package/dist/cli-handlers.d.ts.map +1 -1
- package/dist/cli-handlers.js +5 -9
- package/dist/cli-handlers.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/node-types/agent-execute.d.ts.map +1 -1
- package/dist/node-types/agent-execute.js +95 -63
- package/dist/node-types/agent-execute.js.map +1 -1
- package/dist/node-types/plan-task.js +8 -8
- package/dist/node-types/plan-task.js.map +1 -1
- package/dist/ui/bot-panel.js +1 -1
- package/dist/ui/capability-editor.js +37 -14
- package/dist/ui/chat-task-result.js +1 -7
- package/dist/ui/profile-editor.js +37 -14
- package/dist/ui/swarm-controls.js +2 -2
- package/dist/ui/swarm-dashboard.js +72 -109
- package/dist/ui/task-detail-view.js +21 -42
- package/dist/ui/task-editor.js +13 -50
- package/dist/ui/task-pool-list.js +0 -2
- package/flowweaver.manifest.json +1 -1
- package/package.json +1 -1
- package/src/ai-chat-provider.ts +15 -11
- package/src/bot/ai-router.ts +5 -5
- package/src/bot/assistant-tools.ts +6 -7
- package/src/bot/capability-registry.ts +37 -14
- package/src/bot/dashboard.ts +1 -1
- package/src/bot/index.ts +5 -1
- package/src/bot/instance-manager.ts +3 -3
- package/src/bot/profile-store.ts +12 -10
- package/src/bot/profile-types.ts +2 -2
- package/src/bot/runner.ts +6 -2
- package/src/bot/step-executor.ts +11 -0
- package/src/bot/swarm-controller.ts +164 -78
- package/src/bot/task-prompt-builder.ts +86 -71
- package/src/bot/task-store.ts +101 -78
- package/src/bot/task-types.ts +81 -36
- package/src/bot/types.ts +2 -0
- package/src/bot/weaver-tools.ts +11 -0
- package/src/cli-handlers.ts +5 -9
- package/src/index.ts +6 -0
- package/src/node-types/agent-execute.ts +99 -62
- package/src/node-types/plan-task.ts +8 -8
- package/src/ui/bot-panel.tsx +3 -3
- package/src/ui/chat-task-result.tsx +5 -14
- package/src/ui/swarm-controls.tsx +3 -3
- package/src/ui/swarm-dashboard.tsx +3 -3
- package/src/ui/task-detail-view.tsx +29 -52
- package/src/ui/task-editor.tsx +14 -51
- package/src/ui/task-pool-list.tsx +1 -3
|
@@ -6,12 +6,11 @@
|
|
|
6
6
|
* {description}
|
|
7
7
|
* ### Notes
|
|
8
8
|
* ### Relevant Files
|
|
9
|
-
* ### Previous
|
|
10
|
-
* ### Last Error
|
|
9
|
+
* ### Previous Runs (context decay: last run + acceptance check)
|
|
11
10
|
* ### Parent Context (title + description + sibling status)
|
|
12
11
|
*
|
|
13
12
|
* Truncation cascade when over budget:
|
|
14
|
-
* 1. Older
|
|
13
|
+
* 1. Older runs → one-liners only
|
|
15
14
|
* 2. File list → only files from last 2 runs
|
|
16
15
|
* 3. Parent context → title only
|
|
17
16
|
* 4. Notes → first 500 chars
|
|
@@ -19,7 +18,6 @@
|
|
|
19
18
|
const MAX_CONTEXT_TOKENS = 4000;
|
|
20
19
|
const CHARS_PER_TOKEN = 4; // rough estimate
|
|
21
20
|
const MAX_CONTEXT_CHARS = MAX_CONTEXT_TOKENS * CHARS_PER_TOKEN;
|
|
22
|
-
const FULL_SUMMARY_COUNT = 3;
|
|
23
21
|
export function buildTaskPrompt(task, parentTask, siblingTasks, preferences) {
|
|
24
22
|
// Build the full (un-truncated) prompt first
|
|
25
23
|
const prompt = buildFull(task, parentTask, siblingTasks, preferences);
|
|
@@ -44,24 +42,43 @@ function buildFull(task, parentTask, siblingTasks, preferences) {
|
|
|
44
42
|
if (task.context.files.length > 0) {
|
|
45
43
|
sections.push(`### Relevant Files\n${task.context.files.join('\n')}`);
|
|
46
44
|
}
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
// --- Context decay: workspace is the source of truth, not history ---
|
|
46
|
+
// Workers see: last acceptance check, last run's remainingWork/blockers,
|
|
47
|
+
// stagnation count, and a directive to read the workspace.
|
|
48
|
+
// 2.3.2: Last acceptance check result
|
|
49
|
+
if (task.lastAcceptanceCheck) {
|
|
50
|
+
const ac = task.lastAcceptanceCheck;
|
|
51
|
+
const checkLines = ac.results
|
|
52
|
+
.map(r => `- ${r.name}: ${r.pass ? 'PASS' : 'FAIL'}${r.detail ? ` (${r.detail.slice(0, 100)})` : ''}`)
|
|
53
|
+
.join('\n');
|
|
54
|
+
sections.push(`### Acceptance Check (${ac.met ? 'ALL PASS' : 'ISSUES FOUND'})\n${checkLines}`);
|
|
55
|
+
}
|
|
56
|
+
// 2.3.3: Continue from last run's remaining work
|
|
57
|
+
const lastRun = task.context.runHistory.length > 0
|
|
58
|
+
? task.context.runHistory[task.context.runHistory.length - 1]
|
|
59
|
+
: undefined;
|
|
60
|
+
if (lastRun && 'remainingWork' in lastRun && lastRun.remainingWork) {
|
|
61
|
+
sections.push(`### Continue From\n${lastRun.remainingWork}`);
|
|
62
|
+
}
|
|
63
|
+
// 2.3.4: Blockers from last stalled run
|
|
64
|
+
if (lastRun && 'blockers' in lastRun && Array.isArray(lastRun.blockers) && lastRun.blockers.length > 0) {
|
|
65
|
+
sections.push(`### Previous Run Blocked By\n${lastRun.blockers.map((b) => `- ${b}`).join('\n')}`);
|
|
66
|
+
}
|
|
67
|
+
// Last run summary (one run only, not full history)
|
|
68
|
+
if (lastRun && 'summary' in lastRun) {
|
|
69
|
+
sections.push(`### Last Run\nOutcome: ${lastRun.outcome} | ${lastRun.summary}`);
|
|
70
|
+
}
|
|
71
|
+
// Run count + stagnation
|
|
72
|
+
if (task.context.runHistory.length > 0) {
|
|
73
|
+
let meta = `Total runs: ${task.context.runHistory.length}`;
|
|
74
|
+
if (task.context.stagnationCount > 0) {
|
|
75
|
+
meta += ` | Stagnation: ${task.context.stagnationCount} run(s) with no new changes — try a different approach`;
|
|
59
76
|
}
|
|
60
|
-
sections.push(`###
|
|
77
|
+
sections.push(`### Run History\n${meta}`);
|
|
61
78
|
}
|
|
62
|
-
//
|
|
63
|
-
if (task.context.
|
|
64
|
-
sections.push(`###
|
|
79
|
+
// Directive: read the workspace, don't rely on stale context
|
|
80
|
+
if (task.context.runHistory.length > 0) {
|
|
81
|
+
sections.push(`### Important\nRead the workspace to understand current state. Do not assume previous run summaries are accurate — files may have changed since then.`);
|
|
65
82
|
}
|
|
66
83
|
// Execution preferences
|
|
67
84
|
if (preferences) {
|
|
@@ -81,9 +98,9 @@ function buildFull(task, parentTask, siblingTasks, preferences) {
|
|
|
81
98
|
// Truncation cascade
|
|
82
99
|
// ---------------------------------------------------------------------------
|
|
83
100
|
function truncatePrompt(task, parentTask, siblingTasks, preferences) {
|
|
84
|
-
// Level 1: All
|
|
101
|
+
// Level 1: All runs condensed to one-liners
|
|
85
102
|
let result = buildWithTruncation(task, parentTask, siblingTasks, {
|
|
86
|
-
|
|
103
|
+
allRunsCondensed: true,
|
|
87
104
|
filesFromRecentRunsOnly: false,
|
|
88
105
|
parentTitleOnly: false,
|
|
89
106
|
notesCapped: false,
|
|
@@ -92,7 +109,7 @@ function truncatePrompt(task, parentTask, siblingTasks, preferences) {
|
|
|
92
109
|
return result;
|
|
93
110
|
// Level 2: File list → only files from last 2 runs
|
|
94
111
|
result = buildWithTruncation(task, parentTask, siblingTasks, {
|
|
95
|
-
|
|
112
|
+
allRunsCondensed: true,
|
|
96
113
|
filesFromRecentRunsOnly: true,
|
|
97
114
|
parentTitleOnly: false,
|
|
98
115
|
notesCapped: false,
|
|
@@ -101,7 +118,7 @@ function truncatePrompt(task, parentTask, siblingTasks, preferences) {
|
|
|
101
118
|
return result;
|
|
102
119
|
// Level 3: Parent context → title only
|
|
103
120
|
result = buildWithTruncation(task, parentTask, siblingTasks, {
|
|
104
|
-
|
|
121
|
+
allRunsCondensed: true,
|
|
105
122
|
filesFromRecentRunsOnly: true,
|
|
106
123
|
parentTitleOnly: true,
|
|
107
124
|
notesCapped: false,
|
|
@@ -110,7 +127,7 @@ function truncatePrompt(task, parentTask, siblingTasks, preferences) {
|
|
|
110
127
|
return result;
|
|
111
128
|
// Level 4: Notes → first 500 chars
|
|
112
129
|
result = buildWithTruncation(task, parentTask, siblingTasks, {
|
|
113
|
-
|
|
130
|
+
allRunsCondensed: true,
|
|
114
131
|
filesFromRecentRunsOnly: true,
|
|
115
132
|
parentTitleOnly: true,
|
|
116
133
|
notesCapped: true,
|
|
@@ -135,9 +152,15 @@ function buildWithTruncation(task, parentTask, siblingTasks, flags, preferences)
|
|
|
135
152
|
// Files (potentially only from recent runs)
|
|
136
153
|
if (flags.filesFromRecentRunsOnly) {
|
|
137
154
|
const recentFiles = new Set();
|
|
138
|
-
for (const
|
|
139
|
-
|
|
140
|
-
|
|
155
|
+
for (const rp of task.context.runHistory.slice(-2)) {
|
|
156
|
+
if ('filesModified' in rp) {
|
|
157
|
+
for (const f of rp.filesModified)
|
|
158
|
+
recentFiles.add(f);
|
|
159
|
+
}
|
|
160
|
+
if ('filesCreated' in rp) {
|
|
161
|
+
for (const f of rp.filesCreated)
|
|
162
|
+
recentFiles.add(f);
|
|
163
|
+
}
|
|
141
164
|
}
|
|
142
165
|
if (recentFiles.size > 0) {
|
|
143
166
|
sections.push(`### Relevant Files\n${[...recentFiles].join('\n')}`);
|
|
@@ -146,31 +169,36 @@ function buildWithTruncation(task, parentTask, siblingTasks, flags, preferences)
|
|
|
146
169
|
else if (task.context.files.length > 0) {
|
|
147
170
|
sections.push(`### Relevant Files\n${task.context.files.join('\n')}`);
|
|
148
171
|
}
|
|
149
|
-
//
|
|
150
|
-
if (task.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
172
|
+
// Context decay: last acceptance check + last run only
|
|
173
|
+
if (task.lastAcceptanceCheck) {
|
|
174
|
+
const ac = task.lastAcceptanceCheck;
|
|
175
|
+
const checkLines = ac.results
|
|
176
|
+
.map(r => `- ${r.name}: ${r.pass ? 'PASS' : 'FAIL'}`)
|
|
177
|
+
.join('\n');
|
|
178
|
+
sections.push(`### Acceptance Check (${ac.met ? 'ALL PASS' : 'ISSUES FOUND'})\n${checkLines}`);
|
|
179
|
+
}
|
|
180
|
+
const lastRunT = task.context.runHistory.length > 0
|
|
181
|
+
? task.context.runHistory[task.context.runHistory.length - 1]
|
|
182
|
+
: undefined;
|
|
183
|
+
if (lastRunT && 'remainingWork' in lastRunT && lastRunT.remainingWork) {
|
|
184
|
+
sections.push(`### Continue From\n${lastRunT.remainingWork}`);
|
|
185
|
+
}
|
|
186
|
+
if (lastRunT && 'blockers' in lastRunT && Array.isArray(lastRunT.blockers) && lastRunT.blockers.length > 0) {
|
|
187
|
+
sections.push(`### Previous Run Blocked By\n${lastRunT.blockers.map((b) => `- ${b}`).join('\n')}`);
|
|
188
|
+
}
|
|
189
|
+
if (lastRunT && 'summary' in lastRunT) {
|
|
190
|
+
sections.push(`### Last Run\nOutcome: ${lastRunT.outcome} | ${lastRunT.summary}`);
|
|
191
|
+
}
|
|
192
|
+
if (task.context.runHistory.length > 0) {
|
|
193
|
+
let meta = `Total runs: ${task.context.runHistory.length}`;
|
|
194
|
+
if (task.context.stagnationCount > 0) {
|
|
195
|
+
meta += ` | Stagnation: ${task.context.stagnationCount} — try a different approach`;
|
|
166
196
|
}
|
|
197
|
+
sections.push(`### Run History\n${meta}`);
|
|
167
198
|
}
|
|
168
|
-
//
|
|
169
|
-
if (task.context.
|
|
170
|
-
|
|
171
|
-
? task.context.lastError.slice(0, 300)
|
|
172
|
-
: task.context.lastError;
|
|
173
|
-
sections.push(`### Last Error\n${errorText}`);
|
|
199
|
+
// Directive: read the workspace, don't rely on stale context
|
|
200
|
+
if (task.context.runHistory.length > 0) {
|
|
201
|
+
sections.push(`### Important\nRead the workspace to understand current state. Do not assume previous run summaries are accurate — files may have changed since then.`);
|
|
174
202
|
}
|
|
175
203
|
// Execution preferences
|
|
176
204
|
if (preferences) {
|
|
@@ -194,22 +222,8 @@ function buildWithTruncation(task, parentTask, siblingTasks, flags, preferences)
|
|
|
194
222
|
// ---------------------------------------------------------------------------
|
|
195
223
|
// Formatting helpers
|
|
196
224
|
// ---------------------------------------------------------------------------
|
|
197
|
-
function condenseSummary(s) {
|
|
198
|
-
return `- Run ${s.runId.slice(0, 8)} (${s.botId}): ${s.outcome} — ${s.summary.slice(0, 80)} (${Math.round(s.durationMs / 1000)}s, ${s.tokensUsed} tok)`;
|
|
199
|
-
}
|
|
200
|
-
function fullSummary(s) {
|
|
201
|
-
const lines = [];
|
|
202
|
-
lines.push(`\n**Run ${s.runId.slice(0, 8)} (${s.botId}) — ${s.outcome}**`);
|
|
203
|
-
lines.push(s.summary);
|
|
204
|
-
if (s.filesModified.length > 0)
|
|
205
|
-
lines.push(`Files: ${s.filesModified.join(', ')}`);
|
|
206
|
-
if (s.error)
|
|
207
|
-
lines.push(`Error: ${s.error}`);
|
|
208
|
-
lines.push(`Duration: ${Math.round(s.durationMs / 1000)}s · Tokens: ${s.tokensUsed} · Cost: $${s.cost.toFixed(3)}`);
|
|
209
|
-
return lines.join('\n');
|
|
210
|
-
}
|
|
211
225
|
function buildParentSection(parentTask, siblingTasks) {
|
|
212
|
-
let section = `### Parent Context\nPart of: "${parentTask.title}"
|
|
226
|
+
let section = `### Parent Context\nPart of: "${parentTask.title}" \u2014 ${parentTask.description}`;
|
|
213
227
|
if (siblingTasks && siblingTasks.length > 0) {
|
|
214
228
|
const siblingLines = siblingTasks
|
|
215
229
|
.map((s) => `- ${statusIcon(s.status)} ${s.title} (${s.status})`)
|
|
@@ -237,7 +251,7 @@ function statusIcon(status) {
|
|
|
237
251
|
switch (status) {
|
|
238
252
|
case 'done':
|
|
239
253
|
return '\u2705';
|
|
240
|
-
case '
|
|
254
|
+
case 'cancelled':
|
|
241
255
|
return '\u274C';
|
|
242
256
|
case 'in-progress':
|
|
243
257
|
return '\u25CF';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-prompt-builder.js","sourceRoot":"","sources":["../../src/bot/task-prompt-builder.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"task-prompt-builder.js","sourceRoot":"","sources":["../../src/bot/task-prompt-builder.ts"],"names":[],"mappings":"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"}
|
package/dist/bot/task-store.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Task, TaskFilter, CreateTaskInput,
|
|
1
|
+
import type { Task, TaskFilter, CreateTaskInput, RunProgress } from './task-types.js';
|
|
2
2
|
export declare class TaskStore {
|
|
3
3
|
private readonly projectDir;
|
|
4
4
|
private readonly filePath;
|
|
@@ -8,10 +8,10 @@ export declare class TaskStore {
|
|
|
8
8
|
get(id: string): Promise<Task | null>;
|
|
9
9
|
list(filter?: TaskFilter): Promise<Task[]>;
|
|
10
10
|
update(id: string, patch: Partial<Task>): Promise<Task>;
|
|
11
|
-
updateContext(id: string,
|
|
11
|
+
updateContext(id: string, runProgress: RunProgress): Promise<Task>;
|
|
12
12
|
getSubtasks(parentId: string): Promise<Task[]>;
|
|
13
13
|
assignToInstance(taskId: string, instanceId: string, profileId: string): Promise<Task>;
|
|
14
|
-
release(taskId: string, status: 'done' | '
|
|
14
|
+
release(taskId: string, status: 'done' | 'open', runProgress: RunProgress): Promise<Task>;
|
|
15
15
|
private _handleDependencyEffects;
|
|
16
16
|
private _handleParentEffects;
|
|
17
17
|
clearCompleted(): Promise<number>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/bot/task-store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../../src/bot/task-store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAKtF,qBAAa,SAAS;IAIR,OAAO,CAAC,QAAQ,CAAC,UAAU;IAHvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;gBAEb,UAAU,EAAE,MAAM;IAUzC,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAyG7C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAOrC,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAwB1C,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BvD,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBlE,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAW9C,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BtF,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA6E/F,OAAO,CAAC,wBAAwB;IAkBhC,OAAO,CAAC,oBAAoB;IAgCtB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAUjC,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAajC,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,SAAS;CAKlB"}
|
package/dist/bot/task-store.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as fs from 'node:fs';
|
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import * as crypto from 'node:crypto';
|
|
4
4
|
import { AsyncMutex } from './async-mutex.js';
|
|
5
|
-
/** Don't re-queue tasks completed
|
|
5
|
+
/** Don't re-queue tasks completed within this window (ms). */
|
|
6
6
|
const DEDUP_WINDOW_MS = 3_600_000; // 1 hour
|
|
7
7
|
export class TaskStore {
|
|
8
8
|
projectDir;
|
|
@@ -38,17 +38,11 @@ export class TaskStore {
|
|
|
38
38
|
isParent: true,
|
|
39
39
|
parentId: input.parentId,
|
|
40
40
|
dependsOn: input.dependsOn ?? [],
|
|
41
|
-
|
|
42
|
-
currentRunId: undefined,
|
|
43
|
-
context: { files: [], notes: '', runSummaries: [] },
|
|
44
|
-
runs: [],
|
|
45
|
-
attempt: 0,
|
|
46
|
-
maxAttempts: input.maxAttempts ?? 3,
|
|
47
|
-
budgetTokens: input.budgetTokens,
|
|
41
|
+
context: { files: [], notes: '', runHistory: [], stagnationCount: 0 },
|
|
48
42
|
budgetCost: input.budgetCost,
|
|
49
43
|
tokensUsed: 0,
|
|
50
44
|
costUsed: 0,
|
|
51
|
-
|
|
45
|
+
acceptance: input.acceptance,
|
|
52
46
|
complexity: input.complexity,
|
|
53
47
|
assignedProfile: input.assignedProfile,
|
|
54
48
|
createdBy: input.createdBy ?? 'user',
|
|
@@ -76,16 +70,11 @@ export class TaskStore {
|
|
|
76
70
|
isParent: false,
|
|
77
71
|
parentId: parentId,
|
|
78
72
|
dependsOn: resolvedDeps,
|
|
79
|
-
|
|
80
|
-
currentRunId: undefined,
|
|
81
|
-
context: { files: [], notes: '', runSummaries: [] },
|
|
82
|
-
runs: [],
|
|
83
|
-
attempt: 0,
|
|
84
|
-
maxAttempts: input.maxAttempts ?? 3,
|
|
85
|
-
budgetTokens: input.budgetTokens,
|
|
73
|
+
context: { files: [], notes: '', runHistory: [], stagnationCount: 0 },
|
|
86
74
|
budgetCost: input.budgetCost,
|
|
87
75
|
tokensUsed: 0,
|
|
88
76
|
costUsed: 0,
|
|
77
|
+
acceptance: sub.acceptance ?? input.acceptance,
|
|
89
78
|
complexity: sub.complexity ?? input.complexity,
|
|
90
79
|
assignedProfile: sub.assignedProfile ?? input.assignedProfile,
|
|
91
80
|
createdBy: input.createdBy ?? 'user',
|
|
@@ -112,17 +101,11 @@ export class TaskStore {
|
|
|
112
101
|
isParent: false,
|
|
113
102
|
parentId: input.parentId,
|
|
114
103
|
dependsOn: input.dependsOn ?? [],
|
|
115
|
-
|
|
116
|
-
currentRunId: undefined,
|
|
117
|
-
context: { files: [], notes: '', runSummaries: [] },
|
|
118
|
-
runs: [],
|
|
119
|
-
attempt: 0,
|
|
120
|
-
maxAttempts: input.maxAttempts ?? 3,
|
|
121
|
-
budgetTokens: input.budgetTokens,
|
|
104
|
+
context: { files: [], notes: '', runHistory: [], stagnationCount: 0 },
|
|
122
105
|
budgetCost: input.budgetCost,
|
|
123
106
|
tokensUsed: 0,
|
|
124
107
|
costUsed: 0,
|
|
125
|
-
|
|
108
|
+
acceptance: input.acceptance,
|
|
126
109
|
complexity: input.complexity,
|
|
127
110
|
assignedProfile: input.assignedProfile,
|
|
128
111
|
createdBy: input.createdBy ?? 'user',
|
|
@@ -152,7 +135,7 @@ export class TaskStore {
|
|
|
152
135
|
tasks = tasks.filter(t => t.parentId === filter.parentId);
|
|
153
136
|
}
|
|
154
137
|
if (filter.botId !== undefined) {
|
|
155
|
-
tasks = tasks.filter(t => t.
|
|
138
|
+
tasks = tasks.filter(t => t.assignedProfile === filter.botId);
|
|
156
139
|
}
|
|
157
140
|
if (filter.limit !== undefined && filter.limit > 0) {
|
|
158
141
|
tasks = tasks.slice(0, filter.limit);
|
|
@@ -168,26 +151,30 @@ export class TaskStore {
|
|
|
168
151
|
if (idx === -1)
|
|
169
152
|
throw new Error(`Task not found: ${id}`);
|
|
170
153
|
const task = tasks[idx];
|
|
154
|
+
// Reset stagnation when profile is reassigned (fresh start for new approach)
|
|
155
|
+
if (patch.assignedProfile && patch.assignedProfile !== task.assignedProfile) {
|
|
156
|
+
task.context.stagnationCount = 0;
|
|
157
|
+
}
|
|
158
|
+
// Trigger parent effects when status changes to done or cancelled
|
|
159
|
+
const statusChanged = patch.status && patch.status !== task.status;
|
|
171
160
|
Object.assign(task, patch, { updatedAt: new Date().toISOString() });
|
|
172
161
|
tasks[idx] = task;
|
|
162
|
+
if (statusChanged && (task.status === 'done' || task.status === 'cancelled')) {
|
|
163
|
+
this._handleDependencyEffects(tasks, task);
|
|
164
|
+
this._handleParentEffects(tasks, task);
|
|
165
|
+
}
|
|
173
166
|
this._writeAll(tasks);
|
|
174
167
|
return task;
|
|
175
168
|
});
|
|
176
169
|
}
|
|
177
|
-
async updateContext(id,
|
|
170
|
+
async updateContext(id, runProgress) {
|
|
178
171
|
return this.mutex.runExclusive(async () => {
|
|
179
172
|
const tasks = this._readAll();
|
|
180
173
|
const idx = tasks.findIndex(t => t.id === id);
|
|
181
174
|
if (idx === -1)
|
|
182
175
|
throw new Error(`Task not found: ${id}`);
|
|
183
176
|
const task = tasks[idx];
|
|
184
|
-
task.context.
|
|
185
|
-
if (runSummary.outcome === 'failed' || runSummary.outcome === 'error') {
|
|
186
|
-
task.context.lastError = runSummary.error;
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
task.context.lastError = undefined;
|
|
190
|
-
}
|
|
177
|
+
task.context.runHistory.push(runProgress);
|
|
191
178
|
task.updatedAt = new Date().toISOString();
|
|
192
179
|
tasks[idx] = task;
|
|
193
180
|
this._writeAll(tasks);
|
|
@@ -213,13 +200,12 @@ export class TaskStore {
|
|
|
213
200
|
if (idx === -1)
|
|
214
201
|
throw new Error(`Task not found: ${taskId}`);
|
|
215
202
|
const task = tasks[idx];
|
|
216
|
-
const assignable =
|
|
217
|
-
task.attempt < task.maxAttempts;
|
|
203
|
+
const assignable = task.status === 'open' && !task.context.budgetExhausted;
|
|
218
204
|
if (!assignable) {
|
|
219
|
-
throw new Error(`Task ${taskId} is not assignable (status: ${task.status}
|
|
205
|
+
throw new Error(`Task ${taskId} is not assignable (status: ${task.status})`);
|
|
220
206
|
}
|
|
221
207
|
task.status = 'in-progress';
|
|
222
|
-
task.
|
|
208
|
+
task.activeRunId = instanceId; // will be replaced with actual runId by swarm controller
|
|
223
209
|
task.assignedProfile = profileId;
|
|
224
210
|
task.updatedAt = new Date().toISOString();
|
|
225
211
|
tasks[idx] = task;
|
|
@@ -230,38 +216,61 @@ export class TaskStore {
|
|
|
230
216
|
// ---------------------------------------------------------------------------
|
|
231
217
|
// Release
|
|
232
218
|
// ---------------------------------------------------------------------------
|
|
233
|
-
async release(taskId, status,
|
|
219
|
+
async release(taskId, status, runProgress) {
|
|
234
220
|
return this.mutex.runExclusive(async () => {
|
|
235
221
|
const tasks = this._readAll();
|
|
236
222
|
const idx = tasks.findIndex(t => t.id === taskId);
|
|
237
223
|
if (idx === -1)
|
|
238
224
|
throw new Error(`Task not found: ${taskId}`);
|
|
239
225
|
const task = tasks[idx];
|
|
240
|
-
// Append run
|
|
241
|
-
task.context.
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
226
|
+
// Append run progress
|
|
227
|
+
task.context.runHistory.push(runProgress);
|
|
228
|
+
// Accumulate usage
|
|
229
|
+
task.tokensUsed += runProgress.tokensUsed;
|
|
230
|
+
task.costUsed += runProgress.cost;
|
|
231
|
+
// Update stagnation count
|
|
232
|
+
const prevRun = task.context.runHistory.length >= 2
|
|
233
|
+
? task.context.runHistory[task.context.runHistory.length - 2]
|
|
234
|
+
: undefined;
|
|
235
|
+
if (prevRun && 'filesCreated' in prevRun && 'filesModified' in prevRun) {
|
|
236
|
+
const prevFiles = new Set([...prevRun.filesCreated, ...prevRun.filesModified]);
|
|
237
|
+
const newFiles = new Set([...runProgress.filesCreated, ...runProgress.filesModified]);
|
|
238
|
+
const hasNewFiles = [...newFiles].some(f => !prevFiles.has(f));
|
|
239
|
+
task.context.stagnationCount = hasNewFiles ? 0 : task.context.stagnationCount + 1;
|
|
247
240
|
}
|
|
248
241
|
else {
|
|
249
|
-
task.context.
|
|
242
|
+
task.context.stagnationCount = 0;
|
|
250
243
|
}
|
|
251
|
-
//
|
|
252
|
-
task.
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
task.
|
|
258
|
-
task.currentBotId = undefined;
|
|
259
|
-
task.currentRunId = undefined;
|
|
244
|
+
// Check budget exhaustion
|
|
245
|
+
if (task.budgetCost && task.costUsed >= task.budgetCost) {
|
|
246
|
+
task.context.budgetExhausted = true;
|
|
247
|
+
}
|
|
248
|
+
// Update status
|
|
249
|
+
task.status = status;
|
|
250
|
+
task.activeRunId = undefined;
|
|
260
251
|
task.updatedAt = new Date().toISOString();
|
|
261
252
|
if (status === 'done') {
|
|
262
253
|
task.completedAt = new Date().toISOString();
|
|
263
254
|
}
|
|
264
|
-
//
|
|
255
|
+
// Compact old runs: keep last 5 full, older become audit-only
|
|
256
|
+
if (task.context.runHistory.length > 5) {
|
|
257
|
+
const cutoff = task.context.runHistory.length - 5;
|
|
258
|
+
for (let i = 0; i < cutoff; i++) {
|
|
259
|
+
const old = task.context.runHistory[i];
|
|
260
|
+
if ('filesCreated' in old) {
|
|
261
|
+
task.context.runHistory[i] = {
|
|
262
|
+
runId: old.runId,
|
|
263
|
+
botId: old.botId,
|
|
264
|
+
profileId: old.profileId,
|
|
265
|
+
outcome: old.outcome,
|
|
266
|
+
tokensUsed: old.tokensUsed,
|
|
267
|
+
cost: old.cost,
|
|
268
|
+
durationMs: old.durationMs,
|
|
269
|
+
endedAt: old.endedAt,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
265
274
|
tasks[idx] = task;
|
|
266
275
|
// --- Post-release effects ---
|
|
267
276
|
this._handleDependencyEffects(tasks, task);
|
|
@@ -274,20 +283,18 @@ export class TaskStore {
|
|
|
274
283
|
// Dependency + parent cascading effects
|
|
275
284
|
// ---------------------------------------------------------------------------
|
|
276
285
|
_handleDependencyEffects(tasks, changedTask) {
|
|
277
|
-
if (changedTask.status
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
+
if (changedTask.status !== 'done' && changedTask.status !== 'cancelled')
|
|
287
|
+
return;
|
|
288
|
+
// A dep is resolved when it's done OR cancelled.
|
|
289
|
+
const resolvedIds = new Set(tasks.filter(t => t.status === 'done' || t.status === 'cancelled').map(t => t.id));
|
|
290
|
+
for (const t of tasks) {
|
|
291
|
+
if (t.status === 'open' && t.dependsOn.includes(changedTask.id)) {
|
|
292
|
+
if (t.dependsOn.every(depId => resolvedIds.has(depId))) {
|
|
293
|
+
// All deps resolved — bump updatedAt as a "ready" signal for the dispatcher.
|
|
294
|
+
t.updatedAt = new Date().toISOString();
|
|
286
295
|
}
|
|
287
296
|
}
|
|
288
297
|
}
|
|
289
|
-
// Tasks don't fail — runs fail. Dependents stay blocked until dep
|
|
290
|
-
// succeeds (status=done). No terminal 'failed' state to handle.
|
|
291
298
|
}
|
|
292
299
|
_handleParentEffects(tasks, changedTask) {
|
|
293
300
|
if (!changedTask.parentId)
|
|
@@ -299,15 +306,22 @@ export class TaskStore {
|
|
|
299
306
|
if (!parent.isParent)
|
|
300
307
|
return;
|
|
301
308
|
const subtasks = tasks.filter(t => t.parentId === parent.id);
|
|
302
|
-
// All done => parent
|
|
303
|
-
|
|
309
|
+
// All subtasks resolved (done or cancelled) => parent resolved
|
|
310
|
+
const allResolved = subtasks.every(s => s.status === 'done' || s.status === 'cancelled');
|
|
311
|
+
if (!allResolved)
|
|
312
|
+
return;
|
|
313
|
+
// If ALL subtasks were cancelled (none done), parent is cancelled too
|
|
314
|
+
const anyDone = subtasks.some(s => s.status === 'done');
|
|
315
|
+
if (anyDone) {
|
|
304
316
|
parent.status = 'done';
|
|
305
317
|
parent.completedAt = new Date().toISOString();
|
|
306
|
-
parent.updatedAt = new Date().toISOString();
|
|
307
|
-
return;
|
|
308
318
|
}
|
|
309
|
-
|
|
310
|
-
|
|
319
|
+
else {
|
|
320
|
+
parent.status = 'cancelled';
|
|
321
|
+
parent.cancelledAt = new Date().toISOString();
|
|
322
|
+
parent.cancelReason = 'All subtasks cancelled';
|
|
323
|
+
}
|
|
324
|
+
parent.updatedAt = new Date().toISOString();
|
|
311
325
|
}
|
|
312
326
|
// ---------------------------------------------------------------------------
|
|
313
327
|
// Bulk clear
|
|
@@ -333,8 +347,8 @@ export class TaskStore {
|
|
|
333
347
|
// Deduplication
|
|
334
348
|
// ---------------------------------------------------------------------------
|
|
335
349
|
_findDuplicate(tasks, title, description) {
|
|
336
|
-
// Check open
|
|
337
|
-
const openDup = tasks.find(t =>
|
|
350
|
+
// Check open duplicates
|
|
351
|
+
const openDup = tasks.find(t => t.status === 'open' && t.title === title && t.description === description);
|
|
338
352
|
if (openDup)
|
|
339
353
|
return openDup;
|
|
340
354
|
// Check recently completed (within dedup window)
|