fix: compose named cockpit modes from capabilities

This commit is contained in:
vee
2026-09-07 20:52:19 +08:00
parent cf9b89508c
commit 6b2b644ee6
23 changed files with 2917 additions and 124 deletions
+42
View File
@@ -486,6 +486,9 @@ class SeatDemoHandler(BaseHTTPRequestHandler):
if path.startswith("/api/self-repair/"):
self._handle_self_repair_post(path)
return
if path == "/api/mode-profile-drafts/trial":
self._handle_mode_profile_draft_trial()
return
if path == "/api/mode-profiles" or path.startswith("/api/mode-profiles/"):
self._handle_mode_profile_post(path)
return
@@ -1201,6 +1204,29 @@ class SeatDemoHandler(BaseHTTPRequestHandler):
"""Route IR-only or mixed IR/CAN requests without changing CAN parsing."""
utterance = str(common_arguments.get("utterance") or "").strip()
if self.service.is_mode_profile_configuration_request(utterance):
# Creating, saving, updating, or restoring a reusable mode is
# configuration, never a live-control command. Bypass the
# NFC/peripheral executor so a learned device name embedded in the
# mode sentence cannot claim it before SeatDemoService handles it.
mode_arguments = {
**common_arguments,
"execution_mode": "dry_run",
}
callback = (
on_commands_validated
if callable(on_commands_validated)
else None
)
if path == "/api/requests/preview":
return self.service.preview_native_can(
**mode_arguments,
on_commands_validated=callback,
)
return self.service.process(
**mode_arguments,
_on_commands_validated=callback,
)
catalog = self.extension.list_peripheral_capabilities()
nfc_snapshot = self.nfc.snapshot()
partition = partition_active_peripheral_intent(
@@ -2003,6 +2029,22 @@ class SeatDemoHandler(BaseHTTPRequestHandler):
HTTPStatus.BAD_REQUEST,
)
def _handle_mode_profile_draft_trial(self) -> None:
try:
payload = self._read_json_body(max_bytes=16 * 1024)
result = self.service.trial_mode_profile_draft(
str(payload.get("name", "")),
str(payload.get("instruction", "")),
str(payload.get("source_request_id", "")),
str(payload.get("vehicle_id", "")) or None,
)
self._json(result, HTTPStatus.OK)
except (ValueError, json.JSONDecodeError) as exc:
self._json(
{"error": "invalid_request", "message": str(exc)},
HTTPStatus.BAD_REQUEST,
)
def _saved_mode_infrared_entries(
self,
profile: object,