Skip to content

refactor(cli): break up dimos.py into command modules - #3469

Open
paul-nechifor wants to merge 1 commit into
mainfrom
paul/feat/break-up-dimos-cli
Open

refactor(cli): break up dimos.py into command modules#3469
paul-nechifor wants to merge 1 commit into
mainfrom
paul/feat/break-up-dimos-cli

Conversation

@paul-nechifor

@paul-nechifor paul-nechifor commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Problem

dimos/cli/dimos.py has grown too large.

Solution

Break up the file into individual commands in dimos/cli/commands/*.py

@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

❌ 4 Tests Failed:

Tests completed Failed Passed Skipped
4260 4 4256 69
View the top 3 failed test(s) by shortest run time
dimos.e2e_tests.test_dimsim_path_replaning::test_path_replanning
Stack Traces | 104s run time
lcm_spy = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7c1dc4104a10>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7c1dbe8836a0>
dim_sim = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x7c1dc422ef90>
direct_cmd_vel_explorer = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x7c1ec69dadb0>
spawn_wall_on_pose = <function spawn_wall_on_pose.<locals>.spawn at 0x7c1dbe190400>

    @pytest.mark.self_hosted_large
    def test_path_replanning(
        lcm_spy, start_blueprint, dim_sim, direct_cmd_vel_explorer, spawn_wall_on_pose
    ) -> None:
        start_blueprint(
            "--dimsim-scene=empty",
            "run",
            "unitree-go2-agentic",
            simulator="dimsim",
        )
        lcm_spy.save_topic(".../McpClient/on_system_modules/res")
        lcm_spy.wait_for_saved_topic(".../McpClient/on_system_modules/res", timeout=1200.0)
    
        # robot spawns at (3, 2)
    
        # side wall
        dim_sim.add_wall(2, -2.5, 12, -2.5)
        # other side wall
        dim_sim.add_wall(2, 3.5, 12, 3.5)
        # back wall (behind robot)
        dim_sim.add_wall(2, -2.5, 2, 3.5)
        # forward wall (far end)
        dim_sim.add_wall(12, -2.5, 12, 3.5)
        # dividing wall at x=7 with doors at y=[-1.5,-0.5] and y=[1.5,2.5]
        dim_sim.add_wall(7, -2.5, 7, -1.5)
        dim_sim.add_wall(7, -0.5, 7, 1.5)
        dim_sim.add_wall(7, 2.5, 7, 3.5)
    
        direct_cmd_vel_explorer.linear_speed = 0.8
>       direct_cmd_vel_explorer.follow_points([(10, 2), (2.5, 2), (3, 2)])

dim_sim    = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x7c1dc422ef90>
direct_cmd_vel_explorer = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x7c1ec69dadb0>
lcm_spy    = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7c1dc4104a10>
spawn_wall_on_pose = <function spawn_wall_on_pose.<locals>.spawn at 0x7c1dbe190400>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7c1dbe8836a0>

dimos/e2e_tests/test_dimsim_path_replaning.py:47: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../simulation/mujoco/direct_cmd_vel_explorer.py:105: in follow_points
    self._wait_for_pose()
        self       = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x7c1ec69dadb0>
        waypoints  = [(10, 2), (2.5, 2), (3, 2)]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x7c1ec69dadb0>

    def _wait_for_pose(self) -> PoseStamped:
        self._new_pose.clear()
        self._new_pose.wait(timeout=5.0)
>       assert self._pose is not None, "No odom received"
E       AssertionError: No odom received

self       = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x7c1ec69dadb0>

.../simulation/mujoco/direct_cmd_vel_explorer.py:65: AssertionError
dimos.e2e_tests.test_manipulation_planning_groups::test_single_arm_plans_and_executes_through_control_coordinator
Stack Traces | 137s run time
lcm_spy = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7c1e1c10f500>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7c1dbe1922a0>

    def test_single_arm_plans_and_executes_through_control_coordinator(
        lcm_spy: LcmSpy,
        start_blueprint: Callable[..., DimosCliCall],
    ) -> None:
        """Plan with one arm and execute through its trajectory task."""
        _start_openarm_mock_planner(start_blueprint, lcm_spy)
    
        client = RPCClient(None, ManipulationModule)
        coordinator_client = RPCClient(None, ControlCoordinator)
        try:
>           [left] = _wait_for_groups(client, 1)

client     = <dimos.core.rpc_client.RPCClient object at 0x7c1e2a92d2b0>
coordinator_client = <dimos.core.rpc_client.RPCClient object at 0x7c1e26d59010>
lcm_spy    = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7c1e1c10f500>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7c1dbe1922a0>

dimos/e2e_tests/test_manipulation_planning_groups.py:158: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

client = <dimos.core.rpc_client.RPCClient object at 0x7c1e2a92d2b0>, count = 1

    def _wait_for_groups(
        client: RPCClient,
        count: int,
        *,
        timeout: float = 120.0,
    ) -> tuple[PlanningGroupInfo, ...]:
        deadline = time.time() + timeout
        last_error: BaseException | None = None
        while time.time() < deadline:
            try:
                groups = client.list_planning_groups()
                if len(groups) == count:
                    return groups
            except Exception as exc:
                last_error = exc
            time.sleep(0.5)
>       raise TimeoutError(f"Timed out waiting for {count} planning groups") from last_error
E       TimeoutError: Timed out waiting for 1 planning groups

client     = <dimos.core.rpc_client.RPCClient object at 0x7c1e2a92d2b0>
count      = 1
deadline   = 1786738828.270099
groups     = (PlanningGroupInfo('left_arm/manipulator', joints=('left_arm/openarm_left_joint1', 'left_arm/openarm_left_joint2', 'le...right_joint6', 'right_arm/openarm_right_joint7'), base='openarm_body_link0', tip='openarm_right_link7', gripper=False))
last_error = None
timeout    = 120.0

dimos/e2e_tests/test_manipulation_planning_groups.py:64: TimeoutError
dimos.e2e_tests.test_dimsim_walk_forward::test_walk_forward
Stack Traces | 193s run time
lcm_spy = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7c1dc4a1c500>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7c1dbe191260>
human_input = <function human_input.<locals>.send_human_input at 0x7c1dbe191300>
dim_sim = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x7c1e1cb2f6b0>

    @pytest.mark.self_hosted_large
    def test_walk_forward(lcm_spy, start_blueprint, human_input, dim_sim) -> None:
        start_blueprint(
            "run",
            "--disable",
            "spatial-memory",
            "--disable",
            "security-module",
            "unitree-go2-agentic",
            simulator="dimsim",
        )
        lcm_spy.save_topic(".../McpClient/on_system_modules/res")
        lcm_spy.wait_for_saved_topic(".../McpClient/on_system_modules/res", timeout=1200.0)
    
        origin_x, origin_y = 1, 2
        dim_sim.set_agent_position(origin_x, origin_y)
    
        human_input("move forward 3 meter")
    
>       lcm_spy.wait_until_odom_position(origin_x + 3, origin_y, threshold=0.4, timeout=120)

dim_sim    = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x7c1e1cb2f6b0>
human_input = <function human_input.<locals>.send_human_input at 0x7c1dbe191300>
lcm_spy    = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7c1dc4a1c500>
origin_x   = 1
origin_y   = 2
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7c1dbe191260>

dimos/e2e_tests/test_dimsim_walk_forward.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/e2e_tests/lcm_spy.py:167: in wait_until_odom_position
    self.wait_for_message_result(
        predicate  = <function LcmSpy.wait_until_odom_position.<locals>.predicate at 0x7c1dbe192020>
        self       = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7c1dc4a1c500>
        threshold  = 0.4
        timeout    = 120
        x          = 4
        y          = 2
dimos/e2e_tests/lcm_spy.py:153: in wait_for_message_result
    wait_until(
        event      = <threading.Event at 0x7c1e1da72b40: unset>
        fail_message = 'Failed to get to position x=4, y=2'
        listener   = <function LcmSpy.wait_for_message_result.<locals>.listener at 0x7c1dbe1923e0>
        predicate  = <function LcmSpy.wait_until_odom_position.<locals>.predicate at 0x7c1dbe192020>
        self       = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7c1dc4a1c500>
        timeout    = 120
        topic      = '/odom#geometry_msgs.PoseStamped'
        type       = <class 'dimos.msgs.geometry_msgs.PoseStamped.PoseStamped'>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

predicate = <bound method Event.is_set of <threading.Event at 0x7c1e1da72b40: unset>>

    def wait_until(
        predicate: Callable[[], bool],
        *,
        timeout: float,
        interval: float = 0.1,
        message: str | None = None,
    ) -> None:
        """Poll ``predicate`` until it returns truthy or ``timeout`` elapses."""
        deadline = time.monotonic() + timeout
        while time.monotonic() < deadline:
            if predicate():
                return
            time.sleep(interval)
>       raise TimeoutError(message or f"Timed out after {timeout}s waiting for condition")
E       TimeoutError: Failed to get to position x=4, y=2

deadline   = 3207775.27754194
interval   = 0.1
message    = 'Failed to get to position x=4, y=2'
predicate  = <bound method Event.is_set of <threading.Event at 0x7c1e1da72b40: unset>>
timeout    = 120

.../utils/testing/waiting.py:35: TimeoutError
View the full list of 1 ❄️ flaky test(s)
dimos.e2e_tests.test_dimsim_spatial_memory::test_go_to_the_bed

Flake rate in main: 16.11% (Passed 125 times, Failed 24 times)

Stack Traces | 96.5s run time
lcm_spy = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7c1dbe7eff50>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7c1dbe190e00>
human_input = <function human_input.<locals>.send_human_input at 0x7c1dbe190fe0>
dim_sim = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x7c1dc44f7650>
explore_house = <function explore_house.<locals>.explore at 0x7c1dbe1916c0>

    @pytest.mark.self_hosted_large
    def test_go_to_the_bed(lcm_spy, start_blueprint, human_input, dim_sim, explore_house) -> None:
        start_blueprint(
            "run",
            "unitree-go2-agentic",
            simulator="dimsim",
        )
        lcm_spy.save_topic(".../McpClient/on_system_modules/res")
        lcm_spy.wait_for_saved_topic(".../McpClient/on_system_modules/res", timeout=1200.0)
    
>       explore_house()

dim_sim    = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x7c1dc44f7650>
explore_house = <function explore_house.<locals>.explore at 0x7c1dbe1916c0>
human_input = <function human_input.<locals>.send_human_input at 0x7c1dbe190fe0>
lcm_spy    = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7c1dbe7eff50>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7c1dbe190e00>

dimos/e2e_tests/test_dimsim_spatial_memory.py:28: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/e2e_tests/conftest.py:249: in explore
    direct_cmd_vel_explorer.follow_points(points)
        direct_cmd_vel_explorer = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x7c1dc4a1e300>
        points     = [(3.881, 4.803), (4.16, 1.615), (1.596, 1.505), (1.649, 0.137), (-3.644, -0.064), (-3.759, -2.661), ...]
.../simulation/mujoco/direct_cmd_vel_explorer.py:105: in follow_points
    self._wait_for_pose()
        self       = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x7c1dc4a1e300>
        waypoints  = [(3.881, 4.803), (4.16, 1.615), (1.596, 1.505), (1.649, 0.137), (-3.644, -0.064), (-3.759, -2.661), ...]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x7c1dc4a1e300>

    def _wait_for_pose(self) -> PoseStamped:
        self._new_pose.clear()
        self._new_pose.wait(timeout=5.0)
>       assert self._pose is not None, "No odom received"
E       AssertionError: No odom received

self       = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x7c1dc4a1e300>

.../simulation/mujoco/direct_cmd_vel_explorer.py:65: 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.

@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Required CI checks have passed on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant