Skip to content

feat(a1z): a1z learning workflow - #3318

Draft
TomCC7 wants to merge 1 commit into
feat/experimental-lerobot-policyfrom
cc/advx/a1z-learning
Draft

feat(a1z): a1z learning workflow#3318
TomCC7 wants to merge 1 commit into
feat/experimental-lerobot-policyfrom
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 feat: LeRobot rollout on openyam #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

❌ 14 Tests Failed:

Tests completed Failed Passed Skipped
4510 14 4496 178
View the top 3 failed test(s) by shortest run time
::dimos.imitation.policy.lerobot.python.tests.test_dataprep
Stack Traces | 0s run time
ImportError while importing test module '.../python/tests/test_dataprep.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
.../python/tests/test_dataprep.py:19: in <module>
    from dimos_lerobot.dataprep import write
E   ModuleNotFoundError: No module named 'dimos_lerobot'
::dimos.imitation.policy.lerobot.python.tests.test_runtime
Stack Traces | 0s run time
ImportError while importing test module '.../python/tests/test_runtime.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
.../python/tests/test_runtime.py:22: in <module>
    from dimos_lerobot import runtime as policy_runtime
E   ModuleNotFoundError: No module named 'dimos_lerobot'
dimos.robot.manipulators.a1z.test_teach_replay::test_policy_blueprint_uses_catalog_and_all_joints
Stack Traces | 0.002s run time
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0xffcc2f7422d0>

    def test_policy_blueprint_uses_catalog_and_all_joints(monkeypatch) -> None:
        fake_runtime = ModuleType("dimos.experimental.robot_policy.lerobot")
        fake_runtime.LeRobotPolicyConfig = _FakePolicyConfig
        fake_runtime.LeRobotPolicyModule = _FakePolicyModule
        monkeypatch.setitem(sys.modules, "dimos.experimental.robot_policy.lerobot", fake_runtime)
        policies = {"pick": _FakePolicyConfig(policy_path="checkpoints/pick")}
    
>       blueprint = make_a1z_learned_policy_blueprint(
            policies,
            policy_module=_FakePolicyModule,
        )

fake_runtime = <module 'dimos.experimental.robot_policy.lerobot'>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0xffcc2f7422d0>
policies   = {'pick': _FakePolicyConfig(policy_path='checkpoints/pick')}

.../manipulators/a1z/test_teach_replay.py:121: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

policies = {'pick': _FakePolicyConfig(policy_path='checkpoints/pick')}

    def make_a1z_learned_policy_blueprint(
        policies: dict[str, LeRobotPolicyConfig],
        *,
        policy_module: type[LeRobotPolicyModule] | None = None,
        camera_index: int = 0,
        fps: float = A1Z_TEACH_CAMERA_FPS,
    ) -> Blueprint:
        """Compose an A1Z stack exposing a catalog of trained LeRobot policies."""
        if policy_module is None:
            # LeRobot is optional and intentionally imported only when this factory is used.
            from dimos.imitation.policy.lerobot.module import LeRobotPolicyModule
    
            policy_module = LeRobotPolicyModule
>       hardware = a1z_hardware(
            "arm",
            has_gripper=True,
            dynamics_urdf_path=A1Z_G1Z_MODEL_PATH,
        )
E       TypeError: a1z_hardware() got an unexpected keyword argument 'has_gripper'

camera_index = 0
fps        = 15.0
policies   = {'pick': _FakePolicyConfig(policy_path='checkpoints/pick')}
policy_module = <class 'dimos.robot.manipulators.a1z.test_teach_replay._FakePolicyModule'>

.../a1z/blueprints/learning.py:160: TypeError
dimos.robot.manipulators.a1z.test_teach_replay::test_replay_blueprint_controls_arm_and_gripper
Stack Traces | 0.002s run time
def test_replay_blueprint_controls_arm_and_gripper() -> None:
>       blueprint = make_a1z_replay_blueprint()


.../manipulators/a1z/test_teach_replay.py:105: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def make_a1z_replay_blueprint() -> Blueprint:
        """Run a validated seven-joint arm/gripper trajectory through the coordinator."""
>       hardware = a1z_hardware(
            "arm",
            has_gripper=True,
            dynamics_urdf_path=A1Z_G1Z_MODEL_PATH,
        )
E       TypeError: a1z_hardware() got an unexpected keyword argument 'has_gripper'


