Configs and Task Registry¶
A task is an EdenConfig subclass: one validated Pydantic object that holds every option group an environment is
built from. This page documents the config hierarchy, its serialization helpers, and the task registry that finds
configs by name. For how to write a task config, read the task configuration guide;
for variants and their CLI flags, read the TaskMods guide.
from eden.tasks import TASK_REGISTRY, TaskMod
from eden.utils.configs import EdenConfig, EdenMimicConfig, EdenRLConfig
Each config class pairs with exactly one environment class (EdenConfig with EnvBase, EdenRLConfig with
RLEnvBase, EdenMimicConfig with MimicRLEnvBase); a mismatch raises TypeError at construction. See
Environments.
Config hierarchy¶
EdenConfig
¶
Bases: ConfigurableOptions
Base configuration for all Eden environments (EnvBase).
| PARAMETER | DESCRIPTION |
|---|---|
env_options
|
Environment options (sim dt, num_envs, etc.).
|
scene_options
|
Scene options (entities, attachments).
|
observation_options
|
Observation manager options.
|
action_options
|
Action manager options.
|
event_options
|
Event manager options.
|
cameras_options
|
Cameras options.
|
sensors_options
|
Sensors options.
|
metric_options
|
Metric manager options.
|
recorder_options
|
Recorder manager options.
|
renderer_options
|
Renderer options.
|
language_instructions
|
Language instructions for the task.
|
Source code in eden/options/options.py
Attributes¶
observation_options
class-attribute
instance-attribute
¶
observation_options: ObservationManagerOptions = ObservationManagerOptions()
action_options
class-attribute
instance-attribute
¶
action_options: ActionManagerOptions | None = ActionManagerOptions()
event_options
class-attribute
instance-attribute
¶
event_options: EventManagerOptions = EventManagerOptions()
cameras_options
class-attribute
instance-attribute
¶
cameras_options: CamerasOptions | None = CamerasOptions()
sensors_options
class-attribute
instance-attribute
¶
sensors_options: SensorsOptions | None = SensorsOptions()
metric_options
class-attribute
instance-attribute
¶
metric_options: MetricManagerOptions | None = MetricManagerOptions()
recorder_options
class-attribute
instance-attribute
¶
recorder_options: RecorderManagerOptions | None = RecorderManagerOptions()
renderer_options
class-attribute
instance-attribute
¶
Methods:¶
check_bindings
¶
Raise if a field this config leaves for a :class:~eden.tasks.registry.TaskMod to fill is unset.
:meth:eden.envs.base.EnvBase.from_config calls this before it constructs the env. A task
whose robot (or data) binding lives in a TaskMod ships the robot-specific fields as empty
sentinels, and a config that reaches an env without the mod -- TASK_REGISTRY.get(name)(),
a subclass registered with modifiers=(), a subclass of an unregistered base -- otherwise
fails deep in env.build() on a pattern error that names neither the field nor the mod,
or does not fail at all where an empty link list resolves to no links. The base checks
nothing; a config with mod-bound fields overrides this to name them and the mod
(VelocityTrackingBaseConfig is the worked example).
Source code in eden/utils/configs.py
recording_camera
¶
recording_camera() -> CameraOptions
The camera a recording of this task renders, added as rec by :meth:add_recording_camera.
eden inference --rec adds it; so does any script that records the task and calls
:meth:add_recording_camera. A method rather than a cameras_options entry so that only a recording run
builds it: a camera in the training config costs every training run its setup (and whatever its overlays
allocate) though nothing renders it, and a checkpoint replays the config it was trained with. The default
follows the robot entity from 1.5 m out, which suits a locomoting robot; a task whose subject is
elsewhere, or whose recording paints state the scene does not render (a camera overlay,
:mod:eden.entities.camera_overlays), overrides it.
Source code in eden/utils/configs.py
add_recording_camera
¶
Add :meth:recording_camera to this config as its rec camera, in place, unless it already has one.
A rec camera the config already has (a cameras_options: {rec: {...}} override) is kept: replacing it
would silently discard the override. It replaces the task's camera whole, overlays included, so the overlays
it lacks are named in a warning.
Source code in eden/utils/configs.py
save_as_file
¶
Save the config as either JSON or YAML file with metadata envelope.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
The path to save the config.
TYPE:
|
lock_config
|
Whether to lock the config after saving to prevent further modifications.
TYPE:
|
Source code in eden/utils/configs.py
save_as_json
¶
Save the config as a JSON file with metadata envelope.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
The path to save the config. If not provided, the config will be saved to the log directory.
TYPE:
|
lock_config
|
Whether to lock the config after saving to prevent further modifications.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
Source code in eden/utils/configs.py
save_as_yaml
¶
Save the config as a YAML file with metadata envelope.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
The path to save the config. If not provided, the config will be saved to the log directory.
TYPE:
|
lock_config
|
Whether to lock the config after saving to prevent further modifications.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
Source code in eden/utils/configs.py
load_from_file
classmethod
¶
load_from_file(path: str) -> EdenConfig
Load the config from a JSON or YAML file, reconstructing its saved class.
The class the file was saved from is recorded in its metadata, so
EdenConfig.load_from_file("logs/.../config.json") returns the concrete task config
(ReacherConfig) rather than a bare EdenConfig — which is what makes a generic
loader like eden train --config <a saved config.json> work at all: a base
EdenConfig has nowhere to put reward_options and rejects the file outright.
cls still constrains the result: the saved class must be cls or a subclass of it,
so EdenMimicConfig.load_from_file(<a non-mimic config>) fails loud instead of quietly
handing back something that is not an EdenMimicConfig. Files with no class metadata
(legacy saves) load as cls.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
The path to load the config from.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EdenConfig
|
An instance of the saved class (a |
Source code in eden/utils/configs.py
load_from_data
classmethod
¶
load_from_data(data: dict, source: str = '<data>') -> EdenConfig
Reconstruct a saved config from already-read data — see :meth:load_from_file.
Split out so a caller that has to inspect the data before deciding what to do with it
(eden train --config, which reads :func:is_full_config to tell a full save from a
partial override) can reconstruct without reading the file a second time.
| PARAMETER | DESCRIPTION |
|---|---|
data
|
The file's contents, in either the
TYPE:
|
source
|
Where
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EdenConfig
|
An instance of the saved class (a |
Source code in eden/utils/configs.py
with_overrides_from_file
¶
with_overrides_from_file(path: str) -> EdenConfig
Create a new config by merging this config with values from a partial config file.
The current config is not modified.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
The path to the override file (.json, .yaml, or .yml).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EdenConfig
|
A new config instance based on this config with overrides applied. |
Source code in eden/utils/configs.py
EdenRLConfig
¶
Bases: EdenConfig
Configuration for RL environments (RLEnvBase).
Extends EdenConfig with reward, termination, command, curriculum, and runner options needed for reinforcement learning.
| PARAMETER | DESCRIPTION |
|---|---|
reward_options
|
Reward manager options.
|
termination_options
|
Termination manager options.
|
command_options
|
Command manager options.
|
curriculum_options
|
Curriculum manager options.
|
runner_options
|
Runner/training algorithm options. Framework-agnostic base type; use RslRlOnPolicyRunnerOptions, RlGamesPpoRunnerOptions, etc.
|
Source code in eden/options/options.py
Attributes¶
reward_options
class-attribute
instance-attribute
¶
reward_options: RewardManagerOptions | None = RewardManagerOptions()
termination_options
class-attribute
instance-attribute
¶
termination_options: TerminationManagerOptions | None = TerminationManagerOptions()
command_options
class-attribute
instance-attribute
¶
command_options: CommandManagerOptions | None = CommandManagerOptions()
curriculum_options
class-attribute
instance-attribute
¶
curriculum_options: CurriculumManagerOptions | None = CurriculumManagerOptions()
runner_options
class-attribute
instance-attribute
¶
runner_options: ConfigurableOptions | None = None
EdenMimicConfig
¶
Bases: EdenRLConfig
Configuration for motion imitation environments (MimicRLEnvBase).
Extends EdenRLConfig with motion manager options for motion imitation tasks.
| PARAMETER | DESCRIPTION |
|---|---|
motion_options
|
Motion manager options.
|
Source code in eden/options/options.py
Attributes¶
motion_options
class-attribute
instance-attribute
¶
motion_options: MotionManagerOptions | None = None
Gaussian-splat configs¶
Configs for environments that render a Gaussian-splat background (see Gaussian-splat environments).
EdenSplatConfig
¶
Bases: EdenConfig
Configuration for non-RL gaussian-splat environments (:class:~eden.envs.splat.SplatEnvBase).
A sibling of :class:EdenRLConfig (like :class:EdenNyxSplatConfig): a splat scene with no
reward/termination/command/curriculum surface — viewer / teleop / inference / data collection.
Whether the splat is rendered per-env or broadcast is a camera choice, not a config-leaf one
(see :class:~eden.options.splat.SplatOptions), so this leaf covers both single-env and batched
non-RL rendering. For RL training on a splat scene, use :class:EdenSplatRLConfig.
splat_options is a root field rather than a member of scene_options because it selects
the environment class — :func:~eden.envs.base.env_class_for_config dispatches on this config
type, and a field buried in the scene would leave the dispatcher unable to see it.
| PARAMETER | DESCRIPTION |
|---|---|
splat_options
|
Splat renderer options for photorealistic background rendering (shared / per-env Gaussians, minibatch, camera mode).
|
Source code in eden/options/options.py
Attributes¶
Methods:¶
recording_camera
¶
recording_camera() -> CameraOptions
:meth:EdenConfig.recording_camera with the splat composited behind empty space. A task whose splat
stands in for a sim surface (a table plane) overrides it to name that entity in the SplatComposite.
Source code in eden/utils/configs.py
EdenSplatRLConfig
¶
Bases: EdenRLConfig
Configuration for RL gaussian-splat environments (:class:~eden.envs.splat.SplatRLEnvBase).
The RL counterpart of :class:EdenSplatConfig: the same gsplat splat background plus the full
reward/termination/command/curriculum/runner surface of :class:EdenRLConfig. The env↔env
split mirrors EnvBase / RLEnvBase; the single-vs-batched rendering choice is orthogonal
and lives on the camera (:class:~eden.options.splat.SplatOptions.camera_mode).
| PARAMETER | DESCRIPTION |
|---|---|
splat_options
|
Splat renderer options for photorealistic background rendering (shared / per-env Gaussians, minibatch, camera mode).
|
Source code in eden/options/options.py
Attributes¶
Methods:¶
recording_camera
¶
recording_camera() -> CameraOptions
:meth:EdenConfig.recording_camera with the splat composited behind empty space, as for
:class:EdenSplatConfig.
EdenNyxSplatConfig
¶
Bases: EdenConfig
Configuration for Nyx path-traced splat environments (NyxSplatEnvBase).
A sibling of :class:EdenSplatConfig, mirroring the env classes: both render splats, but
through different backends with different options types. (Nyx has no batched path.)
| PARAMETER | DESCRIPTION |
|---|---|
splat_options
|
Nyx splat renderer options for path-traced background rendering.
|
Source code in eden/options/options.py
Attributes¶
Reading and converting config files¶
Eden config hierarchy (EdenConfig/EdenRLConfig/EdenMimicConfig) and serialization.
- :class:
EdenConfig— base config for all environments (EnvBase). - :class:
EdenRLConfig— adds reward, termination, command, curriculum, and runner options. - :class:
EdenMimicConfig— adds motion options for motion-imitation tasks.
Root config classes use Pydantic extra="forbid" (so misspelled fields raise), while
inner ManagerOptions / SceneOptions keep extra="allow" to hold dynamic
term/entity children. Saved configs use a _meta/config envelope; nested Options
recover their type from _option_module_ / _option_class_ keys.
The root config recovers its type the same way: :meth:EdenConfig.load_from_file reads the
saved class out of _meta and reconstructs that class, so a generic
EdenConfig.load_from_file(path) returns the concrete task config it was saved from.
The requested class still constrains the result — the saved class must be a subclass of it —
and files with no class metadata load as the requested class. Round-tripping a config through
save/load is therefore type-preserving and idempotent (pinned by
tests/utils/test_configs.py::test_every_task_config_round_trips_to_a_fixed_point).
Functions:¶
read_config_file
¶
Read a .json / .yaml / .yml config file into a raw dict.
The single file-reading primitive behind :meth:EdenConfig.load_from_file and
:meth:EdenConfig.with_overrides_from_file, so both dispatch on the extension the
same way and report an unsupported one identically.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
The path to read.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict
|
The file's contents, exactly as parsed — envelope and all, if it has one. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the extension is not |
Source code in eden/utils/configs.py
is_full_config
¶
Whether data is a saved config (replaces a base) rather than a partial override.
A save from :meth:EdenConfig.save_as_file carries its class and version tags — under a
_meta envelope, or (legacy flat saves) alongside the fields. A hand-written partial
override never does, which is what makes the two forms distinguishable by content instead
of by flag: eden train --config reads this to decide whether the file replaces the
task's config or layers onto it.
Source code in eden/utils/configs.py
saved_config_qualname
¶
The module.Class a saved config records, or None when it records no class.
Reads the same tags :meth:EdenConfig.load_from_data reconstructs from, without importing
anything — so a caller can compare identities (eden train --config, checking that a
saved config is the one its --task builds) and report a mismatch by name even when the
saved class is not importable here.
| PARAMETER | DESCRIPTION |
|---|---|
data
|
A saved config's contents, in either the
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str | None
|
The dotted qualname, or |
Source code in eden/utils/configs.py
overrides_from_str
¶
Parse one --override argument — an inline YAML (or JSON) mapping — into a dict.
YAML flow style keeps the shell-facing form short and quote-free
('env_options: {num_envs: 64}'); JSON is a subset, so the explicit form works too.
Note that PyYAML implements YAML 1.1 implicit typing, where off / no / yes
parse as booleans — quote any value that should stay a string.
| PARAMETER | DESCRIPTION |
|---|---|
text
|
The inline mapping.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict
|
The parsed override data, ready for :meth: |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
Source code in eden/utils/configs.py
serialize_obj_with_metadata
¶
Recursively serialize an object, capturing Options type metadata.
Captures _option_module_ and _option_class_ metadata from Options
instances. This works by using model_dump() for data but accessing actual
Option objects to extract their metadata.
NamedTuple values (e.g. Genesis TemperatureProperties) subclass tuple and are
serialized as plain lists of fields in field order; to_options reconstructs them
using the surrounding Pydantic field annotations on load.
Source code in eden/utils/configs.py
get_options_class_from_qualname
¶
get_options_class_from_qualname(qualname: str)
Dynamically import and retrieve an Options class from its fully qualified name.
| PARAMETER | DESCRIPTION |
|---|---|
qualname
|
The fully qualified name of the Options class (e.g., "eden.options.managers.actions.ActionTermOptions")
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Type[Options]
|
The Options class |
| RAISES | DESCRIPTION |
|---|---|
ImportError
|
If the module cannot be imported |
AttributeError
|
If the class cannot be found in the module |
Source code in eden/utils/configs.py
to_options
¶
Reconstruct the original Options instance from serialized data.
Eden options (config root classes included) are rebuilt with validation, so an unknown key on
an extra="forbid" class raises, while extra="allow" classes (ManagerOptions,
SceneOptions, etc.) keep unknown keys as their dynamic term/entity children. Genesis-native
options skip validation, and an extra="forbid" one drops unknown keys with a warning — see
:func:_safe_model_construct.
| PARAMETER | DESCRIPTION |
|---|---|
config
|
The serialized field data.
TYPE:
|
base_options
|
The target type, as either a class or an instance to take the class of. Only the
type is read, so pass the class when there is nothing to instantiate it from —
a task config's
TYPE:
|
Source code in eden/utils/configs.py
Task registry¶
Tasks register themselves with @TASK_REGISTRY.register() on the config class. The registry scans the source of
eden.tasks (and of every package an installed distribution names under the eden.tasks entry-point group) on
first lookup without importing it, so there is no central index to update. TASK_REGISTRY.build(name, **kwargs)
returns a configured instance with the task's TaskMods applied, which is what eden train does;
TASK_REGISTRY.get(name) returns the bare class, and instantiating that yourself skips every mod.
TaskRegistry
¶
Task registry with two lookup paths, tried in order.
- Eager registry — populated by
@TASK_REGISTRY.register()decorators or explicitregister(cls, ...)calls. - Auto-discovery — an AST scan of the configured search packages (default
["eden.tasks"]) finds@TASK_REGISTRY.register()decorators in every*.pyfile without importing them. On first :meth:getmiss we import only the one file that matches the requested name; that triggers the decorator and populates the eager registry.
Tasks self-register at the definition site — no central index in
eden/tasks/__init__.py to keep in sync. Out-of-tree tasks join the
scan through the :data:TASK_ENTRY_POINT_GROUP entry point of the
distribution that ships them, so eden list / eden train --task
see them without importing anything; a script can also call
:meth:add_search_path before its first lookup.
Auto-discovery rules (files that are NOT scanned):
__init__.pyis skipped — put decorated classes in a sibling module such asconfig.py.- files whose name starts with
_are skipped (e.g._meta.py) — private modules are treated as implementation details.
Auto-discovery rules (decorator recognition):
- The scan recognizes
@<name>.registerwhere<name>is bound, in the same file, toTASK_REGISTRYvia an absolute import fromeden.tasksoreden.tasks.registry(from ... import TASK_REGISTRYor... as X). Both forms work. - Using the literal name
TASK_REGISTRYwithout importing it from a recognized location emits a warning — the scan will not silently miss the registration.
Usage::
# Preferred: decorator at definition site; modifiers passed to the
# decorator so they live on the registry (not on the config class,
# which is a Pydantic model and should only hold serializable schema).
@TASK_REGISTRY.register(modifiers=(ReacherDifficultyMod,))
class ReacherConfig(EdenRLConfig):
...
cfg = TASK_REGISTRY.build("reacher", difficulty="hard") # a configured instance, mods applied
cls = TASK_REGISTRY.get("reacher") # the bare class; cls() runs no mod
Source code in eden/tasks/registry.py
Methods:¶
register
¶
register(obj: Any = None, *, name: str | None = None, override: bool = False, modifiers: tuple[ModifierEntry, ...] | None = None) -> Any
Register a config class eagerly. Can be used as a decorator or function call.
| PARAMETER | DESCRIPTION |
|---|---|
obj
|
The config class to register. When
TYPE:
|
name
|
Lookup name. Defaults to
TYPE:
|
override
|
If
TYPE:
|
modifiers
|
Sequence of TaskMod instances (preferred) or bare TaskMod
subclasses (auto-instantiated with no args). Applied in order by
:meth:
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
Source code in eden/tasks/registry.py
add_search_path
¶
add_search_path(package: str) -> None
Register an additional package root to AST-scan for decorated tasks.
Only the process that calls it sees the package, so it suits a script that does its own lookups::
from eden.tasks import TASK_REGISTRY
TASK_REGISTRY.add_search_path("my_project.tasks")
For the eden CLI to see an installed project's tasks, name the package under the
:data:TASK_ENTRY_POINT_GROUP entry-point group in the project's pyproject.toml
instead. A package that cannot be found is skipped, unlike a broken entry point.
Source code in eden/tasks/registry.py
get
¶
Get a config CLASS by name.
Resolution order: eager registry → auto-discovery. The returned object
is the bare config class, so get(name)() runs none of the task's
registered TaskMods. For a task whose robot binding lives in a mod,
that yields a config that constructs and serializes without
complaint and then fails in env.build() on an empty link name — an
error that says nothing about modifiers.
Use :meth:build to obtain a configured instance; reach for get
only when the class itself is what you want (issubclass checks,
subclassing, matching a loaded config's type).
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
RuntimeError
|
If |
KeyError
|
If |
Source code in eden/tasks/registry.py
get_modifiers
¶
Resolve and return the TaskMod instances associated with name.
Modifiers live on the registry itself (not on the config class),
attached via register(modifiers=...). For decorator-registered
tasks the decorator's modifiers= tuple is populated when the
module is imported, so we call :meth:get first to ensure that
import has happened. A registration that inherits its modifiers
resolves them here, against the registry as it stands now.
Source code in eden/tasks/registry.py
modifier_names
¶
Modifier display-names for name without importing its module.
Unlike :meth:get_modifiers (which imports the task to return live
instances), this is purely informational — used by eden list so a
read-only listing never triggers a task-module import and the asset
downloads that can ride along. Prefers modifier instances already
attached (eager registrations / already-loaded tasks) for exactness,
an inherited registration included — resolving one reads the other live
registrations, which needs no import either. Otherwise falls back to the
identifier names captured from the @register(modifiers=...) decorator
during AST auto-discovery — for a decorator without modifiers=, the
ones its base class's decorator names, since that is what registering it
inherits. A listing renders rather than raises, so an inherited
registration left ambiguous by a later one falls back here too; the
error still belongs to :meth:get_modifiers and :meth:build, which
are what a caller acts on.
Source code in eden/tasks/registry.py
build
¶
Instantiate the config and apply registered TaskMods.
Modifier kwargs are flat and use each mod's prefixed field names
(see :meth:TaskMod.flag_for). For an unprefixed mod that exposes
difficulty, pass difficulty=...; for an instance registered
with prefix="left" that exposes robot, pass left_robot=....
Collisions — two mods that would claim the same flag — raise
ValueError at build time with both owners listed. Unknown kwargs
raise ValueError with the list of accepted flags.
Source code in eden/tasks/registry.py
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 | |
list_tasks
¶
List all registered task names (eager + discovered).
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If a task name is registered in several scanned files. |
RuntimeError
|
If an installed :data: |
Source code in eden/tasks/registry.py
config_qualname_for_task
¶
The module.Class of the config name builds, or None if no such task.
The forward direction of :meth:task_for_config_qualname, and import-free for the same
reason — eager entries are already in memory, discovered-only entries carry the
module:Class string the AST scan recorded — so a caller can ask "is this saved config
the one --task builds?" without importing the task module. The replay path
(eden inference / eden deploy) never needs that module: it loads the checkpoint's
own config, and only wants the identity.
Prefer this over reversing :meth:task_for_config_qualname whenever the question is about
a named task. Nothing stops one config class being registered under two names (aliases
are ordinary here — :meth:register keys on name alone), and the reverse lookup
returns only the first of them, so an alias would read as a mismatch.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Registered task name.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str | None
|
The dotted qualname, or |
Source code in eden/tasks/registry.py
task_for_config_qualname
¶
The task whose config class is module.Class, or None if no task owns it.
The reverse of :meth:get, and deliberately import-free: eager entries are already
in memory, and discovered-only entries are matched against the module:Class string
the AST scan recorded. Calling :meth:get in a loop instead would import every task
module in the tree — and could raise out of an unrelated one — which is the wrong trade
for a lookup whose caller is building an error message.
| PARAMETER | DESCRIPTION |
|---|---|
qualname
|
Dotted
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str | None
|
The task name, or |
Source code in eden/tasks/registry.py
task_source
¶
Where the config name builds comes from, as eden list shows it.
"eden" for a built-in, the distribution's name for a task found through its
:data:TASK_ENTRY_POINT_GROUP entry point, the package for one under a package passed to
:meth:add_search_path, and the defining module for a class registered from anywhere else
— so a built-in name shadowed by a register(..., override=True) reads as the module
that shadowed it. Import-free, like :meth:config_qualname_for_task, which it reads.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
Registered task name.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
str | None
|
The source label, or |
Source code in eden/tasks/registry.py
missing_task_message
¶
The message for a miss on name: a close match, every task there is, and where to declare one.
The text of :meth:get's KeyError (so one line), for a caller that reports a miss its own way,
as eden's --task check does. Unlike :meth:list_tasks, it lists what the scan resolved
even while another name clashes or a plugin is broken, since those are reported where they
are looked up, and the reader here needs the name they mistyped. It raises only what the scan
itself does (a search-path package whose parents fail to import), and nothing once a lookup
has scanned.
Source code in eden/tasks/registry.py
TaskMod
¶
Tool that modifies an EdenConfig instance.
TaskMod is a plain Python class (not a Pydantic model) because it is
logic with a few parameters, not user-facing data. EdenConfig is the
Pydantic data model; TaskMod operates on it.
To define one: subclass, declare CLI-tunable parameters as
positional-or-keyword __init__ arguments with type annotations,
and implement :meth:apply. Non-CLI constructor state goes in
keyword-only parameters (after *) — the CLI introspection skips
those.
Quick reference (this is the convention agents miss most often)::
def __init__(
self,
difficulty: Literal["easy", "hard"] = "easy", # ← CLI flag (--difficulty)
*,
entity_name: str = "robot", # ← non-CLI ctor state
):
self.difficulty = difficulty
self.entity_name = entity_name
Calling super().__init__() is optional — TaskMod keeps no
instance state of its own; _prefix is a class-attribute default that
:meth:with_prefix shadows on assignment. So your subclass __init__
can just store its parameters and return.
For per-field CLI --help text, wrap the annotation in
typing.Annotated[T, "help text"]. The string metadata is forwarded
to argparse; the inner type is what drives validation::
difficulty: Annotated[Literal["easy", "hard"], "Task difficulty preset."] = "easy"
Implement :meth:apply to return the modified config; in-place mutation
is fine because :meth:TaskRegistry.build calls cls() fresh on every
build (and Pydantic deep-copies the config's BaseModel defaults per
instance), so mutations do not leak across builds.
Modifiers attach to a task by passing instances to
@TASK_REGISTRY.register(modifiers=(...)) (a bare subclass is accepted
and instantiated with no args). Modifiers are stored on the registry,
not on the config class. A config registered without modifiers=
inherits them from its nearest registered base class; modifiers=()
opts out (see :meth:TaskRegistry.register).
Per-instance scoping: chain :meth:with_prefix on a constructed instance
so its CLI flags rename from <field> to <prefix>_<field>. The same
subclass can be registered multiple times with distinct prefixes.
Example
::
from typing import Annotated, Literal
class RobotMod(TaskMod):
def __init__(
self,
robot: Annotated[
Literal["allegro", "shadow", "xhand1"],
"Hand model to load into the scene.",
] = "xhand1",
*,
entity_name: str = "robot", # keyword-only → not CLI-exposed
):
self.robot = robot
self.entity_name = entity_name
def apply(self, config):
setattr(config.scene_options, self.entity_name, ROBOT_REGISTRY.get(self.robot)())
return config
@TASK_REGISTRY.register(modifiers=(
RobotMod(robot="shadow", entity_name="robot_left").with_prefix("left"),
RobotMod(entity_name="robot_right").with_prefix("right"),
))
class TwoArmTask(EdenRLConfig):
...
# CLI: --left_robot shadow --right_robot xhand1
TASK_REGISTRY.build("two_arm_task", left_robot="allegro", right_robot="shadow")
Attributes¶
Methods:¶
with_prefix
¶
with_prefix(prefix: str) -> 'TaskMod'
Set this instance's CLI/kwarg prefix and return self for chaining.
Chain at registration time::
RobotMod(entity_name="robot_left").with_prefix("left")
Source code in eden/tasks/registry.py
flag_for
¶
Return the CLI/build-kwarg name for a field on this instance.
With a non-empty :attr:prefix, returns f"{prefix}_{field_name}";
otherwise returns field_name unchanged.
Source code in eden/tasks/registry.py
Command-line parsing¶
The helpers the task commands (eden train, eden inference, ...) use to turn --task, TaskMod flags and config
overrides into a config instance.
CLI helpers for building task configs from argparse.
This module wires :class:~eden.tasks.registry.TaskMod parameters into a
standard argparse.ArgumentParser so that user-facing scripts can accept
flat flags (--difficulty hard, --robot g1) that are translated into
typed mod kwargs and applied via :meth:TaskRegistry.build.
Functions:¶
get_task_argparser
¶
get_task_argparser(description: str, default_task_name: str = '', argv: list[str] | None = None) -> ArgumentParser
Build an ArgumentParser with standard flags plus the selected task's mod flags.
The selected task is determined by pre-parsing --task from argv
(defaults to sys.argv[1:]). Modifier flags are added only for the
selected task, so --help shows only the relevant options. Pass
argv explicitly when invoking this from a wrapper that already has
its own arg slice (e.g. the eden train / eden inference
subcommands forward extra_args) so the peek and the final parse
agree on input.
Source code in eden/tasks/parser.py
get_task_config
¶
get_task_config(task_name: str, *, run_name: str = '', modifier_kwargs: dict[str, Any] | None = None, config_path: str | None = None, config_overrides: Sequence[dict[str, Any]] | None = None) -> Any
Build a task config programmatically.
:meth:TaskRegistry.build, then — in this order, later winning — an optional
config_path file and any config_overrides dicts, then a sanitized run_name
written to runner_options if present.
| PARAMETER | DESCRIPTION |
|---|---|
task_name
|
Registered task to build.
TYPE:
|
run_name
|
Run name to write onto
TYPE:
|
modifier_kwargs
|
TaskMod kwargs forwarded to :meth: |
config_path
|
A
TYPE:
|
config_overrides
|
Override dicts applied on top of everything else, in order — the |
| RETURNS | DESCRIPTION |
|---|---|
Any
|
The task's config instance. |
Source code in eden/tasks/parser.py
get_task_config_from_args
¶
Build a task config from an argparse Namespace produced by :func:get_task_argparser.
Source code in eden/tasks/parser.py
overrides_from_args
¶
Parse the repeated --override arguments on args, in the order given.
read_config_arg
¶
Read the --config argument — :func:read_config_file plus the CLI's own redirect.
The two flags each take what the other rejects, so each names the other when handed it:
--override <a path> already points at --config, and this is the mirror. The
redirect fires on a positive identification — the value is something --override
itself would accept — not on a guess about the string, so a genuine path with the wrong
extension (or unreadable contents) still gets the plain message.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
The
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict
|
The file's contents, as :func: |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
Naming |
Source code in eden/tasks/parser.py
explicit_task_mods
¶
Return the -- flags for task mods set away from their default.
The comparison baseline is getattr(mod, field_name) — the mod instance's value,
which is exactly what :func:_add_mod_field_to_parser uses as the argparse default (not
the __init__ signature default, which can differ when a task registers a mod with an
overridden instance value). So a flag left unset — or passed at its default — reads as
not explicitly set.
Used to fail fast wherever mods collide with a config that is authoritative on its own
(a saved --config, a checkpoint's sibling config.json) and would otherwise be
silently ignored.
| PARAMETER | DESCRIPTION |
|---|---|
task_name
|
The registered task whose mods to compare against.
TYPE:
|
modifier_kwargs
|
Flag-keyed mod values, as produced by :func: |
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
The dash-prefixed flag names that differ from their default. |