Skip to content

feat: add component config#200

Closed
maxxgx wants to merge 21 commits into
mainfrom
max/comp-config
Closed

feat: add component config#200
maxxgx wants to merge 21 commits into
mainfrom
max/comp-config

Conversation

@maxxgx

@maxxgx maxxgx commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Why

Validation

Breaking changes

  • None

Related issues

  • Closes #

maxxgx and others added 16 commits July 22, 2026 13:36
Drop the report/brief duplicates of the design note, fold the rollout status into the spec, and track the wire-decision record the spec links to.

Co-authored-by: Cursor <cursoragent@cursor.com>
Deduplicate the copy-pasted owner/publisher envelope validators and class-path normalizers into one parameterized module, and replace the lazy physicalai.config __getattr__ with plain imports.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the unused _resolve_public_class_path alias and no-op keep_by_reference parameter, collapse the _session kwargs duplication in SharedRobot, and trim design-note prose restated on private helpers.

Co-authored-by: Cursor <cursoragent@cursor.com>
A live robot/camera recipe missing its protocol's is_connected surface now raises TypeError instead of silently passing the disconnected check; also type the robot CLI test namespaces so pyrefly stops flagging SimpleNamespace.

Co-authored-by: Cursor <cursoragent@cursor.com>
@maxxgx
maxxgx force-pushed the max/comp-config branch from 4db1133 to 589a8b6 Compare July 23, 2026 12:14
maxxgx and others added 5 commits July 24, 2026 15:04
Simplify the component-config transport integration and close config
round-trip gaps found while making the branch review-ready.

- transport: remove SharedRobot.from_robot / SharedCamera.from_camera
  sugar; the constructor coercion path already covers live-instance
  recipes. Convert the sugar tests to constructor-path tests so the
  connected / config-exportable / disconnected validation stays covered.
- cli: accept both a runtime:-rooted document and a bare exported
  RobotRuntime ComponentConfig in `physicalai run --config`, via a small
  ActionConfigFile subclass that unwraps a top-level class_path on load.
  This makes to_config(runtime) + save_yaml round-trip with no separate
  export API; a foreign class_path is rejected via parser.error.
- capture: rename transport CameraSpec to CameraPublisherConfig to avoid
  colliding with inference.manifest.CameraSpec.
- robot(so101): make allow_uncalibrated public and default calibration to
  None so an uncalibrated export round-trips through jsonargparse; the
  runtime guard still requires explicit opt-in.
- docs: update the component-config spec (CLI both-ways, save_yaml
  round-trip, coercion contract, uncalibrated note); drop the
  from_robot / from_camera / CameraSpec mandates and the scratch issues note.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds @export_config(config_args=...) so a class can declare init args it
consumes as ComponentConfig *data*. instantiate() hands those mappings over
undecoded instead of building the nested component and letting the owner
immediately re-serialize it.

SharedRobot and SharedCamera declare robot/camera this way, which removes the
build-then-unbuild round trip, the live-instance coercion helpers, and the
is_connected property-vs-method asymmetry between the two protocols. Both
constructors now take a ComponentConfig mapping only; a caller holding a live
driver converts it explicitly with to_config(driver).
…opes

normalize_class_reference imported every string class_path so a
defining-module path could be rewritten to its public re-export. That import
runs in the subscriber process, which made SharedCamera/SharedRobot
construction require the vendor SDK on machines that only attach to a
publisher - realsense/_camera.py imports pyrealsense2 at module scope. The
same problem sat in builtin.py, which imported all three driver modules
behind an lru_cache to resolve the token map live.

A string class_path is now trusted and stored exactly as written; only class
objects resolve to a public path. Import errors surface where they belong, in
the process that calls instantiate(). builtin.py becomes a static table
listing every accepted spelling per backend, so one device still derives one
service name however the config names its driver.
validate_component_config already requires class_path to be a string, so
normalize_class_reference's class-object branch was unreachable from every
envelope path. Its only remaining callers were normalize_robot_class and
normalize_camera_class, which had no production call sites at all.

Inlines the dotted-path check into normalize_component_config and removes
normalize_class_reference from the physicalai.config surface, leaving two
public envelope helpers instead of three. Also records why the camera
envelope is CameraPublisherConfig rather than CameraSpec, mirroring the
collision rationale already documented on RobotOwnerConfig.
@maxxgx

maxxgx commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@maxxgx maxxgx closed this Jul 27, 2026
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.

1 participant