feat(voice): ARIA erkennt Gespraechs-Phase selbst (Befehl/Frage, Kette/Ende)
Voice-First: ARIA deklariert die Phase aus dem Text per Inline-Marker — dasselbe Muster wie [[AWAIT]], die Marker werden vor Anzeige/TTS/History entfernt. Loest: - Claude-Pfad las Steuerbefehle vor, obwohl das Skill lief (Manifest-speak-Flag kennt den Unterschied Befehl/Frage nicht — dasselbe Skill ist mal Aktion, mal Auskunft). Jetzt entscheidet ARIA aus dem Kontext. - Befehlsketten (VNC oeffnen, Menue klicken, ...): Mikro soll offen bleiben und stumm gearbeitet werden, bis Stefan die Kette beendet. Marker (ARIA haengt sie ans Antwort-Ende): [[STUMM]] -> Steuerbefehl, nicht vorlesen. Allein = Einzelbefehl -> danach Stop. [[WEITER]] -> Konversation/Kette laeuft weiter -> Mikro offen halten. [[ENDE]] -> Konversation/Kette beenden -> zurueck aufs Wake-Word. Brain: - _extract_flow_markers() zieht [[STUMM]]/[[WEITER]]/[[ENDE]] aus dem Claude-Reply und ueberschreibt speak/converse (Marker ist autoritativ ueber Skill-Flag). [[STUMM]] allein impliziert converse=false; [[ENDE]] schlaegt [[WEITER]]. - prompts.py: neue Sektion build_voice_flow_section() bringt ARIA Marker + Befehl/Frage-Klassifikation + Ketten-/Ende-Erkennung bei. App (ChatScreen): stiller Antwort-Zweig verzweigt jetzt auf converse — converse=true (Kette) -> endConversation(false), Mikro bleibt offen fuer den naechsten Kettenbefehl; converse=false -> ariaStopRecording (Stop wie gehabt). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1410,11 +1410,21 @@ const ChatScreen: React.FC = () => {
|
||||
if (_isSilent) {
|
||||
// Steuerbefehl (speak=false) ist ausgefuehrt und wird NICHT vorgelesen.
|
||||
// Ohne TTS feuert onPlaybackFinished nie — der Mikro-/Konversations-
|
||||
// Lifecycle haengt sonst (das Ohr bleibt grau, das Aufnahme-Fenster offen).
|
||||
// ARIA "drueckt hier selbst Stop": jede offene Aufnahme schliessen +
|
||||
// zurueck aufs Wake-Word, egal in welchem Zustand (conversing, passives
|
||||
// Lauschen ODER eine noch offene Streaming-Aufnahme).
|
||||
ariaStopRecording('silent-command').catch(() => {});
|
||||
// Lifecycle muss hier selbst weitergeschaltet werden, sonst haengt das Ohr.
|
||||
if (converseRef.current) {
|
||||
// Befehlskette laeuft WEITER ([[WEITER]]): Mikro NICHT schliessen,
|
||||
// sondern das passive Lausch-Fenster oeffnen (endConversation(false)),
|
||||
// damit der naechste Kettenbefehl direkt gesprochen werden kann. ARIA
|
||||
// haelt bewusst offen, bis sie [[ENDE]] (converse=false) schickt.
|
||||
if (wakeWordService.isConversing()) {
|
||||
wakeWordService.endConversation(false).catch(() => {});
|
||||
}
|
||||
} else {
|
||||
// Einzelbefehl / [[ENDE]] → ARIA "drueckt selbst Stop": jede offene
|
||||
// Aufnahme schliessen + zurueck aufs Wake-Word, egal in welchem Zustand
|
||||
// (conversing, passives Lauschen ODER offene Streaming-Aufnahme).
|
||||
ariaStopRecording('silent-command').catch(() => {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user