fix: generischer Skill-Prompt (kein Hardcode) + Stop im 30s-Lauschen beendet

- router.py: die run_spotify-Faehigkeiten NICHT mehr im Prompt aufzaehlen
  (war selbst Hardcoding). Generisch: "run_*-Skills — was sie koennen steht in
  IHRER Tool-Beschreibung, lies + nutze sie fuer alles Passende". Skills
  beschreiben sich selbst (dynamisch, ARIA-authored). Anti-Halluzination bleibt.
- App: Stop-Button waehrend passivem 30s-Lauschen ('listening') beendet jetzt
  sauber (exitPassiveListening) statt via leerem Endpoint den Passiv-Stream neu
  zu starten — die 30s liefen sonst von vorne los.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 22:36:01 +02:00
co-authored by Claude Opus 4.8
parent fb06ed928c
commit 54ebd57990
2 changed files with 20 additions and 9 deletions
+10
View File
@@ -2070,6 +2070,16 @@ const ChatScreen: React.FC = () => {
// forwarded direkt an Brain. Im wake-word-conversing-Fall zusaetzlich
// endConversation: User hat explizit gestoppt → kein Multi-Turn-Resume.
const handleVoiceButtonStop = useCallback(async (): Promise<void> => {
// Stop WAEHREND des passiven 30s-Lauschens ('listening'): sauber beenden
// (zurueck aufs Wake-Word), NICHT den passiven Stream neu starten.
// exitPassiveListening cancelt den Stream selbst (via _freeMic) → es feuert
// kein leeres Endpoint, das startPassiveStreamingRecording erneut ausloest
// (genau das liess die 30s vorher von vorne loslaufen).
if (wakeWordService.getState() === 'listening') {
console.log('[Chat] Manueller Stop im Passiv-Lauschen → exitPassiveListening (Ende)');
await wakeWordService.exitPassiveListening('manual');
return;
}
await audioService.stopStreamingRecording('user');
if (wakeWordService.isConversing()) {
console.log('[Chat] Manueller Stop in Konversation → endConversation, zurueck zu armed');
+10 -9
View File
@@ -153,18 +153,19 @@ def build_local_system_prompt(identity_anchor: str, has_tools: bool = False,
"GPS-Hinweis in der Nachricht.",
"- `memory_search`: in ARIAs Gedaechtnis nachsehen (lesen).",
"- `trigger_timer`: Timer/Erinnerung setzen ('in 10 Minuten…').",
"- `run_spotify`: JEDE Musiksteuerung — Titel wechseln/ueberspringen "
"(auch mehrere), Pause/Weiter, eine PLAYLIST abspielen, auf einem "
"GERAET abspielen, Lautstaerke, 'was laeuft gerade'. Fuer ALLES rund "
"um Musik/Spotify IMMER dieses Werkzeug rufen — nie selbst antworten.",
"- `run_*`-Skills: konkrete Faehigkeiten (z.B. Musik/Spotify u.a.). "
"Was ein Skill kann + welche Parameter er nimmt, steht in SEINER "
"Tool-Beschreibung — LIES sie und nutze den Skill fuer ALLES was "
"dazu passt (nicht nur die offensichtlichen Faelle). Nie selbst eine "
"Aktion 'spielen'/'nachschauen', wenn ein Skill das kann.",
"WICHTIG: Bei reinem Smalltalk ('wie gehts', Begruessung, Meinung) "
"KEIN Werkzeug — einfach direkt antworten. Werkzeuge nur bei echtem "
"Bedarf; erfinde keine.",
"ANTI-HALLUZINATION (kritisch): Behaupte NIEMALS eine Aktion (Musik, "
"Timer, Suche) als erledigt, ohne das Werkzeug WIRKLICH aufgerufen zu "
"haben. Kein 'Spotify: …' / 'Playlist abspielen' o.ae. ohne echten "
"run_spotify-Aufruf. Kannst/willst du es nicht per Werkzeug tun, sag "
"es ehrlich oder eskaliere — erfinde keine Bestaetigung.",
"ANTI-HALLUZINATION (kritisch): Behaupte NIEMALS eine Aktion als "
"erledigt, ohne das Werkzeug WIRKLICH aufgerufen zu haben. Keine "
"'Spotify: …' / 'Playlist abspielen'-Quittung o.ae. ohne echten "
"Skill-Aufruf. Kannst/willst du es nicht per Werkzeug tun, sag es "
"ehrlich oder eskaliere — erfinde keine Bestaetigung.",
]
parts += [
"",