rlmesh.adapters.Adapter
A resolved env-to-model adapter; build instances with resolve().
Adapter(
plan: AdapterPlan,
customs: Mapping[Placement, ObsTransform],
obs_enc_shims: tuple[ObsEncShim, ...] = (),
action_enc_shims: tuple[ActEncShim, ...] = (),
)Declarative plans run in the native rlmesh-adapters core; custom
inputs run their host-language transforms on the raw Python
observation.
Methods
- transform_obs_value()Convert a raw env observation into a canonical Value-tree payload.
- transform_obs()Convert a raw env observation into the model input payload.
- observe()Advance the frame windows for a step that predicted nothing.
- history_windows()
(placement, span, frame_bytes)per frame window, per live episode. - history_keys()Canonical placements of the inputs that hold a frame window.
- reset()Clear the frame-history windows at an episode boundary.
- transform_action_value()Convert a model action vector into a canonical env action value.
- transform_action()Convert a model action vector into the env action vector.
- serve_route()The served-route payload the native engine drives.
- explain()Return a human-readable summary of the resolved transformations.
- advisories()Per-env data-loss / fabrication notes for this resolved adapter.
- wrap_predict()Wrap a model predict function with both transforms.
transform_obs_value
function[source]transform_obs_value(
raw_obs: RawObs,
*,
input_bridge: ValueBridge | None = None,
custom_bridge: ValueBridge | None = None,
) -> ValueConvert a raw env observation into a canonical Value-tree payload.
The result is the model input payload tree (a nested dict/list, or a
bare leaf for a single-leaf model input) – the same shape the model’s
predict receives. Only the observation keys the plan actually reads
are encoded and sent across the native boundary, so an unused – possibly
unencodable – observation key never aborts a step. Custom inputs still
see the full raw observation. Inputs that request frame history are
stacked here from a rolling buffer, cleared by reset().
transform_obs
function[source]transform_obs(raw_obs: RawObs) -> AnyConvert a raw env observation into the model input payload.
Returns the payload tree (a dict for a Dict-shaped model input, a bare array/scalar for a single-leaf input, a list for a Tuple-shaped input).
observe
function[source]observe(
raw_obs: RawObs,
*,
input_bridge: ValueBridge | None = None,
) -> NoneAdvance the frame windows for a step that predicted nothing.
The tick a replayed chunk owes its history: the env step happened, so
every input that declares a stack still sees its frame, and the next
assembled payload stacks consecutive steps rather than decision points.
Only the observation keys the plan reads are encoded – exactly as
transform_obs_value() does – and nothing else in the spec is
applied, so a custom input’s transform never runs on a replayed step.
It also counts the step, so the action transform_action()
converts next is recorded as the one executed here for a part reading
the previous action. A no-op for a plan with no per-episode history.
Without input_bridge the observation is read as NumPy, like
transform_obs().
history_windows
function[source]history_windows() -> tuple[tuple[str, int, int], ...](placement, span, frame_bytes) per frame window, per live episode.
span is how many consecutive frames the window holds to reach its
oldest offset (4 for stack=4, 7 for stack=4, stride=2);
frame_bytes is one processed frame, or 0 when the env’s camera
resolution was not derivable. A caller sizes an admission budget from
num_envs * sum(span * frame_bytes).
history_keys
function[source]history_keys() -> tuple[str, ...]Canonical placements of the inputs that hold a frame window.
Empty when the model declares no stack; observe() is then a
no-op and a caller may skip it.
reset
function[source]reset() -> NoneClear the frame-history windows at an episode boundary.
Used on the local per-episode loop (a single env); the served path keeps its own episode-keyed buffers in the engine, so this is the local-path counterpart.
transform_action_value
function[source]transform_action_value(
raw_action: object,
*,
action_bridge: ValueBridge | None = None,
) -> ValueConvert a model action vector into a canonical env action value.
transform_action
function[source]transform_action(raw_action: object) -> NumpyArrayConvert a model action vector into the env action vector.
serve_route
function[source]serve_route(bridge: ValueBridge) -> dict[str, object]The served-route payload the native engine drives.
The engine applies the native plan, frame-stacking, customs, and
encoding shims in Rust; this hands it the native plan plus the host
(Python) holes as neutral Value-tree callables (framework/numpy bridging
stays here). Used only on the serve path; transform_obs_value()
remains the in-process run(env) single-lane path.
explain
function[source]explain() -> strReturn a human-readable summary of the resolved transformations.
advisories
function[source]advisories() -> list[Advisory]Per-env data-loss / fabrication notes for this resolved adapter.
The “warn” subset of describe() – e.g. a camera the env did not
provide that is being zero-filled, or an aspect crop that drops pixels.
Each note carries a severity: "info" for benign hints and
"caution" when the adapter substituted or fabricated model-visible
data (a role-rebound camera, a zero-filled frame) – the tier a managed
runner or eval harness may want to hard-fail on. str(note) is the
message; empty when nothing noteworthy happened.
wrap_predict
function[source]wrap_predict(
predict_fn: Callable[[Any], object],
) -> Callable[[Any], ActionT]Wrap a model predict function with both transforms.
predict_fn receives the model input payload tree – a dict for a
Dict-shaped input, a list for a Tuple-shaped input, or a bare leaf for a
single-leaf input (whatever transform_obs() produces). The
returned callable takes a raw env observation – a mapping, or a
bare array/leaf for a flat (non-Dict) env – and returns an env-ready
action, suitable for rlmesh.numpy.Model.
The execution horizon is a runtime decision (execution_horizon on
ResolveAdapter, owned by the runtime driver) and the served engine
emits the chunk. This direct wrapper applies one action per step;
in-process chunk replay lives in
rlmesh._models._chunk.ChunkReplay, driven by run with a
locally chosen horizon.