Skip to content

Registry

Resolve an alias to a canonical robot, list robots by category, inspect a provider entry, add your own.

The registry is strands_robots/registry/robots.json and policies.json, read through the functions below: resolve an alias to a canonical robot name, list robots by category, inspect a provider entry, add your own robot without editing the package.

Robots

Robot registry - query, resolve, and list robot definitions.

All robot definitions live in robots.json. This module provides the public read API; the JSON file is the only thing you edit to add or modify robots.

resolve_name

resolve_name(name: str) -> str

Resolve a robot name or alias to the canonical name.

Parameters:

Name Type Description Default
name str

Any robot name, alias, or data_config string.

required

Returns:

Type Description
str

Canonical robot name (e.g. "so100", "panda", "unitree_g1").

Examples::

resolve_name("franka")        # → "panda"
resolve_name("SO100_follower") # → "so100"
resolve_name("g1")            # → "unitree_g1"

get_robot

get_robot(name: str) -> dict[str, Any] | None

Get full robot definition by name or alias.

Parameters:

Name Type Description Default
name str

Robot name, alias, or data_config.

required

Returns:

Type Description
dict[str, Any] | None

Robot dict with keys like description, category, joints, asset,

dict[str, Any] | None

hardware - or None if not found. A robot_descriptions URDF-only

dict[str, Any] | None

robot (see :func:~strands_robots.registry.discovery.list_urdf_only)

dict[str, Any] | None

gets a synthesized entry with source: "urdf"; a curated entry

dict[str, Any] | None

always wins over it.

list_robots

list_robots(mode: str = 'all') -> list[dict[str, Any]]

List available robots, optionally filtered.

Parameters:

Name Type Description Default
mode str

Filter, one of :data:LIST_ROBOTS_MODES:

  • "all": every registered robot (no filter).
  • "sim": robots Robot(name) can simulate (has_sim); an auto_download: false entry is listed once its asset is on disk.
  • "real": robots declaring a hardware backend (has_hardware). Every robot a shipped driver builds declares one, so this matches :func:~strands_robots.drivers.list_driver_coverage; a driver registered at runtime without a declaration shows only there.
  • "both": robots that have BOTH sim and real.
'all'

Returns:

Type Description
list[dict[str, Any]]

List of dicts with name, aliases, description, category, joints,

list[dict[str, Any]]

has_sim, has_real and source. aliases is every spelling

list[dict[str, Any]]

func:list_aliases maps to the row (sorted, empty for a robot that

list[dict[str, Any]]

declares none), so Robot("g1") is traceable to its

list[dict[str, Any]]

unitree_g1 row. source is "curated" for a robots.json

list[dict[str, Any]]

entry and "urdf" for a robot_descriptions URDF-only robot the MuJoCo

list[dict[str, Any]]

backend compiles on first use; a URDF robot whose description does

list[dict[str, Any]]

not build is listed with has_sim false.

Raises:

Type Description
ValueError

If mode is not one of :data:LIST_ROBOTS_MODES. An unrecognized filter is rejected loudly instead of silently returning the full, unfiltered list.

list_robots_by_category

list_robots_by_category() -> dict[str, list[dict[str, Any]]]

Group every registered robot under the category name it is listed by.

A group name is something a caller switches on and a reader sees in a table cell, so every group here has one. A robot whose registry entry declares no category - category is optional in both the package registry and the user overlay, and :func:register_robot accepts category="" - is grouped under "other", and a declared name is stripped of surrounding whitespace so a padded spelling joins its own group instead of opening a blank-looking second one beside it. :func:list_robots still reports each robot's category exactly as the entry declares it; the normalization is this grouping's, not the registry's.

Returns:

Type Description
dict[str, list[dict[str, Any]]]

Group name to the :func:list_robots records in it. Every robot appears

dict[str, list[dict[str, Any]]]

in exactly one group, so the group sizes sum to len(list_robots()).

list_aliases

list_aliases() -> dict[str, str]

Return the full alias → canonical mapping.

joint_labels

joint_labels(name: str) -> dict[str, str]

Meaningful names for a robot's simulation joints, {joint: label}.

Some assets name their joints by servo id (SO-101: 1..6) or by CAD term (SO-100: Rotation, Jaw), while the same arm's driver and LeRobot datasets speak shoulder_pan .. gripper. The registry's optional joint_labels block bridges the two so an agent can address a joint by what it does. Returns {} for an unknown robot or one that declares no labels.

Parameters:

Name Type Description Default
name str

