fix: /stop leaves stale paired task, sawOutput guard, progress text overwrite

- /stop now resets the active paired task to completed so the next
  user message routes to the owner instead of the stuck reviewer
- Owner completion with sawOutput=false (e.g. interrupted by /stop)
  no longer auto-triggers the reviewer — treated as interrupted
- Clear pendingProgressText when intermediate updates arrive on an
  existing progress message, preventing flushPendingProgress from
  overwriting latestProgressText with stale buffered content
This commit is contained in:
Eyejoker
2026-03-31 02:54:04 +09:00
parent 33575c84f1
commit dddf18428e
6 changed files with 38 additions and 11 deletions

View File

@@ -181,11 +181,17 @@ function makeDeps() {
describe('runAgentForGroup room memory', () => {
beforeEach(() => {
vi.resetAllMocks();
vi.mocked(agentRunner.runAgentProcess).mockResolvedValue({
status: 'success',
result: 'ok',
newSessionId: 'session-123',
});
vi.mocked(agentRunner.runAgentProcess).mockImplementation(
async (_group, _input, _onProcess, onOutput) => {
await onOutput?.({
status: 'success',
result: 'ok',
output: { visibility: 'public', text: 'ok' },
phase: 'final',
});
return { status: 'success', result: 'ok', newSessionId: 'session-123' };
},
);
vi.mocked(buildRoomMemoryBriefing).mockResolvedValue(
'## Shared Room Memory\n- remembered context',
);
@@ -461,12 +467,15 @@ describe('runAgentForGroup room memory', () => {
EJCLAW_PAIRED_ROLE: 'owner',
}),
);
// Owner produced no visible output (mock doesn't go through streamed
// evaluator) → treated as interrupted, status is 'failed' to prevent
// auto-triggering the reviewer.
expect(
pairedExecutionContext.completePairedExecutionContext,
).toHaveBeenCalledWith({
taskId: 'paired-task-1',
role: 'owner',
status: 'succeeded',
status: 'failed',
summary: 'ok',
});
});