fix(FN-2054): harden agent loop stuck-detection and self-healing

- Add defensive cleanup for in-memory task tracking when tasks move state or agents pause
- Improve stuck-detection and self-healing flow to reduce leaked state and missed recovery paths
- Add logging around previously swallowed errors and tighten executor cleanup behavior
- Expand restart and self-healing reliability tests to cover regression scenarios
This commit is contained in:
Fusion
2026-04-18 11:08:41 -07:00
committed by gsxdsm
parent 89b5a722dc
commit 36cec38c14
8 changed files with 290 additions and 91 deletions

View File

@@ -700,6 +700,15 @@ describe("mission-interview module", () => {
expect(agentConfig).toHaveProperty("onThinking");
expect(agentConfig).toHaveProperty("onText");
// Verify stream callbacks use the active session id
const broadcastSpy = vi.spyOn(missionInterviewStreamManager, "broadcast").mockReturnValue(1);
agentConfig.onText("Hello");
expect(broadcastSpy).toHaveBeenCalledWith(sessionId, { type: "text", data: "Hello" });
agentConfig.onThinking("thinking...");
expect(broadcastSpy).toHaveBeenCalledWith(sessionId, { type: "thinking", data: "thinking..." });
broadcastSpy.mockRestore();
// Verify no unexpected model override fields
expect(agentConfig).not.toHaveProperty("modelProvider");
expect(agentConfig).not.toHaveProperty("modelId");

View File

@@ -171,6 +171,7 @@ export type MissionInterviewResponse =
/** SSE event types for mission interview streaming */
export type MissionInterviewStreamEvent =
| { type: "thinking"; data: string }
| { type: "text"; data: string }
| { type: "question"; data: PlanningQuestion }
| { type: "summary"; data: MissionPlanSummary }
| { type: "error"; data: string }
@@ -777,6 +778,10 @@ async function createMissionInterviewAgent(
},
onText: (delta: string) => {
session.thinkingOutput += delta;
missionInterviewStreamManager.broadcast(session.id, {
type: "text",
data: delta,
});
},
});
}