Environment Contract
The Gymnasium-style environment shape RLMesh serves and the contract clients receive on connect.
RLMesh follows the Gymnasium reset/step contract. Any environment that
implements this shape can be served over an endpoint. Environments created
with gym.make(...) work as-is, and custom objects only need to match the
same surface.
observation, info = env.reset(seed=42, options=None)
observation, reward, terminated, truncated, info = env.step(action)
Environment shape
An environment exposes its spaces alongside the lifecycle methods:
class Env:
observation_space = ...
action_space = ...
def reset(self, seed=None, options=None):
...
def step(self, action):
...
def close(self):
...
RLMesh reads the two spaces and drives reset, step, and close.
Vectorized environments can additionally expose num_envs,
single_observation_space, and single_action_space. See
Connect a Client for how those are
served and consumed.
Common Gymnasium wrappers can stay in place. RLMesh reads the spaces and drives the wrapped environment through the normal Gymnasium API, so a wrapper stack behaves the same locally and behind a server.
Serving the contract
When EnvServer wraps an environment it derives an environment contract
from the spaces and metadata. That contract is what travels to clients:
server = rlmesh.EnvServer(env, "127.0.0.1:5555")
contract = server.env_contract
print(contract.id)
print(contract.observation_space.kind)
print(contract.action_space.kind)
print(contract.num_envs)
server.spec is an alias for server.env_contract. See
Serving Environments for the full
serving workflow.
Remote contract
On connect, a client receives the environment contract before any step runs. It carries:
- environment id and metadata
- render mode
- number of environments
- observation space
- action space
from rlmesh.numpy import RemoteEnv
env = RemoteEnv("127.0.0.1:5555")
print(env.env_contract)
print(env.observation_space)
print(env.action_space)
env.close()
Because the contract arrives up front, a remote client can validate shapes and dtypes without taking a step. Observation and action values cross the RLMesh protocol as transport values and are decoded by whichever backend adapter the client chose — see Spaces and Values for how that decoding works, and Remote Clients for the client side of the connection.