Robot name, alias, or data_config.

required

Returns:

Type Description
dict[str, str]

Mapping from the asset's joint name (as get_robot_state reports it,

dict[str, str]

without the robot namespace) to its label.

has_sim

has_sim(name: str) -> bool

Check if Robot(name) can obtain a simulation model (MJCF/URDF).

An entry declaring auto_download: false is never fetched, so it counts only once its model file is on disk; any other asset entry is downloaded on first use. A pure filesystem check - no download, no network.

has_hardware

has_hardware(name: str) -> bool

Check if a robot declares a real-hardware backend.

Reads the registry entry's hardware block, which has two independent fields: lerobot_type names a lerobot robot type, and driver names which driver builds the robot. Either alone is a hardware declaration -- the Reachy Mini and the Microduck declare only a driver, because lerobot has no robot type for them at all -- so this reads the block rather than one field of it.

A robot may be drivable without declaring anything: a native driver registered through :func:~strands_robots.drivers.register_native_driver needs no registry declaration (every driver shipped here declares one; a driver package outside this one may not). Declaration and registration are two different facts and this predicate reports only the first, because it is the one a caller can read without importing a driver package. :func:~strands_robots.drivers.list_driver_coverage joins both and is what answers "can this robot be driven for real" completely.

Parameters:

Name Type Description Default
name str

Robot name, alias, or data_config.

required

Returns:

Type Description
bool

True when the robot's registry entry carries a hardware block,

bool

False when it does not or the robot is not registered at all.

get_driver

get_driver(name: str) -> str | None

Get the driver a robot declares, verbatim, or None if it declares none.

A pure reader, like its sibling :func:get_hardware_type: it reports what the registry says and applies no default. hardware.driver is optional and most robots declare none. Where it is declared it says which of two possible drivers wins: one declarer has no lerobot robot type at all, so the native driver is the only one that can build it; the other has a working lerobot type and prefers its native driver anyway.

An absent declaration therefore means "no preference", not "no native driver" - a robot may have one registered and declare nothing, in which case the default still routes to lerobot. Deciding what an absent - or "auto" - declaration means is :func:~strands_robots.drivers.resolve_driver's job, which is also where a caller's explicit choice outranks the registry.

Parameters:

Name Type Description Default
name str

Robot name, alias, or data_config.

required

Returns:

Type Description
str | None

The declared driver name, or None when the robot declares no driver

str | None

(or is not registered at all).

get_hardware_type

get_hardware_type(name: str) -> str | None

Get the LeRobot hardware type for a robot.

Returns:

Type Description
str | None

LeRobot type string (e.g. "so100_follower"), or None.

format_robot_table

format_robot_table(max_width: int = 100) -> str

Human-readable table of all robots for CLI/tool output.

The Sim and Real columns hold the ASCII token "yes" when the robot declares that mode and are left blank otherwise. Real reads the registry's hardware block, the same declaration :func:has_hardware reports: a robot a native driver can build without declaring one is left blank here, and :func:~strands_robots.drivers.list_driver_coverage is what answers "can this robot be driven for real" completely. The output is pure ASCII so it aligns correctly in any monospace terminal and is safe to embed in logs and tool responses.

Parameters:

Name Type Description Default
max_width int

Target terminal width. The Description column is truncated with an ellipsis to fit. Pass a large value (e.g. 1000) to disable truncation entirely. Default 100 is safe for a typical 100-column terminal.

100

Returns:

Type Description
str

Multi-line string: a header row, a rule, one row per robot grouped

str

by category (common categories first, then any custom categories in

str

sorted order), then a totals footer. Every registered robot gets

str

exactly one row, so the body row count always matches the footer

str

Total.

Loader

JSON registry loader with content-keyed hot-reload and validation.

Loads robots.json and policies.json from the registry directory, re-reading only when the on-disk source changes. Validates uniqueness of aliases, shorthands, and URL patterns on every reload.

The robots registry is not a single file: its effective contents are the package robots.json merged with the user-local overlay ($STRANDS_BASE_DIR/user_robots.json, read through :mod:._overlay - see :func:_merge_user_robots). The hot-reload signature therefore covers both files, so an edit to the user overlay made outside this process (a second process, a manual edit, or any writer that does not call :func:invalidate_cache) is picked up on the next read - honoring the "re-read when the source changes" contract for the overlay just as for the package file.

