refactor(agents): remove terminated AgentState; collapse to paused/error

Drops "terminated" from AGENT_STATES. The agent lifecycle now runs through
idle | active | running | paused | error. paused (carrying a pauseReason)
absorbs every former terminated use case — manual stop, heartbeat run
termination, spawned-child cleanup. Run status (agentRuns.status) is
unchanged: "terminated" stays a valid run-status value.

AGENT_VALID_TRANSITIONS allows direct any→idle transitions so resetAgent
no longer needs the intermediate hop.

Stack-wide:
- core/agent-store: lastError clearing + resetAgent simplified.
- engine/agent-heartbeat, executor, in-process-runtime: terminated state
  writes → paused; halt-state listener fires on paused/error.
- dashboard: AgentsView/AgentListModal/AgentDetailView lose the Terminated
  badge/option/state-block; agent pickers no longer filter terminated;
  agentHealth drops the Terminated branch; routes/state cast widened to
  the new AgentState union.

Tests across core and engine updated to assert paused for AgentState and
left "terminated" intact for run-status assertions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-05 19:30:42 -07:00
parent 7d41271601
commit 8eb5c3dc60
21 changed files with 81 additions and 157 deletions

View File

@@ -63,7 +63,7 @@ export function registerAgentCoreListCreateRoutes(ctx: ApiRoutesContext, deps: A
const agentStore = new AgentStore({ rootDir: scopedStore.getFusionDir() });
await agentStore.init();
const agents = await agentStore.listAgents(filter as { state?: "idle" | "active" | "paused" | "terminated"; role?: AgentCapability; includeEphemeral?: boolean });
const agents = await agentStore.listAgents(filter as { state?: "idle" | "active" | "running" | "paused" | "error"; role?: AgentCapability; includeEphemeral?: boolean });
const sanitizedAgents = await sanitizeAgentTaskLinks(agents, scopedStore);
res.json(sanitizedAgents);
} catch (err: unknown) {

View File

@@ -481,7 +481,7 @@ export function registerAgentRuntimeRoutes(ctx: ApiRoutesContext, deps: AgentRun
});
}
if (nextState === "active" || nextState === "terminated") {
if (nextState === "active") {
const pausedTasks = await scopedStore.getTasksByAssignedAgent(agentId, {
pausedOnly: true,
excludeArchived: true,