Skip to content

fix(rpc): send commands to omp as single unchunked lines (#105) - #107

Merged
kahme247 merged 2 commits into
mainfrom
fix/issue-105-inbound-chunking
Sep 15, 2026
Merged

kahme247 merged 2 commits into
mainfrom
fix/issue-105-inbound-chunking

Conversation

@kahme247

Copy link
Copy Markdown
Owner

Summary

Fixes #105.

Attaching a normal photo or clipboard screenshot reset the session with "The OMP session stopped responding and was reset." Root cause is exactly as reported: RpcProcess.writeFrame ran encodeRpcFrames on every stdin command, so once protocol v2 was negotiated any command over MAX_RPC_FRAME_BYTES (1 MiB) was split into rpc_chunk records. OMP's stdin reader parses one JSONL object per line and never runs the chunk decoder, so each record was rejected:

{"type":"response","command":"rpc_chunk","success":false,"error":"Unknown command: rpc_chunk"}

with no id to correlate. The prompt never acked, and after PROMPT_ACK_TIMEOUT_MS the healthy child was killed and reported as session_unresponsive.

Protocol-v2 chunking is an outbound encoding (omp → host); the advertised maxFrameBytes bounds omp's physical frames, not the host's commands.

Change

  • lib/omp/rpc-frame.ts: encodeRpcFrames(frame, protocolVersion, chunkId)encodeRpcCommand(frame), which always returns a single unchunked JSONL record however large. Added MAX_INBOUND_COMMAND_BYTES (32 MiB) so a pathological command fails fast with a clear error (RPC command exceeds the …-byte inbound transport limit) instead of an unbounded pipe write. RpcFrameDecoder is unchanged — omp's oversized outbound frames are still reassembled.
  • lib/omp/rpc-process.ts: writeFrame writes one line, chunk-id bookkeeping removed, doc comments updated. Commands stay serialized through the FIFO queue so they cannot interleave and a failed write cannot reorder pending responses.

The composer/route preflight the issue asks for already exists (validateOutgoingPrompt in components/ChatInput.tsx, parseJsonWithinLimit(req, MAX_AGENT_COMMAND_REQUEST_BYTES) in both agent routes), so messages over 8 MiB are rejected before send, and a serialization failure now surfaces immediately rather than as a session reset.

Verification

Reproduced against a real omp/18.1.19 child (omp --mode rpc-ui, protocol v2 negotiated), sending the same 1.2 MB logical command both ways:

(a) old framing — 5 rpc_chunk records on stdin
    → 5 × {"id":null,"success":false,"error":"Unknown command: rpc_chunk"}

(b) new framing — the same command as one unchunked 1.2 MB line
    → {"id":"w1","command":"switch_session","success":false,"error":"ENAMETOOLONG: …"}

The oversized command is now parsed and correlated by its own id (the error is just the bogus path used as a payload), so the prompt can no longer wedge.

Tests:

  • lib/omp/rpc-frame.test.mjs: oversized command stays one record (and never contains rpc_chunk); over-cap command throws before any write; unchunked command still decodes; decoder still reassembles and still rejects reordered/mismatched chunk sequences.
  • lib/omp/rpc-process-runtime.test.mjs: new regression test — after v2 negotiation a ~2 MiB prompt is written as one stdin line, acks, and produces no rpc_chunk command.
  • npm test — 800 pass / 0 fail / 5 skipped (full suite), tsc --noEmit clean, eslint clean.

kahme247 and others added 2 commits September 15, 2026 21:53
Protocol-v2 `rpc_chunk` framing is an outbound encoding only. omp parses one
JSONL object per stdin line and never runs the chunk decoder, so every command
above 1 MiB — any prompt carrying a photo, clipboard screenshot, or similar
attachment — was answered `Unknown command: rpc_chunk` under an id it could not
correlate. The prompt then sat until the 30s ack timeout killed the child and
reported `session_unresponsive`.

`encodeRpcCommand` always emits one record, however large, with a 32 MiB bound
so a pathological command fails fast with a clear error instead of hanging.
Reproduced against a real `omp --mode rpc-ui`: the old framing produced five
`Unknown command: rpc_chunk` responses for a 1.2 MB `switch_session`, the new
framing is parsed and correlated normally.
@kahme247
kahme247 merged commit b4c29e2 into main Sep 15, 2026
2 of 3 checks passed
@kahme247
kahme247 deleted the fix/issue-105-inbound-chunking branch September 15, 2026 20:44
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.

[Bug] Image attachments reset the session: inbound prompt is v2-chunked, OMP rejects rpc_chunk on stdin

1 participant