The signature is the file contents, not a stat. A timestamp cannot express "the source changed": the kernel stamps st_mtime from a coarse clock, so two writes inside one tick share a timestamp and the second one is invisible - permanently, because that timestamp never changes again. The bytes are the only field that always differs when the contents differ, so a cached value is served only while the file still holds the bytes it was parsed from. The read is what licenses the hit; the parse and validation are the work it saves.

normalize_robot_name

normalize_robot_name(name: str) -> str

Fold a robot name or alias to the key every registry lookup uses.

One rule, spelled once: lowercase, trim surrounding whitespace, and read a dash as an underscore. It is the rule :func:~strands_robots.registry.robots.resolve_name applies to a caller's query, so it is also the rule the things a query is matched against have to be keyed by - a canonical robot name (normalized by :func:~strands_robots.registry.user_registry.register_robot), an alias (keyed by :func:~strands_robots.registry.robots._build_alias_map), and the uniqueness constraints :func:_validate_robots enforces over both. A consumer that folds while a producer or a validator does not is how "Franka-Panda" becomes a lookup nobody can satisfy, or worse, one that lands on a different robot. A user_robots.json key that is not already its own fold is refused when the registry loads, naming the spelling to rename it to.

Parameters:

Name Type Description Default
name str

A robot name or alias, in any spelling.

required

Returns:

Type Description
str

The lookup key for name.

Raises:

Type Description
ValueError

name is not a string. Every registry read (get_robot, resolve_name, has_sim, ...) folds its argument here first, so this is the one place a non-name is refused.

reload

reload() -> None

Force-reload all registry files (clears the cached sources).

invalidate_cache

invalidate_cache(name: str | None = None) -> None

Invalidate cached registry data, forcing a reload on next access.

Parameters:

Name Type Description Default
name str | None

Registry name to invalidate (e.g. "robots"). If None, clears all.

None

Discovery through robot_descriptions

Auto-discovery of robots from the optional robot_descriptions package.

The curated registry (robots.json) deliberately carries only robots that need project-specific metadata: hardware ports, custom joint counts, scene tweaks, aliases, or local mesh overrides. The much larger long tail of standard robots shipped by robot_descriptions (MuJoCo Menagerie and friends) does not need a hand-written entry - this module resolves those on demand so Robot("go2", mode="sim") works without touching robots.json.

Resolution rules
  • A curated robots.json entry always wins. Discovery is consulted only for names unknown to the curated registry (see :func:strands_robots.registry.get_robot).
  • Curated-registry / MJCF discovery (descriptions_module, list_discoverable, discover_robot) is MJCF-only: the MuJoCo backend and the curated registry need an .xml model.
  • URDF discovery (urdf_descriptions_module, list_urdf_discoverable, discover_urdf_path) is a parallel surface for URDF-native backends (Newton via ModelBuilder.add_urdf). It covers the large URDF-only long tail that MJCF discovery cannot (humanoids, quadrupeds, hands).
  • The MuJoCo backend reaches that same long tail through :func:discover_robot: a name with a URDF description and no MJCF one gets an entry whose asset.source.type is "urdf", and :mod:strands_robots.assets.urdf compiles the URDF into robot.xml + scene.xml on first resolution (:func:list_urdf_only names them).
  • :func:descriptions_module, :func:is_discoverable, and :func:list_discoverable are cheap - a static dict lookup with no module import and no network. :func:discover_robot is heavy: importing a description module makes robot_descriptions clone the upstream asset repository on first use, so it is called only from asset-resolution paths that are already allowed to download.

is_discoverable

is_discoverable(name: str) -> bool

Return True if name resolves from robot_descriptions (cheap).

list_discoverable

list_discoverable() -> list[str]

Return sorted canonical names resolvable from robot_descriptions.

This is the MJCF long tail - the standard robots that work in the MuJoCo backend without a curated robots.json entry (e.g. go2, spot, h1, anymal_c, cassie). Cheap: no import, no network.

discover_robot

discover_robot(name: str) -> dict[str, Any] | None

Synthesize a registry entry for name from robot_descriptions.

Heavy: imports the description module, which makes robot_descriptions clone the upstream asset repository on first use. Call only from asset-resolution paths that are allowed to download. Results (including misses) are cached.

Parameters:

Name Type Description Default
name str

Robot name or alias (e.g. "go2").

required

Returns:

Type Description
dict[str, Any] | None

A registry-style entry with the same shape as a robots.json value -

dict[str, Any] | None

an asset block wired to the resolved robot_descriptions module -

dict[str, Any] | None

or None if the robot is not an MJCF-capable robot_descriptions

dict[str, Any] | None

robot.

