docs: heutige Brain-/Chat-Fixes + Gedanken-Stream

issue.md — drei neue Eintraege im Chat-Stabilitaet-Block:
- chat_backup ts auf UNIX-ms umgestellt + Migration
- User-Bubble →failed durch agent_activity-impliziten ACK gefixt
- Gedanken-Stream Modal scrollte nicht — Touchable→View+responder
Neuer Block 'Brain-Hang: Multi-Tool-Timeouts + RVS-Block + Skill-
Aggressivitaet' mit den drei Brain-Hang-Fixes.
Neuer Block 'Gedanken-Stream + Live-Tool-Events'.

README.md:
- Feature-Liste der App ergaenzt um Gedanken-Stream
- Diagnostic Main-Tab ergaenzt um 💭 Gedanken-Stream Modal
- Proxy-Sektion: dritter sed-Patch (DEFAULT_TIMEOUT 5→20 Min) +
  routes.js-Patch (tool_use-Hook) dokumentiert
- Brain↔Bridge ist async-Hinweis (send_to_core als create_task)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-15 11:51:57 +02:00
parent 93db6a3156
commit b2ac013765
2 changed files with 22 additions and 3 deletions
+14
View File
@@ -350,6 +350,20 @@ Skills mit Tool-Use.
- [x] **Delivery-Handshake (WhatsApp-Style)**: pro User-Bubble ein lokaler `clientMsgId` + `deliveryStatus` (queued/sending/sent/delivered/failed). Bridge sendet `chat_ack` zurueck (✓ sent) und schreibt die ID ins `chat_backup.jsonl`. ARIA-Reply markiert alle vorigen User-Bubbles als delivered (✓✓). LRU-Idempotenz auf der Bridge (200 cmids) verhindert Doppelte beim Retry. Offline-Queue: Nachrichten im Flugmodus bleiben lokal als ⏱-queued, beim Reconnect feuert `flushQueuedMessages`. ACK-Timeout 30 s, bis zu 3 Retries, danach ⚠ + Tap-fuer-Retry
- [x] **Offline-Bubble verschwand nach Reconnect (Race)**: parallel laufen `chat_history_request` und `flushQueuedMessages` beim Reconnect; die History-Antwort kam an bevor die Bridge die Bubble persistiert hatte → Merge ersetzte den lokalen Stand → Bubble weg (war aber in Diagnostic drin). Fix: Bridge spiegelt `clientMsgId` im `chat_backup.jsonl`, App-Merge dedupt per cmid und behaelt lokale Bubbles deren ID der Server noch nicht kennt
- [x] **Doppel-Bubble nach Retry**: Backup-Eintraege von vor dem cmid-Patch hatten keine `clientMsgId` — Server-Bubble (ohne cmid) und lokale failed-Bubble (mit cmid) standen beide im Merge. Plus ACK-Timer lief gelegentlich weiter obwohl die Bubble schon `delivered` war → Retry pushte den Status zurueck auf `sending`. Fix: Merge faellt zusaetzlich auf `text+timestamp`-Heuristik im 5-Min-Fenster zurueck; `dispatchWithAck` prueft per Ref ob die Bubble inzwischen `delivered` ist und cancelt dann; bei ARIA-Reply werden alle laufenden ACK-Timer gecleart
- [x] **chat_backup ts war Container-Uptime statt UNIX-ms**: `_append_chat_backup` nutzte `asyncio.get_event_loop().time()` (Monotonic, bei jedem Restart wieder 0) statt `time.time()`. Folge: Server-Bubbles mit ts wie 394M (6 min Uptime) wurden in der App-History neben App-side Bubbles mit Date.now() (1.778e12) sortiert — Hello-Kitty-Konversation von gestern landete chronologisch nach heutigen Karten-Routen, neue Nachrichten verschwanden unter dem 500er-Cap. Plus: Doppelpost-Schutz griff nicht weil das 5-Min-ts-Fenster bei 1.7 Bio ms Diff nie zutraf. Fix: Bridge schreibt jetzt UNIX-ms, Migration-Script `tools/migrate_chat_backup_ts.py` repariert vorhandene jsonl (284/299 ts umgeschrieben auf der VM, Datei-Reihenfolge bleibt). App-Merge dedupt zusaetzlich per blossem Text-Match (ohne ts-Diff) — schuetzt auch gegen vorhandene lokale Duplikate
- [x] **User-Bubble ⏳→failed bei langsamen ARIA-Antworten**: ACK-Timer (30 s × 3 Retries) lief durch obwohl Brain laengst arbeitete — wenn `chat_ack` aus irgendwelchen Gruenden nicht durchkam (RVS-Frame verloren etc.), wurde die Bubble nach 90 s auf failed gesetzt obwohl die Antwort gleich danach kam. Fix: jedes `agent_activity != idle`-Event ist impliziter ACK — Brain wuerde nicht arbeiten wenn es die Nachricht nicht haette. Beim ersten non-idle Event werden alle laufenden ACK-Timer gecanceled und sending-Bubbles auf 'sent' gesetzt. ACK_TIMEOUT_MS zusaetzlich von 30 s auf 60 s als Backup
- [x] **Gedanken-Stream Modal scrollte nicht**: innerer `TouchableOpacity` (eigentlich nur fuer close-on-tap-outside-Schutz) hat alle Touch-Events konsumiert. Fix: durch `View` mit `onStartShouldSetResponder={true}` + `onResponderTerminationRequest={false}` ersetzt — blockt Tap-Propagation ohne Scrolls der Children zu verschlucken
### Brain-Hang: Multi-Tool-Timeouts + RVS-Block + Skill-Aggressivitaet
- [x] **Skill-Erstellung aggressiver als gewollt**: Prompt sagte „Harte Regel — IMMER Skill anlegen wenn pip-Library noetig". ARIA hat das wortwoertlich genommen und bei einer simplen pdf-extract-Frage sofort `skill_create` aufgerufen → Brain 12 Min blockiert (venv 2 min + pip install 10 min Timeout in `skills.py`). App zeigt „ARIA denkt", Bridge emitted nach 5 Min Timeout idle, User ohne Antwort. Fix in `prompts.py`: „Goldene Regel: NIE ungefragt Skills anlegen" + nur bei expliziter Anfrage („mach daraus einen Skill") und auch dann nur wenn die 4 Kriterien (wiederkehrend / nicht-trivial / parametrisierbar / wiederverwendbar) zutreffen. Greift auf der VM nach `docker compose restart aria-brain` ohne Re-Build
- [x] **Brain-Timeouts 5 Min → 20 Min**: drei verkettete 5-Min-Timeouts (Bridge `urlopen`, Brain `proxy_client`, Proxy `DEFAULT_TIMEOUT` im claude-max-api-proxy npm-Modul) feuerten exakt gleichzeitig. Live in den Logs nachvollzogen: ein Proxy-Call brauchte 4m51s und wurde von der Bridge auf den Sekundenbruchteil genau gekappt. Aufgabenstellungen wie Karten-Rekonstruktion mit 10+ curl-Calls oder PDF-Verarbeitung brauchen aber locker 815 Min. Fix: alle drei Timeouts auf 1200 s, plus dritter sed-Patch im docker-compose proxy-Service (`DEFAULT_TIMEOUT = 300000 → 1200000`). App-Stuck-Watchdog auf 1260 s (21 Min, knapp drueber)
- [x] **RVS-Block waehrend Brain-Call** (mobil.hacker-net.de:444 droppt nach 4 Min idle): `async for raw_message in ws: await _handle_rvs_message(...)` — das await blockierte den recv-Loop solange `send_to_core` lief. Die websockets-Lib beantwortete Pings im Hintergrund, aber der RVS-Server zaehlt nur echte App-Frames und droppt sonst die Verbindung. Symptom: App+Diagnostic zeigten „abgebrochen" obwohl Brain noch arbeitete. Fix: `send_to_core` als `asyncio.create_task` statt `await` — RVS-recv-Loop bleibt frei, neue Messages werden weiter verarbeitet, Verbindung bleibt lebendig
### Gedanken-Stream + Live-Tool-Events
- [x] **Gedanken-Stream in App + Diagnostic**: chronologisches Log was ARIA intern macht, gefuettert aus `agent_activity`-Events (thinking/tool/assistant/idle). Bleibt zwischen Denk-Phasen stehen, lange Pausen sichtbar als Trennlinie mit Minuten-Hint. App: 💭-Icon in der Statusleiste oeffnet Bottom-Sheet mit chronologischer Liste, 🗑-Confirm zum Leeren. Diagnostic: 💭 Gedanken-Button im Chat-Test-Header oeffnet zentrales Modal, Live-Update wenn neue Eintraege kommen (autoscroll ans Ende). Persistierung in AsyncStorage / localStorage, capped auf 500 Eintraege
- [x] **Live-Tool-Events vom Proxy**: dritter Proxy-Patch (`proxy-patches/routes.js`) hookt Claude-CLI `assistant`-Events — bei jedem `tool_use`-Block (Bash, Read, Edit, Grep, ...) wird per HTTP-POST an die Bridge gemeldet. Bridge spiegelt das als `agent_activity tool=<name>` an RVS-Clients. Vorher kam pro Brain-Call nur EIN „💭 denkt" am Anfang und EIN „✓ fertig" am Ende — jetzt sieht man **live** in beiden UIs wie ARIA durch die Tools haengt. Hook ist fire-and-forget (ARIA_TOOL_HOOK_URL Env-Variable, default http://aria-bridge:8090/internal/agent-activity)
## Offen