Files
Cognitive_Agent/docs/superpowers/plans/2026-07-30-vehicle-profile-seat-calibration.md
2026-07-30 14:09:04 +08:00

127 lines
5.9 KiB
Markdown

# Vehicle Profile Seat Calibration Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add vehicle-selectable Denza N7 seat calibration so natural-language physical deltas can be deterministically converted to absolute seat `position_pct` before CAN compilation.
**Architecture:** Add a small vehicle profile layer under `src/cognitive_agent/application/` that loads YAML profiles from `config/vehicles/`. `SeatDemoService` passes the selected profile into model-plan adaptation and returns available profiles via `/api/runtime`; the frontend stores a selected vehicle id and includes it in `/api/requests`. CAN compilers remain unchanged and continue receiving absolute `position_pct`.
**Tech Stack:** Python 3.11 stdlib + PyYAML, existing unittest suite, existing static HTML/JS frontend.
---
### Task 1: Vehicle Profile Loader
**Files:**
- Create: `config/vehicles/denza_n7.yaml`
- Create: `src/cognitive_agent/application/vehicle_profile.py`
- Test: `tests/unit/test_vehicle_profile.py`
- [ ] **Step 1: Write failing tests**
Create `tests/unit/test_vehicle_profile.py` with tests that load the Denza N7 profile, expose all four motors, convert relative physical deltas into target percentages, and expose angle ranges for frontend display.
- [ ] **Step 2: Run tests and verify RED**
Run: `PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src:domains/seat/src .omx/python311-venv/bin/python -m unittest tests.unit.test_vehicle_profile -v`
Expected: fails because `cognitive_agent.application.vehicle_profile` does not exist.
- [ ] **Step 3: Implement loader**
Create the Denza N7 YAML profile with `longitudinal`, `cushion_tilt`, `backrest_recline`, and `legrest_height` motors. Implement `VehicleProfileRegistry`, `VehicleProfile`, and `SeatMotorProfile` with methods to compute clamped absolute targets from relative deltas.
- [ ] **Step 4: Run tests and verify GREEN**
Run the same unittest command and expect PASS.
### Task 2: Apply Vehicle Profile During Intent Adaptation
**Files:**
- Modify: `src/cognitive_agent/application/model_plan_adapter.py`
- Test: `tests/unit/test_vehicle_profile.py`
- [ ] **Step 1: Write failing tests**
Add tests showing a request with `distance_mm=50` and `operation=increase` for `seat.set_longitudinal_position` converts from current 50% to 73% using Denza N7's 215mm range. Add a test showing `angle_delta_deg=10` for `seat.set_backrest_recline` converts from 20% to 38% using the 55 degree range and preserves `motion_intent`.
- [ ] **Step 2: Run tests and verify RED**
Run the vehicle profile unittest and expect failure because `ModelPlanAdapter.adapt()` does not accept a vehicle profile and rejects unknown `distance_mm` / `angle_delta_deg` parameters.
- [ ] **Step 3: Implement adaptation**
Allow vehicle-profile-backed physical delta parameters for seat motion requests. Translate them to absolute `position_pct`, preserve relative motion metadata, and keep the compiler-facing `FunctionConfig` unchanged.
- [ ] **Step 4: Run tests and verify GREEN**
Run the vehicle profile unittest and expect PASS.
### Task 3: Thread Vehicle Selection Through API and Runtime
**Files:**
- Modify: `src/cognitive_agent/application/seat_service.py`
- Modify: `src/cognitive_agent/server.py`
- Test: `tests/e2e/test_seat_web_api.py`
- [ ] **Step 1: Write failing tests**
Add e2e coverage that `/api/runtime` includes `vehicles` and `default_vehicle_id`, and that a POST containing `vehicle_id: "denza_n7"` records the selected profile in the result and uses it for conversion.
- [ ] **Step 2: Run tests and verify RED**
Run: `PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src:domains/seat/src .omx/python311-venv/bin/python -m unittest tests.e2e.test_seat_web_api -v`
Expected: fails because runtime has no vehicles and POST ignores `vehicle_id`.
- [ ] **Step 3: Implement API threading**
Instantiate `VehicleProfileRegistry` in `SeatDemoService`, return public profiles from `runtime_info()`, accept `vehicle_id` in `process()`, pass the selected profile to `ModelPlanAdapter`, and include `vehicle_id` / `vehicle_name` in the API result. Update `server.py` to read `vehicle_id` from JSON.
- [ ] **Step 4: Run tests and verify GREEN**
Run the e2e unittest and expect PASS.
### Task 4: Add Frontend Vehicle Selector
**Files:**
- Modify: `apps/web-console/index.html`
- Modify: `apps/web-console/app.js`
- Modify: `apps/web-console/styles.css`
- Test: `tests/e2e/test_seat_web_api.py`
- [ ] **Step 1: Write failing tests**
Extend the static HTML/runtime e2e test to assert that the page has a vehicle selector and that runtime-provided vehicles are expected by the frontend.
- [ ] **Step 2: Run tests and verify RED**
Run the e2e unittest and expect failure because the selector does not exist.
- [ ] **Step 3: Implement UI**
Add a compact selector in the top bar or command panel, populate it from `/api/runtime.vehicles`, keep `denza_n7` selected by default, store the selected id in `state.vehicleId`, and include `vehicle_id` in POST `/api/requests`.
- [ ] **Step 4: Run tests and verify GREEN**
Run the e2e unittest and expect PASS.
### Task 5: Verification
**Files:**
- No new production files beyond Tasks 1-4.
- [ ] **Step 1: Run targeted tests**
Run:
`PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src:domains/seat/src .omx/python311-venv/bin/python -m unittest tests.unit.test_vehicle_profile domains.seat.tests.unit.test_t2g_hardware tests.e2e.test_seat_web_api -v`
- [ ] **Step 2: Smoke running service**
Use the existing Python 3.11 venv to GET `/api/runtime` and verify Denza N7 appears. POST a local/direct request with `vehicle_id=denza_n7` and confirm a successful dry-run still returns a `CommandPlan`.
- [ ] **Step 3: Review diff**
Run `git diff --stat` and inspect changed files. Do not revert the pre-existing `README.md` change unless explicitly requested.