descriptions_module

descriptions_module(name: str) -> str | None

Return the MJCF robot_descriptions module for name, or None.

Cheap: a dict lookup against the static description table, with no module import and no network. Returns None when the robot is not an MJCF-capable robot_descriptions robot or when the package is missing.

Examples::

descriptions_module("go2")   # -> "go2_mj_description"
descriptions_module("so100") # -> None (curated, not a description)

is_urdf_discoverable

is_urdf_discoverable(name: str) -> bool

Return True if name resolves to a URDF robot_descriptions model.

list_urdf_discoverable

list_urdf_discoverable() -> list[str]

Return sorted canonical names resolvable to a URDF from robot_descriptions.

This is the URDF long tail consumable by URDF-native backends (Newton). It includes robots with no MJCF model at all (e.g. atlas_v4, baxter, b1), which is why it is disjoint from :func:list_discoverable for those entries. Cheap: no import, no network.

discover_urdf_path

discover_urdf_path(name: str) -> str | None

Resolve the on-disk URDF path for name via robot_descriptions.

Heavy: imports the description module, which makes robot_descriptions clone the upstream asset repository on first use. Call only from asset-resolution paths that are allowed to download.

Parameters:

Name Type Description Default
name str

Robot name or alias (e.g. "panda").

required

Returns:

Type Description
str | None

Absolute path to the URDF file, or None when name is not a

str | None

URDF-capable robot_descriptions robot, the module cannot be

str | None

imported, or it exposes no readable URDF_PATH.

urdf_descriptions_module

urdf_descriptions_module(name: str) -> str | None

Return the URDF robot_descriptions module for name, or None.

Cheap: a dict lookup against the static description table, with no module import and no network. Returns None when name is not a URDF-capable robot_descriptions robot or when the package is missing.

Examples::

urdf_descriptions_module("panda")    # -> "panda_description"
urdf_descriptions_module("atlas_v4") # -> "atlas_v4_description"
urdf_descriptions_module("so100")    # -> None (curated, not a description)

User robots

User-local robot registry - runtime registration without editing package JSON.

Provides register_robot() and unregister_robot() for adding custom robots that persist across sessions via a user_robots.json file stored alongside the asset cache.

File location (in priority order): 1. $STRANDS_BASE_DIR/user_robots.json 2. ~/.strands_robots/user_robots.json

Note

STRANDS_ASSETS_DIR only controls where assets live, not the user registry. Use STRANDS_BASE_DIR to relocate user metadata.

At load time the user overlay is merged on top of the package robots.json - user entries win on name collision, so you can also override built-in robots locally.

Usage::

from strands_robots.registry import register_robot, unregister_robot

# Register a custom robot with MJCF
register_robot(
    name="my_arm",
    model_xml="my_arm.xml",
    description="My custom 6-DOF arm",
    category="arm",
    joints=6,
    asset_dir="my_arm",  # resolved relative to assets dir
)

# Now works everywhere:
from strands_robots.simulation import create_simulation
sim = create_simulation()
sim.create_world()
sim.add_robot("my_arm")   # auto-resolved

# Remove it
unregister_robot("my_arm")

register_robot

register_robot(name: str, *, model_xml: str | None = None, description: str = '', category: str = 'arm', joints: int = 0, asset_dir: str | None = None, scene_xml: str | None = None, aliases: list[str] | None = None, robot_descriptions_module: str | None = None, hardware: dict[str, Any] | None = None, overwrite: bool = False) -> dict[str, Any]

Register a custom robot in the user-local registry.

.. warning:: Security

This function is a **library-only** API and must NOT be exposed
as an agent @tool without additional safeguards.  A malicious
agent could register a robot pointing to attacker-controlled MJCF
that executes code via MuJoCo plugins.  If tool exposure is needed
in the future, gate it behind STRANDS_TRUST_REMOTE_CODE and
validate all paths with :func:`strands_robots.utils.safe_join`.

The robot becomes immediately available in get_robot(), list_robots(), resolve_model_path(), sim.add_robot(), etc. A robot registered without model_xml is available to the registry readers only, not to resolve_model_path() or sim.add_robot().

Parameters:

Name Type Description Default
name str

Canonical robot name (lowercase, underscores).

required
model_xml str | None

Path to MJCF/URDF model file, relative to asset_dir. None (default) registers a robot with no simulation asset - a remote sensor node, a remote service robot - stored with no asset block, like the package's hardware-only entries. Such a robot must declare hardware and is reachable in real mode only.

None
description str

