feat(chat): Muelltonne pro Bubble — gezielt eine Nachricht loeschen
Stefan kann jetzt einzelne Chat-Bubbles loeschen (mit Rueckfrage).
Die Bubble verschwindet aus chat_backup.jsonl (Bridge), Brain-
Conversation (rolling window + jsonl) und allen Clients (App +
Diagnostic). Genauso wichtig fuer ARIA: der gloeschte Turn ist im
naechsten Chat-Prompt nicht mehr im Window.
Pipeline:
UI 🗑 + confirm
→ RVS delete_message_request {ts}
→ Bridge._delete_chat_message:
- chat_backup.jsonl Zeile mit ts entfernen (atomar via tmp+rename)
- Brain POST /conversation/delete-turn (role+content match)
- RVS broadcast chat_message_deleted {ts}
→ App + Diagnostic entfernen Bubble lokal per ts-Match
Backend-Aenderungen:
- aria-brain/conversation.py: remove_by_match(role, content, ts_hint)
+ _rewrite_file (atomar). Match nahester Turn bei mehrfach gleichem
content.
- aria-brain/main.py: POST /conversation/delete-turn (POST statt DELETE
weil FastAPI keine Bodys auf DELETE erlaubt)
- bridge/aria_bridge.py: HTTP-Listener /internal/delete-chat-message
+ RVS-Handler delete_message_request. _append_chat_backup gibt jetzt
ts zurueck, _process_core_response packt backupTs ins chat-Event.
- rvs/server.js: ALLOWED_TYPES um delete_message_request +
chat_message_deleted erweitert.
- diagnostic/server.js: delete_chat_message-Action + chat_message_deleted
Relay zum Browser.
Frontend-Aenderungen:
- diagnostic/index.html: 🗑 erscheint on-hover in Bubbles mit data-ts,
confirm()-Dialog, addChat + chat_history setzen data-ts. WS-Listener
fuer chat_message_deleted entfernt Bubble per data-ts.
- android/ChatScreen.tsx: backupTs in ChatMessage, Muelltonne-Button
unten rechts in jeder Bubble, Alert-confirm, RVS-Listener fuer
chat_message_deleted entfernt aus messages-State.
Live-User-Bubbles (sofort gerendert vom eigenen Send) haben noch
keinen backupTs bis der Bridge-Roundtrip durch ist — die Muelltonne
erscheint dort erst nach kurzer Verzoegerung / Reload. Folgekommit
kann das polieren wenn noetig.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -432,6 +432,28 @@ def conversation_reset():
|
||||
return {"ok": True, "turns": 0}
|
||||
|
||||
|
||||
class ConvDeleteBody(BaseModel):
|
||||
role: str
|
||||
content: str
|
||||
ts_iso_hint: Optional[str] = None
|
||||
|
||||
|
||||
@app.post("/conversation/delete-turn")
|
||||
def conversation_delete_turn(body: ConvDeleteBody):
|
||||
"""Entfernt einen einzelnen Turn aus dem Rolling-Window + jsonl.
|
||||
Match per role + content (erstes Vorkommen wenn ts_iso_hint None,
|
||||
sonst nahester zur Zeit). 404 wenn kein Match.
|
||||
|
||||
POST statt DELETE weil FastAPI 0.115 keine Bodys auf DELETE
|
||||
erlaubt — semantisch trotzdem eine Loeschung."""
|
||||
ok = conversation().remove_by_match(
|
||||
role=body.role, content=body.content, ts_iso_hint=body.ts_iso_hint,
|
||||
)
|
||||
if not ok:
|
||||
raise HTTPException(404, "Turn mit diesem role+content nicht gefunden")
|
||||
return {"ok": True, "turns": len(conversation().turns)}
|
||||
|
||||
|
||||
@app.post("/conversation/distill")
|
||||
def conversation_distill_now():
|
||||
"""Manueller Trigger fuer Destillat — fuer Tests oder vor einem
|
||||
|
||||
Reference in New Issue
Block a user