feat(FN-3630): document lastError recovery semantics in agents.md
Documents `lastError` recovery semantics in the agents reference, clarifying how the system handles and recovers from error states. Fusion-Task-Id: FN-3630
This commit is contained in:
@@ -325,6 +325,27 @@ describe("executeHeartbeat", () => {
|
||||
expect(store.endHeartbeatRun).toHaveBeenCalledWith(run.id, "terminated");
|
||||
});
|
||||
|
||||
it("clears stale lastError after a subsequent successful heartbeat run", async () => {
|
||||
const store = createStoreWithAgentForExec({ state: "running" });
|
||||
const monitor = new HeartbeatMonitor({ store, taskStore: mockTaskStore, rootDir: "/tmp" });
|
||||
|
||||
const failedRun = await monitor.startRun("agent-001", { source: "on_demand" });
|
||||
await monitor.completeRun("agent-001", failedRun.id, {
|
||||
status: "failed",
|
||||
stderrExcerpt: "Prompt failed",
|
||||
});
|
||||
|
||||
const successfulRun = await monitor.startRun("agent-001", { source: "on_demand" });
|
||||
await monitor.completeRun("agent-001", successfulRun.id, {
|
||||
status: "completed",
|
||||
});
|
||||
|
||||
expect(store.updateAgentState).toHaveBeenCalledWith("agent-001", "error");
|
||||
expect(store.updateAgent).toHaveBeenCalledWith("agent-001", { lastError: "Prompt failed" });
|
||||
expect(store.updateAgentState).toHaveBeenCalledWith("agent-001", "active");
|
||||
expect(store.updateAgent).toHaveBeenCalledWith("agent-001", { lastError: undefined });
|
||||
});
|
||||
|
||||
it("completes as failed when agent not found in store", async () => {
|
||||
const store = createStoreWithAgentForExec();
|
||||
(store.getAgent as ReturnType<typeof vi.fn>).mockResolvedValue(null);
|
||||
|
||||
@@ -904,8 +904,9 @@ export class HeartbeatMonitor {
|
||||
} else if (completionResult.status === "terminated") {
|
||||
await this.store.updateAgentState(agentId, "paused");
|
||||
} else {
|
||||
// Completed successfully - back to active
|
||||
// Completed successfully - back to active and clear any stale failure marker.
|
||||
await this.store.updateAgentState(agentId, "active");
|
||||
await this.store.updateAgent(agentId, { lastError: undefined });
|
||||
}
|
||||
} catch (stateTransErr) {
|
||||
heartbeatLog.warn(`Agent ${agentId} state transition failed: ${stateTransErr instanceof Error ? stateTransErr.message : String(stateTransErr)} — continuing`);
|
||||
|
||||
Reference in New Issue
Block a user