oh-my-claude-sisyphus 3.5.8 → 3.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/agents/executor-high.md +2 -0
- package/agents/executor-low.md +2 -0
- package/agents/executor.md +2 -0
- package/agents/templates/base-agent.md +9 -0
- package/commands/cancel.md +8 -8
- package/commands/swarm.md +350 -148
- package/dist/__tests__/hooks.test.js +10 -9
- package/dist/__tests__/hooks.test.js.map +1 -1
- package/dist/agents/codex-agents.d.ts +20 -0
- package/dist/agents/codex-agents.d.ts.map +1 -0
- package/dist/agents/codex-agents.js +36 -0
- package/dist/agents/codex-agents.js.map +1 -0
- package/dist/agents/preamble.d.ts +14 -0
- package/dist/agents/preamble.d.ts.map +1 -0
- package/dist/agents/preamble.js +26 -0
- package/dist/agents/preamble.js.map +1 -0
- package/dist/hooks/autopilot/__tests__/cancel.test.js +14 -4
- package/dist/hooks/autopilot/__tests__/cancel.test.js.map +1 -1
- package/dist/hooks/autopilot/__tests__/state.test.js +1 -0
- package/dist/hooks/autopilot/__tests__/state.test.js.map +1 -1
- package/dist/hooks/autopilot/__tests__/summary.test.js +38 -3
- package/dist/hooks/autopilot/__tests__/summary.test.js.map +1 -1
- package/dist/hooks/autopilot/state.d.ts +1 -1
- package/dist/hooks/autopilot/state.d.ts.map +1 -1
- package/dist/hooks/autopilot/state.js +15 -8
- package/dist/hooks/autopilot/state.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +7 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/mode-registry/index.d.ts +135 -0
- package/dist/hooks/mode-registry/index.d.ts.map +1 -0
- package/dist/hooks/mode-registry/index.js +445 -0
- package/dist/hooks/mode-registry/index.js.map +1 -0
- package/dist/hooks/mode-registry/types.d.ts +31 -0
- package/dist/hooks/mode-registry/types.d.ts.map +1 -0
- package/dist/hooks/mode-registry/types.js +7 -0
- package/dist/hooks/mode-registry/types.js.map +1 -0
- package/dist/hooks/ralph/loop.js +6 -6
- package/dist/hooks/ralph/loop.js.map +1 -1
- package/dist/hooks/swarm/__tests__/claiming.test.d.ts +2 -0
- package/dist/hooks/swarm/__tests__/claiming.test.d.ts.map +1 -0
- package/dist/hooks/swarm/__tests__/claiming.test.js +170 -0
- package/dist/hooks/swarm/__tests__/claiming.test.js.map +1 -0
- package/dist/hooks/swarm/__tests__/index.test.d.ts +2 -0
- package/dist/hooks/swarm/__tests__/index.test.d.ts.map +1 -0
- package/dist/hooks/swarm/__tests__/index.test.js +157 -0
- package/dist/hooks/swarm/__tests__/index.test.js.map +1 -0
- package/dist/hooks/swarm/__tests__/mode-registry.test.d.ts +2 -0
- package/dist/hooks/swarm/__tests__/mode-registry.test.d.ts.map +1 -0
- package/dist/hooks/swarm/__tests__/mode-registry.test.js +177 -0
- package/dist/hooks/swarm/__tests__/mode-registry.test.js.map +1 -0
- package/dist/hooks/swarm/claiming.d.ts +101 -0
- package/dist/hooks/swarm/claiming.d.ts.map +1 -0
- package/dist/hooks/swarm/claiming.js +460 -0
- package/dist/hooks/swarm/claiming.js.map +1 -0
- package/dist/hooks/swarm/index.d.ts +221 -0
- package/dist/hooks/swarm/index.d.ts.map +1 -0
- package/dist/hooks/swarm/index.js +413 -0
- package/dist/hooks/swarm/index.js.map +1 -0
- package/dist/hooks/swarm/state.d.ts +94 -0
- package/dist/hooks/swarm/state.d.ts.map +1 -0
- package/dist/hooks/swarm/state.js +530 -0
- package/dist/hooks/swarm/state.js.map +1 -0
- package/dist/hooks/swarm/types.d.ts +116 -0
- package/dist/hooks/swarm/types.d.ts.map +1 -0
- package/dist/hooks/swarm/types.js +22 -0
- package/dist/hooks/swarm/types.js.map +1 -0
- package/dist/hooks/ultrapilot/decomposer.d.ts +141 -0
- package/dist/hooks/ultrapilot/decomposer.d.ts.map +1 -0
- package/dist/hooks/ultrapilot/decomposer.js +377 -0
- package/dist/hooks/ultrapilot/decomposer.js.map +1 -0
- package/dist/hooks/ultrapilot/index.d.ts +31 -0
- package/dist/hooks/ultrapilot/index.d.ts.map +1 -1
- package/dist/hooks/ultrapilot/index.js +43 -2
- package/dist/hooks/ultrapilot/index.js.map +1 -1
- package/dist/hooks/ultrapilot/state.d.ts +1 -1
- package/dist/hooks/ultrapilot/state.d.ts.map +1 -1
- package/dist/hooks/ultrapilot/state.js +7 -0
- package/dist/hooks/ultrapilot/state.js.map +1 -1
- package/dist/hooks/ultraqa/index.js +5 -5
- package/dist/hooks/ultraqa/index.js.map +1 -1
- package/dist/hooks/ultrawork/index.js +3 -3
- package/dist/hooks/ultrawork/index.js.map +1 -1
- package/package.json +3 -1
- package/skills/autopilot/SKILL.md +18 -0
- package/skills/cancel/SKILL.md +166 -141
- package/skills/ecomode/SKILL.md +14 -0
- package/skills/pipeline/SKILL.md +13 -0
- package/skills/ralph/SKILL.md +22 -1
- package/skills/swarm/SKILL.md +521 -197
- package/skills/ultrapilot/SKILL.md +82 -13
- package/skills/ultraqa/SKILL.md +13 -0
- package/skills/ultrawork/SKILL.md +14 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swarm Task Claiming
|
|
3
|
+
*
|
|
4
|
+
* Atomic task claiming with lease-based ownership.
|
|
5
|
+
* Uses SQLite transactions to ensure only one agent can claim a task.
|
|
6
|
+
* Implements 5-minute lease timeout and heartbeat monitoring.
|
|
7
|
+
*/
|
|
8
|
+
import type { ClaimResult, SwarmTask } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Atomically claim the next available task
|
|
11
|
+
*
|
|
12
|
+
* Uses a transaction to ensure only one agent can claim a task.
|
|
13
|
+
* Claims are lease-based with a 5-minute timeout.
|
|
14
|
+
*
|
|
15
|
+
* @param agentId - Unique identifier for the claiming agent
|
|
16
|
+
* @returns ClaimResult indicating success/failure and task details
|
|
17
|
+
*/
|
|
18
|
+
export declare function claimTask(agentId: string): ClaimResult;
|
|
19
|
+
/**
|
|
20
|
+
* Release a claimed task back to the pending pool
|
|
21
|
+
*
|
|
22
|
+
* Used when an agent fails to complete a task or wants to give it up.
|
|
23
|
+
*
|
|
24
|
+
* @param agentId - Agent releasing the task
|
|
25
|
+
* @param taskId - Task to release
|
|
26
|
+
* @returns true if release was successful
|
|
27
|
+
*/
|
|
28
|
+
export declare function releaseTask(agentId: string, taskId: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Mark a task as completed
|
|
31
|
+
*
|
|
32
|
+
* @param agentId - Agent that completed the task
|
|
33
|
+
* @param taskId - Completed task ID
|
|
34
|
+
* @param result - Optional result/output from the task
|
|
35
|
+
* @returns true if completion was recorded
|
|
36
|
+
*/
|
|
37
|
+
export declare function completeTask(agentId: string, taskId: string, result?: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Mark a task as failed
|
|
40
|
+
*
|
|
41
|
+
* @param agentId - Agent that failed the task
|
|
42
|
+
* @param taskId - Failed task ID
|
|
43
|
+
* @param error - Error message/reason for failure
|
|
44
|
+
* @returns true if failure was recorded
|
|
45
|
+
*/
|
|
46
|
+
export declare function failTask(agentId: string, taskId: string, error: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Record agent heartbeat
|
|
49
|
+
*
|
|
50
|
+
* Agents should call this every 60 seconds to indicate they're still alive.
|
|
51
|
+
* Used by cleanupStaleClaims to detect dead agents.
|
|
52
|
+
*
|
|
53
|
+
* @param agentId - Agent sending heartbeat
|
|
54
|
+
* @returns true if heartbeat was recorded
|
|
55
|
+
*/
|
|
56
|
+
export declare function heartbeat(agentId: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Clean up stale claims from dead agents
|
|
59
|
+
*
|
|
60
|
+
* Releases tasks that have been claimed for longer than the lease timeout
|
|
61
|
+
* (default 5 minutes) by agents that haven't sent a heartbeat.
|
|
62
|
+
*
|
|
63
|
+
* @param leaseTimeout - Lease timeout in milliseconds (default: 5 minutes)
|
|
64
|
+
* @returns Number of tasks released
|
|
65
|
+
*/
|
|
66
|
+
export declare function cleanupStaleClaims(leaseTimeout?: number): number;
|
|
67
|
+
/**
|
|
68
|
+
* Get tasks claimed by a specific agent
|
|
69
|
+
*
|
|
70
|
+
* @param agentId - Agent to query
|
|
71
|
+
* @returns Array of tasks claimed by the agent
|
|
72
|
+
*/
|
|
73
|
+
export declare function getTasksClaimedBy(agentId: string): SwarmTask[];
|
|
74
|
+
/**
|
|
75
|
+
* Check if there are any pending tasks
|
|
76
|
+
*
|
|
77
|
+
* @returns true if there are pending tasks
|
|
78
|
+
*/
|
|
79
|
+
export declare function hasPendingTasks(): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Check if all tasks are complete (done or failed)
|
|
82
|
+
*
|
|
83
|
+
* @returns true if all tasks are complete
|
|
84
|
+
*/
|
|
85
|
+
export declare function allTasksComplete(): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Get the number of active agents (with recent heartbeats)
|
|
88
|
+
*
|
|
89
|
+
* @param heartbeatTimeout - How old a heartbeat can be to still be considered active
|
|
90
|
+
* @returns Number of active agents
|
|
91
|
+
*/
|
|
92
|
+
export declare function getActiveAgentCount(heartbeatTimeout?: number): number;
|
|
93
|
+
/**
|
|
94
|
+
* Attempt to reclaim a failed task
|
|
95
|
+
*
|
|
96
|
+
* @param agentId - Agent attempting to reclaim
|
|
97
|
+
* @param taskId - Task to reclaim
|
|
98
|
+
* @returns ClaimResult
|
|
99
|
+
*/
|
|
100
|
+
export declare function reclaimFailedTask(agentId: string, taskId: string): ClaimResult;
|
|
101
|
+
//# sourceMappingURL=claiming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claiming.d.ts","sourceRoot":"","sources":["../../../src/hooks/swarm/claiming.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAazD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAqEtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAsCpE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAsCtF;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAsChF;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAgBlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,GAAE,MAA0C,GAAG,MAAM,CA2DnG;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAiC9D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAczC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAc1C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,gBAAgB,GAAE,MAA0C,GAAG,MAAM,CAexG;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAgE9E"}
|
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swarm Task Claiming
|
|
3
|
+
*
|
|
4
|
+
* Atomic task claiming with lease-based ownership.
|
|
5
|
+
* Uses SQLite transactions to ensure only one agent can claim a task.
|
|
6
|
+
* Implements 5-minute lease timeout and heartbeat monitoring.
|
|
7
|
+
*/
|
|
8
|
+
import { DEFAULT_SWARM_CONFIG } from './types.js';
|
|
9
|
+
import { getDb, recordHeartbeat } from './state.js';
|
|
10
|
+
/**
|
|
11
|
+
* Atomically claim the next available task
|
|
12
|
+
*
|
|
13
|
+
* Uses a transaction to ensure only one agent can claim a task.
|
|
14
|
+
* Claims are lease-based with a 5-minute timeout.
|
|
15
|
+
*
|
|
16
|
+
* @param agentId - Unique identifier for the claiming agent
|
|
17
|
+
* @returns ClaimResult indicating success/failure and task details
|
|
18
|
+
*/
|
|
19
|
+
export function claimTask(agentId) {
|
|
20
|
+
const db = getDb();
|
|
21
|
+
if (!db) {
|
|
22
|
+
return {
|
|
23
|
+
success: false,
|
|
24
|
+
taskId: null,
|
|
25
|
+
reason: 'Database not initialized'
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
// Use a transaction for atomic claim
|
|
30
|
+
const claimTransaction = db.transaction(() => {
|
|
31
|
+
// Find the first pending task
|
|
32
|
+
const findStmt = db.prepare(`
|
|
33
|
+
SELECT id, description FROM tasks
|
|
34
|
+
WHERE status = 'pending'
|
|
35
|
+
ORDER BY id
|
|
36
|
+
LIMIT 1
|
|
37
|
+
`);
|
|
38
|
+
const task = findStmt.get();
|
|
39
|
+
if (!task) {
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
taskId: null,
|
|
43
|
+
reason: 'No pending tasks available'
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Claim the task
|
|
47
|
+
const claimStmt = db.prepare(`
|
|
48
|
+
UPDATE tasks
|
|
49
|
+
SET status = 'claimed', claimed_by = ?, claimed_at = ?
|
|
50
|
+
WHERE id = ? AND status = 'pending'
|
|
51
|
+
`);
|
|
52
|
+
const result = claimStmt.run(agentId, Date.now(), task.id);
|
|
53
|
+
if (result.changes === 0) {
|
|
54
|
+
// Task was claimed by another agent between SELECT and UPDATE
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
taskId: null,
|
|
58
|
+
reason: 'Task was claimed by another agent'
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Update heartbeat
|
|
62
|
+
const heartbeatStmt = db.prepare(`
|
|
63
|
+
INSERT OR REPLACE INTO heartbeats (agent_id, last_heartbeat, current_task_id)
|
|
64
|
+
VALUES (?, ?, ?)
|
|
65
|
+
`);
|
|
66
|
+
heartbeatStmt.run(agentId, Date.now(), task.id);
|
|
67
|
+
return {
|
|
68
|
+
success: true,
|
|
69
|
+
taskId: task.id,
|
|
70
|
+
description: task.description
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
return claimTransaction.immediate();
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
return {
|
|
77
|
+
success: false,
|
|
78
|
+
taskId: null,
|
|
79
|
+
reason: `Claim failed: ${error instanceof Error ? error.message : String(error)}`
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Release a claimed task back to the pending pool
|
|
85
|
+
*
|
|
86
|
+
* Used when an agent fails to complete a task or wants to give it up.
|
|
87
|
+
*
|
|
88
|
+
* @param agentId - Agent releasing the task
|
|
89
|
+
* @param taskId - Task to release
|
|
90
|
+
* @returns true if release was successful
|
|
91
|
+
*/
|
|
92
|
+
export function releaseTask(agentId, taskId) {
|
|
93
|
+
const db = getDb();
|
|
94
|
+
if (!db)
|
|
95
|
+
return false;
|
|
96
|
+
try {
|
|
97
|
+
const releaseTransaction = db.transaction(() => {
|
|
98
|
+
// Verify the agent owns this task
|
|
99
|
+
const verifyStmt = db.prepare(`
|
|
100
|
+
SELECT claimed_by FROM tasks WHERE id = ?
|
|
101
|
+
`);
|
|
102
|
+
const task = verifyStmt.get(taskId);
|
|
103
|
+
if (!task || task.claimed_by !== agentId) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
// Release the task
|
|
107
|
+
const releaseStmt = db.prepare(`
|
|
108
|
+
UPDATE tasks
|
|
109
|
+
SET status = 'pending', claimed_by = NULL, claimed_at = NULL
|
|
110
|
+
WHERE id = ? AND claimed_by = ?
|
|
111
|
+
`);
|
|
112
|
+
releaseStmt.run(taskId, agentId);
|
|
113
|
+
// Update heartbeat to show no current task
|
|
114
|
+
const heartbeatStmt = db.prepare(`
|
|
115
|
+
UPDATE heartbeats SET current_task_id = NULL WHERE agent_id = ?
|
|
116
|
+
`);
|
|
117
|
+
heartbeatStmt.run(agentId);
|
|
118
|
+
return true;
|
|
119
|
+
});
|
|
120
|
+
return releaseTransaction.immediate();
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
console.error('Failed to release task:', error);
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Mark a task as completed
|
|
129
|
+
*
|
|
130
|
+
* @param agentId - Agent that completed the task
|
|
131
|
+
* @param taskId - Completed task ID
|
|
132
|
+
* @param result - Optional result/output from the task
|
|
133
|
+
* @returns true if completion was recorded
|
|
134
|
+
*/
|
|
135
|
+
export function completeTask(agentId, taskId, result) {
|
|
136
|
+
const db = getDb();
|
|
137
|
+
if (!db)
|
|
138
|
+
return false;
|
|
139
|
+
try {
|
|
140
|
+
const completeTransaction = db.transaction(() => {
|
|
141
|
+
// Verify the agent owns this task
|
|
142
|
+
const verifyStmt = db.prepare(`
|
|
143
|
+
SELECT claimed_by FROM tasks WHERE id = ?
|
|
144
|
+
`);
|
|
145
|
+
const task = verifyStmt.get(taskId);
|
|
146
|
+
if (!task || task.claimed_by !== agentId) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
// Mark task as done
|
|
150
|
+
const completeStmt = db.prepare(`
|
|
151
|
+
UPDATE tasks
|
|
152
|
+
SET status = 'done', completed_at = ?, result = ?
|
|
153
|
+
WHERE id = ? AND claimed_by = ?
|
|
154
|
+
`);
|
|
155
|
+
completeStmt.run(Date.now(), result ?? null, taskId, agentId);
|
|
156
|
+
// Update heartbeat to show no current task
|
|
157
|
+
const heartbeatStmt = db.prepare(`
|
|
158
|
+
UPDATE heartbeats SET current_task_id = NULL WHERE agent_id = ?
|
|
159
|
+
`);
|
|
160
|
+
heartbeatStmt.run(agentId);
|
|
161
|
+
return true;
|
|
162
|
+
});
|
|
163
|
+
return completeTransaction.immediate();
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
console.error('Failed to complete task:', error);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Mark a task as failed
|
|
172
|
+
*
|
|
173
|
+
* @param agentId - Agent that failed the task
|
|
174
|
+
* @param taskId - Failed task ID
|
|
175
|
+
* @param error - Error message/reason for failure
|
|
176
|
+
* @returns true if failure was recorded
|
|
177
|
+
*/
|
|
178
|
+
export function failTask(agentId, taskId, error) {
|
|
179
|
+
const db = getDb();
|
|
180
|
+
if (!db)
|
|
181
|
+
return false;
|
|
182
|
+
try {
|
|
183
|
+
const failTransaction = db.transaction(() => {
|
|
184
|
+
// Verify the agent owns this task
|
|
185
|
+
const verifyStmt = db.prepare(`
|
|
186
|
+
SELECT claimed_by FROM tasks WHERE id = ?
|
|
187
|
+
`);
|
|
188
|
+
const task = verifyStmt.get(taskId);
|
|
189
|
+
if (!task || task.claimed_by !== agentId) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
// Mark task as failed
|
|
193
|
+
const failStmt = db.prepare(`
|
|
194
|
+
UPDATE tasks
|
|
195
|
+
SET status = 'failed', completed_at = ?, error = ?
|
|
196
|
+
WHERE id = ? AND claimed_by = ?
|
|
197
|
+
`);
|
|
198
|
+
failStmt.run(Date.now(), error, taskId, agentId);
|
|
199
|
+
// Update heartbeat to show no current task
|
|
200
|
+
const heartbeatStmt = db.prepare(`
|
|
201
|
+
UPDATE heartbeats SET current_task_id = NULL WHERE agent_id = ?
|
|
202
|
+
`);
|
|
203
|
+
heartbeatStmt.run(agentId);
|
|
204
|
+
return true;
|
|
205
|
+
});
|
|
206
|
+
return failTransaction.immediate();
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
console.error('Failed to fail task:', error);
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Record agent heartbeat
|
|
215
|
+
*
|
|
216
|
+
* Agents should call this every 60 seconds to indicate they're still alive.
|
|
217
|
+
* Used by cleanupStaleClaims to detect dead agents.
|
|
218
|
+
*
|
|
219
|
+
* @param agentId - Agent sending heartbeat
|
|
220
|
+
* @returns true if heartbeat was recorded
|
|
221
|
+
*/
|
|
222
|
+
export function heartbeat(agentId) {
|
|
223
|
+
const db = getDb();
|
|
224
|
+
if (!db)
|
|
225
|
+
return false;
|
|
226
|
+
try {
|
|
227
|
+
// Get current task for this agent
|
|
228
|
+
const taskStmt = db.prepare(`
|
|
229
|
+
SELECT id FROM tasks WHERE claimed_by = ? AND status = 'claimed'
|
|
230
|
+
`);
|
|
231
|
+
const task = taskStmt.get(agentId);
|
|
232
|
+
return recordHeartbeat(agentId, task?.id ?? null);
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
console.error('Failed to record heartbeat:', error);
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Clean up stale claims from dead agents
|
|
241
|
+
*
|
|
242
|
+
* Releases tasks that have been claimed for longer than the lease timeout
|
|
243
|
+
* (default 5 minutes) by agents that haven't sent a heartbeat.
|
|
244
|
+
*
|
|
245
|
+
* @param leaseTimeout - Lease timeout in milliseconds (default: 5 minutes)
|
|
246
|
+
* @returns Number of tasks released
|
|
247
|
+
*/
|
|
248
|
+
export function cleanupStaleClaims(leaseTimeout = DEFAULT_SWARM_CONFIG.leaseTimeout) {
|
|
249
|
+
const db = getDb();
|
|
250
|
+
if (!db)
|
|
251
|
+
return 0;
|
|
252
|
+
try {
|
|
253
|
+
const cutoffTime = Date.now() - leaseTimeout;
|
|
254
|
+
const cleanupTransaction = db.transaction(() => {
|
|
255
|
+
// Find tasks claimed longer than the timeout
|
|
256
|
+
// Only release if the agent hasn't sent a heartbeat recently
|
|
257
|
+
const findStaleStmt = db.prepare(`
|
|
258
|
+
SELECT t.id, t.claimed_by
|
|
259
|
+
FROM tasks t
|
|
260
|
+
LEFT JOIN heartbeats h ON t.claimed_by = h.agent_id
|
|
261
|
+
WHERE t.status = 'claimed'
|
|
262
|
+
AND t.claimed_at < ?
|
|
263
|
+
AND (h.last_heartbeat IS NULL OR h.last_heartbeat < ?)
|
|
264
|
+
`);
|
|
265
|
+
const staleTasks = findStaleStmt.all(cutoffTime, cutoffTime);
|
|
266
|
+
if (staleTasks.length === 0) {
|
|
267
|
+
return 0;
|
|
268
|
+
}
|
|
269
|
+
// Release stale tasks
|
|
270
|
+
const releaseStmt = db.prepare(`
|
|
271
|
+
UPDATE tasks
|
|
272
|
+
SET status = 'pending', claimed_by = NULL, claimed_at = NULL
|
|
273
|
+
WHERE id = ?
|
|
274
|
+
`);
|
|
275
|
+
// Remove stale heartbeats
|
|
276
|
+
const removeHeartbeatStmt = db.prepare(`
|
|
277
|
+
DELETE FROM heartbeats WHERE agent_id = ?
|
|
278
|
+
`);
|
|
279
|
+
const staleAgents = new Set();
|
|
280
|
+
for (const task of staleTasks) {
|
|
281
|
+
releaseStmt.run(task.id);
|
|
282
|
+
if (task.claimed_by) {
|
|
283
|
+
staleAgents.add(task.claimed_by);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
for (const agentId of staleAgents) {
|
|
287
|
+
removeHeartbeatStmt.run(agentId);
|
|
288
|
+
}
|
|
289
|
+
return staleTasks.length;
|
|
290
|
+
});
|
|
291
|
+
return cleanupTransaction.immediate();
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
console.error('Failed to cleanup stale claims:', error);
|
|
295
|
+
return 0;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Get tasks claimed by a specific agent
|
|
300
|
+
*
|
|
301
|
+
* @param agentId - Agent to query
|
|
302
|
+
* @returns Array of tasks claimed by the agent
|
|
303
|
+
*/
|
|
304
|
+
export function getTasksClaimedBy(agentId) {
|
|
305
|
+
const db = getDb();
|
|
306
|
+
if (!db)
|
|
307
|
+
return [];
|
|
308
|
+
try {
|
|
309
|
+
const stmt = db.prepare(`
|
|
310
|
+
SELECT * FROM tasks WHERE claimed_by = ? AND status = 'claimed'
|
|
311
|
+
`);
|
|
312
|
+
const rows = stmt.all(agentId);
|
|
313
|
+
return rows.map(row => ({
|
|
314
|
+
id: row.id,
|
|
315
|
+
description: row.description,
|
|
316
|
+
status: row.status,
|
|
317
|
+
claimedBy: row.claimed_by,
|
|
318
|
+
claimedAt: row.claimed_at,
|
|
319
|
+
completedAt: row.completed_at,
|
|
320
|
+
error: row.error ?? undefined,
|
|
321
|
+
result: row.result ?? undefined
|
|
322
|
+
}));
|
|
323
|
+
}
|
|
324
|
+
catch (error) {
|
|
325
|
+
console.error('Failed to get tasks claimed by agent:', error);
|
|
326
|
+
return [];
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Check if there are any pending tasks
|
|
331
|
+
*
|
|
332
|
+
* @returns true if there are pending tasks
|
|
333
|
+
*/
|
|
334
|
+
export function hasPendingTasks() {
|
|
335
|
+
const db = getDb();
|
|
336
|
+
if (!db)
|
|
337
|
+
return false;
|
|
338
|
+
try {
|
|
339
|
+
const stmt = db.prepare(`
|
|
340
|
+
SELECT COUNT(*) as count FROM tasks WHERE status = 'pending'
|
|
341
|
+
`);
|
|
342
|
+
const result = stmt.get();
|
|
343
|
+
return result.count > 0;
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
console.error('Failed to check pending tasks:', error);
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Check if all tasks are complete (done or failed)
|
|
352
|
+
*
|
|
353
|
+
* @returns true if all tasks are complete
|
|
354
|
+
*/
|
|
355
|
+
export function allTasksComplete() {
|
|
356
|
+
const db = getDb();
|
|
357
|
+
if (!db)
|
|
358
|
+
return false;
|
|
359
|
+
try {
|
|
360
|
+
const stmt = db.prepare(`
|
|
361
|
+
SELECT COUNT(*) as count FROM tasks WHERE status IN ('pending', 'claimed')
|
|
362
|
+
`);
|
|
363
|
+
const result = stmt.get();
|
|
364
|
+
return result.count === 0;
|
|
365
|
+
}
|
|
366
|
+
catch (error) {
|
|
367
|
+
console.error('Failed to check if all tasks complete:', error);
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Get the number of active agents (with recent heartbeats)
|
|
373
|
+
*
|
|
374
|
+
* @param heartbeatTimeout - How old a heartbeat can be to still be considered active
|
|
375
|
+
* @returns Number of active agents
|
|
376
|
+
*/
|
|
377
|
+
export function getActiveAgentCount(heartbeatTimeout = DEFAULT_SWARM_CONFIG.leaseTimeout) {
|
|
378
|
+
const db = getDb();
|
|
379
|
+
if (!db)
|
|
380
|
+
return 0;
|
|
381
|
+
try {
|
|
382
|
+
const cutoffTime = Date.now() - heartbeatTimeout;
|
|
383
|
+
const stmt = db.prepare(`
|
|
384
|
+
SELECT COUNT(*) as count FROM heartbeats WHERE last_heartbeat > ?
|
|
385
|
+
`);
|
|
386
|
+
const result = stmt.get(cutoffTime);
|
|
387
|
+
return result.count;
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
console.error('Failed to get active agent count:', error);
|
|
391
|
+
return 0;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Attempt to reclaim a failed task
|
|
396
|
+
*
|
|
397
|
+
* @param agentId - Agent attempting to reclaim
|
|
398
|
+
* @param taskId - Task to reclaim
|
|
399
|
+
* @returns ClaimResult
|
|
400
|
+
*/
|
|
401
|
+
export function reclaimFailedTask(agentId, taskId) {
|
|
402
|
+
const db = getDb();
|
|
403
|
+
if (!db) {
|
|
404
|
+
return {
|
|
405
|
+
success: false,
|
|
406
|
+
taskId: null,
|
|
407
|
+
reason: 'Database not initialized'
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
const reclaimTransaction = db.transaction(() => {
|
|
412
|
+
// Check if task is failed
|
|
413
|
+
const checkStmt = db.prepare(`
|
|
414
|
+
SELECT id, description, status FROM tasks WHERE id = ?
|
|
415
|
+
`);
|
|
416
|
+
const task = checkStmt.get(taskId);
|
|
417
|
+
if (!task) {
|
|
418
|
+
return {
|
|
419
|
+
success: false,
|
|
420
|
+
taskId: null,
|
|
421
|
+
reason: 'Task not found'
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
if (task.status !== 'failed') {
|
|
425
|
+
return {
|
|
426
|
+
success: false,
|
|
427
|
+
taskId: null,
|
|
428
|
+
reason: `Task is ${task.status}, not failed`
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
// Reclaim the task
|
|
432
|
+
const reclaimStmt = db.prepare(`
|
|
433
|
+
UPDATE tasks
|
|
434
|
+
SET status = 'claimed', claimed_by = ?, claimed_at = ?, error = NULL
|
|
435
|
+
WHERE id = ?
|
|
436
|
+
`);
|
|
437
|
+
reclaimStmt.run(agentId, Date.now(), taskId);
|
|
438
|
+
// Update heartbeat
|
|
439
|
+
const heartbeatStmt = db.prepare(`
|
|
440
|
+
INSERT OR REPLACE INTO heartbeats (agent_id, last_heartbeat, current_task_id)
|
|
441
|
+
VALUES (?, ?, ?)
|
|
442
|
+
`);
|
|
443
|
+
heartbeatStmt.run(agentId, Date.now(), taskId);
|
|
444
|
+
return {
|
|
445
|
+
success: true,
|
|
446
|
+
taskId: task.id,
|
|
447
|
+
description: task.description
|
|
448
|
+
};
|
|
449
|
+
});
|
|
450
|
+
return reclaimTransaction.immediate();
|
|
451
|
+
}
|
|
452
|
+
catch (error) {
|
|
453
|
+
return {
|
|
454
|
+
success: false,
|
|
455
|
+
taskId: null,
|
|
456
|
+
reason: `Reclaim failed: ${error instanceof Error ? error.message : String(error)}`
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
//# sourceMappingURL=claiming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claiming.js","sourceRoot":"","sources":["../../../src/hooks/swarm/claiming.ts"],"names":[],"mappings":"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"}
|