Skip to content

fix(server): keep-alive heartbeat on POST /:sessionID/message stream#1354

Merged
wqymi merged 2 commits into
mainfrom
vb/1b3d-mimocode-error
Jun 25, 2026
Merged

fix(server): keep-alive heartbeat on POST /:sessionID/message stream#1354
wqymi merged 2 commits into
mainfrom
vb/1b3d-mimocode-error

Conversation

@wqymi

@wqymi wqymi commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

The POST /:sessionID/message stream wrote nothing until the whole turn finished. When a turn blocks for a long time — most notably while the question tool waits on an un-timed Deferred for a human reply — the response stayed completely silent.

The Bun server never times out (adapter.bun.ts 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 I/O error: error sending request for url .... This reproduced reliably whenever the user took a while to answer a question prompt.

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").

  • The trailing JSON.stringify(msg) still parses as the whole body: clients JSON.parse the full body and leading whitespace is JSON-insignificant.
  • Interval is read per-request via MIMOCODE_PROMPT_HEARTBEAT_INTERVAL_MS (default 10s) for runtime tuning and tests.

Note: this keeps the connection alive while the server waits for human input. A genuinely long-running turn that exceeds the external driver's hard per-turn budget still needs that budget raised on the driver side (outside this repo).

Test

New test/server/session-prompt-heartbeat.test.ts drives a question tool 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 — clean
  • bun test test/server/ — 52/52 pass (incl. new test)

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.
@wqymi wqymi force-pushed the vb/1b3d-mimocode-error branch from cf1fa0a to 85a1545 Compare June 25, 2026 15:58
@wqymi wqymi merged commit ecbdff7 into main Jun 25, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant