pi-mono/packages
robopipi[bot] f6278a472e
fix(mcp): read large stdio messages in linear time (#11791)
`JsonRpcLineReader.readStdout` (used by the stdio transport and by
`PipeTransport`) appended every stdout chunk to the buffered bytes with
`Buffer.concat`, then searched the whole buffer from the start for a
newline. A large message arriving in many chunks was therefore copied
and scanned again on every chunk. A 12 MiB tool result in 64 KiB chunks
took about 350 ms just to frame.

Now the reader keeps the bytes of an incomplete message as a list of
chunks, with a running byte count, and searches only the new chunk for a
newline. When the newline arrives, the chunks are joined once. A line
that fits inside a single chunk is sliced directly. The rest is
unchanged: the `maxMessageBytes` limit (now checked against the running
count), CRLF and blank-line handling, errors for invalid JSON and
oversized messages, and the incomplete-message error in `end()`.

Testing:
- New `packages/mcp/test/lines.test.ts`:
- a 1 MiB message fed in 4 KiB chunks calls `Buffer.concat` once (fails
on the old code);
- a mixed input of multi-byte UTF-8, CRLF, blank lines, an invalid line
and several messages gives the same results at every chunk size from 1
byte to the whole input;
  - reading recovers after an oversized message;
  - a message without its newline is reported at the end.
- `test/lines.test.ts`, `test/stdio.test.ts` and `test/pipe.test.ts`
pass. `npm run check` passes.
- Micro-benchmark, one message fed in 64 KiB chunks:
  - before: 1 MiB 5.4 ms, 4 MiB 49.9 ms, 12 MiB 348 ms;
  - after: 2.2 ms, 7.9 ms, 21.6 ms.

Fixes #11761

Requested by @badlogic

Co-authored-by: triagent <triagent@localhost>
2026-11-04 10:09:23 +01:00
..
agent Anthropic message threads (#11545) 2026-11-03 14:07:57 +01:00
ai fix(ai): add glm-5.3 to qwen-token-plan-individual models (#11785) 2026-11-04 09:54:48 +01:00
chord docs(chord): the tutorial uses tx.update with its integer key now that int keys type-check 2026-11-04 09:07:34 +00:00
codemode Add [Unreleased] section for next cycle 2026-11-02 11:38:21 +01:00
coding-agent fix(coding-agent): load user keybindings in pi config (#11788) 2026-11-04 09:59:49 +01:00
durable feat(chord): Chord v2 is the package's root 2026-11-02 22:36:55 +00:00
env fix(env): kill what a process program left running when it exits 2026-11-03 14:17:21 +01:00
evals Release v1.5.0 2026-11-02 11:38:21 +01:00
mcp fix(mcp): read large stdio messages in linear time (#11791) 2026-11-04 10:09:23 +01:00
schema fix(schema): apply a relative root $id only once when resolving references (#11726) 2026-11-03 23:14:11 +01:00
telemetry Add [Unreleased] section for next cycle 2026-11-02 11:38:21 +01:00
tui fix(tui): detect Alacritty for OSC 8 hyperlinks without TERM_PROGRAM (#11777) 2026-11-04 09:26:27 +01:00