.../a1z/blueprints/learning.py:104: TypeError
dimos.robot.manipulators.a1z.test_teach_replay::test_teach_blueprint_records_webcam_and_all_joint_state
Stack Traces | 0.002s run time
tmp_path = PosixPath('.../pytest-0/popen-gw2/test_teach_blueprint_records_w0')

    def test_teach_blueprint_records_webcam_and_all_joint_state(tmp_path: Path) -> None:
>       blueprint = make_a1z_teach_blueprint(tmp_path / "teach.db", camera_index=3)

tmp_path   = PosixPath('.../pytest-0/popen-gw2/test_teach_blueprint_records_w0')

.../manipulators/a1z/test_teach_replay.py:85: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

db_path = PosixPath('.../pytest-0/popen-gw2/test_teach_blueprint_records_w0/teach.db')

    def make_a1z_teach_blueprint(
        db_path: Path,
        *,
        task_label: str | None = None,
        camera_index: int = 0,
        gripper_free_drive: bool = False,
    ) -> Blueprint:
        """Record camera and measured arm/gripper state while hand-drivable."""
>       hardware = a1z_hardware(
            "arm",
            has_gripper=True,
            dynamics_urdf_path=A1Z_G1Z_MODEL_PATH,
            adapter_config=A1ZConfig(
                gripper=A1ZGripperConfig(),
                teaching=A1ZTeachingConfig(gripper_free_drive=gripper_free_drive),
            ),
        )
E       TypeError: a1z_hardware() got an unexpected keyword argument 'has_gripper'

camera_index = 3
db_path    = PosixPath('.../pytest-0/popen-gw2/test_teach_blueprint_records_w0/teach.db')
gripper_free_drive = False
task_label = None

.../a1z/blueprints/learning.py:78: TypeError
dimos.codebase_checks.test_blueprint_kwargs::test_blueprint_atom_kwargs_match_module_config[teleop-quest-dual-openyam]
Stack Traces | 0.003s run time
blueprint_name = 'teleop-quest-dual-openyam'

    @pytest.mark.parametrize("blueprint_name", _blueprint_params())
    def test_blueprint_atom_kwargs_match_module_config(blueprint_name: str) -> None:
        """Fail when blueprint kwargs cannot be consumed by their target module."""
        blueprint = _get_blueprint_or_skip(blueprint_name)
    
        violations: list[str] = []
        for atom in blueprint.blueprints:
            unknown_kwargs = sorted(set(atom.kwargs) - _allowed_kwarg_names(atom.module))
            if unknown_kwargs:
                violations.append(
                    f"{atom.module.__module__}.{atom.module.__name__}: unknown kwargs {unknown_kwargs}"
                )
    
        if violations:
            listing = "\n".join(f"  - {violation}" for violation in violations)
>           raise AssertionError(
                f"Blueprint {blueprint_name!r} passes unknown module kwargs:\n{listing}\n\n"
                "Blueprint kwargs are forwarded into the module constructor. For modules "
                "with an explicit `config` annotation, use fields from that config model; "
                "for legacy modules with direct constructor parameters, use the declared "
                "`__init__` keyword names."
            )
E           AssertionError: Blueprint 'teleop-quest-dual-openyam' passes unknown module kwargs:
E             - dimos.teleop.quest.quest_extensions.ArmTeleopModule: unknown kwargs ['task_names']
E           
E           Blueprint kwargs are forwarded into the module constructor. For modules with an explicit `config` annotation, use fields from that config model; for legacy modules with direct constructor parameters, use the declared `__init__` keyword names.

atom       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] BlueprintAtom object at 0xffbec19ba990>
blueprint  = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...box_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] Blueprint object at 0xffbec19b9d30>
blueprint_name = 'teleop-quest-dual-openyam'
listing    = "  - dimos.teleop.quest.quest_extensions.ArmTeleopModule: unknown kwargs ['task_names']"
unknown_kwargs = []
violations = ["dimos.teleop.quest.quest_extensions.ArmTeleopModule: unknown kwargs ['task_names']"]

dimos/codebase_checks/test_blueprint_kwargs.py:103: AssertionError
dimos.codebase_checks.test_no_init_files::test_no_init_files
Stack Traces | 0.022s run time
def test_no_init_files():
        dimos_dir = DIMOS_PROJECT_ROOT / "dimos"
        init_files = sorted(dimos_dir.rglob("__init__.py"))
        # The root dimos/__init__.py is allowed for the porcelain lazy import.
        init_files = [f for f in init_files if f != dimos_dir / "__init__.py"]
        if init_files:
            listing = "\n".join(f"  - {f.relative_to(dimos_dir)}" for f in init_files)
