-
Notifications
You must be signed in to change notification settings - Fork 3.1k
fix(cli): recover stalled response streams #11585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f6805e0
4bc9e27
872ccb2
01af872
7265d56
4eb2ce5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@kilocode/cli": patch | ||
| --- | ||
|
|
||
| Prevent subagents from hanging on stalled model response streams or interactive suggestions. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,8 @@ import { | |
| patchKiloProviderPrivacy, | ||
| kiloSmallModelPriority, | ||
| buildTimeoutSignal, | ||
| STREAM_IDLE_TIMEOUT_MS, | ||
| streamTimeout, | ||
| } from "@/kilocode/provider/provider" | ||
| import * as ModelsRefresh from "@/kilocode/provider/models-refresh" | ||
| // kilocode_change end | ||
|
|
@@ -1677,7 +1679,12 @@ export const layer = Layer.effect( | |
| if (existing) return existing | ||
|
|
||
| const customFetch = options["fetch"] | ||
| const chunkTimeout = options["chunkTimeout"] | ||
| // kilocode_change start - prevent indefinitely stalled response streams | ||
| const chunkTimeout = streamTimeout({ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WARNING: The new default idle timeout cannot be disabled from config This makes Reply with |
||
| options, | ||
| defaultMs: STREAM_IDLE_TIMEOUT_MS, | ||
| }) | ||
| // kilocode_change end | ||
| const headerTimeout = options["headerTimeout"] | ||
| delete options["chunkTimeout"] | ||
| delete options["headerTimeout"] | ||
|
|
@@ -1725,7 +1732,7 @@ export const layer = Layer.effect( | |
| timeout: false, | ||
| }).finally(() => headerTimeoutCtl?.clear()) | ||
| timeout.clear() | ||
| if (!chunkAbortCtl) return res | ||
| if (chunkTimeout === undefined || !chunkAbortCtl) return res | ||
| return wrapSSE(res, chunkTimeout, chunkAbortCtl) | ||
| } catch (err) { | ||
| timeout.clear() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WARNING: Permanent fallback entries can accumulate per session
poolis keyed bysession-id/x-session-affinity, so every session that exhausts websocket retries leaves behind onePoolEntry. Skipping fallback entries here means those entries are never removed until the plugin is disposed, which can turn into an unbounded map in long-lived CLI or extension processes. A bounded TTL for fallback entries would preserve the sticky fallback behavior without pinning every failed session forever.Reply with
@kilocode-bot fix itto have Kilo Code address this issue.