# Voice Control Simplification Plan ## Current State **30 files** across 7 directories (~3300 lines): ``` dora_voice_control/ ├── behaviors/ # 2 files │ ├── __init__.py │ └── base.py ├── node/ # 5 files │ ├── __init__.py │ ├── adapter.py │ ├── context.py │ ├── dispatcher.py │ └── logging.py ├── robot/ # 6 files │ ├── __init__.py │ ├── adapter.py # VacuumGripperAdapter, ParallelGripperAdapter │ ├── command_queue.py │ ├── image_handler.py │ ├── pose_handler.py │ └── status_handler.py ├── scene/ # 4 files │ ├── __init__.py │ ├── notifier.py │ ├── objects_handler.py │ └── state.py ├── utils/ # 3 files │ ├── __init__.py │ ├── config.py │ └── state.py ├── voice/ # 4 files │ ├── __init__.py │ ├── handler.py │ ├── intent.py │ └── parser.py ├── web/ # 4 files │ ├── __init__.py │ ├── api.py │ ├── models.py │ └── templates.py ├── __init__.py └── main.py ``` ## Problems 1. **Too many small files** - Many files are <50 lines 2. **Robot-specific code scattered** - Adapter in robot/, behavior in behaviors/ 3. **Hard to add new robots** - Need to touch multiple directories 4. **Deep import chains** - `from ..node import ...` --- ## Proposed Structure **12 files** across 3 directories: ``` dora_voice_control/ ├── __init__.py ├── main.py ├── node.py # Dora infrastructure (adapter, context, dispatcher, logger) ├── handlers.py # All event handlers (voice, robot, scene) ├── scene.py # SceneState, SceneObject ├── state.py # SharedState, RobotStep, config loading ├── web.py # API server (api + models + templates) └── behaviors/ ├── __init__.py # get_behavior() factory ├── base.py # ActionContext, ActionInfo, RobotBehavior base └── littlehand/ ├── __init__.py └── robot.py # LittlehandBehavior + VacuumGripperAdapter ``` --- ## File Consolidation Map ### `node.py` (merge 5 files) | From | Content | |------|---------| | `node/logging.py` | VoiceControlLogger | | `node/adapter.py` | NodePort, DoraNodeAdapter, MockNodeAdapter | | `node/context.py` | OutputPort, NodeContext | | `node/dispatcher.py` | EventHandler, EventDispatcher | ### `handlers.py` (merge 7 files) | From | Content | |------|---------| | `voice/handler.py` | VoiceInputHandler | | `voice/intent.py` | Intent, IntentQueue | | `robot/pose_handler.py` | PoseHandler | | `robot/status_handler.py` | StatusHandler | | `robot/image_handler.py` | ImageHandler | | `robot/command_queue.py` | CommandQueueService | | `scene/objects_handler.py` | ObjectsHandler | | `scene/notifier.py` | SceneNotifier | ### `scene.py` (merge 2 files) | From | Content | |------|---------| | `scene/state.py` | SceneState, SceneObject | Already consolidated - just move to root. ### `state.py` (merge 2 files) | From | Content | |------|---------| | `utils/state.py` | SharedState, RobotStep, VoiceState, DebugState | | `utils/config.py` | VoiceConfig, ApiConfig, LLMConfig, loaders | ### `web.py` (merge 3 files) | From | Content | |------|---------| | `web/api.py` | create_api(), start_api_server() | | `web/models.py` | CommandRequest, CommandResponse | | `web/templates.py` | HTML_TEMPLATE | ### `behaviors/littlehand/robot.py` (new) | From | Content | |------|---------| | `robot/adapter.py` | VacuumGripperAdapter (robot-specific) | | `behaviors/base.py` | Action implementations (robot-specific) | Robot adapter moves INTO the behavior folder. --- ## Per-Robot Folder Structure Each robot gets its own folder with everything it needs: ``` behaviors/ ├── __init__.py # get_behavior(robot_type) factory ├── base.py # Shared base classes │ - ActionContext │ - ActionInfo │ - RobotBehavior (abstract) │ └── littlehand/ # Vacuum gripper robot ├── __init__.py └── robot.py - VacuumGripperAdapter - LittlehandBehavior (actions, LLM signature) - ACTIONS dict - CommandSignature (DSPy) ``` ### Adding a New Robot (e.g., "gripper_arm") 1. Create `behaviors/gripper_arm/` 2. Create `robot.py` with: - `ParallelGripperAdapter` - `GripperArmBehavior` - Custom actions 3. Register in `behaviors/__init__.py` No need to touch other files. --- ## Implementation Steps ### Phase 1: Consolidate node/ → node.py 1. Create `node.py` merging adapter, context, dispatcher, logging 2. Update imports in all files 3. Delete `node/` directory ### Phase 2: Consolidate handlers 1. Create `handlers.py` merging all handlers 2. Update imports 3. Delete `voice/`, `robot/` directories (except adapter) ### Phase 3: Consolidate utils/ → state.py 1. Create `state.py` merging config and state 2. Update imports 3. Delete `utils/` directory ### Phase 4: Move scene/ → scene.py 1. Move `scene/state.py` to `scene.py` 2. Update imports 3. Delete `scene/` directory ### Phase 5: Consolidate web/ → web.py 1. Create `web.py` merging api, models, templates 2. Update imports 3. Delete `web/` directory ### Phase 6: Restructure behaviors per robot 1. Create `behaviors/littlehand/robot.py` 2. Move VacuumGripperAdapter from robot/adapter.py 3. Move action implementations from behaviors/base.py 4. Update `behaviors/__init__.py` factory 5. Delete old robot/adapter.py ### Phase 7: Update main.py 1. Update all imports to new structure 2. Simplify initialization --- ## Final Structure Comparison | Before | After | |--------|-------| | 30 files | 12 files | | 7 directories | 3 directories | | Robot code scattered | Robot code in one folder | | Deep imports | Flat imports | --- ## Benefits 1. **Easier navigation** - Fewer files to search 2. **Self-contained robots** - One folder per robot type 3. **Simpler imports** - `from .node import ...` instead of `from ..node import ...` 4. **Easier testing** - Mock one module instead of many 5. **Clear ownership** - Robot-specific code in robot folder