Files
ObsiGate/docs/features/ai-assistant-history.md
T
bruno c9e3240ae2
CI / lint (push) Successful in 1m28s
CI / security (push) Successful in 58s
CI / test (push) Successful in 2m9s
CI / build (push) Successful in 1m3s
CI / e2e (push) Successful in 11m12s
feat(assistant): #94-#97 historique permanent, sidebar IA, panneau + et bouton rond
2026-09-16 14:56:45 -04:00

6.6 KiB
Raw Blame History

#94–#97 — Assistant IA : historique permanent, accès sidebar, bouton rond et panneau « + »

Statut : ✅ Livré (en attente de validation utilisateur) Effort : ~7 jours | Impact : 🟡 Références : Roadmap · Changelog

  • Description : quatre améliorations de l'Assistant IA livrées ensemble :
    1. #94 — bouton de soumission circulaire avec icône Lucide arrow-up (remplace l'avion ✈️).
    2. #95 — historique permanent des conversations persisté côté backend (les échanges survivent aux rechargements de page et aux navigateurs).
    3. #96 — accès rapide à l'historique depuis la sidebar de navigation (onglet dédié).
    4. #97 — panneau « + » extensible remplaçant « Attach an image » (modules : fichiers, image, contextes, skills, Deep Research, web, Canva).

A. Backend — persistance des conversations (#95) — ✅ livré

  • backend/ai_history.py (nouveau) : stockage JSON par utilisateur (data/ai_history/{username}.json), écriture atomique (tmp + shutil.move), plafond MAX_SESSIONS = 200 (purge des plus anciennes), tri par updatedAt desc.
  • list_sessions, get_session, upsert_session, delete_session ; la liste renvoie des résumés sans messages (_summary : titre, mode, vault, contexte, message_count, preview) pour rester légère.
  • backend/bookslm_routes.py : modèle Pydantic BookslmSession et 4 endpoints : - GET /api/ai/bookslm/history — liste des conversations (résumés). - GET /api/ai/bookslm/history/{session_id} — conversation complète (404 si absente). - PUT /api/ai/bookslm/history/{session_id} — création/mise à jour (l'id du corps est forcé à l'id du path → jamais d'écriture sous une autre clé). - DELETE /api/ai/bookslm/history/{session_id} — suppression (booléen ok).
  • Isolation par utilisateur (require_auth) ; saisies défensives (username/id vides) → [] ou None.

B. Frontend — sync serveur + cache local (#95) — ✅ livré

  • frontend/js/bookslm.js : clé local globale bookslm-sessions-all-{username} ; migration des anciennes clés périmées bookslm-sessions-<ctx> et bookslm-history-<ctx> à la première ouverture.
  • _loadHistory(preferredSessionId) async au chargement du panneau : lecture serveur (GET /history), hydratation du localStorage, repli hors-ligne silencieux si le serveur ne répond pas.
  • Synchronisation debounced 600 ms (_syncHistoryToServer → _flushHistoryToServer) via _dirtySessionIds / _deletedIds : PUT/DELETE seulement pour les sessions modifiées ; pas d'appel réseau à la simple ouverture.
  • _positionSession : nouvelle session insérée en tête, session rechargée remise à jour.
  • openContext(opts, preferredSessionId) async ; openWithSession(sessionOrId) public pour ouvrir une conversation connue (utilisé par la sidebar #96).
  • _notifyHistoryChanged() : événement bookslm:history-updated pour rafraîchir la sidebar #96 sans rechargement.

C. Frontend — sidebar & historique (#96) — ✅ livré

  • frontend/index.html : cinquième onglet #sidebar-tab-ai (icône Lucide messages-square) et panneau #sidebar-panel-ai (#ai-history-list, #ai-history-empty).
  • frontend/js/config.js : loadAISessionList() / renderAIHistoryList() (réutilise les classes .recent-* de l'UI), placeholder « Aucune conversation », listener bookslm:history-updated monté par initSidebarTabs() et actif quand l'onglet ai est affiché.
  • Le clic sur une conversation l'ouvre dans le panneau Assistant IA (via openWithSession) et bascule la sidebar.

D. Frontend — panneau « + » extensible (#97) — ✅ livré

  • Bouton « Attach an image » remplacé par un bouton « + » circulaire (frontend/js/bookslm.js, .bookslm-btn-plus).
  • Panneau overlay .bookslm-ext-menu (dropdown au-dessus de la zone de saisie, fermeture au clic extérieur / Échap) listant les modules.
  • Architecture modulaire : registre _extensions (objet d'enregistrement simple) — chaque entrée : id, icône, libellé i18n, action ; renderExtMenu() construit la liste ; un nouveau module s'ajoute en une entrée.
  • Modules livrés : Fichiers (sélecteur général .bookslm-files-input), Image (joindre une image), Contextes/fichiers, Skills, Deep Research (mode agent + prompt pré-rempli), Recherche sur Internet, Canva.
  • web/canva affichés désactivés avec badge « Bientôt » (.bookslm-ext-soon) — le catalogue d'outils #92 les alimentera.
  • _startDeepResearch() : active le mode agent, injecte le prompt Deep Research et déclenche l'envoi.

E. UI — bouton rond & icône (#94) — ✅ livré

  • .bookslm-btn-send circulaire (40 px, border-radius: 50%), icône Lucide arrow-up à la place de l'emoji ✈️, aligné en bas à droite de la zone de saisie.
  • i18n FR/EN : bookslm.add_options, bookslm.ext_files, bookslm.ext_image_hint, bookslm.ext_contexts, bookslm.ext_skills, bookslm.ext_deep_research, bookslm.ext_web, bookslm.ext_canva, bookslm.coming_soon, bookslm.soon, bookslm.ext_more_coming, bookslm.deep_research_prompt, bookslm.deep_research_started, bookslm.mode_*.

F. Tests — ✅ livré

  • tests/test_bookslm.py : TestBooksLMSessionHistoryEndpoints (7) + TestAIGatewayHistoryStore (4) — liste résumée sans messages, full 404, upsert qui force l'id et isole par utilisateur, delete, cap à 200, purge.
  • tests/frontend/ai.test.mjs : persistance/reouverture/suppression de sessions, migration de l'historique legacy, menu d'historique.
  • Vérifs : pytest 1088 passed / 6 skipped, ruff 0, mypy 0 (71 fichiers), frontend ai.test.mjs 84/84, unit.test.mjs 9/9, validate-imports 38 modules.

G. Points d'attention

  • Le localStorage reste un cache : le serveur est la source de vérité (data/ai_history/). En cas de données locales corrompues, un localStorage.clear() réinitialise proprement.
  • MAX_SESSIONS = 200 : le comportement de purge est testé (TestAIGatewayHistoryStore) ; la rétention configurable (item #95 du backlog) pourra s'appuyer sur ce plafond.
  • Les modules web/Canva du panneau « + » sont volontairement désactivés tant que l'écosystème d'outils phase 2 (#92) n'est pas livré.