chore: update stuck task handling and dashboard tweaks
This commit is contained in:
@@ -736,7 +736,7 @@ export class TaskExecutor {
|
||||
this.createTaskCreateTool(),
|
||||
this.createTaskAddDepTool(task.id),
|
||||
this.createTaskDoneTool(task.id, () => { taskDone = true; }),
|
||||
this.createReviewStepTool(task.id, worktreePath, detail.prompt, codeReviewVerdicts, sessionRef, stepCheckpoints, detail),
|
||||
this.createReviewStepTool(task.id, worktreePath, detail.prompt, codeReviewVerdicts, sessionRef, stepCheckpoints, detail, stuckDetector),
|
||||
this.createSpawnAgentTool(task.id, worktreePath, settings),
|
||||
];
|
||||
|
||||
@@ -1471,6 +1471,7 @@ export class TaskExecutor {
|
||||
sessionRef: { current: AgentSession | null },
|
||||
stepCheckpoints: Map<number, string>,
|
||||
detail: TaskDetail,
|
||||
stuckDetector?: StuckTaskDetector,
|
||||
): ToolDefinition {
|
||||
const store = this.store;
|
||||
const options = this.options;
|
||||
@@ -1518,6 +1519,7 @@ export class TaskExecutor {
|
||||
result.summary,
|
||||
);
|
||||
reviewerLog.log(`${taskId}: Step ${step} ${reviewType} → ${result.verdict}`);
|
||||
stuckDetector?.recordProgress(taskId);
|
||||
|
||||
// Track code review verdicts for enforcement. Plan reviews remain
|
||||
// advisory — only code reviews write to the verdict map.
|
||||
|
||||
@@ -30,7 +30,7 @@ function createMockStore(overrides: Record<string, unknown> = {}): TaskStore & E
|
||||
autoUnpauseEnabled: true,
|
||||
autoUnpauseBaseDelayMs: 100,
|
||||
autoUnpauseMaxDelayMs: 800,
|
||||
maxStuckKills: 3,
|
||||
maxStuckKills: 6,
|
||||
maintenanceIntervalMs: 0,
|
||||
maxWorktrees: 4,
|
||||
globalPause: true, // default: paused (for auto-unpause tests)
|
||||
@@ -192,7 +192,7 @@ describe("SelfHealingManager", () => {
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-001", { stuckKillCount: 1 });
|
||||
expect(store.logEntry).toHaveBeenCalledWith(
|
||||
"FN-001",
|
||||
expect.stringContaining("Stuck kill 1/3"),
|
||||
expect.stringContaining("Stuck kill 1/6"),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -213,7 +213,7 @@ describe("SelfHealingManager", () => {
|
||||
it("returns false and marks failed when budget exceeded", async () => {
|
||||
(store.getTask as ReturnType<typeof vi.fn>).mockResolvedValue({
|
||||
id: "FN-001",
|
||||
stuckKillCount: 3,
|
||||
stuckKillCount: 6,
|
||||
} as unknown as Task);
|
||||
|
||||
manager.start();
|
||||
@@ -222,9 +222,9 @@ describe("SelfHealingManager", () => {
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-001", {
|
||||
stuckKillCount: 4,
|
||||
stuckKillCount: 7,
|
||||
status: "failed",
|
||||
error: expect.stringContaining("exceeded maximum of 3"),
|
||||
error: expect.stringContaining("exceeded maximum of 6"),
|
||||
});
|
||||
expect(store.logEntry).toHaveBeenCalledWith(
|
||||
"FN-001",
|
||||
|
||||
@@ -188,7 +188,7 @@ export class SelfHealingManager {
|
||||
async checkStuckBudget(taskId: string): Promise<boolean> {
|
||||
try {
|
||||
const settings = await this.store.getSettings();
|
||||
const maxKills = settings.maxStuckKills ?? 3;
|
||||
const maxKills = settings.maxStuckKills ?? 6;
|
||||
|
||||
const task = await this.store.getTask(taskId);
|
||||
const newCount = (task.stuckKillCount ?? 0) + 1;
|
||||
|
||||
Reference in New Issue
Block a user