@cleocode/core 2026.3.58 → 2026.3.60
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/agents/agent-registry.d.ts +206 -0
- package/dist/agents/agent-registry.d.ts.map +1 -0
- package/dist/agents/agent-registry.js +288 -0
- package/dist/agents/agent-registry.js.map +1 -0
- package/dist/agents/agent-schema.js +5 -0
- package/dist/agents/agent-schema.js.map +1 -1
- package/dist/agents/execution-learning.js +474 -0
- package/dist/agents/execution-learning.js.map +1 -0
- package/dist/agents/health-monitor.d.ts +161 -0
- package/dist/agents/health-monitor.d.ts.map +1 -0
- package/dist/agents/health-monitor.js +217 -0
- package/dist/agents/health-monitor.js.map +1 -0
- package/dist/agents/index.d.ts +3 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +9 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/retry.d.ts +57 -4
- package/dist/agents/retry.d.ts.map +1 -1
- package/dist/agents/retry.js +57 -4
- package/dist/agents/retry.js.map +1 -1
- package/dist/backfill/index.d.ts +27 -0
- package/dist/backfill/index.d.ts.map +1 -1
- package/dist/backfill/index.js +229 -0
- package/dist/backfill/index.js.map +1 -0
- package/dist/bootstrap.d.ts +2 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +135 -28
- package/dist/bootstrap.js.map +1 -1
- package/dist/cleo.d.ts +40 -0
- package/dist/cleo.d.ts.map +1 -1
- package/dist/config.js +83 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1036 -536
- package/dist/index.js.map +4 -4
- package/dist/intelligence/adaptive-validation.js +497 -0
- package/dist/intelligence/adaptive-validation.js.map +1 -0
- package/dist/intelligence/impact.d.ts +34 -1
- package/dist/intelligence/impact.d.ts.map +1 -1
- package/dist/intelligence/impact.js +176 -0
- package/dist/intelligence/impact.js.map +1 -1
- package/dist/intelligence/index.d.ts +2 -2
- package/dist/intelligence/index.d.ts.map +1 -1
- package/dist/intelligence/index.js +6 -1
- package/dist/intelligence/index.js.map +1 -1
- package/dist/intelligence/types.d.ts +60 -0
- package/dist/intelligence/types.d.ts.map +1 -1
- package/dist/internal.d.ts +5 -4
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +11 -2
- package/dist/internal.js.map +1 -1
- package/dist/lib/index.d.ts +10 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +10 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/retry.d.ts +128 -0
- package/dist/lib/retry.d.ts.map +1 -0
- package/dist/lib/retry.js +152 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/nexus/sharing/index.d.ts +48 -2
- package/dist/nexus/sharing/index.d.ts.map +1 -1
- package/dist/nexus/sharing/index.js +110 -1
- package/dist/nexus/sharing/index.js.map +1 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +22 -2
- package/dist/scaffold.js.map +1 -1
- package/dist/sessions/session-enforcement.js +4 -0
- package/dist/sessions/session-enforcement.js.map +1 -1
- package/dist/stats/index.js +2 -0
- package/dist/stats/index.js.map +1 -1
- package/dist/stats/workflow-telemetry.d.ts +15 -0
- package/dist/stats/workflow-telemetry.d.ts.map +1 -1
- package/dist/stats/workflow-telemetry.js +400 -0
- package/dist/stats/workflow-telemetry.js.map +1 -0
- package/dist/store/brain-schema.js +4 -1
- package/dist/store/brain-schema.js.map +1 -1
- package/dist/store/converters.js +2 -0
- package/dist/store/converters.js.map +1 -1
- package/dist/store/cross-db-cleanup.d.ts +35 -0
- package/dist/store/cross-db-cleanup.d.ts.map +1 -1
- package/dist/store/cross-db-cleanup.js +169 -0
- package/dist/store/cross-db-cleanup.js.map +1 -0
- package/dist/store/db-helpers.js +2 -0
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/migration-sqlite.js +5 -0
- package/dist/store/migration-sqlite.js.map +1 -1
- package/dist/store/sqlite-data-accessor.js +20 -28
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite.js +13 -2
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/task-store.js +4 -0
- package/dist/store/task-store.js.map +1 -1
- package/dist/store/tasks-schema.js +50 -20
- package/dist/store/tasks-schema.js.map +1 -1
- package/dist/tasks/add.js +87 -3
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +15 -4
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/enforcement.d.ts.map +1 -1
- package/dist/tasks/enforcement.js +8 -1
- package/dist/tasks/enforcement.js.map +1 -1
- package/dist/tasks/epic-enforcement.d.ts +61 -0
- package/dist/tasks/epic-enforcement.d.ts.map +1 -1
- package/dist/tasks/epic-enforcement.js +294 -0
- package/dist/tasks/epic-enforcement.js.map +1 -0
- package/dist/tasks/index.js +1 -1
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/pipeline-stage.d.ts +70 -1
- package/dist/tasks/pipeline-stage.d.ts.map +1 -1
- package/dist/tasks/pipeline-stage.js +248 -0
- package/dist/tasks/pipeline-stage.js.map +1 -0
- package/dist/tasks/update.js +28 -0
- package/dist/tasks/update.js.map +1 -1
- package/package.json +5 -5
- package/schemas/config.schema.json +37 -1547
- package/src/__tests__/sharing.test.ts +24 -0
- package/src/agents/__tests__/agent-registry.test.ts +351 -0
- package/src/agents/__tests__/health-monitor.test.ts +332 -0
- package/src/agents/agent-registry.ts +394 -0
- package/src/agents/health-monitor.ts +279 -0
- package/src/agents/index.ts +24 -1
- package/src/agents/retry.ts +57 -4
- package/src/backfill/index.ts +27 -0
- package/src/bootstrap.ts +171 -30
- package/src/cleo.ts +103 -2
- package/src/config.ts +3 -3
- package/src/index.ts +1 -0
- package/src/intelligence/__tests__/impact.test.ts +165 -1
- package/src/intelligence/impact.ts +203 -0
- package/src/intelligence/index.ts +3 -0
- package/src/intelligence/types.ts +76 -0
- package/src/internal.ts +20 -0
- package/src/lib/__tests__/retry.test.ts +321 -0
- package/src/lib/index.ts +16 -0
- package/src/lib/retry.ts +224 -0
- package/src/nexus/sharing/index.ts +142 -2
- package/src/scaffold.ts +24 -2
- package/src/stats/workflow-telemetry.ts +15 -0
- package/src/store/__tests__/session-store.test.ts +43 -7
- package/src/store/__tests__/task-store.test.ts +1 -1
- package/src/store/__tests__/test-db-helper.ts +7 -3
- package/src/store/cross-db-cleanup.ts +35 -0
- package/src/tasks/__tests__/epic-enforcement.test.ts +9 -4
- package/src/tasks/__tests__/minimal-test.test.ts +2 -2
- package/src/tasks/__tests__/update.test.ts +25 -25
- package/src/tasks/complete.ts +11 -6
- package/src/tasks/enforcement.ts +6 -3
- package/src/tasks/epic-enforcement.ts +61 -0
- package/src/tasks/pipeline-stage.ts +70 -1
- package/templates/config.template.json +5 -116
- package/templates/global-config.template.json +2 -44
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Health Monitoring -- Heartbeat and crash detection for live agent instances.
|
|
3
|
+
*
|
|
4
|
+
* Provides the public-facing health API specified by T039:
|
|
5
|
+
* - `recordHeartbeat` — update last_heartbeat for a live agent
|
|
6
|
+
* - `checkAgentHealth` — check health of a specific agent by ID
|
|
7
|
+
* - `detectStaleAgents` — find agents whose heartbeat is older than threshold
|
|
8
|
+
* - `detectCrashedAgents` — find active agents with no heartbeat for >3 min
|
|
9
|
+
*
|
|
10
|
+
* These functions delegate to the lower-level `registry.ts` primitives
|
|
11
|
+
* (`heartbeat`, `checkAgentHealth`, `listAgentInstances`) and add the
|
|
12
|
+
* named, task-spec-aligned surface required for T039.
|
|
13
|
+
*
|
|
14
|
+
* @module agents/health-monitor
|
|
15
|
+
* @task T039
|
|
16
|
+
* @epic T038
|
|
17
|
+
*/
|
|
18
|
+
import { heartbeat, listAgentInstances, markCrashed } from './registry.js';
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Constants
|
|
21
|
+
// ============================================================================
|
|
22
|
+
/** Default heartbeat interval (30 seconds) per BRAIN spec. */
|
|
23
|
+
export const HEARTBEAT_INTERVAL_MS = 30_000;
|
|
24
|
+
/** Default staleness threshold: 3 minutes without a heartbeat. */
|
|
25
|
+
export const STALE_THRESHOLD_MS = 3 * 60_000;
|
|
26
|
+
/** Statuses considered "alive" for health-check purposes. */
|
|
27
|
+
const ALIVE_STATUSES = ['starting', 'active', 'idle'];
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// recordHeartbeat
|
|
30
|
+
// ============================================================================
|
|
31
|
+
/**
|
|
32
|
+
* Record a heartbeat for an agent instance.
|
|
33
|
+
*
|
|
34
|
+
* Updates `last_heartbeat` to the current time and returns the agent's
|
|
35
|
+
* current {@link AgentInstanceStatus}. Returns `null` if the agent does not
|
|
36
|
+
* exist or is already in a terminal state (`stopped` / `crashed`).
|
|
37
|
+
*
|
|
38
|
+
* This is the primary mechanism by which long-running agents signal liveness.
|
|
39
|
+
* Call this every {@link HEARTBEAT_INTERVAL_MS} (30 s) from the agent loop.
|
|
40
|
+
*
|
|
41
|
+
* @param agentId - The agent instance ID (e.g. `agt_20260322120000_a1b2c3`)
|
|
42
|
+
* @param cwd - Working directory used to resolve the tasks.db path (optional)
|
|
43
|
+
* @returns The agent's current status, or `null` if not found / terminal
|
|
44
|
+
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* Terminal agents (`stopped`, `crashed`) will NOT have their heartbeat
|
|
47
|
+
* updated — the existing status is returned as-is so callers can detect
|
|
48
|
+
* external shutdown signals.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* // Inside the agent's main loop:
|
|
53
|
+
* const heartbeatTimer = setInterval(async () => {
|
|
54
|
+
* const status = await recordHeartbeat(agentId);
|
|
55
|
+
* if (status === 'stopped' || status === null) {
|
|
56
|
+
* // Orchestrator shut us down — exit cleanly
|
|
57
|
+
* clearInterval(heartbeatTimer);
|
|
58
|
+
* process.exit(0);
|
|
59
|
+
* }
|
|
60
|
+
* }, HEARTBEAT_INTERVAL_MS);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export async function recordHeartbeat(agentId, cwd) {
|
|
64
|
+
return heartbeat(agentId, cwd);
|
|
65
|
+
}
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// checkAgentHealth
|
|
68
|
+
// ============================================================================
|
|
69
|
+
/**
|
|
70
|
+
* Check the health of a specific agent instance by ID.
|
|
71
|
+
*
|
|
72
|
+
* Queries the agent's current record and returns a structured
|
|
73
|
+
* {@link AgentHealthStatus} describing staleness, heartbeat age, and
|
|
74
|
+
* whether the agent is considered healthy relative to `thresholdMs`.
|
|
75
|
+
*
|
|
76
|
+
* Returns `null` if the agent ID is not found in the database.
|
|
77
|
+
*
|
|
78
|
+
* @param agentId - The agent instance ID to check
|
|
79
|
+
* @param thresholdMs - Staleness threshold in milliseconds (default: 3 minutes)
|
|
80
|
+
* @param cwd - Working directory used to resolve the tasks.db path (optional)
|
|
81
|
+
* @returns {@link AgentHealthStatus} or `null` if the agent does not exist
|
|
82
|
+
*
|
|
83
|
+
* @remarks
|
|
84
|
+
* Returns null if the agent is not found. A non-null result includes
|
|
85
|
+
* staleness status based on the threshold comparison.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* const health = await checkAgentHealth('agt_20260322120000_a1b2c3');
|
|
90
|
+
* if (health && health.stale) {
|
|
91
|
+
* console.log(`Agent stale for ${health.heartbeatAgeMs}ms — presumed crashed`);
|
|
92
|
+
* }
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export async function checkAgentHealth(agentId, thresholdMs = STALE_THRESHOLD_MS, cwd) {
|
|
96
|
+
const all = await listAgentInstances(undefined, cwd);
|
|
97
|
+
const agent = all.find((a) => a.id === agentId);
|
|
98
|
+
if (!agent)
|
|
99
|
+
return null;
|
|
100
|
+
return buildHealthStatus(agent, thresholdMs);
|
|
101
|
+
}
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// detectStaleAgents
|
|
104
|
+
// ============================================================================
|
|
105
|
+
/**
|
|
106
|
+
* Find all non-terminal agents whose last heartbeat is older than `thresholdMs`.
|
|
107
|
+
*
|
|
108
|
+
* "Stale" means an agent with status `starting`, `active`, or `idle` has
|
|
109
|
+
* not sent a heartbeat within the threshold window. This is a precursor to
|
|
110
|
+
* crash detection — a stale agent may still recover if it is under heavy load.
|
|
111
|
+
*
|
|
112
|
+
* Agents with status `stopped` or `crashed` are excluded — they are already
|
|
113
|
+
* in a terminal state and do not participate in the heartbeat protocol.
|
|
114
|
+
*
|
|
115
|
+
* @param thresholdMs - Staleness threshold in ms (default: 3 minutes / 180 000 ms)
|
|
116
|
+
* @param cwd - Working directory used to resolve the tasks.db path (optional)
|
|
117
|
+
* @returns Array of {@link AgentHealthStatus} for each stale agent, sorted by
|
|
118
|
+
* heartbeat age descending (most-stale first)
|
|
119
|
+
*
|
|
120
|
+
* @remarks
|
|
121
|
+
* The default threshold matches the crash-detection window specified in T039:
|
|
122
|
+
* "timeout detection after 3 minutes".
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* const stale = await detectStaleAgents();
|
|
127
|
+
* for (const s of stale) {
|
|
128
|
+
* console.log(`${s.agentId} has been stale for ${s.heartbeatAgeMs / 1000}s`);
|
|
129
|
+
* }
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export async function detectStaleAgents(thresholdMs = STALE_THRESHOLD_MS, cwd) {
|
|
133
|
+
const agents = await listAgentInstances({ status: ALIVE_STATUSES }, cwd);
|
|
134
|
+
return agents
|
|
135
|
+
.map((a) => buildHealthStatus(a, thresholdMs))
|
|
136
|
+
.filter((s) => s.stale)
|
|
137
|
+
.sort((a, b) => b.heartbeatAgeMs - a.heartbeatAgeMs);
|
|
138
|
+
}
|
|
139
|
+
// ============================================================================
|
|
140
|
+
// detectCrashedAgents
|
|
141
|
+
// ============================================================================
|
|
142
|
+
/**
|
|
143
|
+
* Find agents with status `active` whose heartbeat has been silent for
|
|
144
|
+
* longer than `thresholdMs`, and mark them as `crashed` in the database.
|
|
145
|
+
*
|
|
146
|
+
* An agent is considered crashed when it:
|
|
147
|
+
* 1. Has status `active` (not `idle`, `starting`, `stopped`, or `crashed`)
|
|
148
|
+
* 2. Has not sent a heartbeat for longer than `thresholdMs`
|
|
149
|
+
*
|
|
150
|
+
* Each detected agent is immediately marked `crashed` via {@link markCrashed},
|
|
151
|
+
* incrementing its error count and writing a reason to `agent_error_log`.
|
|
152
|
+
*
|
|
153
|
+
* @param thresholdMs - Crash threshold in ms (default: 3 minutes / 180 000 ms)
|
|
154
|
+
* @param cwd - Working directory used to resolve the tasks.db path (optional)
|
|
155
|
+
* @returns Array of agent instance rows for each agent that was just marked
|
|
156
|
+
* `crashed`, sorted by last heartbeat ascending (oldest first).
|
|
157
|
+
*
|
|
158
|
+
* @remarks
|
|
159
|
+
* This function is WRITE-side: it mutates the database. Callers should run
|
|
160
|
+
* it on a schedule (e.g. every 60 s) from an orchestrator or health watchdog.
|
|
161
|
+
* For a read-only view, use {@link detectStaleAgents} instead.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```ts
|
|
165
|
+
* // Inside an orchestrator health watchdog:
|
|
166
|
+
* const crashed = await detectCrashedAgents();
|
|
167
|
+
* if (crashed.length > 0) {
|
|
168
|
+
* logger.warn({ crashed: crashed.map(a => a.id) }, 'Agents marked crashed');
|
|
169
|
+
* }
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
export async function detectCrashedAgents(thresholdMs = STALE_THRESHOLD_MS, cwd) {
|
|
173
|
+
// Only consider agents that are explicitly 'active' — idle/starting agents
|
|
174
|
+
// may not yet have established a regular heartbeat interval.
|
|
175
|
+
const activeAgents = await listAgentInstances({ status: 'active' }, cwd);
|
|
176
|
+
const cutoff = new Date(Date.now() - thresholdMs).toISOString();
|
|
177
|
+
const crashed = [];
|
|
178
|
+
for (const agent of activeAgents) {
|
|
179
|
+
if (agent.lastHeartbeat < cutoff) {
|
|
180
|
+
const updated = await markCrashed(agent.id, `Heartbeat timeout — no heartbeat for >${Math.round(thresholdMs / 1000)}s`, cwd);
|
|
181
|
+
if (updated) {
|
|
182
|
+
crashed.push(updated);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Sort oldest-heartbeat first (most severely stale)
|
|
187
|
+
crashed.sort((a, b) => {
|
|
188
|
+
const aHb = a.lastHeartbeat ?? '';
|
|
189
|
+
const bHb = b.lastHeartbeat ?? '';
|
|
190
|
+
return aHb < bHb ? -1 : aHb > bHb ? 1 : 0;
|
|
191
|
+
});
|
|
192
|
+
return crashed;
|
|
193
|
+
}
|
|
194
|
+
// ============================================================================
|
|
195
|
+
// Internal helpers
|
|
196
|
+
// ============================================================================
|
|
197
|
+
/**
|
|
198
|
+
* Build an {@link AgentHealthStatus} from a raw agent row.
|
|
199
|
+
*/
|
|
200
|
+
function buildHealthStatus(agent, thresholdMs) {
|
|
201
|
+
const lastHeartbeatMs = new Date(agent.lastHeartbeat).getTime();
|
|
202
|
+
const heartbeatAgeMs = Date.now() - lastHeartbeatMs;
|
|
203
|
+
const stale = ALIVE_STATUSES.includes(agent.status)
|
|
204
|
+
? heartbeatAgeMs > thresholdMs
|
|
205
|
+
: false;
|
|
206
|
+
const healthy = !stale && ALIVE_STATUSES.includes(agent.status);
|
|
207
|
+
return {
|
|
208
|
+
agentId: agent.id,
|
|
209
|
+
status: agent.status,
|
|
210
|
+
lastHeartbeat: agent.lastHeartbeat,
|
|
211
|
+
heartbeatAgeMs,
|
|
212
|
+
healthy,
|
|
213
|
+
stale,
|
|
214
|
+
thresholdMs,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=health-monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-monitor.js","sourceRoot":"","sources":["../../src/agents/health-monitor.ts"],"names":[],"mappings":"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"}
|
package/dist/agents/index.d.ts
CHANGED
|
@@ -10,9 +10,11 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @module agents
|
|
12
12
|
*/
|
|
13
|
+
export { type AgentCapacity, type AgentPerformanceMetrics, getAgentCapacity, getAgentSpecializations, getAgentsByCapacity, MAX_TASKS_PER_AGENT, recordAgentPerformance, updateAgentSpecializations, } from './agent-registry.js';
|
|
13
14
|
export { AGENT_INSTANCE_STATUSES, AGENT_TYPES, type AgentErrorLogRow, type AgentErrorType, type AgentInstanceRow, type AgentInstanceStatus, type AgentType, agentErrorLog, agentInstances, type NewAgentErrorLogRow, type NewAgentInstanceRow, } from './agent-schema.js';
|
|
14
15
|
export { type CapacitySummary, findLeastLoadedAgent, getAvailableCapacity, getCapacitySummary, isOverloaded, updateCapacity, } from './capacity.js';
|
|
15
16
|
export { type AgentExecutionEvent, type AgentExecutionOutcome, type AgentPerformanceSummary, getAgentPerformanceHistory, getSelfHealingSuggestions, type HealingSuggestion, processAgentLifecycleEvent, recordAgentExecution, recordFailurePattern, storeHealingStrategy, } from './execution-learning.js';
|
|
16
|
-
export { type
|
|
17
|
+
export { type AgentHealthStatus, checkAgentHealth, detectCrashedAgents, detectStaleAgents, HEARTBEAT_INTERVAL_MS, recordHeartbeat, STALE_THRESHOLD_MS, } from './health-monitor.js';
|
|
18
|
+
export { type AgentHealthReport, checkAgentHealth as findStaleAgentRows, classifyError, deregisterAgent, generateAgentId, getAgentErrorHistory, getAgentInstance, getHealthReport, heartbeat, incrementTasksCompleted, type ListAgentFilters, listAgentInstances, markCrashed, type RegisterAgentOptions, registerAgent, type UpdateStatusOptions, updateAgentStatus, } from './registry.js';
|
|
17
19
|
export { type AgentRecoveryResult, calculateDelay, createRetryPolicy, DEFAULT_RETRY_POLICY, type RetryPolicy, type RetryResult, recoverCrashedAgents, shouldRetry, withRetry, } from './retry.js';
|
|
18
20
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EACL,uBAAuB,EACvB,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,aAAa,EACb,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,KAAK,eAAe,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,KAAK,iBAAiB,EACtB,0BAA0B,EAC1B,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,WAAW,EACX,KAAK,oBAAoB,EACzB,aAAa,EACb,KAAK,mBAAmB,EACxB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,mBAAmB,EACxB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,oBAAoB,EACpB,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,uBAAuB,EACvB,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,aAAa,EACb,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,KAAK,eAAe,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,KAAK,iBAAiB,EACtB,0BAA0B,EAC1B,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EACL,KAAK,iBAAiB,EACtB,gBAAgB,IAAI,kBAAkB,EACtC,aAAa,EACb,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,WAAW,EACX,KAAK,oBAAoB,EACzB,aAAa,EACb,KAAK,mBAAmB,EACxB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,mBAAmB,EACxB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,oBAAoB,EACpB,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC"}
|
package/dist/agents/index.js
CHANGED
|
@@ -10,12 +10,20 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @module agents
|
|
12
12
|
*/
|
|
13
|
+
// Load-balancing registry: task-count capacity, specializations, performance recording
|
|
14
|
+
export { getAgentCapacity, getAgentSpecializations, getAgentsByCapacity, MAX_TASKS_PER_AGENT, recordAgentPerformance, updateAgentSpecializations, } from './agent-registry.js';
|
|
13
15
|
// Schema & types
|
|
14
16
|
export { AGENT_INSTANCE_STATUSES, AGENT_TYPES, agentErrorLog, agentInstances, } from './agent-schema.js';
|
|
15
17
|
// Capacity tracking
|
|
16
18
|
export { findLeastLoadedAgent, getAvailableCapacity, getCapacitySummary, isOverloaded, updateCapacity, } from './capacity.js';
|
|
19
|
+
// Execution learning, failure pattern tracking, and self-healing
|
|
20
|
+
export { getAgentPerformanceHistory, getSelfHealingSuggestions, processAgentLifecycleEvent, recordAgentExecution, recordFailurePattern, storeHealingStrategy, } from './execution-learning.js';
|
|
21
|
+
// Health monitoring (T039)
|
|
22
|
+
export { checkAgentHealth, detectCrashedAgents, detectStaleAgents, HEARTBEAT_INTERVAL_MS, recordHeartbeat, STALE_THRESHOLD_MS, } from './health-monitor.js';
|
|
17
23
|
// Registry (CRUD, heartbeat, health, errors)
|
|
18
|
-
|
|
24
|
+
// Note: registry.checkAgentHealth (thresholdMs, cwd) -> AgentInstanceRow[] is exported
|
|
25
|
+
// as findStaleAgentRows to avoid conflict with health-monitor.checkAgentHealth (T039).
|
|
26
|
+
export { checkAgentHealth as findStaleAgentRows, classifyError, deregisterAgent, generateAgentId, getAgentErrorHistory, getAgentInstance, getHealthReport, heartbeat, incrementTasksCompleted, listAgentInstances, markCrashed, registerAgent, updateAgentStatus, } from './registry.js';
|
|
19
27
|
// Retry & self-healing
|
|
20
28
|
export { calculateDelay, createRetryPolicy, DEFAULT_RETRY_POLICY, recoverCrashedAgents, shouldRetry, withRetry, } from './retry.js';
|
|
21
29
|
//# sourceMappingURL=index.js.map
|
package/dist/agents/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,iBAAiB;AACjB,OAAO,EACL,uBAAuB,EACvB,WAAW,EAMX,aAAa,EACb,cAAc,GAGf,MAAM,mBAAmB,CAAC;AAC3B,oBAAoB;AACpB,OAAO,EAEL,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,6CAA6C;AAC7C,OAAO,EAEL,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,uFAAuF;AACvF,OAAO,EAGL,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,iBAAiB;AACjB,OAAO,EACL,uBAAuB,EACvB,WAAW,EAMX,aAAa,EACb,cAAc,GAGf,MAAM,mBAAmB,CAAC;AAC3B,oBAAoB;AACpB,OAAO,EAEL,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,iEAAiE;AACjE,OAAO,EAIL,0BAA0B,EAC1B,yBAAyB,EAEzB,0BAA0B,EAC1B,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,2BAA2B;AAC3B,OAAO,EAEL,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,6CAA6C;AAC7C,uFAAuF;AACvF,uFAAuF;AACvF,OAAO,EAEL,gBAAgB,IAAI,kBAAkB,EACtC,aAAa,EACb,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,uBAAuB,EAEvB,kBAAkB,EAClB,WAAW,EAEX,aAAa,EAEb,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,uBAAuB;AACvB,OAAO,EAEL,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EAGpB,oBAAoB,EACpB,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC"}
|
package/dist/agents/retry.d.ts
CHANGED
|
@@ -26,18 +26,54 @@ export interface RetryPolicy {
|
|
|
26
26
|
export declare const DEFAULT_RETRY_POLICY: Readonly<RetryPolicy>;
|
|
27
27
|
/**
|
|
28
28
|
* Create a retry policy by merging overrides with the default policy.
|
|
29
|
+
*
|
|
30
|
+
* @remarks
|
|
31
|
+
* Unspecified fields fall back to {@link DEFAULT_RETRY_POLICY}.
|
|
32
|
+
*
|
|
33
|
+
* @param overrides - Partial policy to merge with defaults
|
|
34
|
+
* @returns A complete RetryPolicy
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const policy = createRetryPolicy({ maxRetries: 5 });
|
|
39
|
+
* ```
|
|
29
40
|
*/
|
|
30
41
|
export declare function createRetryPolicy(overrides?: Partial<RetryPolicy>): RetryPolicy;
|
|
31
42
|
/**
|
|
32
43
|
* Calculate the delay for a given retry attempt using exponential backoff.
|
|
33
44
|
*
|
|
34
|
-
*
|
|
45
|
+
* @remarks
|
|
46
|
+
* Formula: `min(baseDelay * multiplier^attempt, maxDelay) + jitter`.
|
|
35
47
|
* Jitter adds 0-25% randomness to prevent thundering herd.
|
|
48
|
+
*
|
|
49
|
+
* @param attempt - Zero-based attempt index
|
|
50
|
+
* @param policy - Retry policy with delay configuration
|
|
51
|
+
* @returns Delay in milliseconds before the next attempt
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const delay = calculateDelay(1, createRetryPolicy());
|
|
56
|
+
* // => ~2000ms (with jitter)
|
|
57
|
+
* ```
|
|
36
58
|
*/
|
|
37
59
|
export declare function calculateDelay(attempt: number, policy: RetryPolicy): number;
|
|
38
60
|
/**
|
|
39
61
|
* Determine whether an error should be retried based on its classification
|
|
40
62
|
* and the retry policy.
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* Permanent errors are never retried. Retriable errors are always retried
|
|
66
|
+
* (within attempt limits). Unknown errors defer to `policy.retryOnUnknown`.
|
|
67
|
+
*
|
|
68
|
+
* @param error - The caught error to classify
|
|
69
|
+
* @param attempt - Current attempt number (0-based)
|
|
70
|
+
* @param policy - Retry policy with limits and classification rules
|
|
71
|
+
* @returns True if the error should be retried
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* if (shouldRetry(err, attempt, policy)) { /* retry *\/ }
|
|
76
|
+
* ```
|
|
41
77
|
*/
|
|
42
78
|
export declare function shouldRetry(error: unknown, attempt: number, policy: RetryPolicy): boolean;
|
|
43
79
|
/** Result of a retried operation. */
|
|
@@ -51,13 +87,20 @@ export interface RetryResult<T> {
|
|
|
51
87
|
/**
|
|
52
88
|
* Wrap an async function with retry logic using configurable exponential backoff.
|
|
53
89
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
90
|
+
* @remarks
|
|
91
|
+
* Agent-specific variant that integrates with error classification from the
|
|
92
|
+
* agent registry. For a dependency-free generic retry, use `lib/retry.ts`.
|
|
57
93
|
*
|
|
94
|
+
* @typeParam T - The resolved type of the async function
|
|
58
95
|
* @param fn - The async function to execute with retries
|
|
59
96
|
* @param policy - Retry policy (uses DEFAULT_RETRY_POLICY if not provided)
|
|
60
97
|
* @returns The result of the operation with retry metadata
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* const result = await withRetry(() => fetchAgentTask(agentId));
|
|
102
|
+
* if (!result.success) console.error(result.error);
|
|
103
|
+
* ```
|
|
61
104
|
*/
|
|
62
105
|
export declare function withRetry<T>(fn: () => Promise<T>, policy?: Partial<RetryPolicy>): Promise<RetryResult<T>>;
|
|
63
106
|
/** Result of a recovery attempt for a single agent. */
|
|
@@ -75,9 +118,19 @@ export interface AgentRecoveryResult {
|
|
|
75
118
|
* classified as 'permanent' are abandoned. Agents with retriable errors
|
|
76
119
|
* are reset to 'starting' for the orchestration layer to re-assign.
|
|
77
120
|
*
|
|
121
|
+
* @remarks
|
|
122
|
+
* Two-phase process: first detects stale agents via heartbeat threshold,
|
|
123
|
+
* then evaluates each crashed agent's error history for recoverability.
|
|
124
|
+
*
|
|
78
125
|
* @param thresholdMs - Heartbeat threshold for crash detection (default: 30000)
|
|
79
126
|
* @param cwd - Working directory
|
|
80
127
|
* @returns Recovery results for each crashed agent
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* const results = await recoverCrashedAgents(60_000);
|
|
132
|
+
* results.filter(r => r.recovered).forEach(r => console.log(r.agentId));
|
|
133
|
+
* ```
|
|
81
134
|
*/
|
|
82
135
|
export declare function recoverCrashedAgents(thresholdMs?: number, cwd?: string): Promise<AgentRecoveryResult[]>;
|
|
83
136
|
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/agents/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,wCAAwC;AACxC,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB,yEAAyE;IACzE,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,6DAA6D;AAC7D,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,WAAW,CAOrD,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/agents/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,wCAAwC;AACxC,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,MAAM,EAAE,OAAO,CAAC;IAChB,yEAAyE;IACzE,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,6DAA6D;AAC7D,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,WAAW,CAOrD,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAE/E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAU3E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAUzF;AAMD,qCAAqC;AACrC,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAC5B,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAyCzB;AAMD,uDAAuD;AACvD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;IAC9C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,GAAE,MAAe,EAC5B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAyDhC"}
|
package/dist/agents/retry.js
CHANGED
|
@@ -19,6 +19,17 @@ export const DEFAULT_RETRY_POLICY = Object.freeze({
|
|
|
19
19
|
});
|
|
20
20
|
/**
|
|
21
21
|
* Create a retry policy by merging overrides with the default policy.
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* Unspecified fields fall back to {@link DEFAULT_RETRY_POLICY}.
|
|
25
|
+
*
|
|
26
|
+
* @param overrides - Partial policy to merge with defaults
|
|
27
|
+
* @returns A complete RetryPolicy
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const policy = createRetryPolicy({ maxRetries: 5 });
|
|
32
|
+
* ```
|
|
22
33
|
*/
|
|
23
34
|
export function createRetryPolicy(overrides) {
|
|
24
35
|
return { ...DEFAULT_RETRY_POLICY, ...overrides };
|
|
@@ -26,8 +37,19 @@ export function createRetryPolicy(overrides) {
|
|
|
26
37
|
/**
|
|
27
38
|
* Calculate the delay for a given retry attempt using exponential backoff.
|
|
28
39
|
*
|
|
29
|
-
*
|
|
40
|
+
* @remarks
|
|
41
|
+
* Formula: `min(baseDelay * multiplier^attempt, maxDelay) + jitter`.
|
|
30
42
|
* Jitter adds 0-25% randomness to prevent thundering herd.
|
|
43
|
+
*
|
|
44
|
+
* @param attempt - Zero-based attempt index
|
|
45
|
+
* @param policy - Retry policy with delay configuration
|
|
46
|
+
* @returns Delay in milliseconds before the next attempt
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const delay = calculateDelay(1, createRetryPolicy());
|
|
51
|
+
* // => ~2000ms (with jitter)
|
|
52
|
+
* ```
|
|
31
53
|
*/
|
|
32
54
|
export function calculateDelay(attempt, policy) {
|
|
33
55
|
const exponentialDelay = policy.baseDelayMs * policy.backoffMultiplier ** attempt;
|
|
@@ -42,6 +64,20 @@ export function calculateDelay(attempt, policy) {
|
|
|
42
64
|
/**
|
|
43
65
|
* Determine whether an error should be retried based on its classification
|
|
44
66
|
* and the retry policy.
|
|
67
|
+
*
|
|
68
|
+
* @remarks
|
|
69
|
+
* Permanent errors are never retried. Retriable errors are always retried
|
|
70
|
+
* (within attempt limits). Unknown errors defer to `policy.retryOnUnknown`.
|
|
71
|
+
*
|
|
72
|
+
* @param error - The caught error to classify
|
|
73
|
+
* @param attempt - Current attempt number (0-based)
|
|
74
|
+
* @param policy - Retry policy with limits and classification rules
|
|
75
|
+
* @returns True if the error should be retried
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* if (shouldRetry(err, attempt, policy)) { /* retry *\/ }
|
|
80
|
+
* ```
|
|
45
81
|
*/
|
|
46
82
|
export function shouldRetry(error, attempt, policy) {
|
|
47
83
|
if (attempt >= policy.maxRetries)
|
|
@@ -57,13 +93,20 @@ export function shouldRetry(error, attempt, policy) {
|
|
|
57
93
|
/**
|
|
58
94
|
* Wrap an async function with retry logic using configurable exponential backoff.
|
|
59
95
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
96
|
+
* @remarks
|
|
97
|
+
* Agent-specific variant that integrates with error classification from the
|
|
98
|
+
* agent registry. For a dependency-free generic retry, use `lib/retry.ts`.
|
|
63
99
|
*
|
|
100
|
+
* @typeParam T - The resolved type of the async function
|
|
64
101
|
* @param fn - The async function to execute with retries
|
|
65
102
|
* @param policy - Retry policy (uses DEFAULT_RETRY_POLICY if not provided)
|
|
66
103
|
* @returns The result of the operation with retry metadata
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* const result = await withRetry(() => fetchAgentTask(agentId));
|
|
108
|
+
* if (!result.success) console.error(result.error);
|
|
109
|
+
* ```
|
|
67
110
|
*/
|
|
68
111
|
export async function withRetry(fn, policy) {
|
|
69
112
|
const effectivePolicy = createRetryPolicy(policy);
|
|
@@ -112,9 +155,19 @@ export async function withRetry(fn, policy) {
|
|
|
112
155
|
* classified as 'permanent' are abandoned. Agents with retriable errors
|
|
113
156
|
* are reset to 'starting' for the orchestration layer to re-assign.
|
|
114
157
|
*
|
|
158
|
+
* @remarks
|
|
159
|
+
* Two-phase process: first detects stale agents via heartbeat threshold,
|
|
160
|
+
* then evaluates each crashed agent's error history for recoverability.
|
|
161
|
+
*
|
|
115
162
|
* @param thresholdMs - Heartbeat threshold for crash detection (default: 30000)
|
|
116
163
|
* @param cwd - Working directory
|
|
117
164
|
* @returns Recovery results for each crashed agent
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* const results = await recoverCrashedAgents(60_000);
|
|
169
|
+
* results.filter(r => r.recovered).forEach(r => console.log(r.agentId));
|
|
170
|
+
* ```
|
|
118
171
|
*/
|
|
119
172
|
export async function recoverCrashedAgents(thresholdMs = 30_000, cwd) {
|
|
120
173
|
const results = [];
|
package/dist/agents/retry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/agents/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAsBvB,6DAA6D;AAC7D,MAAM,CAAC,MAAM,oBAAoB,GAA0B,MAAM,CAAC,MAAM,CAAC;IACvE,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,MAAM;IAClB,iBAAiB,EAAE,CAAC;IACpB,MAAM,EAAE,IAAI;IACZ,cAAc,EAAE,IAAI;CACrB,CAAC,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/agents/retry.ts"],"names":[],"mappings":"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"}
|
package/dist/backfill/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* backfillTasks(root, {}) -- apply changes
|
|
9
9
|
* backfillTasks(root, { rollback: true }) -- revert backfill
|
|
10
10
|
*
|
|
11
|
+
* @packageDocumentation
|
|
11
12
|
* @epic T056
|
|
12
13
|
* @task T066
|
|
13
14
|
*/
|
|
@@ -44,13 +45,39 @@ export interface BackfillResult {
|
|
|
44
45
|
/**
|
|
45
46
|
* Generate 3 baseline acceptance criteria from a task description.
|
|
46
47
|
* Uses simple text analysis — no LLM required.
|
|
48
|
+
*
|
|
49
|
+
* @remarks
|
|
50
|
+
* Extracts action verbs from the title + description to produce contextually
|
|
51
|
+
* relevant criteria. Falls back to generic criteria when no verbs match.
|
|
52
|
+
*
|
|
53
|
+
* @param title - The task title
|
|
54
|
+
* @param description - The task description
|
|
55
|
+
* @returns Array of 3 acceptance criteria strings
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* generateAcFromDescription('Fix login bug', 'Users cannot log in');
|
|
60
|
+
* // => ['The defect is resolved...', 'No breaking changes...', 'Changes verified...']
|
|
61
|
+
* ```
|
|
47
62
|
*/
|
|
48
63
|
export declare function generateAcFromDescription(title: string, description: string): string[];
|
|
49
64
|
/**
|
|
50
65
|
* Retroactively populate AC and verification metadata for tasks that lack them.
|
|
51
66
|
*
|
|
67
|
+
* @remarks
|
|
68
|
+
* In dry-run mode, computes changes without writing to the database.
|
|
69
|
+
* Backfilled tasks are tagged with a note so they can be identified and
|
|
70
|
+
* optionally rolled back later.
|
|
71
|
+
*
|
|
52
72
|
* @param projectRoot - Project root directory (cwd for CLEO operations)
|
|
53
73
|
* @param options - Backfill options (dryRun, rollback, taskIds)
|
|
74
|
+
* @returns Summary of changes applied (or previewed in dry-run mode)
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* const result = await backfillTasks('/my/project', { dryRun: true });
|
|
79
|
+
* console.log(result.changed); // number of tasks that would be modified
|
|
80
|
+
* ```
|
|
54
81
|
*/
|
|
55
82
|
export declare function backfillTasks(projectRoot: string, options?: BackfillOptions): Promise<BackfillResult>;
|
|
56
83
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backfill/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backfill/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAUH,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,mEAAmE;AACnE,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,kDAAkD;AAClD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA4DtF;AAoBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAiIzB"}
|