>           raise AssertionError(
                f"Found __init__.py files in dimos/:\n{listing}\n\n"
                "__init__.py files are not allowed because they lead to unnecessary "
                "extraneous imports. Everything should be imported straight from the "
                "source module."
            )
E           AssertionError: Found __init__.py files in dimos/:
E             - .../python/dimos_lerobot/__init__.py
E           
E           __init__.py files are not allowed because they lead to unnecessary extraneous imports. Everything should be imported straight from the source module.

dimos_dir  = PosixPath('.../dimos/dimos/dimos')
init_files = [PosixPath('.../dimos/dimos/dimos/.../python/dimos_lerobot/__init__.py')]
listing    = '  - .../python/dimos_lerobot/__init__.py'

dimos/codebase_checks/test_no_init_files.py:25: AssertionError
dimos.core.test_isolated_python_end_to_end::test_isolated_python_rpc_refs_and_restart
Stack Traces | 2.75s 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 371, in build
  |     coordinator.build_all_modules()
  |   File ".../core/coordination/module_coordinator.py", line 248, 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 646ms
    | 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/pubsubrpc.py", line 280, in execute_and_respond
    |     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 265, 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 261, in _maybe_build
    |     self._run_prepare()
    |   File ".../dimos/core/isolated_python_module.py", line 160, 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 646ms
    | 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 248, 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 646ms
    | error: The lockfile at `uv.lock` needs to be updated, but `--locked` was
    |        provided.
    | 
    | hint: To update the lockfile, run `uv lock`.
    +------------------------------------
dimos.hardware.whole_body.dual_openyam_damiao.test_adapter::test_adapter_connects_complete_dual_yam_topology
Stack Traces | 3.14s run time
adapter = <dimos.hardware.whole_body.dual_openyam_damiao.adapter.DualOpenYamDamiaoAdapter object at 0xff4e98641040>

    def test_adapter_connects_complete_dual_yam_topology(
        adapter: DualOpenYamDamiaoAdapter,
    ) -> None:
>       assert adapter.connect()
E       assert False
E        +  where False = connect()
E        +    where connect = <dimos.hardware.whole_body.dual_openyam_damiao.adapter.DualOpenYamDamiaoAdapter object at 0xff4e98641040>.connect

adapter    = <dimos.hardware.whole_body.dual_openyam_damiao.adapter.DualOpenYamDamiaoAdapter object at 0xff4e98641040>

.../whole_body/dual_openyam_damiao/test_adapter.py:44: AssertionError
dimos.robot.manipulators.openyam.test_openyam::test_quest_teleop_selects_physical_hardware_with_explicit_can_port
Stack Traces | 3.21s 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 0xff4f0597eed0>

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

