Skip to content

feat(imitation): add controlled OpenYAM policy rollout - #3855

Draft
TomCC7 wants to merge 4 commits into
feat/openyam-native-collectionfrom
feat/openyam-lerobot-rollout
Draft

feat(imitation): add controlled OpenYAM policy rollout#3855
TomCC7 wants to merge 4 commits into
feat/openyam-native-collectionfrom
feat/openyam-lerobot-rollout

Conversation

@TomCC7

@TomCC7 TomCC7 commented Sep 1, 2026

Copy link
Copy Markdown
Member

This is layer 4 of the OpenYAM learning slice in the original stack. It adds fail-closed policy task activation, semantic Quest action bindings, queued rollout supervision, and the OpenYAM rollout blueprint.

Learning slice

  1. feat: add isolated Python module runtime #3478 — external Python native-module runtime
  2. fix(openyam): align learning stack with canonical model #3853 — OpenYAM learning baseline
  3. refactor(imitation): isolate LeRobot policy runtime #3315 — isolated LeRobot policy runtime
  4. feat(imitation): add native OpenYAM collection #3854 — native OpenYAM collection
  5. feat(imitation): add controlled OpenYAM policy rollout #3855 — controlled OpenYAM policy rollout
  6. feat(a1z): a1z learning workflow #3318 — A1Z learning workflow

Validation: 217 focused rollout and control tests plus 3 generated-registry tests passed.

@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

❌ 5 Tests Failed:

