rlmesh.adapters.Adapter

classfrom rlmesh.adapters import Adapter[source]

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.

transform_obs_value

function[source]
transform_obs_value(
    raw_obs: RawObs,
    *,
    input_bridge: ValueBridge | None = None,
    custom_bridge: ValueBridge | None = None,
) -> Value

Convert 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) -> Any

Convert 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,
) -> None

Advance 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() -> None

Clear 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,
) -> Value

Convert a model action vector into a canonical env action value.

transform_action

function[source]
transform_action(raw_action: object) -> NumpyArray

Convert 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() -> str

Return 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.