feat(config): use jsonargparse as construction engine - #227
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors Physical AI Runtime’s configuration system to make jsonargparse the primary construction engine for known/expected types, while simplifying physicalai.config around a smaller Config recipe API and removing generic loader/mixin/YAML helper facades. It updates runtime/inference/transport boundaries to use expected-type construction, and rewrites tests/docs/examples/skills to match the new canonical APIs.
Changes:
- Reworked
physicalai.config.Configto own recipe parsing/saving/loading and to delegate typed parsing/instantiation tojsonargparse, includingexpected_type=...instantiation paths. - Updated runtime, inference, and robot/camera transport code to use expected-type instantiation and to move envelope validation into the owning modules.
- Removed legacy config utility modules and documentation, and migrated unit tests/examples/skills to the new public surface.
Reviewed changes
Copilot reviewed 40 out of 41 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/runtime/test_runtime_config.py | Migrates runtime config round-trip tests to Config.from_instance/from_dict().instantiate(). |
| tests/unit/robot/transport/test_shared_robot.py | Updates SharedRobot validation expectation text. |
| tests/unit/robot/transport/test_owner_config.py | Aligns owner-config error expectations with new config validation behavior. |
| tests/unit/robot/test_robot_config.py | Migrates robot config tests to new Config capture/instantiate APIs. |
| tests/unit/inference/test_inference_model_config.py | Migrates inference-model config tests to new Config APIs. |
| tests/unit/config/test_yaml.py | Removes YAML helper tests tied to deleted YAML facade APIs. |
| tests/unit/config/test_from_config_and_instantiate.py | Removes tests for deleted FromConfig/instantiate_obj/typed reconstruction utilities. |
| tests/unit/config/test_export_config.py | Rebinds helpers to Config methods and updates enum/name persistence expectations. |
| tests/unit/config/test_config.py | Updates core config tests for jsonargparse-backed typed config load/save and enum name persistence. |
| tests/unit/capture/test_transport.py | Updates SharedCamera validation expectation text. |
| tests/unit/capture/test_factory.py | Updates imports to new config importing/export resolution locations. |
| tests/unit/capture/test_camera_config.py | Migrates camera config tests to Config capture/expected-type instantiate and enum name persistence. |
| src/physicalai/runtime/core.py | Uses Config.from_dict(...).resolve_type() to unwrap exported runtime documents safely. |
| src/physicalai/robot/transport/_owner_config.py | Moves owner envelope validation logic into robot transport module; uses expected-type instantiation. |
| src/physicalai/inference/runners/factory.py | Updates runner instantiation to require an expected base type. |
| src/physicalai/inference/model.py | Updates processor/feature construction to go through expected-type component instantiation and refactors loader helper. |
| src/physicalai/inference/component_factory.py | Replaces custom recursive construction with jsonargparse-based typed instantiation and canonical spec normalization. |
| src/physicalai/config/serializable.py | Removes legacy typed dataclass (de)serialization utility module. |
| src/physicalai/config/mixin.py | Removes FromConfig / @from_config mixin/decorator module. |
| src/physicalai/config/loading.py | Removes generic instantiate_obj loader helpers module. |
| src/physicalai/config/base.py | Implements jsonargparse-backed typed parsing and expands Config load/save/instantiate behavior. |
| src/physicalai/config/_yaml.py | Removes YAML helper facade module. |
| src/physicalai/config/_normalize.py | Switches enum normalization to persist enum names (jsonargparse-native). |
| src/physicalai/config/_instantiate.py | Adds expected_type instantiation lane that uses jsonargparse for typed construction/validation. |
| src/physicalai/config/_envelope.py | Removes shared envelope validation helpers (migrated to owning domains). |
| src/physicalai/config/init.py | Shrinks public surface to focus on Config, errors, types, and export_config. |
| src/physicalai/capture/transport/_spec.py | Moves publisher envelope validation logic into capture transport module; uses expected-type instantiation. |
| skills/config/README.md | Updates skills scope text to reflect jsonargparse-centered config workflow. |
| skills/config/physicalai-runtime-working-with-config/SKILL.md | Updates guidance to remove legacy helpers and emphasize Config + jsonargparse usage. |
| pyproject.toml | Updates jsonargparse dependency constraint. |
| mkdocs.yml | Removes navigation entries for deleted legacy config docs. |
| examples/runtime/utils.py | Updates SharedRobot example to pass captured Config recipe instead of to_config. |
| examples/runtime/sync_inference.py | Updates export path to Config.save() instead of YAML helper. |
| examples/runtime/rtc_inference.py | Updates export path to Config.save() instead of YAML helper. |
| examples/runtime/async_inference.py | Updates export path to Config.save() instead of YAML helper. |
| docs/how-to/config/use-from-config.md | Removes documentation for deleted FromConfig / @from_config. |
| docs/how-to/config/instantiate-objects.md | Removes documentation for deleted instantiate_obj API. |
| docs/how-to/config/instantiate-components.md | Updates examples to use Config.from_instance(...).save(). |
| docs/explanation/configuration.md | Reframes “generic instantiation” section into typed jsonargparse-first configuration guidance. |
| configuration-with-jsonargparse.md | Adds implementation specification documenting the new configuration architecture and migration policy. |
Keep Studio-compatible APIs (FromConfig, loading, YAML, serializable) as thin facades that delegate to jsonargparse and emit DeprecationWarning, documented with .. deprecated:: sections. Document three-phase rollout with Studio migration before shim removal. Co-authored-by: Cursor <cursoragent@cursor.com>
32465a0 to
095b10b
Compare
Rewrite explanation, how-to, skills, and spec intro for beginner-friendly prose; simplify the physicalai.config package docstring. Co-authored-by: Cursor <cursoragent@cursor.com>
Remove redundant alias reassignment; recipe validation stays on _normalize. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the module-wide noqa with line-level ruff ignores for lazy imports and known lint exceptions. Co-authored-by: Cursor <cursoragent@cursor.com>
Use jsonargparse's original class name in the deprecated FromConfig shim. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace module-wide noqa with line-level ruff ignores for the private hub import and existing Any/magic-value exceptions. Co-authored-by: Cursor <cursoragent@cursor.com>
…onfig Decorate @export_config classes with instance export helpers, coerce shared robot input via those methods, and keep ConfigExportable internal for typing. Co-authored-by: Cursor <cursoragent@cursor.com>
Remove configuration-with-jsonargparse.md from the branch and gitignore it so the design spec stays local and out of PR diffs. Co-authored-by: Cursor <cursoragent@cursor.com>
The jsonargparse design spec is not part of this repository. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Note: description says |
…antiate StrEnum members no longer bypass enum normalization into init_args. Schema-free instantiate resolves enum-typed constructor params from jsonargparse wire names. Add enum round-trip tests without a JSON detour. Co-authored-by: Cursor <cursoragent@cursor.com>
…nput Avoid cast plus supports_config_export() so arbitrary objects raise TypeError instead of AttributeError. Co-authored-by: Cursor <cursoragent@cursor.com>
Save typed dataclass configs using to_jsonargparse() so nested fields stay plain; unwrap init_args when loading files for backward compatibility. Co-authored-by: Cursor <cursoragent@cursor.com>
Reject incompatible class_path via issubclass before typed construction; use allow_nan=False in normalize_robot_config; accept Config recipes in export test helper. Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve uv.lock by regenerating after merge with main. Co-authored-by: Cursor <cursoragent@cursor.com>
Component instantiation no longer raises uncaught ArgumentError on invalid flat params, fixing fuzz/component crashes after the config migration. Co-authored-by: Cursor <cursoragent@cursor.com>
Canonical spec normalization now raises ConfigError for excessive nesting; catch it alongside ValueError so libFuzzer does not exit. Co-authored-by: Cursor <cursoragent@cursor.com>
Coerce legacy wire values before jsonargparse parse_class_config so main-style YAML with mode: fast still loads. Co-authored-by: Cursor <cursoragent@cursor.com>
Fix ruff DOC201 on _typed_wire; add runnable examples/config script for legacy enum-value YAML. Co-authored-by: Cursor <cursoragent@cursor.com>
Remove the ad hoc backward-compatibility demo from the repository while retaining it as an untracked local script for manual verification. Co-authored-by: Cursor <cursoragent@cursor.com>
maxxgx
left a comment
There was a problem hiding this comment.
LGTM, manual config roundtrip passed
Summary
Minimal configuration architecture built around
Configand jsonargparse:loading.py,mixin.py,serializable.py,_yaml.py, and_envelope.py.instantiate_obj,FromConfig, package-level YAML helpers, import helpers, and generic normalization helpers.Configdirectly owns typed mapping/file parsing, saving, portable recipe load/save, exportability, and class resolution.Config.instantiate(expected_type=...)is used at robot/camera ownership boundaries.