feat(voice): Wake-Word per Befehl wieder anschalten (Gegenstück zu wake_off)

"Wake-Word an" / "mach das Ohr an" / "hör wieder zu" / "wach auf" → App startet
den Listener wieder. Geht per Text-Nachricht ODER manuellem Aufnahme-Button —
beide laufen unabhängig vom Wake-Word-Listener, also funktioniert das Wieder-An
auch wenn das Ohr gerade taub ist (nur nicht per "Computer", das hört ja nicht).

Symmetrisch zu wake_off: Detektor _user_wants_wake_on → wake_on durch ChatOut →
Bridge → App löst wakeWordService.start() + setWakeWordActive(true) aus. An/Aus
kollidieren nicht (12 Fälle getestet). Damit: Ohr per Befehl ein UND aus, plus
weiterhin der Ohr-Button.

Fix nebenbei: gerades " in den Reply-Strings (hätte den Brain-Start gecrasht) →
einfache Anführungszeichen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-16 20:33:16 +02:00
co-authored by Claude Opus 4.8
parent 93401d42d1
commit 41714f7cf1
4 changed files with 59 additions and 5 deletions
+7 -2
View File
@@ -1623,8 +1623,10 @@ class ARIABridge:
# DIESE Rueckfrage weiter, statt sie als neuen Auftrag anzustellen.
"awaiting_reply": bool(payload.get("awaiting_reply", False)) if isinstance(payload, dict) else False,
# User hat "Wake-Word aus" gesagt → App stoppt den Listener komplett
# (Mikro frei). Wieder-An nur ueber den App-Button.
# (Mikro frei).
"wake_off": bool(payload.get("wake_off", False)) if isinstance(payload, dict) else False,
# "Wake-Word an" (Text/Aufnahme-Button) → App startet den Listener.
"wake_on": bool(payload.get("wake_on", False)) if isinstance(payload, dict) else False,
},
"timestamp": int(asyncio.get_event_loop().time() * 1000),
})
@@ -2022,6 +2024,8 @@ class ARIABridge:
awaiting_reply = bool(data.get("awaiting_reply", False))
# User hat per Sprache "Wake-Word aus" gesagt → App stoppt den Listener.
wake_off = bool(data.get("wake_off", False))
# "Wake-Word an" (Text/Aufnahme-Button) → App startet den Listener wieder.
wake_on = bool(data.get("wake_on", False))
# Side-Channel-Events VOR der Chat-Bubble broadcasten (z.B. skill_created)
# damit sie in der UI vor der Reply auftauchen
@@ -2114,7 +2118,8 @@ class ARIABridge:
"speak": speak,
"converse": converse,
"awaiting_reply": awaiting_reply,
"wake_off": wake_off})
"wake_off": wake_off,
"wake_on": wake_on})
except Exception:
logger.exception("[brain] _process_core_response Fehler")
await self._emit_activity("idle", "", project_id=project_id)