.../coordination/blueprint_config/values.py:148: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
........................................../usr/lib/python3.12/copy.py:162: in deepcopy
    y = _reconstruct(x, memo, *rv)
        _nil       = []
        cls        = <class 'dimos.control.coordinator.TaskConfig'>
        copier     = None
        d          = 280714861342416
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        reductor   = <built-in method __reduce_ex__ of TaskConfig object at 0xff4f0597eed0>
        rv         = (<function __newobj__ at 0xff4f8b0b05e0>, (<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 0xff4f0597eed0>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xff4e88b0a890>
        deep       = True
        deepcopy   = <function deepcopy at 0xff4f8aa42020>
        dictiter   = None
        func       = <function __newobj__ at 0xff4f8b0b05e0>
        listiter   = None
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        state      = {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/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 0xff4f0597eed0>
        y          = <[AttributeError("'TaskConfig' object has no attribute 'name'") raised in repr()] TaskConfig object at 0xff4e981e2030>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff4f8a840ae0>
        d          = 280712766340800
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        x          = {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/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 0xff4f8aa42020>
        key        = 'params'
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/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': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], 'name': 'teleop_openyam', 'priority': 10, ...}
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff4f8a840ae0>
        d          = 280714858619008
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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 0xff4f8aa42020>
        key        = 'robot_model'
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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 0xff4f05852210>
        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 0xff4e98301f00>
        d          = 280714860110352
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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 0xff4f05852210>
        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       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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 0xff4f05852210>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff4f8a840ae0>
        d          = 280714858601920
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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 0xff4f8aa42020>
        key        = 'model'
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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 0xff4f0564cbc0>
        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...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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          = 280714857991104
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        reductor   = <built-in method __reduce_ex__ of RobotModel object at 0xff4f0564cbc0>
        rv         = (<function __newobj__ at 0xff4f8b0b05e0>, (<class 'dimos.robot.assets.model.RobotModel'>,), {'_fixed_frames': (), '_fi...xclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xff4f05788fd0>),), ...}, 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 0xff4f0564cbc0>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xff4e88b0ac50>
        deep       = True
        deepcopy   = <function deepcopy at 0xff4f8aa42020>
        dictiter   = None
        func       = <function __newobj__ at 0xff4f8b0b05e0>
        listiter   = None
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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 0xff4f05788fd0>),), ...}
        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 0xff4f0564cbc0>
        y          = <[AttributeError("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xff4f8a840ae0>
        d          = 280713055650048
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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 0xff4f05788fd0>),), ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xff4f8aa42020>
        key        = '_source_path'
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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 0xff4f0578a650>
        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 0xff4f05788fd0>),), ...}
        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          = 280714859292240
        memo       = {280712766331648: [['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], {'build': 864...ror("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xff4e981fd520>, ...}
        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 0xff4f0578a650>
        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 0xff4f0578a650>
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 0xff4f0578a650>
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': '8e3d288c-f44d-443d-86e2-4726cfd4a386.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_quest_teleop_selects_physical_hardware_with_explicit_can_port() -> None:
>       parsed = BlueprintConfigParser(teleop_quest_openyam).parse(
            ["--can-port", "can8"],
            environ={},
        )


.../manipulators/openyam/test_openyam.py:92: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../coordination/blueprint_config/parser.py:169: in parse
    key: plain(value)
        cli_tokens = ['--can-port', 'can8']
        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 0xff4e981c0340>
        self       = <dimos.core.coordination.blueprint_config.parser.BlueprintConfigParser object at 0xff4e98238920>
.../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...arm/joint6', 'arm/gripper'], priority=20, 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 0xff4f0597eed0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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

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

.../coordination/blueprint_config/values.py:150: BlueprintConfigError
dimos.robot.manipulators.dual_openyam.test_blueprints::test_quest_blueprint_selects_physical_hardware_from_both_can_ports
Stack Traces | 3.21s run time
value = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...ox_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffbec19b95e0>

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

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

.../coordination/blueprint_config/values.py:148: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
........................................../usr/lib/python3.12/copy.py:162: in deepcopy
    y = _reconstruct(x, memo, *rv)
        _nil       = []
        cls        = <class 'dimos.control.coordinator.TaskConfig'>
        copier     = None
        d          = 281194757068256
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        reductor   = <built-in method __reduce_ex__ of TaskConfig object at 0xffbec19b95e0>
        rv         = (<function __newobj__ at 0xffbfb1f745e0>, (<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/dual_openyam_abc_box_v2.tar.gz after 3...ox_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffbec19b95e0>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xffbf9c4cfb50>
        deep       = True
        deepcopy   = <function deepcopy at 0xffbfb190e020>
        dictiter   = None
        func       = <function __newobj__ at 0xffbfb1f745e0>
        listiter   = None
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        state      = {'auto_start': False, 'joint_names': ['left_arm/joint1', 'left_arm/joint2', 'left_arm/joint3', 'left_arm/joint4', 'lef...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/dual_openyam_abc_box_v2.tar.gz after 3...ox_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffbec19b95e0>
        y          = <[AttributeError("'TaskConfig' object has no attribute 'name'") raised in repr()] TaskConfig object at 0xffbf9c5feb70>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xffbfb170cae0>
        d          = 281198423787648
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        x          = {'auto_start': False, 'joint_names': ['left_arm/joint1', 'left_arm/joint2', 'left_arm/joint3', 'left_arm/joint4', 'lef...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 0xffbfb190e020>
        key        = 'params'
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        value      = {'bindings': [{'hand': 'left', 'target_frame': 'left_grasp_frame'}, {'hand': 'right', 'target_frame': 'right_grasp_fra..., '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': ['left_arm/joint1', 'left_arm/joint2', 'left_arm/joint3', 'left_arm/joint4', 'lef...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': ['left_arm/joint1', 'left_arm/joint2', 'left_arm/joint3', 'left_arm/joint4', 'left_arm/joint5', 'left_arm/joint6', ...], 'name': 'teleop_dual_openyam', 'priority': 10, ...}
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xffbfb170cae0>
        d          = 281194751129088
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        x          = {'bindings': [{'hand': 'left', 'target_frame': 'left_grasp_frame'}, {'hand': 'right', 'target_frame': 'right_grasp_fra..., '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 0xffbfb190e020>
        key        = 'robot_model'
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModelConfig object at 0xffbec0ed5090>
        x          = {'bindings': [{'hand': 'left', 'target_frame': 'left_grasp_frame'}, {'hand': 'right', 'target_frame': 'right_grasp_fra..., '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/dual_openyam_abc_box_v2.tar.gz after 3...bc_box_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] method object at 0xffbf9c25b280>
        d          = 281194745647248
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModelConfig object at 0xffbec0ed5090>
        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       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModelConfig object at 0xffbec0ed5090>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xffbfb170cae0>
        d          = 281194751128768
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        x          = {'auto_convert_meshes': True, 'base_link': 'dual_openyam_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 0xffbfb190e020>
        key        = 'model'
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...ox_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModel object at 0xffbf2c93c080>
        x          = {'auto_convert_meshes': True, 'base_link': 'dual_openyam_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...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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          = 281196551716992
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        reductor   = <built-in method __reduce_ex__ of RobotModel object at 0xffbf2c93c080>
        rv         = (<function __newobj__ at 0xffbfb1f745e0>, (<class 'dimos.robot.assets.model.RobotModel'>,), {'_fixed_frames': (), '_fi...xclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffbf2c62ca50>),), ...}, None, None)
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...ox_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModel object at 0xffbf2c93c080>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xffbf9c520400>
        deep       = True
        deepcopy   = <function deepcopy at 0xffbfb190e020>
        dictiter   = None
        func       = <function __newobj__ at 0xffbfb1f745e0>
        listiter   = None
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        state      = {'_fixed_frames': (), '_fixed_joints': (), '_joint_position_limits': (), '_package_paths': (('dual_openyam_abc_box', <...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffbf2c62ca50>),), ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...ox_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] RobotModel object at 0xffbf2c93c080>
        y          = <[AttributeError("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xffbf9c5ffb30>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xffbfb170cae0>
        d          = 281198424081280
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        x          = {'_fixed_frames': (), '_fixed_joints': (), '_joint_position_limits': (), '_package_paths': (('dual_openyam_abc_box', <...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffbf2c62ca50>),), ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xffbfb190e020>
        key        = '_source_path'
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        value      = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...c_box_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffbf2c62ccd0>
        x          = {'_fixed_frames': (), '_fixed_joints': (), '_joint_position_limits': (), '_package_paths': (('dual_openyam_abc_box', <...tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffbf2c62ca50>),), ...}
        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          = 281196548508880
        memo       = {281194745647168: GlobalConfig(robot_ip=None, robot_ips=None, unitree_aes_128_key=None, xarm7_ip=None, xarm6_ip=None, ..., relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}, 281194751129088: {}, ...}
        x          = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...c_box_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffbf2c62ccd0>
        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/dual_openyam_abc_box_v2.tar.gz after 3...c_box_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffbf2c62ccd0>
dimos/utils/data.py:353: in _ensure_downloaded
    cache = get_data(filename)
        cache      = None
        filename   = 'dual_openyam_abc_box_v2/dual_openyam.urdf'
        self       = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3...c_box_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xffbf2c62ccd0>
dimos/utils/data.py:310: in get_data
    archive_path = _decompress_archive(_pull_lfs_archive(archive_name))
        archive_name = 'dual_openyam_abc_box_v2'
        data_dir   = PosixPath('.../dimos/dimos/data')
        file_path  = PosixPath('.../dimos/dimos/data/dual_openyam_abc_box_v2/dual_openyam.urdf')
        name       = 'dual_openyam_abc_box_v2/dual_openyam.urdf'
        nested_path = PosixPath('dual_openyam.urdf')
        path_parts = ('dual_openyam_abc_box_v2', 'dual_openyam.urdf')
dimos/utils/data.py:254: in _pull_lfs_archive
    _lfs_pull(file_path, repo_root)
        file_path  = PosixPath('.../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz')
        filename   = 'dual_openyam_abc_box_v2'
        repo_root  = PosixPath('.../work/dimos/dimos')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

file_path = PosixPath('.../dimos/data/.lfs/dual_openyam_abc_box_v2.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/dual_openyam_abc_box_v2.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/dual_openyam_abc_box_v2.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': '8e3d288c-f44d-443d-86e2-4726cfd4a386.tests.ubuntu-24_04-arm_3_14_fal', ...}
file_path  = PosixPath('.../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz')
last_err   = CalledProcessError(1, ['git', 'lfs', 'pull', '--include', 'data/.lfs/dual_openyam_abc_box_v2.tar.gz', '--exclude='])
relative_path = PosixPath('data/.lfs/dual_openyam_abc_box_v2.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_quest_blueprint_selects_physical_hardware_from_both_can_ports() -> None:
>       parsed = BlueprintConfigParser(teleop_quest_dual_openyam).parse(
            [
                "--left-can-port",
                "follower_l",
                "--right-can-port",
                "follower_r",
                "--manipulationmodule.visualization.host=0.0.0.0",
            ],
            environ={},
        )


.../manipulators/dual_openyam/test_blueprints.py:49: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../coordination/blueprint_config/parser.py:169: in parse
    key: plain(value)
        cli_tokens = ['--left-can-port', 'follower_l', '--right-can-port', 'follower_r', '--manipulationmodule.visualization.host=0.0.0.0']
        config_path = None
        environ    = {}
        global_overrides = None
        overrides  = None
        schema     = <[RuntimeError("Failed to pull LFS file .../dimos/data/.lfs/dual_openyam_abc_box_v2.tar.gz after 3..._v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] ParserSchema object at 0xffbf9c2dc740>
        self       = <dimos.core.coordination.blueprint_config.parser.BlueprintConfigParser object at 0xffbf9d25fda0>
.../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/dual_openyam_abc_box_v2.tar.gz after ...oint5', 'right_arm/joint6'], priority=20, 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/dual_openyam_abc_box_v2.tar.gz after 3...ox_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.") raised in repr()] TaskConfig object at 0xffbec19b95e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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

    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/dual_openyam_abc_box_v2.tar.gz after 3 attempts: Command '['git', 'lfs', 'pull', '--include', 'data/.lfs/dual_openyam_abc_box_v2.tar.gz', '--exclude=']' returned non-zero exit status 1.

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

.../coordination/blueprint_config/values.py:150: BlueprintConfigError
dimos.imitation.collection.test_blueprint::test_openyam_wrist_camera_device_is_configurable_from_cli[2-2]
Stack Traces | 3.21s 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 0xfffbda0dab70>

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

.../coordination/blueprint_config/values.py:148: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
........................................../usr/lib/python3.12/copy.py:162: in deepcopy
    y = _reconstruct(x, memo, *rv)
        _nil       = []
        cls        = <class 'dimos.control.coordinator.TaskConfig'>
        copier     = None
        d          = 281457160203120
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}
        reductor   = <built-in method __reduce_ex__ of TaskConfig object at 0xfffbda0dab70>
        rv         = (<function __newobj__ at 0xfffc5f9fc5e0>, (<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 0xfffbda0dab70>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xfffb6d5424d0>
        deep       = True
        deepcopy   = <function deepcopy at 0xfffc5f39e020>
        dictiter   = None
        func       = <function __newobj__ at 0xfffc5f9fc5e0>
        listiter   = None
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}
        state      = {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/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 0xfffbda0dab70>
        y          = <[AttributeError("'TaskConfig' object has no attribute 'name'") raised in repr()] TaskConfig object at 0xfffb575116d0>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc5f19cae0>
        d          = 281455334798144
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}
        x          = {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/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 0xfffc5f39e020>
        key        = 'params'
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/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': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], 'name': 'teleop_openyam', 'priority': 10, ...}
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc5f19cae0>
        d          = 281457161849152
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffc5f39e020>
        key        = 'robot_model'
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbda039c20>
        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 0xfffbccd2d2c0>
        d          = 281457159543840
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbda039c20>
        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       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbda039c20>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc5f19cae0>
        d          = 281457161422784
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffc5f39e020>
        key        = 'model'
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbda2cf050>
        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...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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          = 281457162252368
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}
        reductor   = <built-in method __reduce_ex__ of RobotModel object at 0xfffbda2cf050>
        rv         = (<function __newobj__ at 0xfffc5f9fc5e0>, (<class 'dimos.robot.assets.model.RobotModel'>,), {'_fixed_frames': (), '_fi...xclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffbd9efbad0>),), ...}, 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 0xfffbda2cf050>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xfffbce1f9d50>
        deep       = True
        deepcopy   = <function deepcopy at 0xfffc5f39e020>
        dictiter   = None
        func       = <function __newobj__ at 0xfffc5f9fc5e0>
        listiter   = None
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbd9efbad0>),), ...}
        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 0xfffbda2cf050>
        y          = <[AttributeError("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xfffb6d60f830>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc5f19cae0>
        d          = 281455354019008
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbd9efbad0>),), ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xfffc5f39e020>
        key        = '_source_path'
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbd9efb950>
        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 0xfffbd9efbad0>),), ...}
        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          = 281457158240592
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbd9efb950>
        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 0xfffbd9efb950>
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 0xfffbd9efb950>
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': '8e3d288c-f44d-443d-86e2-4726cfd4a386.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:

argument = '2', expected = 2

    @pytest.mark.parametrize(
        ("argument", "expected"),
        [("2", 2), (".../v4l/by-id/usb-wrist-camera", ".../v4l/by-id/usb-wrist-camera")],
    )
    def test_openyam_wrist_camera_device_is_configurable_from_cli(
        argument: str, expected: int | str
    ) -> None:
>       parsed = BlueprintConfigParser(learning_collect_quest_openyam).parse(
            ["--WristCamera.webcam.camera-index", argument],
            environ={},
        )

argument   = '2'
expected   = 2

.../imitation/collection/test_blueprint.py:137: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../coordination/blueprint_config/parser.py:169: in parse
    key: plain(value)
        cli_tokens = ['--WristCamera.webcam.camera-index', '2']
        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 0xfffb6e6a9b80>
        self       = <dimos.core.coordination.blueprint_config.parser.BlueprintConfigParser object at 0xfffb6d60f260>
.../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...arm/joint6', 'arm/gripper'], priority=20, 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 0xfffbda0dab70>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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

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

.../coordination/blueprint_config/values.py:150: BlueprintConfigError
dimos.imitation.collection.test_blueprint::test_openyam_wrist_camera_device_is_configurable_from_cli[/dev/v4l/by-id/usb-wrist-camera-/dev/v4l/by-id/usb-wrist-camera]
Stack Traces | 3.31s 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 0xfffbda0dab70>

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

.../coordination/blueprint_config/values.py:148: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
........................................../usr/lib/python3.12/copy.py:162: in deepcopy
    y = _reconstruct(x, memo, *rv)
        _nil       = []
        cls        = <class 'dimos.control.coordinator.TaskConfig'>
        copier     = None
        d          = 281457160203120
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}
        reductor   = <built-in method __reduce_ex__ of TaskConfig object at 0xfffbda0dab70>
        rv         = (<function __newobj__ at 0xfffc5f9fc5e0>, (<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 0xfffbda0dab70>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xfffb575546d0>
        deep       = True
        deepcopy   = <function deepcopy at 0xfffc5f39e020>
        dictiter   = None
        func       = <function __newobj__ at 0xfffc5f9fc5e0>
        listiter   = None
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}
        state      = {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/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 0xfffbda0dab70>
        y          = <[AttributeError("'TaskConfig' object has no attribute 'name'") raised in repr()] TaskConfig object at 0xfffb6d58ee40>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc5f19cae0>
        d          = 281455334798144
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}
        x          = {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/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 0xfffc5f39e020>
        key        = 'params'
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/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': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/joint5', 'arm/joint6'], 'name': 'teleop_openyam', 'priority': 10, ...}
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc5f19cae0>
        d          = 281457161849152
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffc5f39e020>
        key        = 'robot_model'
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbda039c20>
        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 0xfffbce64cc80>
        d          = 281457159543840
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbda039c20>
        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       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbda039c20>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc5f19cae0>
        d          = 281457161422784
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffc5f39e020>
        key        = 'model'
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbda2cf050>
        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...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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          = 281457162252368
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.dimensional.org', dimos_api_key=None), ...}
        reductor   = <built-in method __reduce_ex__ of RobotModel object at 0xfffbda2cf050>
        rv         = (<function __newobj__ at 0xfffc5f9fc5e0>, (<class 'dimos.robot.assets.model.RobotModel'>,), {'_fixed_frames': (), '_fi...xclude=']' returned non-zero exit status 1.") raised in repr()] LfsPath object at 0xfffbd9efbad0>),), ...}, 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 0xfffbda2cf050>
        y          = []
........................................../usr/lib/python3.12/copy.py:259: in _reconstruct
    state = deepcopy(state, memo)
        args       = <generator object _reconstruct.<locals>.<genexpr> at 0xfffbce1fa020>
        deep       = True
        deepcopy   = <function deepcopy at 0xfffc5f39e020>
        dictiter   = None
        func       = <function __newobj__ at 0xfffc5f9fc5e0>
        listiter   = None
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbd9efbad0>),), ...}
        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 0xfffbda2cf050>
        y          = <[AttributeError("'RobotModel' object has no attribute '_source_path'") raised in repr()] RobotModel object at 0xfffb6d58db80>
........................................../usr/lib/python3.12/copy.py:136: in deepcopy
    y = copier(x, memo)
        _nil       = []
        cls        = <class 'dict'>
        copier     = <function _deepcopy_dict at 0xfffc5f19cae0>
        d          = 281456964599552
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbd9efbad0>),), ...}
        y          = []
........................................../usr/lib/python3.12/copy.py:221: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
        deepcopy   = <function deepcopy at 0xfffc5f39e020>
        key        = '_source_path'
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbd9efb950>
        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 0xfffbd9efbad0>),), ...}
        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          = 281457158240592
        memo       = {281455334798144: {'auto_start': False, 'joint_names': ['arm/joint1', 'arm/joint2', 'arm/joint3', 'arm/joint4', 'arm/j...ess=True, local_relay=False, relay_url=None, dimos_cloud_url='https://login.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 0xfffbd9efb950>
        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 0xfffbd9efb950>
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 0xfffbd9efb950>
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': '8e3d288c-f44d-443d-86e2-4726cfd4a386.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:

argument = '.../v4l/by-id/usb-wrist-camera'
expected = '.../v4l/by-id/usb-wrist-camera'

    @pytest.mark.parametrize(
        ("argument", "expected"),
        [("2", 2), (".../v4l/by-id/usb-wrist-camera", ".../v4l/by-id/usb-wrist-camera")],
    )
    def test_openyam_wrist_camera_device_is_configurable_from_cli(
        argument: str, expected: int | str
    ) -> None:
>       parsed = BlueprintConfigParser(learning_collect_quest_openyam).parse(
            ["--WristCamera.webcam.camera-index", argument],
            environ={},
        )

argument   = '.../v4l/by-id/usb-wrist-camera'
expected   = '.../v4l/by-id/usb-wrist-camera'

.../imitation/collection/test_blueprint.py:137: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../coordination/blueprint_config/parser.py:169: in parse
    key: plain(value)
        cli_tokens = ['--WristCamera.webcam.camera-index', '.../v4l/by-id/usb-wrist-camera']
        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 0xfffbce7458c0>
        self       = <dimos.core.coordination.blueprint_config.parser.BlueprintConfigParser object at 0xfffb6d500bf0>
.../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...arm/joint6', 'arm/gripper'], priority=20, 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 0xfffbda0dab70>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

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

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

.../coordination/blueprint_config/values.py:150: BlueprintConfigError
dimos.core.test_isolated_python_end_to_end::test_example_script_exits_after_printing_results
Stack Traces | 4.68s 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 371, in build
E           |     coordinator.build_all_modules()
E           |   File ".../core/coordination/module_coordinator.py", line 248, 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 47ms
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/pubsubrpc.py", line 280, in execute_and_respond
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 265, 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 261, in _maybe_build
E             self._run_prepare()
E           File ".../dimos/core/isolated_python_module.py", line 160, in _run_prepare
E             raise RuntimeError(
E         RuntimeError: Isolated Python environment preparation failed (exit 1): Resolved 195 packages in 47ms
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 248, 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 47ms
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='23:32:20.958 [inf][dination/module_coordinator.py] Building the blueprint\n23:32:20.960 [inf][ce/system_configurator/base.py] Pytest run detected: skipping system configuration.\n23:32:20.960 [inf][dination/module_coordinator.py] Starting the modules\n23:32:22.285 [inf][ation/worker_manager_python.py] Worker pool started. n_workers=2\n23:32:23.659 [inf][/coordination/python_worker.py] Deployed module. module=Offset module_id=1 worker_id=1\n23:32:23.716 [inf][/coordination/python_worker.py] Deployed module. module=ExampleExternal module_id=0 worker_id=0\n23:32:23.772 [inf][dination/module_coordinator.py] Transport module=exampleexternal name=value original_name=value topic=/value#std_msgs.Int32 transport=LCMTransport type=dimos.msgs.std_msgs.Int32.Int32\n23:32:23.775 [inf][dination/module_coordinator.py] Transport module=exampleexternal name=doubled original_name=doubled topic=/doubled#std_msgs.Int32 transport=LCMTransport type=dimos.msgs.std_msgs.Int32.Int32\n23:32:23.943 [err][.../protocol/rpc/pubsubrpc.py] Exception in RPC handler for Exampl...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 248, 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 47ms\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 cc/advx/a1z-learning branch 2 times, most recently from 188f271 to e862f0d Compare August 21, 2026 05:15
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch from e862f0d to 5ce3e7c Compare August 21, 2026 06:51
@TomCC7
TomCC7 force-pushed the cc/advx/a1z-learning branch from 5ce3e7c to 776ca6e Compare August 25, 2026 00:56
@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 cc/advx/a1z-learning branch 2 times, most recently from 1199ef4 to fff3eb7 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 cc/advx/a1z-learning branch 2 times, most recently from 3e11ccf to 776ca6e Compare August 25, 2026 23:50
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