237 lines
6.3 KiB
Markdown
237 lines
6.3 KiB
Markdown
# 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
|