fix: clear stale agent activity on cancel

Clear only still-active side-panel agent states when a run ends as cancelled or error, while preserving completed agent statuses. Add a renderer regression test for cancelled runs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-25 22:17:33 +01:00
co-authored by Copilot
parent 82fdadb312
commit c9cc2fd8e7
2 changed files with 89 additions and 0 deletions
+40
View File
@@ -48,6 +48,14 @@ export function applySessionEventActivity(
}
}
if (
event.kind === 'run-updated'
&& event.run
&& (event.run.status === 'cancelled' || event.run.status === 'error')
) {
return clearActiveSessionActivity(current, event.sessionId);
}
return current;
}
@@ -137,6 +145,38 @@ function removeSessionActivity(
return next;
}
function clearActiveSessionActivity(
current: SessionActivityMap,
sessionId: string,
): SessionActivityMap {
const sessionActivity = current[sessionId];
if (!sessionActivity) {
return current;
}
let changed = false;
const nextSessionActivity = Object.fromEntries(
Object.entries(sessionActivity).filter(([, activity]) => {
const keep = !isAgentActivityActive(activity);
changed ||= !keep;
return keep;
}),
);
if (!changed) {
return current;
}
if (Object.keys(nextSessionActivity).length === 0) {
return removeSessionActivity(current, sessionId);
}
return {
...current,
[sessionId]: nextSessionActivity,
};
}
function resolveAgentKey(event: SessionEventRecord): string | undefined {
return event.agentId?.trim() || event.agentName?.trim();
}
+49
View File
@@ -179,6 +179,55 @@ describe('session activity helpers', () => {
).toEqual(current);
});
test('clears only active agent states when a run is cancelled', () => {
const current: SessionActivityMap = {
'session-1': {
architect: {
agentId: 'architect',
agentName: 'Architect',
activityType: 'completed',
},
reviewer: {
agentId: 'reviewer',
agentName: 'Reviewer',
activityType: 'thinking',
},
},
};
expect(
applySessionEventActivity(current, {
sessionId: 'session-1',
kind: 'run-updated',
occurredAt: '2026-03-23T00:00:01.000Z',
run: {
id: 'run-1',
requestId: 'turn-1',
projectId: 'project-1',
projectPath: 'C:\\workspace\\project',
workspaceKind: 'project',
patternId: 'pattern-1',
patternName: 'Pattern',
patternMode: 'single',
triggerMessageId: 'msg-1',
startedAt: '2026-03-23T00:00:00.000Z',
completedAt: '2026-03-23T00:00:01.000Z',
status: 'cancelled',
agents: [],
events: [],
},
}),
).toEqual({
'session-1': {
architect: {
agentId: 'architect',
agentName: 'Architect',
activityType: 'completed',
},
},
});
});
test('builds rows for all agents with sensible defaults', () => {
expect(buildAgentActivityRows(undefined, agents)).toEqual([
{