Skip to content

feat(a1z): a1z learning workflow - #3318

Closed
TomCC7 wants to merge 7 commits into
feat/openyam-lerobot-rolloutfrom
cc/advx/a1z-learning
Closed

feat(a1z): a1z learning workflow#3318
TomCC7 wants to merge 7 commits into
feat/openyam-lerobot-rolloutfrom
cc/advx/a1z-learning

Conversation

@TomCC7

@TomCC7 TomCC7 commented Aug 1, 2026

Copy link
Copy Markdown
Member

Contribution path

Problem

The A1Z learning workflow needs safe teaching, replay, dataset preparation, and learned-policy execution on top of the shared hardware and isolated LeRobot layers.

Solution

  • Add episode loading, validation, smoothing, time scaling, and replay trajectory generation.
  • Add A1Z teach, replay, and policy blueprint factories using the isolated LeRobot contract from refactor(imitation): isolate LeRobot policy runtime #3315.
  • Extend the current dimos hardware a1z CLI with teach, replay, and run-policy while preserving the lower stack's diagnostics and CAN configuration.
  • Add episode undo support, the Galaxea A1Z data-preparation profile, immediate camera metadata, and deterministic recorder shutdown.
  • Preserve the newer A1Z hardware implementation already present below feat(damiao): support native macOS CAN transport #3465 instead of replaying obsolete hardware commits.

How to Test

Focused A1Z CLI, camera, episode monitor, data-preparation, recorder, teach, and replay suites: 62 passed.

Targeted mypy passed for seven production modules. Blueprint generation and changed-file pre-commit checks passed.

Checklist

  • CLA signed, if required
  • Tests added or updated
  • Documentation added or updated

@TomCC7 TomCC7 changed the title feat(a1z): add learning workflow feat(a1z): a1z learning workflow Aug 1, 2026
@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

❌ 6 Tests Failed:

Tests completed Failed Passed Skipped
4729 6 4723 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.67s 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 796ms
    | 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 796ms
    | 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 796ms
    | 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.17s 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 0xfffb7094ab20>

.../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 0xfffc5b972a50>
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 0xfffc5b972a50>
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': 'f7705bc4-8d02-4cf6-922f-bab902d0527a.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.28s 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 0xff85316f2930>

    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 0xff85316f2930>

