fix: task subagent static race main (#843)

This commit is contained in:
Charles Packer
2026-02-05 18:15:43 -08:00
committed by GitHub
parent ee28095ebc
commit 2b7d618b39
3 changed files with 287 additions and 3 deletions

View File

@@ -212,6 +212,10 @@ import {
interruptActiveSubagents,
subscribe as subscribeToSubagents,
} from "./helpers/subagentState";
import {
flushEligibleLinesBeforeReentry,
shouldClearCompletedSubagentsOnTurnStart,
} from "./helpers/subagentTurnStart";
import { extractTaskNotificationsForDisplay } from "./helpers/taskNotifications";
import {
getRandomPastTenseVerb,
@@ -2960,9 +2964,13 @@ export default function App({
// Reset interrupted flag since we're starting a fresh stream
buffersRef.current.interrupted = false;
// Clear completed subagents from the UI when starting a new turn,
// but only if no subagents are still running.
if (!hasActiveSubagents()) {
// Clear completed subagents only on true new turns.
if (
shouldClearCompletedSubagentsOnTurnStart(
allowReentry,
hasActiveSubagents(),
)
) {
clearCompletedSubagents();
}
@@ -8773,6 +8781,13 @@ ${SYSTEM_REMINDER_CLOSE}
} else if (hadNotifications) {
refreshDerived();
}
// Flush finished items synchronously before reentry. This avoids a
// race where deferred non-Task commits delay Task grouping while the
// reentry path continues.
flushEligibleLinesBeforeReentry(
commitEligibleLines,
buffersRef.current,
);
toolResultsInFlightRef.current = true;
await processConversation(input, { allowReentry: true });
toolResultsInFlightRef.current = false;
@@ -8808,6 +8823,7 @@ ${SYSTEM_REMINDER_CLOSE}
syncTrajectoryElapsedBase,
closeTrajectorySegment,
openTrajectorySegment,
commitEligibleLines,
],
);

View File

@@ -0,0 +1,27 @@
import type { Buffers } from "./accumulator.js";
/**
* Completed subagents should only be cleared on true new turns.
* During allowReentry (post-approval continuation), completed subagents
* must remain available so deferred Task grouping can still resolve.
*/
export function shouldClearCompletedSubagentsOnTurnStart(
allowReentry: boolean,
hasActiveSubagents: boolean,
): boolean {
return !allowReentry && !hasActiveSubagents;
}
/**
* Flush static-eligible lines before reentry so Task grouping is not delayed
* by deferred non-Task tool commits.
*/
export function flushEligibleLinesBeforeReentry(
commitEligibleLines: (
b: Buffers,
opts?: { deferToolCalls?: boolean },
) => void,
buffers: Buffers,
): void {
commitEligibleLines(buffers, { deferToolCalls: false });
}