Skip to content

Repository files navigation

plugrl-protocol

CI License: Apache 2.0

The wire protocol between a PlugRL training server, which holds the policy and the learning algorithm, and an env client, which runs environments and asks for actions.

The two are separate processes, usually on separate machines, deliberately: an environment stack and a training stack can then be installed, versioned and scheduled independently, and an env client need not be Python at all.

SPEC.md is the specification. It is normative, it names its own known defects, and everything in it that can be checked by a test is.

What is here

SPEC.md the protocol, in full
src/plugrl_protocol/ the message types and the msgpack codec — 101 lines
examples/ two env clients written against the spec, sharing no code with PlugRL
tests/ the spec's checkable clauses, as tests

The package is small on purpose. It is the piece both sides import, so anything that could live on one side does.

The protocol in one screen

Four message types, four lowercase strings. The server speaks first.

client                                     server
  |------------ WebSocket handshake ---------->|
  |<---------------- metadata -----------------|
  |------------------ infer ------------------>|   observations
  |<----------------- action ------------------|   an action chunk
  |----------------- feedback ---------------->|   reward, done, next obs

Messages are msgpack maps carrying a message_type. Arrays travel as

{b"__ndarray__": true, b"data": <bin>, b"dtype": "<f4", b"shape": [4, 1, 7]}

dtype is a numpy typestr — a byte-order character, a kind character and an item size. It is nearly the only piece of numpy vocabulary on the wire, and about ten lines of code to parse. The exception is the text field; see SPEC.md section 3.4, which does not pretend otherwise.

Three things a first implementation usually gets wrong, all specified:

  • messages strictly alternate infer, action, feedback — the server has no dispatcher (section 4.2);
  • the environment set in a feedback need not match the one in the infer it follows (section 4.3);
  • the reward in a feedback is the sum over the action chunk, not the last step's (section 5.4).

Relationship to openpi

The serialization is openpi's. msgpack_numpy.py is taken from it under Apache-2.0 (attributed in the file header and in NOTICE) and reformatted only — the array encoding is byte-identical, so the part of a client that takes real work in C++ or Rust carries across between the two ecosystems.

The message layer is where they differ: openpi sends a bare observation and gets a bare action back, which is what serving a policy needs. PlugRL wraps both in an envelope and adds a feedback return channel, which is what training one needs. SPEC.md section 9 has the full comparison.

Installing

Not on PyPI. Install from git, pinned to a commit - which is how plugrl-server and plugrl-env-client depend on it:

uv add "plugrl-protocol @ git+https://github.com/PlugRL/plugrl-protocol.git@<commit>"
# or
pip install "plugrl-protocol @ git+https://github.com/PlugRL/plugrl-protocol.git@<commit>"

Only Python clients that want the shared codec need this at all. A client in another language should implement SPEC.md directly, which is what the C++ example does - and what examples/conformance_server.py will grade it against.

License

Apache-2.0. See LICENSE and NOTICE.

About

The written boundary between RL training and its environments: WebSocket + msgpack, with a feedback return channel. SPEC.md is normative and its checkable clauses are tests; two reference env clients are written against it, one of them C++17 with no third-party libraries.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages