mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
fix(cli): defer finish-reason default until after compact branch
Setting handle.message.finish before the result === "compact" branch broke guardCompactionAttempt (which fills in "error" with ??=) and the overflow detection at compaction.create. Move the default to right before "continue" and gate it on result !== "compact" so the compaction paths see the original undefined value.
This commit is contained in:
@@ -1600,21 +1600,6 @@ NOTE: At any point in time through this workflow you should feel free to ask the
|
||||
toolChoice: format.type === "json_schema" ? "required" : undefined,
|
||||
})
|
||||
|
||||
// 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 — the
|
||||
// tool-call path is unaffected because `!hasToolCalls` keeps the break
|
||||
// gated when the assistant did emit tool calls.
|
||||
if (!handle.message.finish) {
|
||||
handle.message.finish = "unknown"
|
||||
yield* sessions.updateMessage(handle.message)
|
||||
}
|
||||
// kilocode_change end
|
||||
|
||||
if (structured !== undefined) {
|
||||
handle.message.structured = structured
|
||||
handle.message.finish = handle.message.finish ?? "stop"
|
||||
@@ -1672,6 +1657,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
|
||||
|
||||
Reference in New Issue
Block a user