Skip to content

fix: return Gymnasium-style dict infos from MarkovVectorEnv - #270

Open
teddytennant wants to merge 1 commit into
Farama-Foundation:mainfrom
teddytennant:fix/markov-vector-env-infos-249
Open

fix: return Gymnasium-style dict infos from MarkovVectorEnv#270
teddytennant wants to merge 1 commit into
Farama-Foundation:mainfrom
teddytennant:fix/markov-vector-env-infos-249

Conversation

@teddytennant

Copy link
Copy Markdown
Contributor

Problem

pettingzoo_env_to_vec_env_v1 wraps a PettingZoo parallel env in MarkovVectorEnv, which is a gymnasium.vector.VectorEnv. On reset and step it returned infos as a Python list of per-agent dicts:

infs = [infos.get(agent, {}) for agent in self.par_env.possible_agents]

Gymnasium vector environments (since v0.25) expect infos to be a dict of arrays with boolean _<key> masks (see VectorEnv._add_info). Wrappers such as gymnasium.wrappers.RecordEpisodeStatistics (and the vector variant) assert isinstance(infos, dict) and fail with:

AssertionError: `info` dtype is <class 'list'> while supported dtype is `dict`.

This breaks CleanRL multi-agent PPO (ppo_pettingzoo_ma_atari.py), which wraps the SuperSuit vec env with RecordEpisodeStatistics.

Root cause

MarkovVectorEnv never adopted the post-v0.25 Gymnasium vector info layout. Downstream ConcatVecEnv / ProcConcatVec also assumed list-of-dicts and flattened nested lists, so the whole SuperSuit vector stack was list-shaped.

Fix

  • Add supersuit/vector/utils/info_dict.py with list_infos_to_dict (list of per-env dicts -> Gymnasium vector dict) and merge_vector_infos (concat blocks along the env axis).
  • MarkovVectorEnv.reset / step now return dict infos. Non-agent (global) PettingZoo info keys are still propagated into every agent slot. Terminal auto-reset still merges step + reset infos with reset keys winning.
  • Set metadata["autoreset_mode"] = AutoresetMode.SAME_STEP to match the existing same-step auto-reset when the underlying PZ env finishes.
  • ConcatVecEnv and ProcConcatVec merge vector info dicts instead of flattening lists.
  • SingleVecEnv returns dict infos for consistency.
  • SB3VecEnvWrapper converts dict infos back to a list of per-env dicts, which is what Stable-Baselines3 expects.

Test plan

  • test_infos_are_dict_not_list - reset/step return dict
  • test_record_episode_statistics_compatible - gymnasium.wrappers.vector.RecordEpisodeStatistics works and emits episode / _episode
  • test_infos_dict_through_concat_vec_envs - same through concat_vec_envs_v1
  • Existing test_pettingzoo_to_vec.py suite updated for dict infos (terminal_observation masks, etc.) - 9 passed
  • Related vector tests (test_gym_vector, test_vector_dict, vec_env_test) - passed / skipped as before
pytest test/test_vector/test_pettingzoo_to_vec.py -o addopts=''

Fixes #249

MarkovVectorEnv (and concat/multiproc helpers) returned infos as a list
of per-env dicts. Gymnasium vector envs since v0.25 expect a dict of
arrays with boolean _key masks, so wrappers like RecordEpisodeStatistics
raise when used with pettingzoo_env_to_vec_env_v1 (e.g. CleanRL multi-
agent PPO).

Convert agent infos via list_infos_to_dict, merge concatenated vector
infos along the env axis, and convert back to a list only at the SB3
boundary. Also set autoreset_mode=SAME_STEP metadata to match the
existing same-step auto-reset behavior.

Fixes Farama-Foundation#249
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MarkovVectorEnv casts infos as a Python list throws error while training CleanRL's multi-agent PPO code

1 participant