Human-readable description.

''
category str

Robot category, one of the groups the catalog shows (arm, bimanual, hand, humanoid, expressive, mobile, mobile_manip, aerial) or a new group of your own. A spelling close to a known group ("arms", "mobile-manip") is registered as given and logs a warning naming the group it probably meant.

'arm'
joints int

Number of actuated joints.

0
asset_dir str | None

Directory containing the model file and meshes. - Absolute path: used as-is (~/ expanded). - Relative path: resolved against the assets directory (STRANDS_ASSETS_DIR or ~/.strands_robots/assets/). - None: defaults to <assets_dir>/<name>/.

None
scene_xml str | None

Scene XML (with ground/lights). Defaults to model_xml.

None
aliases list[str] | None

Alternative names for this robot. Folded to a lookup key the same way name is (see :func:~strands_robots.registry.loader.normalize_robot_name), so "My-Arm" and "my_arm" are one alias, and an alias that folds onto another robot's canonical name or alias is refused rather than resolving to that robot.

None
robot_descriptions_module str | None

Optional robot_descriptions module name.

None
hardware dict[str, Any] | None

Hardware config dict: driver, lerobot_type, requires_lerobot_from_source. Any other key is stored but never read, so it is named in a warning with the field it was probably meant to be. Optional with model_xml; required without it, where it must declare a non-empty lerobot_type or driver="strands".

None
overwrite bool

If False (default), raises ValueError if name is already registered, in the user overlay or as a built-in robot. True replaces the user entry, or shadows the built-in until :func:unregister_robot removes the user entry.

False

Returns:

Type Description
dict[str, Any]

The registered robot definition dict.

Raises:

Type Description
ValueError

If name already exists (user overlay or built-in) and overwrite is False, or if an aliases entry collides with an existing canonical robot name or another robot's alias (the same constraint the loader enforces at read time, checked here so the registration cannot brick lookups). Also raised when model_xml or scene_xml escapes the asset directory they are declared relative to (see :func:_asset_relative), since the readers refuse such a path and the registration would persist a robot that cannot be loaded, and when a value in hardware (or any other field) is not JSON-serializable, since the overlay is a JSON document - see :func:_save_user_registry, which refuses such an entry before the stored overlay is touched; when model_xml is empty; and when model_xml is omitted and hardware declares no backend, or scene_xml, asset_dir or robot_descriptions_module is given without it.

TypeError

If hardware is given and is not a dict, or model_xml is given and is not a str.

FileNotFoundError

If model_xml doesn't exist at the resolved path.

Example::

register_robot(
    name="my_arm",
    model_xml="my_arm.xml",
    asset_dir="~/robots/my_arm_v2",
    description="Custom 6-DOF arm with gripper",
    category="arm",
    joints=7,
    aliases=["myarm", "custom_arm"],
)
register_robot("drone", category="aerial", hardware={"driver": "strands"})

unregister_robot

unregister_robot(name: str) -> bool

Remove a robot from the user-local registry.

Does not affect the package robots.json. If the robot exists only in the package registry, this is a no-op.

A key spelled exactly as name is removed first, so a hand-written key the loader refuses as not folded (rover-001) can be removed by the spelling the refusal quotes. Otherwise name is folded and that key is removed. The overlay file is read directly, not through the merged registry, which fails to load while such a key is present.

Parameters:

Name Type Description Default
name str

Robot name to remove, as the exact key in user_robots.json or any spelling that folds to it.

required

Returns:

Type Description
bool

True if the robot was removed, False if it wasn't in the user registry.

list_user_robots

list_user_robots() -> list[dict[str, Any]]

List all user-registered robots.

Returns:

Type Description
list[dict[str, Any]]

List of dicts with name, description, category, path info.

Policy providers

Policy registry - resolve, import, and configure policy providers.

All provider definitions live in policies.json. This module provides the public read API for resolving smart policy strings, importing provider classes, and building provider-specific kwargs.

get_policy_provider

get_policy_provider(name: str) -> dict[str, Any] | None

Get policy provider config by name or alias.

Parameters:

Name Type Description Default
name str

Provider name or alias (e.g. "lerobot", "cosmos", "remote").

required

Returns:

Type Description
dict[str, Any] | None

Provider dict with module, class, config_keys, defaults, etc.

dict[str, Any] | None

None if not found.

list_policy_providers

list_policy_providers() -> list[str]

List all registered policy provider names (canonical only).

list_policy_aliases

list_policy_aliases() -> dict[str, str]

