0da5e2aba1
Store SQLite conversations/messages (propriété par actor, fenêtre 20), historique rejoué au LLM (runAgentTurn history), ChatService persiste et renvoie conversationId. API GET/DELETE /conversations + chat avec conversationId. UI Chat: sidebar conversations (drawer mobile), nouvelle, reprise, suppression. docs/conversations.md. 83 tests verts, build web vert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016w5jRe87MGdd6AMvXQcHNi
2.4 KiB
2.4 KiB
Conversations persistantes (mémoire multi-tour)
CHLOVA stocke chaque conversation et rejoue l'historique récent au LLM, pour qu'il garde le contexte d'un message à l'autre et que l'utilisateur puisse reprendre une conversation plus tard.
Modèle
SQLite (node:sqlite, même fichier que la table assets — CHLOVA_DB_PATH).
| Table | Colonnes |
|---|---|
conversations |
id (uuid), actor, title, created_at, updated_at |
messages |
id, conversation_id, role (user/assistant), content, ts |
- Propriété : une conversation appartient à un
actor(API =api:owner, Telegram =telegram:<userId>). Accès à une conversation d'un autre acteur refusé (ForbiddenConversationError→ HTTP 403 / 404 selon l'endpoint). - Titre : dérivé du 1er message (tronqué à 60 car.).
- Fenêtre de contexte : les
HISTORY_WINDOW(= 20) derniers messages sont rejoués au LLM (ChatService→runAgentTurn({ history })). Au-delà, l'ancien n'est pas envoyé (pas de résumé/troncature par tokens en v1 — amélioration possible si les conversations deviennent longues).
Flux
POST /api/chat { message, conversationId? }:- sans
conversationId→ nouvelle conversation créée, son id renvoyé ; - avec
conversationId→ historique chargé + rejoué, message ajouté. - réponse :
{ reply, conversationId }.
- sans
GET /api/conversations→ liste (id, titre, dates) de l'acteur, par récence.GET /api/conversations/:id→ messages complets (reprise).DELETE /api/conversations/:id→ suppression (messages + conversation).
UI
Onglet Chat : barre latérale des conversations (drawer sur mobile, fixe en
md+), bouton Nouvelle, sélection pour reprendre, suppression. L'envoi
transmet le conversationId courant ; une nouvelle conversation rafraîchit la
liste.
Surfaces
- API/UI : pleinement câblé (création, reprise, suppression).
- Telegram (si activé) :
conversationIdstable =telegram:<userId>→ mémoire continue par utilisateur. - Mobile (Expo) : chat encore sans état — branchement des conversations à faire (réutilise les mêmes endpoints).
Sécurité / vie privée
Les messages sont stockés en clair dans la base (volume chlova-data). Pas de
secret n'y transite normalement (l'agent manipule des références). La base n'est
jamais exposée ; seul le backend y accède.