fix(smolvla2): use TransitionKey enum (not .value) as transition keys

``EnvTransition`` is declared as a ``TypedDict`` keyed by
``TransitionKey.OBSERVATION.value`` (the string ``'observation'``),
but every concrete ``ProcessorStep`` in the pipeline indexes the
transition with the enum *member* (``transition[TransitionKey.
OBSERVATION]`` / ``transition.get(TransitionKey.OBSERVATION)``).
Those are two different keys in a Python dict — string key vs enum
key — so steps couldn't find the observation we'd placed under the
string variant, and bailed every tick with
``ObservationProcessorStep requires an observation in the
transition``.

Build the transition with the enum members directly. Matches how
``BatchProcessor``, ``RelativeActionProcessor``, ``HilProcessor``,
etc. read the dict.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pepijn
2026-05-12 14:50:22 +02:00
parent 992d13d4e9
commit 3f7436ff8a
@@ -629,21 +629,28 @@ def _build_robot_observation_provider(
return None
if preprocessor is not None:
transition: dict[str, Any] = {
TransitionKey.OBSERVATION.value: obs_tensors,
TransitionKey.ACTION.value: None,
TransitionKey.REWARD.value: None,
TransitionKey.DONE.value: None,
TransitionKey.TRUNCATED.value: None,
TransitionKey.INFO.value: None,
TransitionKey.COMPLEMENTARY_DATA.value: {},
# ``EnvTransition``'s TypedDict is declared with
# ``TransitionKey.OBSERVATION.value`` as keys, but every
# ProcessorStep in the pipeline does
# ``transition.get(TransitionKey.OBSERVATION)`` / indexes
# with the *enum member* — not the string ``.value``. Build
# the dict with enum keys so the steps actually find the
# observation.
transition: dict[Any, Any] = {
TransitionKey.OBSERVATION: obs_tensors,
TransitionKey.ACTION: None,
TransitionKey.REWARD: None,
TransitionKey.DONE: None,
TransitionKey.TRUNCATED: None,
TransitionKey.INFO: None,
TransitionKey.COMPLEMENTARY_DATA: {},
}
try:
transition = preprocessor(transition)
except Exception as exc: # noqa: BLE001
logger.warning("preprocessor failed on robot observation: %s", exc)
return None
obs_tensors = transition.get(TransitionKey.OBSERVATION.value) or {}
obs_tensors = transition.get(TransitionKey.OBSERVATION) or {}
observation = {
k: v