Return the full alias -> canonical provider mapping.

:func:list_policy_providers reports canonical names only, but :func:get_policy_provider, :func:resolve_policy and create_policy all accept a provider's declared aliases and shorthands as well. This is the surface that enumerates them, so a caller can discover every spelling the registry honours instead of having to already know it.

A provider that redundantly lists its own canonical name among its aliases contributes no entry: a name is not an alias of itself, and such an entry would double-count the spelling :func:list_policy_providers already reports.

Returns:

Type Description
dict[str, str]

Mapping of alias to the canonical provider name it resolves to.

resolve_policy

resolve_policy(policy: str, **extra_kwargs) -> tuple[str, dict[str, Any]]

Resolve a smart policy string to (provider_name, kwargs).

Accepts HuggingFace model IDs, server URLs, or shorthand names and returns the canonical provider + ready-to-use kwargs.

Resolution order
  1. URL patterns declared in policies.json (ws://, wss://, cosmos3://)
  2. Shorthand names (mock, lerobot_local, remote, ...); a removed provider's spelling (:data:REMOVED_PROVIDERS) is refused here
  3. HuggingFace model IDs (org/model)
  4. Registered provider name
  5. Fallback to lerobot_local

Stage 1 recognises exactly the forms the registry declares: the url_patterns entries providers carry are the whole vocabulary. A scheme:// outside it is refused here, naming :func:_declared_url_schemes, because it is an address and no later stage can dial one -- it would reach stage 3 or stage 5 and be forwarded to lerobot_local as a checkpoint id, so the caller's next report is a HuggingFace lookup failure for a string that was never a repo id.

A scheme-less host:port address is matched only by a provider that declares a scheme-less pattern -- the generic server_address branch below exists for that -- and none of the shipped providers declares one, so with the shipped registry such a string reaches stage 5 and is forwarded to lerobot_local as a checkpoint id rather than dialled as an address. It carries no scheme, so the refusal above does not read it as an address either.

Every stage matches case-insensitively. A URL scheme is folded per RFC 3986 section 3.1 (WS://gpu:8765 resolves exactly as ws://gpu:8765, and the emitted URL carries the lowercased scheme); shorthands and provider names are lowercased; a HuggingFace org is matched lowercased while the repo id itself is forwarded exactly as given, since repo ids are case-sensitive.

Parameters:

Name Type Description Default
policy str

Smart string - HF model ID, URL, or provider name.

required
**extra_kwargs

Additional kwargs merged into result.

{}

Returns:

Type Description
tuple[str, dict[str, Any]]

(provider_name, kwargs_dict) tuple.

Raises:

Type Description
ValueError

The string carries a scheme:// no provider declares.

Examples:: resolve_policy("lerobot/act_aloha_sim") # → ("lerobot_local", {"pretrained_name_or_path": "lerobot/act_aloha_sim"})

resolve_policy("ws://gpu-box:8765")
# → ("remote", {"url": "ws://gpu-box:8765"})

resolve_policy("mock")
# → ("mock", {})

build_policy_kwargs

build_policy_kwargs(provider: str, policy_port: int | None = None, policy_host: str | None = None, model_path: str | None = None, server_address: str | None = None, policy_type: str | None = None, data_config: Any = None, **extra) -> dict[str, Any]

Build provider-specific kwargs from generic parameters.

Maps generic parameter names (policy_port, model_path, ...) to the provider-specific keys declared in policies.json.

Parameters:

Name Type Description Default
provider str

Policy provider name.

required
policy_port int | None

Port number (cosmos3, moveit2, remote).

None
policy_host str | None

Hostname. None leaves the key unset so the provider's registry default -- or, failing that, its own constructor default -- applies.

None
model_path str | None

Local model path or HF ID.

None
server_address str | None

Full server address host:port (grpc:// URLs, remote providers).

None
policy_type str | None

Sub-type (pi0, act, smolvla, ...).

None
**extra

Any additional provider-specific kwargs. A key declared in the provider's config_keys is forwarded; any other key is dropped, which is what config_keys exists to decide.

{}

Returns:

Type Description
dict[str, Any]

Dict of kwargs ready for create_policy(provider, **kwargs).

dict[str, Any]

Where two sources name the same key, the more explicit one wins:

dict[str, Any]

a provider-specific value in extra beats the generic parameter

dict[str, Any]

that maps onto it (host beats policy_host), and both beat the

dict[str, Any]

provider's registry default. A default only ever fills a key the

dict[str, Any]

caller left unset.

Edit page