Merge pull request #9969 from Kilo-Org/fix/cli-prompt-loop-missing-finish-reason

fix(cli): prevent agent loop hang when stream ends without stop_reason
This commit is contained in:
Christiaan Arnoldus
2026-05-08 10:10:48 +02:00
committed by GitHub
2 changed files with 20 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@kilocode/cli": patch
---
Prevent an infinite agent loop when a provider ends the response stream without a terminal stop reason.
+15
View File
@@ -1677,6 +1677,21 @@ NOTE: At any point in time through this workflow you should feel free to ask the
return "break" as const
}
// kilocode_change end
// kilocode_change start - guard against providers that end the stream
// without a terminal stop_reason (e.g. an Anthropic-style message_delta
// with stop_reason: null followed immediately by message_stop). Without
// a finishReason, the loop-exit check at the top of the next iteration
// sees a falsy `finish` (loaded from storage via filterCompactedEffect)
// and keeps stepping forever. Default to "unknown" and persist so the
// regular break condition fires when there are no tool calls. Skipped
// for the compact path so guardCompactionAttempt can still fill in
// "error" on exhaustion. Tool-call turns already get "tool-calls" from
// the AI SDK; even without it, !hasToolCalls keeps the break gated.
if (result !== "compact" && !handle.message.finish) {
handle.message.finish = "unknown"
yield* sessions.updateMessage(handle.message)
}
// kilocode_change end
return "continue" as const
}).pipe(Effect.ensuring(instruction.clear(handle.message.id)))
if (outcome === "break") break