fix(run): prevent premature exit on idle before meaningful work (#1263)
The run command's completion check had a race condition: when a session transitions busy->idle before the LLM generates any output (empty response or API delay), checkCompletionConditions() returns true because 0 incomplete todos + 0 busy children = complete. This caused the runner to exit with 'All tasks completed' before any work was done. Fix: - Add hasReceivedMeaningfulWork flag to EventState - Set flag on: assistant text content, tool execution, or message update with actual content (all scoped to main session only) - Guard completion check in runner poll loop: skip if no meaningful work has been observed yet This ensures the runner waits until the session has produced at least one observable output before considering completion conditions. Adds 6 new test cases covering the race condition scenarios.
This commit is contained in:
@@ -63,6 +63,8 @@ export interface EventState {
|
||||
lastOutput: string
|
||||
lastPartText: string
|
||||
currentTool: string | null
|
||||
/** Set to true when the main session has produced meaningful work (text, tool call, or tool result) */
|
||||
hasReceivedMeaningfulWork: boolean
|
||||
}
|
||||
|
||||
export function createEventState(): EventState {
|
||||
@@ -73,6 +75,7 @@ export function createEventState(): EventState {
|
||||
lastOutput: "",
|
||||
lastPartText: "",
|
||||
currentTool: null,
|
||||
hasReceivedMeaningfulWork: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,6 +244,7 @@ function handleMessagePartUpdated(
|
||||
const newText = part.text.slice(state.lastPartText.length)
|
||||
if (newText) {
|
||||
process.stdout.write(newText)
|
||||
state.hasReceivedMeaningfulWork = true
|
||||
}
|
||||
state.lastPartText = part.text
|
||||
}
|
||||
@@ -267,6 +271,7 @@ function handleMessageUpdated(
|
||||
}
|
||||
}
|
||||
state.lastOutput = content
|
||||
state.hasReceivedMeaningfulWork = true
|
||||
}
|
||||
|
||||
function handleToolExecute(
|
||||
@@ -296,6 +301,7 @@ function handleToolExecute(
|
||||
}
|
||||
}
|
||||
|
||||
state.hasReceivedMeaningfulWork = true
|
||||
process.stdout.write(`\n${pc.cyan(">")} ${pc.bold(toolName)}${inputPreview}\n`)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user