Files
codex/codex-rs/exec-server/src/proto/codex.exec_server.relay.v1.proto
Anton Panasenko ac466c0dbd feat(exec-server): use protobuf relay frames (#22343)
## Why

Remote exec-server now needs one executor websocket to serve multiple
harness JSON-RPC sessions. Rendezvous routes by `stream_id`, and the
exec-server side needs to use the same stable relay frame contract
instead of a hand-rolled JSON shape.

The relay protocol also needs to make ownership boundaries clear:
harness and executor endpoints own sequencing, acks, retries, duplicate
suppression, segmentation, and reassembly; rendezvous only routes
frames.

## What Changed

- Add the checked-in `codex.exec_server.relay.v1.RelayMessageFrame`
proto plus generated prost bindings for `codex-exec-server`.
- Encode remote harness/executor relay traffic as binary protobuf
websocket frames while keeping local websocket JSON-RPC unchanged.
- Demux executor-side relay streams into independent
`ConnectionProcessor` sessions keyed by `stream_id`.
- Add a programmatic `RemoteExecutorConfig::with_bearer_token(...)`
constructor for non-CLI callers and integration tests.
- Add an integration test that starts the remote executor against a fake
registry/rendezvous websocket and verifies two virtual streams share one
executor websocket without cross-talk, including per-stream reset
behavior.
- Document the remote relay envelope, sequence ranges, `ack`/`ack_bits`,
and endpoint responsibilities in `exec-server/README.md`.

## Verification

- `cargo test -p codex-exec-server --test relay
multiplexed_remote_executor_routes_independent_virtual_streams --
--exact`
- `cargo test -p codex-exec-server --test relay`
- `cargo test -p codex-exec-server` passed outside the sandbox. The
sandboxed run hit macOS `sandbox-exec: sandbox_apply: Operation not
permitted` in filesystem sandbox tests.
2026-05-12 16:50:45 -07:00

38 lines
593 B
Protocol Buffer

syntax = "proto3";
package codex.exec_server.relay.v1;
message RelayMessageFrame {
uint32 version = 1;
string stream_id = 2;
uint32 ack = 3;
uint32 ack_bits = 4;
oneof body {
RelayData data = 5;
RelayAck ack_frame = 6;
RelayResume resume = 7;
RelayReset reset = 8;
RelayHeartbeat heartbeat = 9;
}
}
message RelayData {
uint32 seq = 1;
uint32 segment_index = 2;
uint32 segment_count = 3;
bytes payload = 4;
}
message RelayAck {}
message RelayResume {
uint32 next_seq = 1;
}
message RelayReset {
string reason = 1;
}
message RelayHeartbeat {}