From cd4d356d5d1c068f8c0e0becc87efa22c2a0d9ae Mon Sep 17 00:00:00 2001 From: artboy <80608452+itxaiohanglover@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:10:39 +0800 Subject: [PATCH 1/3] fix(kosong): add idle timeout to streaming response loop The for-await loop in generate() waits forever when the connection stalls without closing. Add a 60s idle timeout that aborts the stream if no chunks arrive. Fixes #1050 --- packages/kosong/src/generate.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/kosong/src/generate.ts b/packages/kosong/src/generate.ts index d17fef39c5..899accc7c3 100644 --- a/packages/kosong/src/generate.ts +++ b/packages/kosong/src/generate.ts @@ -111,7 +111,21 @@ export async function generate( // the stream. await throwIfAborted(options?.signal, stream); + // Idle timeout: if no chunk arrives within this period, abort the stream + // to prevent indefinite hangs when the connection stalls without closing. + const IDLE_TIMEOUT_MS = 60_000; + let idleTimer: ReturnType | undefined; + const resetIdleTimer = () => { + if (idleTimer) clearTimeout(idleTimer); + idleTimer = setTimeout(() => { + stream.return?.(undefined); + }, IDLE_TIMEOUT_MS); + }; + resetIdleTimer(); + + try { for await (const part of stream) { + resetIdleTimer(); await throwIfAborted(options?.signal, stream); // Notify raw part callback (deep copy to avoid aliasing mutations). From bfb015fce65a392c92f502784a4e776fc83a3f06 Mon Sep 17 00:00:00 2001 From: artboy <80608452+itxaiohanglover@users.noreply.github.com> Date: Thu, 25 Jun 2026 14:38:23 +0800 Subject: [PATCH 2/3] chore: add changeset for stream idle timeout --- .changeset/stream-idle-timeout.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/stream-idle-timeout.md diff --git a/.changeset/stream-idle-timeout.md b/.changeset/stream-idle-timeout.md new file mode 100644 index 0000000000..e6c95cf0b2 --- /dev/null +++ b/.changeset/stream-idle-timeout.md @@ -0,0 +1,5 @@ +--- +"@moonshot-ai/kimi-code": patch +--- + +Add 60s idle timeout to streaming response loop to prevent indefinite hangs. From 614f2cd2bd8632da5137396b7928e0b94a56437b Mon Sep 17 00:00:00 2001 From: artboy <80608452+itxaiohanglover@users.noreply.github.com> Date: Thu, 25 Jun 2026 14:41:14 +0800 Subject: [PATCH 3/3] fix: close try block with finally to clean up idle timer Codex P1: the try block was never closed with catch/finally. Added finally block after the for-await loop to clear the idle timer. --- packages/kosong/src/generate.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/kosong/src/generate.ts b/packages/kosong/src/generate.ts index 899accc7c3..8f4edadc44 100644 --- a/packages/kosong/src/generate.ts +++ b/packages/kosong/src/generate.ts @@ -169,6 +169,9 @@ export async function generate( pendingPart = part; } } + } finally { + if (idleTimer) clearTimeout(idleTimer); + } await throwIfAborted(options?.signal, stream); options?.onStreamEnd?.();