.../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          = 280947525101872
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff85316f2930>
        rv         = (<function __newobj__ at 0xff86244b05e0>, (<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 0xff85316f2930>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xff84f94ecd60>
        deep       = True
        deepcopy   = <function deepcopy at 0xff8623e72020>
        dictiter   = None
        func       = <function __newobj__ at 0xff86244b05e0>
        listiter   = None
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff85316f2930>
        y          = <[AttributeError("'TaskConfig' object has no attribute 'name'") raised in repr()] TaskConfig object at 0xff8520a36840>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff8623ca0ae0>
        d          = 280947271696960
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff8623e72020>
        key        = 'params'
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff8623ca0ae0>
        d          = 280947511758336
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff8623e72020>
        key        = 'robot_model'
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff8530b55a90>
        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 0xff8521e3cbc0>
        d          = 280947512924816
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff8530b55a90>
        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       = {280946582437056: {}, 280947271696960: {'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 0xff8530b55a90>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff8623ca0ae0>
        d          = 280947511757056
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff8623e72020>
        key        = 'model'
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff85316f37a0>
        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          = 280947525105568
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff85316f37a0>
        rv         = (<function __newobj__ at 0xff86244b05e0>, (<class 'dimos.robot.assets.model.RobotModel'>,), {'_fixed_frames': (), '_fi...xclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xff859e7bded0>),), ...}, 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 0xff85316f37a0>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xff84f93967a0>
        deep       = True
        deepcopy   = <function deepcopy at 0xff8623e72020>
        dictiter   = None
        func       = <function __newobj__ at 0xff86244b05e0>
        listiter   = None
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff859e7bded0>),), ...}
        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 0xff85316f37a0>
        y          = <[AttributeError("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff8520c524e0>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff8623ca0ae0>
        d          = 280946582437056
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff859e7bded0>),), ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xff8623e72020>
        key        = '_source_path'
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff859e7bc0d0>
        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 0xff859e7bded0>),), ...}
        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          = 280949354643664
        memo       = {280946582437056: {}, 280947271696960: {'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 0xff859e7bc0d0>
        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 0xff859e7bc0d0>
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 0xff859e7bc0d0>
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': 'f7705bc4-8d02-4cf6-922f-bab902d0527a.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 0xff84faaa7bc0>
        self       = <dimos.core.coordination.blueprint_config.parser.BlueprintConfigParser object at 0xff8520a379b0>
.../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 0xff85316f2930>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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 0xff85316f2930>

    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 0xff85316f2930>

.../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.39s 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 0xfffb7249c290>

    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 0xfffb7249c290>

.../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          = 281455419310736
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffb7249c290>
        rv         = (<function __newobj__ at 0xfffc6581c5e0>, (<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 0xfffb7249c290>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xfffb4dab3b50>
        deep       = True
        deepcopy   = <function deepcopy at 0xfffc651be020>
        dictiter   = None
        func       = <function __newobj__ at 0xfffc6581c5e0>
        listiter   = None
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffb7249c290>
        y          = <[AttributeError("'TaskConfig' object has no attribute 'name'") raised in repr()] TaskConfig object at 0xfffb4df729f0>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc64fbcae0>
        d          = 281454805184832
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffc651be020>
        key        = 'params'
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffc64fbcae0>
        d          = 281455430180864
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffc651be020>
        key        = 'robot_model'
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffb724930c0>
        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 0xfffb4dabd400>
        d          = 281455419273408
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffb724930c0>
        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       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffb724930c0>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc64fbcae0>
        d          = 281455430188352
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffc651be020>
        key        = 'model'
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffb7249ce60>
        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          = 281455419313760
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffb7249ce60>
        rv         = (<function __newobj__ at 0xfffc6581c5e0>, (<class 'dimos.robot.assets.model.RobotModel'>,), {'_fixed_frames': (), '_fi...xclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffc5b9729d0>),), ...}, 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 0xfffb7249ce60>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xfffb4dab3a60>
        deep       = True
        deepcopy   = <function deepcopy at 0xfffc651be020>
        dictiter   = None
        func       = <function __newobj__ at 0xfffc6581c5e0>
        listiter   = None
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffc5b9729d0>),), ...}
        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 0xfffb7249ce60>
        y          = <[AttributeError("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xfffb72cc3770>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc64fbcae0>
        d          = 281454810698944
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffc5b9729d0>),), ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xfffc651be020>
        key        = '_source_path'
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffc5b972a50>
        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 0xfffc5b9729d0>),), ...}
        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          = 281459333474896
        memo       = {281454805184832: {'auto_start': False, 'joint_names': ['yam_joint1', 'yam_joint2', 'yam_joint3', 'yam_joint4', 'yam_j...dless=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 0xfffc5b972a50>
        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 0xfffc5b972a50>
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 0xfffc5b972a50>
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': 'f7705bc4-8d02-4cf6-922f-bab902d0527a.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 0xfffb4dadd880>
        self       = <dimos.core.coordination.blueprint_config.parser.BlueprintConfigParser object at 0xfffb4e01b5f0>
.../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 0xfffb7249c290>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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 0xfffb7249c290>

    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 0xfffb7249c290>

.../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.51s 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 51ms
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 51ms
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 51ms
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:49.606 [inf][dination/module_coordinator.py] Building the blueprint\n05:22:49.608 [inf][ce/system_configurator/base.py] Pytest run detected: skipping system configuration.\n05:22:49.608 [inf][dination/module_coordinator.py] Starting the modules\n05:22:50.941 [inf][ation/worker_manager_python.py] Worker pool started. n_workers=2\n05:22:52.317 [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:52.323 [inf][/coordination/python_worker.py] Deployed module. module=ExampleExternal module_id=0 worker_id=0\n05:22:52.326 [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:52.328 [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:52.332 [inf][/coordination/python_worker.py] Deployed module. module=Offset module_id=1 worker_id=1\n05:22:52.453 [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 51ms\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
dimos.codebase_checks.test_import_from_source::test_import_from_source
Stack Traces | 9.11s run time
def test_import_from_source() -> None:
        """Fail if any name is imported from a module that only re-imported it."""
        violations = find_reexport_imports()
        if violations:
            listing = "\n".join(
                f"  - {p.relative_to(DIMOS_PROJECT_ROOT)}:{line}: `{name}` imported from "
                f"{src}, but defined in {origin}"
                for p, line, name, src, origin in sorted(violations)
            )
>           raise AssertionError(
                f"Found import(s) that pull a name from a re-exporter:\n{listing}\n\n"
                "Import each name straight from the module that defines it (shown above). "
                "If a module re-exports a name on purpose, mark its import with "
                "`# noqa: F401` or the `from x import Y as Y` form, and that re-export "
                "will be allowed."
            )
E           AssertionError: Found import(s) that pull a name from a re-exporter:
E             - .../manipulators/a1z/test_teach_replay.py:27: `EpisodeStatus` imported from dimos.imitation.collection.episode_monitor, but defined in dimos.msgs.imitation_msgs.EpisodeStatus
E           
E           Import each name straight from the module that defines it (shown above). If a module re-exports a name on purpose, mark its import with `# noqa: F401` or the `from x import Y as Y` form, and that re-export will be allowed.

listing    = '  - .../manipulators/a1z/test_teach_replay.py:27: `EpisodeStatus` imported from dimos.imitation.collection.episode_monitor, but defined in dimos.msgs.imitation_msgs.EpisodeStatus'
violations = [(PosixPath('/home/runner/work/dimos/dimos/.../manipulators/a1z/test_teach_replay.py'), 27, 'EpisodeStatus', 'dimos.imitation.collection.episode_monitor', 'dimos.msgs.imitation_msgs.EpisodeStatus')]

dimos/codebase_checks/test_import_from_source.py:149: 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/experimental-lerobot-policy branch 5 times, most recently from 884a430 to 2ffca94 Compare August 18, 2026 00:07
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch 2 times, most recently from 188f271 to e862f0d Compare August 21, 2026 05:15
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch 2 times, most recently from 63bb30c to ef7cab3 Compare August 21, 2026 06:51
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch 2 times, most recently from 5ce3e7c to 776ca6e Compare August 25, 2026 00:56
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch 2 times, most recently from 0702490 to 78dee1f Compare August 25, 2026 22:50
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch from 776ca6e to 070a65c Compare August 25, 2026 22:50
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch from 1d816c6 to cf0e7ba Compare August 25, 2026 22:53
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch 2 times, most recently from 1199ef4 to fff3eb7 Compare August 25, 2026 23:08
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch from cf0e7ba to a8f5840 Compare August 25, 2026 23:08
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch from fff3eb7 to 14b01ef Compare August 25, 2026 23:17
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch 2 times, most recently from 124f4f8 to 5d370f3 Compare August 25, 2026 23:25
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch 2 times, most recently from 3e11ccf to 776ca6e Compare August 25, 2026 23:50
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch from 5d370f3 to 0702490 Compare August 25, 2026 23:50
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch from 776ca6e to 55059b7 Compare August 29, 2026 19:26
@TomCC7
TomCC7 force-pushed the feat/experimental-lerobot-policy branch 2 times, most recently from 41d5fb1 to 6bba8fd Compare August 29, 2026 19:58
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch from 98a00d8 to 89a7e11 Compare August 29, 2026 19:58
@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 cc/advx/a1z-learning branch 2 times, most recently from 461cc3c to 9982430 Compare September 1, 2026 05:15
@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch from 8a4b255 to 00b98d8 Compare September 1, 2026 05:15
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch from 9982430 to bd24507 Compare September 1, 2026 17:00
@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch from 00b98d8 to 611eabe Compare September 1, 2026 17:00
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch from bd24507 to 34d818a Compare September 1, 2026 17:16
@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch 2 times, most recently from ecc4e45 to 80d489a Compare September 1, 2026 17:17
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch from 34d818a to 809a268 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 cc/advx/a1z-learning branch 2 times, most recently from a694960 to 86de9c9 Compare September 1, 2026 18:54
@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 cc/advx/a1z-learning branch from 86de9c9 to ee7b5fe Compare September 1, 2026 23:51
@TomCC7
TomCC7 force-pushed the feat/openyam-lerobot-rollout branch 2 times, most recently from 65e9b0e to 19803df Compare September 2, 2026 19:06
@TomCC7 TomCC7 closed this Sep 3, 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