fix(server): keep-alive heartbeat on POST /:sessionID/message stream#1354
Merged
Conversation
The /message POST stream wrote nothing until the whole turn finished, so a turn that blocks for a long time — most notably while the `question` tool waits on an un-timed Deferred for a human reply — left the response silent. The Bun server never times out (idleTimeout:0), but an external client with its own per-turn request timeout (e.g. the `mimo run` driver) sees a dead connection and aborts with "error sending request for url". Write JSON-insignificant whitespace every 10s while the turn is in flight (mirrors the existing SSE heartbeat in event.ts/global.ts), resetting the client's idle timer. The trailing JSON.stringify(msg) still parses as the whole body since clients JSON.parse it and leading whitespace is tolerated. Interval is read per-request via MIMOCODE_PROMPT_HEARTBEAT_INTERVAL_MS (default 10s) for runtime tuning and tests.
cf1fa0a to
85a1545
Compare
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 free
to 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.
Summary
The
POST /:sessionID/messagestream wrote nothing until the whole turn finished. When a turn blocks for a long time — most notably while thequestiontool waits on an un-timedDeferredfor a human reply — the response stayed completely silent.The Bun server never times out (
adapter.bun.tsidleTimeout: 0), but an external client with its own per-turn request timeout (e.g. themimo rundriver) sees a dead connection and aborts withI/O error: error sending request for url .... This reproduced reliably whenever the user took a while to answer aquestionprompt.Fix
Write JSON-insignificant whitespace every 10s while the turn is in flight, resetting the client's idle timer. This mirrors the existing SSE heartbeat in
event.ts/global.ts("Send heartbeat every 10s to prevent stalled proxy streams").JSON.stringify(msg)still parses as the whole body: clientsJSON.parsethe full body and leading whitespace is JSON-insignificant.MIMOCODE_PROMPT_HEARTBEAT_INTERVAL_MS(default 10s) for runtime tuning and tests.Test
New
test/server/session-prompt-heartbeat.test.tsdrives aquestiontool call so the turn blocks, asserts keep-alive whitespace flows on the open stream before the turn completes, then replies and verifies the trailing JSON still parses as the whole body. Verified TDD red/green (without the heartbeat the turn hangs and the test fails).Verification
bun typecheck— cleanbun test test/server/— 52/52 pass (incl. new test)