Core¶
The environment base classes and their result types. See the Environments, Wrappers and Multi-agent guides.
Environments¶
Env
¶
Bases: SeededRNG, ABC, Generic[ObsType, ActType]
Abstract base class for all sekai environments.
Subclasses must
- Set self.observation_space and self.action_space in
__init__ - Implement reset() and step()
Unlike gym/gymnasium: - step() returns a StepResult dataclass, not a 5-tuple - reset() returns a ResetResult dataclass, not a 2-tuple - async_step() and async_reset() are available on all envs by default - render() is NOT part of this interface; use a Renderer object
If a subclass overrides step() (or reset()) without also overriding
async_step() (or async_reset()), the async method is routed through the
sync one. This keeps await env.async_step(a) from silently skipping
logic that only lives in step(), e.g. in a custom wrapper. (A wrapper that
only overrides step() therefore makes async calls through it synchronous;
override async_step() too to keep an async-native env async end to end.)
reset
abstractmethod
¶
reset(*, seed: SeedType = None, options: dict[str, Any] | None = None) -> ResetResult[ObsType]
Reset the environment and return the initial observation.
Call self._set_rng(seed) first thing so seeding behaves consistently: an int seed re-seeds the env's RNG, None continues the current stream.
async_reset
async
¶
async_reset(*, seed: SeedType = None, options: dict[str, Any] | None = None) -> ResetResult[ObsType]
MultiAgentEnv
¶
Bases: SeededRNG, ABC, Generic[ObsType, ActType, AgentID]
Abstract base class for multi-agent environments.
Each agent gets its own typed observation and action space, supporting heterogeneous multi-agent setups (e.g. a portfolio manager agent + a risk manager agent with different obs/action spaces).
agents: currently active agents (may shrink as agents terminate) possible_agents: universe of all possible agent IDs
Seeding works as for Env: call self._set_rng(seed) at the start of reset() and draw randomness from self.rng.
reset
abstractmethod
¶
reset(*, seed: SeedType = None, options: dict[str, Any] | None = None) -> MAResetResult[ObsType, AgentID]
async_reset
async
¶
async_reset(*, seed: SeedType = None, options: dict[str, Any] | None = None) -> MAResetResult[ObsType, AgentID]
Wrappers¶
Wrapper
¶
Wrapper(env: Env[ObsType, ActType])
Bases: Env[WObsType, WActType], Generic[WObsType, WActType, ObsType, ActType]
Transparent wrapper around an Env.
All method calls are delegated to the wrapped env by default. Override only the methods you need to change.
Improvements over gymnasium
__iter__/__len__let you inspect the full wrapper stack- Async methods are transparently delegated
- _observation_space / _action_space overrides are lazy
If you override step() but not async_step(), async_step() calls your step(), so your logic is never bypassed. Override both to keep the inner env's async path end-to-end.
Results¶
StepResult
dataclass
¶
Bases: Generic[ObsType]
Structured result from Env.step().
Replaces the error-prone 5-tuple (obs, reward, terminated, truncated, info) pattern from gym/gymnasium.
ResetResult
dataclass
¶
Bases: Generic[ObsType]
Structured result from Env.reset().
done is always False, so one loop handles both result types:
MAStepResult
dataclass
¶
MAStepResult(observations: dict[Any, ObsType], rewards: dict[Any, float], terminated: dict[Any, bool], truncated: dict[Any, bool], info: dict[Any, InfoDict])
Bases: Generic[ObsType, AgentID]
Structured result from MultiAgentEnv.step().
all_done / any_done look at every agent that appears in terminated or
truncated, matched by agent ID; an agent missing from one of the dicts counts as
not terminated (or not truncated) there. With no agents in either dict, both are False.