Compte Rendu Complet - Refonte de la Gestion des Messages du Chat Agent
Date
2024 - Refonte complète de l'architecture de gestion des messages 2026-02-06 - Extensions fonctionnelles et UX (commandes, formulaires, fichiers)
Problème Identifié
Symptôme Principal
Lors de la suppression d'une conversation, l'ID de conversation restait présent et la conversation se rechargeait automatiquement lors de l'envoi d'un nouveau message.
Causes Racines Identifiées
- Gestion d'état dispersée : L'état de conversation était géré à plusieurs endroits avec des refs et des flags complexes
- Cache React Query mal géré : Le cache n'était pas complètement nettoyé lors des suppressions
- Auto-chargement problématique : Un
useEffectrechargeait automatiquement la dernière conversation même après suppression - Race conditions : Plusieurs états et refs pouvaient entrer en conflit
- Architecture complexe : La logique était concentrée dans un seul hook monolithique
Solution Implémentée
Architecture Refondue
1. Séparation des Responsabilités
Nouveau hook : useConversationState
- Gestion centralisée de l'état des conversations
- Prévention des race conditions
- Gestion propre du cache
- Flag pour empêcher l'auto-chargement après suppression
Nouveau hook : useMessageState
- Gestion centralisée des messages optimistes
- Gestion de l'état de traitement (
isProcessing) - Gestion des AbortControllers
- Prévention des chunks tardifs
Hook refondu : useAgentChatLogic
- Architecture claire et modulaire
- Utilisation des nouveaux hooks spécialisés
- Séparation claire des responsabilités
- Code plus maintenable et testable
2. Améliorations du Cache React Query
Avant :
onSuccess: (_, conversationId) => {
queryClient.invalidateQueries({ queryKey: ["conversations"] });
queryClient.invalidateQueries({ queryKey: ["conversation", conversationId] });
queryClient.removeQueries({ queryKey: ["conversation", conversationId] });
};
Après :
onSuccess: (_, conversationId) => {
// Remove immediately (before invalidation) to prevent race conditions
queryClient.removeQueries({ queryKey: ["conversation", conversationId] });
// Then invalidate list to refresh
queryClient.invalidateQueries({ queryKey: ["conversations"] });
};
3. Correction du Problème d'Auto-chargement
Avant :
- Un
useEffectrechargeait automatiquement la dernière conversation - Le flag
isNewConversationRequestedRefn'était pas toujours respecté - Pas de distinction entre suppression et nouvelle conversation
Après :
- Flag centralisé dans
useConversationState - Vérification stricte avant auto-chargement
- Distinction claire entre suppression et nouvelle conversation
- Nettoyage complet du cache avant auto-chargement
4. Gestion Robuste des Suppressions
Nouvelle logique :
- Marquer la conversation comme en cours de suppression
- Supprimer du cache immédiatement
- Si c'était la conversation courante, la réinitialiser
- Marquer le flag pour empêcher l'auto-chargement
- Nettoyer tous les états associés
Améliorations Visuelles
1. Animations Subtiles
- Fade-in pour les nouveaux messages
- Transitions douces sur les interactions
- Animations de scroll optimisées avec
requestAnimationFrame
2. Feedback Utilisateur Amélioré
- États visuels clairs pour les boutons
- Indicateurs de chargement améliorés
- Transitions sur les hover
3. Performance
- Utilisation de
requestAnimationFramepour le scroll - Optimisation des re-renders avec
useMemo - Réduction des calculs inutiles
Extensions 2026-02-06
Commandes, formulaires et guidage
- ✅ Commandes
/avec auto‑complétion et navigation clavier - ✅ Tokens inline pour actions
/et contexte@ - ✅ Form builder obligatoire pour toute création d’entité
- ✅ Champs requis alignés sur les formulaires standards
- ✅ Formulaires désactivés si message non‑dernier
- ✅ Statuts de formulaires ACTIVE/DONE/CANCELED
Fichiers et contexte
- ✅ Pièces jointes de conversation (upload, listing, suppression)
- ✅ OCR/Extraction PDF/IMG pour enrichir le contexte IA
- ✅ Badge “fichiers attachés” dans le message utilisateur
UX conversation
- ✅ Annulation de requêtes sans toast parasite
- ✅ Nettoyage des tokens après envoi
- ✅ Rappels d’actions dans le message utilisateur
Extensions 2026-02-07 (Form builder)
- ✅ Refactor UI actions en composants spécialisés (
ChatRequestInfo*) + hooks - ✅ Centralisation du préremplissage et des champs modifiés
- ✅ Conformité stricte < 400 lignes par fichier pour les composants agent
- ✅ Commandes
/sans champs (ex:/help) envoyées directement - ✅ Input non bloqué quand un formulaire est ouvert
- ✅ Badges contexte affichent
@type: libellé - ✅ Guard duplication contact par email (y compris email utilisateur)
Mise à jour 2026-04-05
- ✅ Le formulaire inline
/facturelancé depuis une page session expose maintenant des sélecteurs stables pour vérifier le préremplissagesession + contact. - ✅ Couverture e2e critique ajoutée pour le scénario
session -> ouvrir Iris -> /facture -> session/contact déjà résolus.
Fichiers Créés
Nouveaux Hooks
-
hooks/useConversationState.ts- Gestion centralisée de l'état des conversations
- Méthodes :
startNewConversation,selectConversation,deleteConversation,clearConversationMessages - Prévention des race conditions
-
hooks/useMessageState.ts- Gestion centralisée des messages
- Méthodes :
addOptimisticUserMessage,startStreaming,markMessageComplete - Gestion des AbortControllers
Fichiers Modifiés
-
useAgentChatLogic.ts- Refonte complète- Architecture modulaire
- Utilisation des nouveaux hooks
- Code plus clair et maintenable
-
useAgentChat.ts- Amélioration du cache- Nettoyage immédiat du cache lors des suppressions
- Ordre d'exécution optimisé
-
AgentMessages.tsx- Améliorations visuelles- Animations pour les nouveaux messages
- Scroll optimisé
-
AgentMessage.tsx- Améliorations visuelles- Transitions sur hover
- Meilleure expérience utilisateur
-
AgentInput.tsx- Améliorations visuelles- Feedback visuel amélioré
- Animations subtiles
Architecture Finale
useAgentChatLogic (Orchestrateur principal)
├── useConversationState (État des conversations)
│ ├── Gestion de currentConversationId
│ ├── Prévention auto-chargement
│ └── Gestion du cache
├── useMessageState (État des messages)
│ ├── Messages optimistes
│ ├── Traitement en cours (isProcessing)
│ └── AbortControllers
├── useAgentChat (API REST)
│ ├── Conversations
│ ├── Messages
│ └── Cache React Query
└── Réponse synchrone API
├── Completion
└── Erreurs
Mise à jour 2026-02-08
- ✅ Retrait du streaming front/back.
- ✅ Formulaires affichés sans refresh (fix cache + déduplication assistant par
runId). - ✅ Affichage du message utilisateur immédiat (optimistic avant latence réseau).
- ✅ Retour action unifié via
metadata.actionResult(succès/erreur/warning).
Mise à jour 2026-04-02
Le lot n’est plus seulement une refonte technique de la gestion des messages. Le chat est maintenant traité comme un vrai workspace produit.
État actuel du produit
- ✅ Nom produit stabilisé sur
Iris - ✅ Shell unifié entre
sidebar,window,mobileetfullscreen - ✅ Header, composer, dropdowns
@//, fichiers de conversation et welcome state repris dans une même grammaire visuelle - ✅ Messages regroupés, séparateurs temporels, pending states et slash states alignés sur un langage de conversation cohérent
- ✅ Champ de saisie multiline avec envoi
Cmd+Entersur macOS etCtrl+Entersur Windows/Linux - ✅ Notifications mobile en fullscreen, rendues cohérentes avec le chat et la recherche globale
- ✅ Export conversation et fallback upload stabilisés
- ✅ Résultats d’action assistant reliés aux workspaces actuels (
pipeline, vues entité)
Architecture frontend actuelle
Le cœur reste orchestré par useAgentChatLogic, mais le lot s’appuie maintenant sur une structure plus modulaire:
AgentPanelContentpour le shell et l’assemblageAgentHeader,AgentMessages,AgentInputpour les trois blocs principauxAgentMessage*+ utils/types dédiés pour séparer rendu, parsing et metadata assistant
Intégration CRM actuelle
- Les
actionResultassistant ne sont plus traités comme de simples liens texte. - Iris expose maintenant des raccourcis directs vers les workspaces métier quand c’est pertinent:
contact -> pipeline leadquote -> quote view- conservation des liens entité standards pour navigation latérale rapide
- Le contrat de navigation accepte les URLs absolues backend et les routes legacy
/edit, puis les remappe vers les surfaces frontend actives. - Le scénario critique e2e couvre désormais aussi les CTA métier exposés par Iris dans
frontend/e2e/agent-chat.critical.spec.ts. - Le flux pièces jointes est plus explicite dans l’UI:
- fichiers en attente présentés comme contexte prêt à envoyer dans le composer
- fichiers de conversation rendus comme cartes de contexte exploitables dans le fil
- réponses assistant capables d’indiquer explicitement quand elles s’appuient sur les pièces jointes récentes
- provenance plus précise côté UI grâce au type de fichier remonté dans les metadata de conversation
- La latence perçue est mieux traitée dans le fil:
- état de travail affiché immédiatement après l’envoi
- message assistant provisoire directement dans le fil pendant le traitement
- étapes distinctes
préparation,ajout du contexte,réponse - moins de sensation de vide quand Iris prend du temps
- signal explicite quand une réponse dépasse la latence habituelle
- conversation préchauffée dès l’ajout de fichiers pour éviter un temps mort supplémentaire à l’envoi
- Le flux
@adopte maintenant un wording plus produit:clientaffiché côté utilisateur à la place du terme CRM internecontact- compatibilité conservée avec les anciens tokens
@contact:côté parsing - descriptions plus explicites dans le dropdown de contexte pour aider à choisir la bonne surface
- La page lead pipeline peut maintenant ouvrir Iris avec contexte client préchargé:
- ouverture directe du panneau assistant depuis la fiche lead
- token client injecté avant envoi
- prompt de cadrage prêt pour obtenir résumé, prochaine action et prochain message
- Les actions guidées
/sont plus lisibles dans la conversation:- progression visible par étape
- étape courante clarifiée
- navigation retour possible dans le flux guidé
- popover slash plus explicite sur le type d’action et le nombre de champs attendus
- Iris peut maintenant aussi servir de couche d’information externe légère:
/meteopour récupérer une météo lieu/date/lieupour récupérer des informations de base sur un lieu/mapspour obtenir rapidement les liens de carte utiles/materielpour préparer un setup ou une liste de matériel- réponses courtes et directement réutilisables dans la conversation sans sortir du workspace
- détection en langage naturel sur les demandes météo / lieu / maps / matériel, sans exiger un slash explicite
- formulaires inline spécialisés (
SlashCommandInlineForm,ChatRequestInfoForm,ChatUiActionsForm)
Direction produit retenue
- Le chat n’est plus un simple panneau d’outillage.
Irisdevient un espace conversationnel CRM transversal.- Les actions, formulaires, fichiers et résultats doivent se lire comme des objets de conversation, pas comme des widgets techniques séparés.
Sujets encore ouverts
scénarios E2E critiques— couvert partiellement : widget inlinemessage + action + pièce jointerequest_info, action result CTA, endpoint widgets REST (E2E API) ; upload fichier complet reste dépendant du storage E2E.derniers contrôles lint/types/runtime sur le shell complet— lint backend/frontend CI corrigé (2026-07).- intégrations métier plus directes entre
Iriset le pipeline CRM
Tests et Validation
Scénarios Testés
-
✅ Suppression de conversation
- La conversation est supprimée du cache
- L'ID est réinitialisé
- Pas de rechargement automatique
- Nouveau message crée une nouvelle conversation
-
✅ Nouvelle conversation
- Cache nettoyé
- Pas d'auto-chargement
- Nouveau message fonctionne correctement
-
✅ Sélection de conversation
- Chargement correct
- Messages affichés
- Pas de conflit avec les messages optimistes
-
✅ Envoi de message
- Message optimiste affiché immédiatement
- Streaming fonctionne
- Message final sauvegardé
- Pas de doublons
-
✅ Annulation de requête
- AbortController fonctionne
- État nettoyé correctement
-
✅ Gestion des erreurs
- Messages d'erreur affichés
- État nettoyé en cas d'erreur
Bénéfices de la Refonte
1. Maintenabilité
- Code plus modulaire et organisé
- Séparation claire des responsabilités
- Plus facile à tester et déboguer
2. Robustesse
- Élimination des race conditions
- Gestion propre du cache
- Prévention des fuites de mémoire
3. Performance
- Optimisations du scroll
- Réduction des re-renders
- Gestion efficace du cache
4. Expérience Utilisateur
- Animations subtiles
- Feedback visuel amélioré
- Comportement prévisible
5. Fiabilité
- Problème de suppression résolu
- Auto-chargement contrôlé
- Gestion d'erreurs améliorée
Points d'Attention
1. Compatibilité
- Tous les composants existants fonctionnent avec la nouvelle architecture
- L'API publique reste la même
2. Migration
- Aucune migration nécessaire
- Les changements sont internes
3. Tests
- Tous les scénarios critiques ont été testés
- Aucune régression identifiée
Conclusion
La refonte complète de la gestion des messages du chat agent a résolu le problème principal de rechargement après suppression tout en améliorant significativement l'architecture, la maintenabilité et l'expérience utilisateur. L'architecture modulaire facilite les futures évolutions et la maintenance du code.
Évolution livrée : commandes en / (2026-02-06)
Le système de commandes en / est désormais livré (ex. /contact, /session, /devis, /facture, /aide) :
- Backend : Détection du préfixe
/en début de message, routage vers un flux dédié form builder (pas d’action LLM libre pour les créations). - Frontend : Input qui détecte
/et affiche un menu de suggestions ; sélection d’une commande = token inline + formulaire structuré avec champs requis. - Sécurisation des données : Champs obligatoires garantis (email requis pour contact, start_date/title/location pour session). Voir PLAN_AMELIORATIONS_CRM.md.
Évolution livrée : dual‑mode chat + fichiers (2026-02-06)
- Dual‑mode : séparation stricte entre actions via / et conversation libre pour éviter les détections ambiguës.
- Fichiers de conversation : upload, listing, suppression et extraction OCR (PDF/IMG) pour enrichir le contexte de l’IA.
Évolution livrée : contexte @ galeries et diaporamas (2026-05)
- Frontend : le composer
@propose Galerie et Diaporama / film (préfixes localisés :@galerie:/@gallery:et@diaporama:/@slideshow:). Recherche sur titre (et description pour les galeries). Films chargés via/galleries/:id/slideshowspour les galeries qui ont au moins un diaporama. - Métadonnées : jetons
contextTokensavectype: "gallery"(id = UUID galerie) outype: "slideshow"(id compositegalleryId+GALLERY_SLIDESHOW_CONTEXT_ID_JOINER+slideshowId, helpers dansfrontend/src/components/search/agent/contextTokens.ts). - Liens assistant → navigation : URL
/galleries/:id/editorreconnue comme entité galerie (parser messages). - Parité native : conventions résument avec Iris décrites dans MOBILE_APP_DEVELOPMENT.md.
Évolution livrée : widgets taggés inline (2026-07)
- Persistance : table
conversation_widgets(type,dataJSONB,status) liée à la conversation et au message assistant. - Rendu inline : le backend insère des tags
[[widget:UUID]]dans le contenu ; le frontend parse viaMessageWithWidgetset rend viachatWidgetRegistry. - Lifecycle unifié : soumissions via
metadata.widgetResponse(widgetId,response,status) ; plus deformEvent/ footerAgentMessageAssistantMetapour les modules interactifs. - Types :
request_info,ui_actions,slash_command_form,email_send_confirm,action_result,external_info,export_download,conflict. - API :
GET /agent/conversations/:id/widgets,GET/PATCH /agent/widgets/:id.
Prochaines Étapes Recommandées
Tests unitaires : Ajouter des tests pour les nouveaux hooks— helpers widget +chat-widget-responsecouverts (web + backend).OpenAPI agent chat : Documenter— livré (2026-07).POST /agent/chat, conversations CRUDMobile Iris : module— livré danssrc/features/agent/+ écran + Socket.IO/agentaaperture-mobile(MR agent, 2026-07) : registry 8 widgets, cache merge, optimistic UI.- Monitoring : Surveiller les performances en production
- Mobile avancé (post-MVP) : composer
@//, pièces jointes, deep links pipeline depuisaction_result