6.3 KiB
6.3 KiB
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
- Too many small files - Many files are <50 lines
- Robot-specific code scattered - Adapter in robot/, behavior in behaviors/
- Hard to add new robots - Need to touch multiple directories
- 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")
- Create
behaviors/gripper_arm/ - Create
robot.pywith:ParallelGripperAdapterGripperArmBehavior- Custom actions
- Register in
behaviors/__init__.py
No need to touch other files.
Implementation Steps
Phase 1: Consolidate node/ → node.py
- Create
node.pymerging adapter, context, dispatcher, logging - Update imports in all files
- Delete
node/directory
Phase 2: Consolidate handlers
- Create
handlers.pymerging all handlers - Update imports
- Delete
voice/,robot/directories (except adapter)
Phase 3: Consolidate utils/ → state.py
- Create
state.pymerging config and state - Update imports
- Delete
utils/directory
Phase 4: Move scene/ → scene.py
- Move
scene/state.pytoscene.py - Update imports
- Delete
scene/directory
Phase 5: Consolidate web/ → web.py
- Create
web.pymerging api, models, templates - Update imports
- Delete
web/directory
Phase 6: Restructure behaviors per robot
- Create
behaviors/littlehand/robot.py - Move VacuumGripperAdapter from robot/adapter.py
- Move action implementations from behaviors/base.py
- Update
behaviors/__init__.pyfactory - Delete old robot/adapter.py
Phase 7: Update main.py
- Update all imports to new structure
- 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
- Easier navigation - Fewer files to search
- Self-contained robots - One folder per robot type
- Simpler imports -
from .node import ...instead offrom ..node import ... - Easier testing - Mock one module instead of many
- Clear ownership - Robot-specific code in robot folder