Tests completed Failed Passed Skipped
4713 5 4708 178
View the top 3 failed test(s) by shortest run time
dimos.core.test_isolated_python_end_to_end::test_isolated_python_rpc_refs_and_restart
Stack Traces | 2.53s run time
+ Exception Group Traceback (most recent call last):
  |   File ".../dimos/dimos/.venv/lib/python3.12........./site-packages/_pytest/runner.py", line 341, in from_call
  |     result: TResult | None = func()
  |                              ^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12........./site-packages/_pytest/runner.py", line 242, in <lambda>
  |     lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
  |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/pluggy/_hooks.py", line 512, in __call__
  |     return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/pluggy/_manager.py", line 120, in _hookexec
  |     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 167, in _multicall
  |     raise exception
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/_pytest/threadexception.py", line 92, in pytest_runtest_call
  |     yield from thread_exception_runtest_hook()
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/_pytest/threadexception.py", line 68, in thread_exception_runtest_hook
  |     yield
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/_pytest/unraisableexception.py", line 95, in pytest_runtest_call
  |     yield from unraisable_exception_runtest_hook()
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/_pytest/unraisableexception.py", line 70, in unraisable_exception_runtest_hook
  |     yield
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/_pytest/logging.py", line 846, in pytest_runtest_call
  |     yield from self._runtest_for(item, "call")
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/_pytest/logging.py", line 829, in _runtest_for
  |     yield
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 53, in run_old_style_hookwrapper
  |     return result.get_result()
  |            ^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12............/site-packages/pluggy/_result.py", line 103, in get_result
  |     raise exc.with_traceback(tb)
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 38, in run_old_style_hookwrapper
  |     res = yield
  |           ^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../dimos/dimos/.venv/lib/python3.12.../site-packages/_pytest/capture.py", line 898, in pytest_runtest_call
  |     return (yield)
  |             ^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 53, in run_old_style_hookwrapper
  |     return result.get_result()
  |            ^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12............/site-packages/pluggy/_result.py", line 103, in get_result
  |     raise exc.with_traceback(tb)
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 38, in run_old_style_hookwrapper
  |     res = yield
  |           ^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 53, in run_old_style_hookwrapper
  |     return result.get_result()
  |            ^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12............/site-packages/pluggy/_result.py", line 103, in get_result
  |     raise exc.with_traceback(tb)
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 38, in run_old_style_hookwrapper
  |     res = yield
  |           ^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../dimos/dimos/.venv/lib/python3.12.../site-packages/_pytest/skipping.py", line 257, in pytest_runtest_call
  |     return (yield)
  |             ^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 121, in _multicall
  |     res = hook_impl.function(*args)
  |           ^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12........./site-packages/_pytest/runner.py", line 174, in pytest_runtest_call
  |     item.runtest()
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/_pytest/python.py", line 1627, in runtest
  |     self.ihook.pytest_pyfunc_call(pyfuncitem=self)
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/pluggy/_hooks.py", line 512, in __call__
  |     return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/pluggy/_manager.py", line 120, in _hookexec
  |     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 167, in _multicall
  |     raise exception
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 139, in _multicall
  |     teardown.throw(exception)
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 53, in run_old_style_hookwrapper
  |     return result.get_result()
  |            ^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12............/site-packages/pluggy/_result.py", line 103, in get_result
  |     raise exc.with_traceback(tb)
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 38, in run_old_style_hookwrapper
  |     res = yield
  |           ^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12.............................................................../site-packages/pluggy/_callers.py", line 121, in _multicall
  |     res = hook_impl.function(*args)
  |           ^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/dimos/.venv/lib/python3.12....../site-packages/_pytest/python.py", line 159, in pytest_pyfunc_call
  |     result = testfunction(**testargs)
  |              ^^^^^^^^^^^^^^^^^^^^^^^^
  |   File ".../dimos/core/test_isolated_python_end_to_end.py", line 59, in test_isolated_python_rpc_refs_and_restart
  |     coordinator = ModuleCoordinator.build(
  |                   ^^^^^^^^^^^^^^^^^^^^^^^^
  |   File ".../core/coordination/module_coordinator.py", line 377, in build
  |     coordinator.build_all_modules()
  |   File ".../core/coordination/module_coordinator.py", line 249, in build_all_modules
  |     safe_thread_map(modules, lambda m: m.build())
  |   File ".../dimos/utils/safe_thread_map.py", line 84, in safe_thread_map
  |     raise ExceptionGroup("safe_thread_map failed", errors)
  | ExceptionGroup: safe_thread_map failed (1 sub-exception)
  +-+---------------- 1 ----------------
    | dimos.protocol.rpc.rpc_utils.RemoteError: [Remote builtins.RuntimeError] Isolated Python environment preparation failed (exit 1): Using CPython 3.12.3 interpreter at: ........./usr/bin/python3.12
    | Creating virtual environment at: ........./home/runner/.cache........./dimos/python-native/external_python_module-c5c794f5b247
    | Resolved 195 packages in 846ms
    | error: The lockfile at `uv.lock` needs to be updated, but `--locked` was
    |        provided.
    | 
    | hint: To update the lockfile, run `uv lock`.
    | 
    | Remote traceback:
    | Traceback (most recent call last):
    |   File ".../protocol/rpc/zenohrpc.py", line 199, in _execute_rpc
    |     response = f(*args[0], **args[1])
    |                ^^^^^^^^^^^^^^^^^^^^^^
    |   File ".../protocol/rpc/spec.py", line 116, in override_f
    |     return getattr(module, fname)(*args, **kwargs)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File ".../dimos/core/isolated_python_module.py", line 211, in build
    |     super().build()
    |   File ".../dimos/core/native_module.py", line 236, in build
    |     self._maybe_build()
    |   File ".../dimos/core/isolated_python_module.py", line 207, in _maybe_build
    |     self._run_prepare()
    |   File ".../dimos/core/isolated_python_module.py", line 127, in _run_prepare
    |     raise RuntimeError(
    | RuntimeError: Isolated Python environment preparation failed (exit 1): Using CPython 3.12.3 interpreter at: ........./usr/bin/python3.12
    | Creating virtual environment at: ........./home/runner/.cache........./dimos/python-native/external_python_module-c5c794f5b247
    | Resolved 195 packages in 846ms
    | error: The lockfile at `uv.lock` needs to be updated, but `--locked` was
    |        provided.
    | 
    | hint: To update the lockfile, run `uv lock`.
    | 
    | 
    | The above exception was the direct cause of the following exception:
    | 
    | Traceback (most recent call last):
    |   File ".../dimos/utils/safe_thread_map.py", line 68, in safe_thread_map
    |     outcomes[idx] = fut.result()
    |                     ^^^^^^^^^^^^
    |   File "........./usr/lib/python3.12....../concurrent/futures/_base.py", line 449, in result
    |     return self.__get_result()
    |            ^^^^^^^^^^^^^^^^^^^
    |   File "........./usr/lib/python3.12....../concurrent/futures/_base.py", line 401, in __get_result
    |     raise self._exception
    |   File "........./usr/lib/python3.12.../concurrent/futures/thread.py", line 58, in run
    |     result = self.fn(*self.args, **self.kwargs)
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File ".../core/coordination/module_coordinator.py", line 249, in <lambda>
    |     safe_thread_map(modules, lambda m: m.build())
    |                                        ^^^^^^^^^
    |   File ".../dimos/core/rpc_client.py", line 93, in __call__
    |     result, unsub_fn = self._rpc.call_sync(
    |                        ^^^^^^^^^^^^^^^^^^^^
    |   File ".../protocol/rpc/spec.py", line 88, in call_sync
    |     raise result
    | RuntimeError: Isolated Python environment preparation failed (exit 1): Using CPython 3.12.3 interpreter at: ........./usr/bin/python3.12
    | Creating virtual environment at: ........./home/runner/.cache........./dimos/python-native/external_python_module-c5c794f5b247
    | Resolved 195 packages in 846ms
    | error: The lockfile at `uv.lock` needs to be updated, but `--locked` was
    |        provided.
    | 
    | hint: To update the lockfile, run `uv lock`.
    +------------------------------------
dimos.robot.manipulators.openyam.test_openyam::test_make_openyam_model_config_uses_canonical_arm_joints
Stack Traces | 3.13s run time
def test_make_openyam_model_config_uses_canonical_arm_joints() -> None:
        config = make_openyam_model_config()
    
>       assert OPENYAM_MODEL_PATH.parts[-2:] == ("i2rt", "yam.urdf")

config     = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModelConfig object at 0xffd9cfc45040>

.../manipulators/openyam/test_openyam.py:63: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/data.py:370: in __getattribute__
    resolved = object.__getattribute__(self, "_ensure_downloaded")()
        name       = 'parts'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...cription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffda4a30d4d0>
dimos/utils/data.py:353: in _ensure_downloaded
    cache = get_data(filename)
        cache      = None
        filename   = 'yam_description/i2rt/yam.urdf'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...cription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffda4a30d4d0>
dimos/utils/data.py:310: in get_data
    archive_path = _decompress_archive(_pull_lfs_archive(archive_name))
        archive_name = 'yam_description'
        data_dir   = PosixPath('.../dimos/dimos/data')
        file_path  = PosixPath('.../dimos/dimos/data/yam_description/i2rt/yam.urdf')
        name       = 'yam_description/i2rt/yam.urdf'
        nested_path = PosixPath('i2rt/yam.urdf')
        path_parts = ('yam_description', 'i2rt', 'yam.urdf')
dimos/utils/data.py:254: in _pull_lfs_archive
    _lfs_pull(file_path, repo_root)
        file_path  = PosixPath('.../dimos/data/.lfs/yam_description.tar.gz')
        filename   = 'yam_description'
        repo_root  = PosixPath('.../work/dimos/dimos')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

file_path = PosixPath('.../dimos/data/.lfs/yam_description.tar.gz')
repo_root = PosixPath('.../work/dimos/dimos')

    def _lfs_pull(file_path: Path, repo_root: Path, *, retries: int = 2) -> None:
        relative_path = file_path.relative_to(repo_root)
    
        env = os.environ.copy()
        env["GIT_LFS_FORCE_PROGRESS"] = "1"
    
        last_err: subprocess.CalledProcessError | None = None
        for attempt in range(1, retries + 2):  # retries + 1 total attempts
            try:
                subprocess.run(
                    # --exclude= overrides lfs.fetchexclude from .lfsconfig, which
                    # otherwise silently skips data/.lfs/* even when --include matches.
                    ["git", "lfs", "pull", "--include", str(relative_path), "--exclude="],
                    cwd=repo_root,
                    check=True,
                    env=env,
                )
                return
            except subprocess.CalledProcessError as e:
                last_err = e
                if attempt <= retries:
                    time.sleep(attempt)  # 1s, 2s backoff
    
>       raise RuntimeError(
            f"Failed to pull LFS file {file_path} after {retries + 1} attempts: {last_err}"
        )
E       RuntimeError: Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/yam_description.tar.gz', '--exclude=']' returned non-zero exit status 1.

attempt    = 3
env        = {'ACCEPT_EULA': 'Y', 'ACTIONS_ID_TOKEN_REQUEST_TOKEN': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4ODI2YjE3LTZhMzAtNWY5Yi1iMTY5LT...-version=2.0', 'ACTIONS_ORCHESTRATION_ID': 'fc24accd-c30b-4a54-a0cd-b0f14b27d4a6.tests.ubuntu-24_04-arm_3_14_fal', ...}
file_path  = PosixPath('.../dimos/data/.lfs/yam_description.tar.gz')
last_err   = CalledProcessError(1, ['git', 'lfs', 'pull', '--include', 'data/.lfs/yam_description.tar.gz', '--exclude='])
relative_path = PosixPath('data/.lfs/yam_description.tar.gz')
repo_root  = PosixPath('.../work/dimos/dimos')
retries    = 2

dimos/utils/data.py:224: RuntimeError
dimos.robot.manipulators.openyam.blueprints.test_learning_rollout::test_rollout_requires_policy_path_from_cli
Stack Traces | 3.26s run time
value = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffcdb0a4dcd0>

    def _copy_opaque(value: Any) -> Any:
        try:
>           return copy.deepcopy(value)

value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffcdb0a4dcd0>

.../coordination/blueprint_config/values.py:113: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
........................................../usr/lib/python3.12/copy.py:162: in deepcopy
    y = _reconstruct(x, memo, *rv)
        _nil       = []
        cls        = <class 'dimos.control.coordinator.TaskConfig'>
        copier     = None
        d          = 281258896973008
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        reductor   = <built-in method __reduce_ex__ of TaskConfig object at 0xffcdb0a4dcd0>
        rv         = (<function __newobj__ at 0xffcea3dfc5e0>, (<class 'dimos.control.coordinator.TaskConfig'>,), {'auto_start': False, 'jo...lter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}, ...}, None, None)
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffcdb0a4dcd0>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xffce8e2a7b50>
        deep       = True
        deepcopy   = <function deepcopy at 0xffcea379e020>
        dictiter   = None
        func       = <function __newobj__ at 0xffcea3dfc5e0>
        listiter   = None
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        state      = {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_joint5', 'yam_joint...nt_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}, ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffcdb0a4dcd0>
        y          = <[AttributeError("'TaskConfig' object has no attribute 'name'") raised in repr()] TaskConfig object at 0xffce8f5cc3e0>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xffcea359cae0>
        d          = 281262613799168
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        x          = {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_joint5', 'yam_joint...nt_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}, ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xffcea379e020>
        key        = 'params'
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        value      = {'bindings': [{'hand': 'right', 'target_frame': 'gripper_tip'}], 'joint_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}
        x          = {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_joint5', 'yam_joint...nt_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}, ...}
        y          = {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_joint5', 'yam_joint6'], 'name': 'teleop_openyam', 'priority': 20, ...}
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xffcea359cae0>
        d          = 281258893591616
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        x          = {'bindings': [{'hand': 'right', 'target_frame': 'gripper_tip'}], 'joint_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xffcea379e020>
        key        = 'robot_model'
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModelConfig object at 0xffcdb0a33930>
        x          = {'bindings': [{'hand': 'right', 'target_frame': 'gripper_tip'}], 'joint_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}
        y          = {}
........................................../usr/lib/python3.12/copy.py:143: in deepcopy
    y = copier(memo)
        _nil       = []
        cls        = <class 'dimos.manipulation.planning.spec.config.RobotModelConfig'>
        copier     = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...scription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] method object at 0xffce8e2e3840>
        d          = 281258896865584
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModelConfig object at 0xffcdb0a33930>
        y          = []
.venv/lib/python3.12.../site-packages/pydantic/main.py:978: in __deepcopy__
    _object_setattr(m, '__dict__', deepcopy(self.__dict__, memo=memo))
        cls        = <class 'dimos.manipulation.planning.spec.config.RobotModelConfig'>
        m          = RobotModelConfig()
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModelConfig object at 0xffcdb0a33930>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xffcea359cae0>
        d          = 281258893592448
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        x          = {'auto_convert_meshes': True, 'base_link': 'base', 'base_pose': Pose(position=Vector([          0           0           0]), orientation=Quaternion(0.000000, 0.000000, 0.000000, 1.000000)), 'collision_exclusion_pairs': [], ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xffcea379e020>
        key        = 'model'
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModel object at 0xffcdb0a4eae0>
        x          = {'auto_convert_meshes': True, 'base_link': 'base', 'base_pose': Pose(position=Vector([          0           0           0]), orientation=Quaternion(0.000000, 0.000000, 0.000000, 1.000000)), 'collision_exclusion_pairs': [], ...}
        y          = {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': GlobalConfig(robot_ip=None, robot_ips=N...dless=True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}
........................................../usr/lib/python3.12/copy.py:162: in deepcopy
    y = _reconstruct(x, memo, *rv)
        _nil       = []
        cls        = <class 'dimos.robot.assets.model.RobotModel'>
        copier     = None
        d          = 281258896976608
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        reductor   = <built-in method __reduce_ex__ of RobotModel object at 0xffcdb0a4eae0>
        rv         = (<function __newobj__ at 0xffcea3dfc5e0>, (<class 'dimos.robot.assets.model.RobotModel'>,), {'_fixed_frames': (), '_fi...xclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffce1e7f4050>),), ...}, None, None)
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModel object at 0xffcdb0a4eae0>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xffce8e2a55d0>
        deep       = True
        deepcopy   = <function deepcopy at 0xffcea379e020>
        dictiter   = None
        func       = <function __newobj__ at 0xffcea3dfc5e0>
        listiter   = None
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        state      = {'_fixed_frames': (), '_fixed_joints': (), '_joint_position_limits': (), '_package_paths': (('yam_description', <[Runt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffce1e7f4050>),), ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModel object at 0xffcdb0a4eae0>
        y          = <[AttributeError("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xffce8f5fc050>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xffcea359cae0>
        d          = 281262613634176
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        x          = {'_fixed_frames': (), '_fixed_joints': (), '_joint_position_limits': (), '_package_paths': (('yam_description', <[Runt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffce1e7f4050>),), ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xffcea379e020>
        key        = '_source_path'
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...cription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffce1e7f6ad0>
        x          = {'_fixed_frames': (), '_fixed_joints': (), '_joint_position_limits': (), '_package_paths': (('yam_description', <[Runt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffce1e7f4050>),), ...}
        y          = {}
........................................../usr/lib/python3.12/copy.py:141: in deepcopy
    copier = getattr(x, "__deepcopy__", None)
        _nil       = []
        cls        = <class 'dimos.utils.data.LfsPath'>
        copier     = None
        d          = 281260740012752
        memo       = {281258893591616: {}, 281258893592448: {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': ...258893598144: {'build_native': False, 'can_port': None, 'detection_model': 'moondream', 'device_path': None, ...}, ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...cription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffce1e7f6ad0>
        y          = []
dimos/utils/data.py:370: in __getattribute__
    resolved = object.__getattribute__(self, "_ensure_downloaded")()
        name       = '__deepcopy__'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...cription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffce1e7f6ad0>
dimos/utils/data.py:353: in _ensure_downloaded
    cache = get_data(filename)
        cache      = None
        filename   = 'yam_description/i2rt/yam.urdf'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...cription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffce1e7f6ad0>
dimos/utils/data.py:310: in get_data
    archive_path = _decompress_archive(_pull_lfs_archive(archive_name))
        archive_name = 'yam_description'
        data_dir   = PosixPath('.../dimos/dimos/data')
        file_path  = PosixPath('.../dimos/dimos/data/yam_description/i2rt/yam.urdf')
        name       = 'yam_description/i2rt/yam.urdf'
        nested_path = PosixPath('i2rt/yam.urdf')
        path_parts = ('yam_description', 'i2rt', 'yam.urdf')
dimos/utils/data.py:254: in _pull_lfs_archive
    _lfs_pull(file_path, repo_root)
        file_path  = PosixPath('.../dimos/data/.lfs/yam_description.tar.gz')
        filename   = 'yam_description'
        repo_root  = PosixPath('.../work/dimos/dimos')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

file_path = PosixPath('.../dimos/data/.lfs/yam_description.tar.gz')
repo_root = PosixPath('.../work/dimos/dimos')

    def _lfs_pull(file_path: Path, repo_root: Path, *, retries: int = 2) -> None:
        relative_path = file_path.relative_to(repo_root)
    
        env = os.environ.copy()
        env["GIT_LFS_FORCE_PROGRESS"] = "1"
    
        last_err: subprocess.CalledProcessError | None = None
        for attempt in range(1, retries + 2):  # retries + 1 total attempts
            try:
                subprocess.run(
                    # --exclude= overrides lfs.fetchexclude from .lfsconfig, which
                    # otherwise silently skips data/.lfs/* even when --include matches.
                    ["git", "lfs", "pull", "--include", str(relative_path), "--exclude="],
                    cwd=repo_root,
                    check=True,
                    env=env,
                )
                return
            except subprocess.CalledProcessError as e:
                last_err = e
                if attempt <= retries:
                    time.sleep(attempt)  # 1s, 2s backoff
    
>       raise RuntimeError(
            f"Failed to pull LFS file {file_path} after {retries + 1} attempts: {last_err}"
        )
E       RuntimeError: Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/yam_description.tar.gz', '--exclude=']' returned non-zero exit status 1.

attempt    = 3
env        = {'ACCEPT_EULA': 'Y', 'ACTIONS_ID_TOKEN_REQUEST_TOKEN': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4ODI2YjE3LTZhMzAtNWY5Yi1iMTY5LT...-version=2.0', 'ACTIONS_ORCHESTRATION_ID': 'fc24accd-c30b-4a54-a0cd-b0f14b27d4a6.tests.ubuntu-24_04-arm_3_14_fal', ...}
file_path  = PosixPath('.../dimos/data/.lfs/yam_description.tar.gz')
last_err   = CalledProcessError(1, ['git', 'lfs', 'pull', '--include', 'data/.lfs/yam_description.tar.gz', '--exclude='])
relative_path = PosixPath('data/.lfs/yam_description.tar.gz')
repo_root  = PosixPath('.../work/dimos/dimos')
retries    = 2

dimos/utils/data.py:224: RuntimeError

The above exception was the direct cause of the following exception:

    def test_rollout_requires_policy_path_from_cli() -> None:
>       parsed = BlueprintConfigParser(learning_rollout_quest_openyam).parse(
            ["--LeRobotPolicyModule.policy-path", "outputs/checkpoint"],
            environ={},
        )


.../openyam/blueprints/test_learning_rollout.py:92: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../coordination/blueprint_config/parser.py:168: in parse
    key: plain(value)
        cli_tokens = ['--LeRobotPolicyModule.policy-path', 'outputs/checkpoint']
        config_path = None
        environ    = {}
        global_overrides = None
        overrides  = None
        schema     = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ion.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] ParserSchema object at 0xffce8e2b8280>
        self       = <dimos.core.coordination.blueprint_config.parser.BlueprintConfigParser object at 0xffce26bee630>
.../coordination/blueprint_config/values.py:50: in plain
    return [plain(item) for item in value]
        value      = [<[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attemp...params={'hold_duration': 0.1, 'requires_activation': True}, stream_bind={'gripper_command': 'policy_gripper_command'})]
.../coordination/blueprint_config/values.py:55: in plain
    return _copy_opaque(value)
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffcdb0a4dcd0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

value = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffcdb0a4dcd0>

    def _copy_opaque(value: Any) -> Any:
        try:
            return copy.deepcopy(value)
        except Exception as error:
>           raise BlueprintConfigError(
                f"Configuration value of type {type(value).__name__} cannot be copied safely: {error}"
            ) from error
E           dimos.core.coordination.blueprint_config.errors.BlueprintConfigError: Configuration value of type TaskConfig cannot be copied safely: Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/yam_description.tar.gz', '--exclude=']' returned non-zero exit status 1.

value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffcdb0a4dcd0>

.../coordination/blueprint_config/values.py:115: BlueprintConfigError
dimos.robot.manipulators.openyam.blueprints.test_learning_collection::test_native_openyam_paths_are_configurable_from_cli
Stack Traces | 3.29s run time
value = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xff5a125b4a70>

    def _copy_opaque(value: Any) -> Any:
        try:
>           return copy.deepcopy(value)

value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xff5a125b4a70>

.../coordination/blueprint_config/values.py:113: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
........................................../usr/lib/python3.12/copy.py:162: in deepcopy
    y = _reconstruct(x, memo, *rv)
        _nil       = []
        cls        = <class 'dimos.control.coordinator.TaskConfig'>
        copier     = None
        d          = 280762320112240
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        reductor   = <built-in method __reduce_ex__ of TaskConfig object at 0xff5a125b4a70>
        rv         = (<function __newobj__ at 0xff5b094b05e0>, (<class 'dimos.control.coordinator.TaskConfig'>,), {'auto_start': False, 'jo...lter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}, ...}, None, None)
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xff5a125b4a70>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xff5a0027bf10>
        deep       = True
        deepcopy   = <function deepcopy at 0xff5b08e42020>
        dictiter   = None
        func       = <function __newobj__ at 0xff5b094b05e0>
        listiter   = None
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        state      = {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_joint5', 'yam_joint...nt_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}, ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xff5a125b4a70>
        y          = <[AttributeError("'TaskConfig' object has no attribute 'name'") raised in repr()] TaskConfig object at 0xff5a03f28dd0>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff5b08c40ae0>
        d          = 280762075030208
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        x          = {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_joint5', 'yam_joint...nt_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}, ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xff5b08e42020>
        key        = 'params'
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        value      = {'bindings': [{'hand': 'right', 'target_frame': 'gripper_tip'}], 'joint_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}
        x          = {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_joint5', 'yam_joint...nt_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}, ...}
        y          = {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_joint5', 'yam_joint6'], 'name': 'teleop_openyam', 'priority': 20, ...}
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff5b08c40ae0>
        d          = 280762328561536
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        x          = {'bindings': [{'hand': 'right', 'target_frame': 'gripper_tip'}], 'joint_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xff5b08e42020>
        key        = 'robot_model'
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModelConfig object at 0xff5a11a0c190>
        x          = {'bindings': [{'hand': 'right', 'target_frame': 'gripper_tip'}], 'joint_command_filter_cutoff_hz': 30.0, 'max_command_tracking_error_deg': 10.0, 'max_joint_velocity_rad_s': 2.0, ...}
        y          = {}
........................................../usr/lib/python3.12/copy.py:143: in deepcopy
    y = copier(memo)
        _nil       = []
        cls        = <class 'dimos.manipulation.planning.spec.config.RobotModelConfig'>
        copier     = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...scription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] method object at 0xff5a100f0a40>
        d          = 280762307887504
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModelConfig object at 0xff5a11a0c190>
        y          = []
.venv/lib/python3.12.../site-packages/pydantic/main.py:978: in __deepcopy__
    _object_setattr(m, '__dict__', deepcopy(self.__dict__, memo=memo))
        cls        = <class 'dimos.manipulation.planning.spec.config.RobotModelConfig'>
        m          = RobotModelConfig()
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModelConfig object at 0xff5a11a0c190>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff5b08c40ae0>
        d          = 280762297409600
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        x          = {'auto_convert_meshes': True, 'base_link': 'base', 'base_pose': Pose(position=Vector([          0           0           0]), orientation=Quaternion(0.000000, 0.000000, 0.000000, 1.000000)), 'collision_exclusion_pairs': [], ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xff5b08e42020>
        key        = 'model'
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModel object at 0xff5a125b5790>
        x          = {'auto_convert_meshes': True, 'base_link': 'base', 'base_pose': Pose(position=Vector([          0           0           0]), orientation=Quaternion(0.000000, 0.000000, 0.000000, 1.000000)), 'collision_exclusion_pairs': [], ...}
        y          = {'default_rpc_timeout': 120.0, 'frame_id': None, 'frame_id_prefix': None, 'g': GlobalConfig(robot_ip=None, robot_ips=N...dless=True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}
........................................../usr/lib/python3.12/copy.py:162: in deepcopy
    y = _reconstruct(x, memo, *rv)
        _nil       = []
        cls        = <class 'dimos.robot.assets.model.RobotModel'>
        copier     = None
        d          = 280762320115600
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        reductor   = <built-in method __reduce_ex__ of RobotModel object at 0xff5a125b5790>
        rv         = (<function __newobj__ at 0xff5b094b05e0>, (<class 'dimos.robot.assets.model.RobotModel'>,), {'_fixed_frames': (), '_fi...xclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xff5a8472ead0>),), ...}, None, None)
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModel object at 0xff5a125b5790>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xff5a0027ba60>
        deep       = True
        deepcopy   = <function deepcopy at 0xff5b08e42020>
        dictiter   = None
        func       = <function __newobj__ at 0xff5b094b05e0>
        listiter   = None
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        state      = {'_fixed_frames': (), '_fixed_joints': (), '_joint_position_limits': (), '_package_paths': (('yam_description', <[Runt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xff5a8472ead0>),), ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModel object at 0xff5a125b5790>
        y          = <[AttributeError("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff5a03f2a060>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff5b08c40ae0>
        d          = 280762014982720
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        x          = {'_fixed_frames': (), '_fixed_joints': (), '_joint_position_limits': (), '_package_paths': (('yam_description', <[Runt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xff5a8472ead0>),), ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xff5b08e42020>
        key        = '_source_path'
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...cription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xff5a8472ea50>
        x          = {'_fixed_frames': (), '_fixed_joints': (), '_joint_position_limits': (), '_package_paths': (('yam_description', <[Runt...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xff5a8472ead0>),), ...}
        y          = {}
........................................../usr/lib/python3.12/copy.py:141: in deepcopy
    copier = getattr(x, "__deepcopy__", None)
        _nil       = []
        cls        = <class 'dimos.utils.data.LfsPath'>
        copier     = None
        d          = 280764234263120
        memo       = {280762014982720: {}, 280762075030208: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3',...True, local_relay=False, relay_url=None, dimos_cloud_url='https://api.dimensional.org', dimos_api_key=None), ...}, ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...cription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xff5a8472ea50>
        y          = []
dimos/utils/data.py:370: in __getattribute__
    resolved = object.__getattribute__(self, "_ensure_downloaded")()
        name       = '__deepcopy__'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...cription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xff5a8472ea50>
dimos/utils/data.py:353: in _ensure_downloaded
    cache = get_data(filename)
        cache      = None
        filename   = 'yam_description/i2rt/yam.urdf'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...cription.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xff5a8472ea50>
dimos/utils/data.py:310: in get_data
    archive_path = _decompress_archive(_pull_lfs_archive(archive_name))
        archive_name = 'yam_description'
        data_dir   = PosixPath('.../dimos/dimos/data')
        file_path  = PosixPath('.../dimos/dimos/data/yam_description/i2rt/yam.urdf')
        name       = 'yam_description/i2rt/yam.urdf'
        nested_path = PosixPath('i2rt/yam.urdf')
        path_parts = ('yam_description', 'i2rt', 'yam.urdf')
dimos/utils/data.py:254: in _pull_lfs_archive
    _lfs_pull(file_path, repo_root)
        file_path  = PosixPath('.../dimos/data/.lfs/yam_description.tar.gz')
        filename   = 'yam_description'
        repo_root  = PosixPath('.../work/dimos/dimos')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

file_path = PosixPath('.../dimos/data/.lfs/yam_description.tar.gz')
repo_root = PosixPath('.../work/dimos/dimos')

    def _lfs_pull(file_path: Path, repo_root: Path, *, retries: int = 2) -> None:
        relative_path = file_path.relative_to(repo_root)
    
        env = os.environ.copy()
        env["GIT_LFS_FORCE_PROGRESS"] = "1"
    
        last_err: subprocess.CalledProcessError | None = None
        for attempt in range(1, retries + 2):  # retries + 1 total attempts
            try:
                subprocess.run(
                    # --exclude= overrides lfs.fetchexclude from .lfsconfig, which
                    # otherwise silently skips data/.lfs/* even when --include matches.
                    ["git", "lfs", "pull", "--include", str(relative_path), "--exclude="],
                    cwd=repo_root,
                    check=True,
                    env=env,
                )
                return
            except subprocess.CalledProcessError as e:
                last_err = e
                if attempt <= retries:
                    time.sleep(attempt)  # 1s, 2s backoff
    
>       raise RuntimeError(
            f"Failed to pull LFS file {file_path} after {retries + 1} attempts: {last_err}"
        )
E       RuntimeError: Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/yam_description.tar.gz', '--exclude=']' returned non-zero exit status 1.

attempt    = 3
env        = {'ACCEPT_EULA': 'Y', 'ACTIONS_ID_TOKEN_REQUEST_TOKEN': 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjM4ODI2YjE3LTZhMzAtNWY5Yi1iMTY5LT...-version=2.0', 'ACTIONS_ORCHESTRATION_ID': 'fc24accd-c30b-4a54-a0cd-b0f14b27d4a6.tests.ubuntu-24_04-arm_3_14_fal', ...}
file_path  = PosixPath('.../dimos/data/.lfs/yam_description.tar.gz')
last_err   = CalledProcessError(1, ['git', 'lfs', 'pull', '--include', 'data/.lfs/yam_description.tar.gz', '--exclude='])
relative_path = PosixPath('data/.lfs/yam_description.tar.gz')
repo_root  = PosixPath('.../work/dimos/dimos')
retries    = 2

dimos/utils/data.py:224: RuntimeError

The above exception was the direct cause of the following exception:

    def test_native_openyam_paths_are_configurable_from_cli() -> None:
>       parsed = BlueprintConfigParser(learning_collect_quest_openyam).parse(
            [
                "--nativecollectionrecorder.store.path",
                "/tmp/native-openyam.mcap",
                "--WristCamera.webcam.camera-index",
                ".../v4l/by-id/usb-wrist-camera",
                "--task",
                "pick up the red block",
            ],
            environ={},
        )


.../openyam/blueprints/test_learning_collection.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../coordination/blueprint_config/parser.py:168: in parse
    key: plain(value)
        cli_tokens = ['--nativecollectionrecorder.store.path', '/tmp/native-openyam.mcap', '--WristCamera.webcam.camera-index', '.../v4l/by-id/usb-wrist-camera', '--task', 'pick up the red block']
        config_path = None
        environ    = {}
        global_overrides = None
        overrides  = None
        schema     = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ion.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] ParserSchema object at 0xff5a1007a080>
        self       = <dimos.core.coordination.blueprint_config.parser.BlueprintConfigParser object at 0xff5a03f17f80>
.../coordination/blueprint_config/values.py:50: in plain
    return [plain(item) for item in value]
        value      = [<[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attemp...yam_joint6', 'arm/gripper'], priority=30, auto_start=False, params={'start_position_tolerance': 0.05}, stream_bind={})]
.../coordination/blueprint_config/values.py:55: in plain
    return _copy_opaque(value)
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xff5a125b4a70>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

value = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xff5a125b4a70>

    def _copy_opaque(value: Any) -> Any:
        try:
            return copy.deepcopy(value)
        except Exception as error:
>           raise BlueprintConfigError(
                f"Configuration value of type {type(value).__name__} cannot be copied safely: {error}"
            ) from error
E           dimos.core.coordination.blueprint_config.errors.BlueprintConfigError: Configuration value of type TaskConfig cannot be copied safely: Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/yam_description.tar.gz', '--exclude=']' returned non-zero exit status 1.

value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/yam_description.tar.gz after 3 attempt...ption.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xff5a125b4a70>

.../coordination/blueprint_config/values.py:115: BlueprintConfigError
dimos.core.test_isolated_python_end_to_end::test_example_script_exits_after_printing_results
Stack Traces | 4.35s run time
def test_example_script_exits_after_printing_results() -> None:
        repository = Path(__file__).parents[2]
    
        result = subprocess.run(
            [sys.executable, "examples/external_python_module/run.py"],
            cwd=repository,
            capture_output=True,
            text=True,
            timeout=30,
        )
    
>       assert result.returncode == 0, result.stderr
E       AssertionError:   + Exception Group Traceback (most recent call last):
E           |   File ".../examples/external_python_module/run.py", line 38, in <module>
E           |     run_example()
E           |   File ".../examples/external_python_module/run.py", line 22, in run_example
E           |     coordinator = ModuleCoordinator.build(
E           |                   ^^^^^^^^^^^^^^^^^^^^^^^^
E           |   File ".../core/coordination/module_coordinator.py", line 377, in build
E           |     coordinator.build_all_modules()
E           |   File ".../core/coordination/module_coordinator.py", line 249, in build_all_modules
E           |     safe_thread_map(modules, lambda m: m.build())
E           |   File ".../dimos/utils/safe_thread_map.py", line 84, in safe_thread_map
E           |     raise ExceptionGroup("safe_thread_map failed", errors)
E           | ExceptionGroup: safe_thread_map failed (1 sub-exception)
E           +-+---------------- 1 ----------------
E             | dimos.protocol.rpc.rpc_utils.RemoteError: [Remote builtins.RuntimeError] Isolated Python environment preparation failed (exit 1): Resolved 195 packages in 49ms
E         error: The lockfile at `uv.lock` needs to be updated, but `--locked` was
E                provided.
E         
E         hint: To update the lockfile, run `uv lock`.
E         
E         Remote traceback:
E         Traceback (most recent call last):
E           File ".../protocol/rpc/zenohrpc.py", line 199, in _execute_rpc
E             response = f(*args[0], **args[1])
E                        ^^^^^^^^^^^^^^^^^^^^^^
E           File ".../protocol/rpc/spec.py", line 116, in override_f
E             return getattr(module, fname)(*args, **kwargs)
E                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E           File ".../dimos/core/isolated_python_module.py", line 211, in build
E             super().build()
E           File ".../dimos/core/native_module.py", line 236, in build
E             self._maybe_build()
E           File ".../dimos/core/isolated_python_module.py", line 207, in _maybe_build
E             self._run_prepare()
E           File ".../dimos/core/isolated_python_module.py", line 127, in _run_prepare
E             raise RuntimeError(
E         RuntimeError: Isolated Python environment preparation failed (exit 1): Resolved 195 packages in 49ms
E         error: The lockfile at `uv.lock` needs to be updated, but `--locked` was
E                provided.
E         
E         hint: To update the lockfile, run `uv lock`.
E         
E             | 
E             | The above exception was the direct cause of the following exception:
E             | 
E             | Traceback (most recent call last):
E             |   File ".../dimos/utils/safe_thread_map.py", line 68, in safe_thread_map
E             |     outcomes[idx] = fut.result()
E             |                     ^^^^^^^^^^^^
E             |   File ".............../usr/lib/python3.12........./concurrent/futures/_base.py", line 449, in result
E             |     return self.__get_result()
E             |            ^^^^^^^^^^^^^^^^^^^
E             |   File ".............../usr/lib/python3.12........./concurrent/futures/_base.py", line 401, in __get_result
E             |     raise self._exception
E             |   File ".............../usr/lib/python3.12....../concurrent/futures/thread.py", line 58, in run
E             |     result = self.fn(*self.args, **self.kwargs)
E             |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E             |   File ".../core/coordination/module_coordinator.py", line 249, in <lambda>
E             |     safe_thread_map(modules, lambda m: m.build())
E             |                                        ^^^^^^^^^
E             |   File ".../dimos/core/rpc_client.py", line 93, in __call__
E             |     result, unsub_fn = self._rpc.call_sync(
E             |                        ^^^^^^^^^^^^^^^^^^^^
E             |   File ".../protocol/rpc/spec.py", line 88, in call_sync
E             |     raise result
E             | RuntimeError: Isolated Python environment preparation failed (exit 1): Resolved 195 packages in 49ms
E         error: The lockfile at `uv.lock` needs to be updated, but `--locked` was
E                provided.
E         
E         hint: To update the lockfile, run `uv lock`.
E             +------------------------------------
E         
E       assert 1 == 0
E        +  where 1 = CompletedProcess(args=['.../dimos/dimos/.venv/bin/python', 'examples/external_python_module/run.py'], returncode=1, stdout="05:22:41.101 [inf][dination/module_coordinator.py] Building the blueprint\n05:22:41.102 [inf][ce/system_configurator/base.py] Pytest run detected: skipping system configuration.\n05:22:41.103 [inf][dination/module_coordinator.py] Starting the modules\n05:22:42.396 [inf][ation/worker_manager_python.py] Worker pool started. n_workers=2\n05:22:43.741 [inf][otocol/service/zenohservice.py] Zenoh session opened connect=[] gossip=True listen=['tcp/127.0.0.1:0'] mode=peer multicast_interface=lo\n05:22:43.751 [inf][/coordination/python_worker.py] Deployed module. module=ExampleExternal module_id=0 worker_id=0\n05:22:43.755 [inf][otocol/service/zenohservice.py] Zenoh session opened connect=[] gossip=True listen=['tcp/127.0.0.1:0'] mode=peer multicast_interface=lo\n05:22:43.769 [inf][otocol/service/zenohservice.py] Zenoh session opened connect=[] gossip=True listen=['tcp/127.0.0.1:0'] mode=peer multicast_interface=lo\n05:22:43.773 [inf][/coordination/python_worker.py] Deployed module. module=Offset module_id=1 worker_id=1\n05:22:43.887 [err][dimos/protoco...esult()\n    |            ^^^^^^^^^^^^^^^^^^^\n    |   File ".............../usr/lib/python3.12........./concurrent/futures/_base.py", line 401, in __get_result\n    |     raise self._exception\n    |   File ".............../usr/lib/python3.12....../concurrent/futures/thread.py", line 58, in run\n    |     result = self.fn(*self.args, **self.kwargs)\n    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n    |   File ".../core/coordination/module_coordinator.py", line 249, in <lambda>\n    |     safe_thread_map(modules, lambda m: m.build())\n    |                                        ^^^^^^^^^\n    |   File ".../dimos/core/rpc_client.py", line 93, in __call__\n    |     result, unsub_fn = self._rpc.call_sync(\n    |                        ^^^^^^^^^^^^^^^^^^^^\n    |   File ".../protocol/rpc/spec.py", line 88, in call_sync\n    |     raise result\n    | RuntimeError: Isolated Python environment preparation failed (exit 1): Resolved 195 packages in 49ms\nerror: The lockfile at `uv.lock` needs to be updated, but `--locked` was\n       provided.\n\nhint: To update the lockfile, run `uv lock`.\n    +------------------------------------\n').returncode

repository = PosixPath('.../work/dimos/dimos')
result     = CompletedProcess(args=['.../dimos/dimos/.venv/bin/python', 'examples/external_python_module/run.py'], re...d` was\n       provided.\n\nhint: To update the lockfile, run `uv lock`.\n    +------------------------------------\n')

dimos/core/test_isolated_python_end_to_end.py:98: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch from a19c88a to 8a4b255 Compare September 1, 2026 04:46
@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch 2 times, most recently from 00b98d8 to 611eabe Compare September 1, 2026 17:00
@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch from 611eabe to ecc4e45 Compare September 1, 2026 17:16
@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch from ecc4e45 to 80d489a Compare September 1, 2026 17:17
@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch from 80d489a to cb38d4d Compare September 1, 2026 17:56
@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch from cb38d4d to 4c265e6 Compare September 1, 2026 18:54
@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch from 4c265e6 to 65e9b0e Compare September 1, 2026 23:51
joint_names: Ordinary joints this task owns, in command order.
priority: Priority for arbitration.
hold_duration: Seconds to keep emitting a target; 0.0 holds forever.
requires_activation: Reject commands until explicitly activated, and

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bad design why is this required

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this file for

primary_by_hand = {
OperatorHand.LEFT: msg.left_primary,
OperatorHand.RIGHT: msg.right_primary,
grip_by_hand = {

@TomCC7 TomCC7 Sep 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ruthwikdasyam wanted to change teleop deadman lock to grip instead of AX to free more buttons for policy rollout. (notice for AI that this comment is for human and no need to address)


TASK_EXPOSES: dict[str, list[str]] = {
"trajectory": ["execute", "cancel", "get_state", "get_status"],
"trajectory": ["activate", "deactivate", "execute", "cancel", "get_state", "get_status"],

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't need activate/deactive this invalidates the whole point of arbitration



class PolicyRolloutSupervisor(Module):
"""Own policy/task activation without blocking input or RPC handlers."""

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what why we need this class instead of policy only?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and what's the use of this?

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