fix(memory): replace wall-clock timeout with per-chunk SSE liveness - #329
Merged
Conversation
Retire the whole-call wall clock in favor of activity-based liveness on the memory model seam: switch generateObject -> streamObject and re-arm an idle watchdog on every arriving part (reasoning deltas included), so an actively streaming call is never killed however long the reasoning runs. Add a connect timeout (no first part) and an idle timeout (gap between parts), both pure non-response detectors; generation still terminates via max_output_tokens / a natural stop. Addresses the streaming-liveness half of #324; the periodic prepare lock hardening remains tracked there.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题(Refs #324,解决其 streaming-liveness 半区)
#328 用
RESPONSE_TIMEOUT 5min墙钟兜底,但它与"思考即输出、输出即活着"的 SSE 原则相悖:墙钟无法区分"正在思考"与"连接已死",一条 16k-token 的慢思考随时可能被误杀。修法
src/memory/model.ts:generateObject→streamObject,让 chunk 可见(仓库先例:agent.ts同款 fullStream 消费)。drainWithLiveness:消费fullStream,每个到达的 part(含 reasoning delta)都重置 idle 看门狗——只要 SSE 还在推送,调用就活着,无论总时长多长。CONNECT_TIMEOUT 60s(首个 part 未到达=死连接)与IDLE_TIMEOUT 60s(chunk 间断流=卡死),触发即 abort 并失败为TimeoutError。max_output_tokens/ 自然 stop 负责,不设整体墙钟。make({timeout})注入仍保留(测试用硬期限);生产路径不再有默认墙钟。边界覆盖(新增 4 个回归测试,
it.live真实计时)Stalled,且 abort 钩子恰被调用一次。Stalled,且快速失败(<200ms)。errorpart 按原因失败,不误判为 stall。验证
bun typecheck(packages/opencode)干净test/memory/90 pass / 0 fail(其中 4 个为本次新增 liveness 回归)说明
ghostty-web的 429 限流(外部依赖、与本改动无关)无法跑全工作区 typecheck,经确认以--no-verify提交、由 CI 作门禁。