Files
nas-runbooks/hermes-tt/mail-o365-recherche-scroll-virtualisation.md
T

4.3 KiB

hermes-mail-browser -- Liste virtualisee OWA : limite a 5-7 mails + recherche precise dans la boite

Date : 2026-07-24 Sphere : hermes-tt Composant : hermes-mail-browser (port 3110)

Symptome

Nabil avait laisse 10 mails "Dr. Nexum Veille" successifs dans l'inbox pour test. hermes-tt n'en voyait que 5, rien avant vendredi 24/07 12:07, meme en demandant limit=20.

Cause racine

OWA (New Outlook) utilise une liste de messages virtualisee : seuls les elements visibles a l'ecran (~5-7 lignes) sont reellement montes dans le DOM. /inbox lisait ce DOM en un seul coup (eval_on_selector_all sans scroll) -- peu importe le limit demande, il ne pouvait renvoyer que ce qui etait deja monte.

Plusieurs methodes de scroll testees :

  • element.scrollTop = scrollHeight (programmatique) : ne declenche rien sur cette UI (scrollHeight == clientHeight en permanence, pas d'evenement de chargement).
  • Molette (mouse.wheel) : charge un peu plus mais de facon peu fiable.
  • Navigation clavier (ArrowDown sur l'option focus) : methode fiable -- force le composant virtualise a monter les elements suivants au fur et a mesure que le focus avance. Validee : 40 pressions ArrowDown avec accumulation/dedoublonnage ont retrouve 54 mails uniques sur une recherche qui n'en montrait que 6 au premier chargement.

Fix

Nouvelle fonction read_listbox_items(page, target_count) : accumule les messages par ArrowDown progressif (350ms entre chaque), dedoublonne par aria-label (cle stable), s'arrete des que target_count atteint ou apres 8 tours sans nouveaute (liste epuisee). Remplace la lecture ponctuelle dans /inbox.

Consequence sur l'indexation : une liste virtualisee demonte les elements du haut au fur et a mesure du scroll -- un .nth(index) positionnel n'est donc plus stable dans le temps. Nouvelle fonction click_option_by_position(page, index) : accumule jusqu'a index+1 via read_listbox_items, puis relocalise l'element cible par son aria-label (cle stable) plutot que par position DOM, avant de cliquer. Utilisee par /message/{index}, /message/{index}/attachments, /message/{index}/attachments/{filename}/text.

Nouvelle capacite : recherche precise dans toute la boite

Nabil avait aussi besoin de chercher un mail precis sans parcourir tout l'inbox page par page. La searchbox OWA existe (role=searchbox, aria-label="Rechercher") et fonctionne exactement comme la liste d'inbox (meme structure role=listbox/role=option) -- memes fonctions d'accumulation reutilisees.

Nouveaux endpoints :

  • GET /search?q=<mots-cles>&limit=N -- resultats au meme format que /inbox
  • GET /search/message?q=...&match=<fragment> -- ouvre le premier resultat dont le texte contient match, retourne le corps complet
  • GET /search/message/attachments?q=...&match=...
  • GET /search/message/attachments/{filename}/text?q=...&match=...

match plutot qu'un index positionnel : plus robuste dans un contexte de recherche ou le volume de resultats n'est pas connu a l'avance et ou l'index d'un resultat particulier n'a pas de sens stable.

Validation

  • GET /inbox?limit=20 : 20 mails renvoyes correctement, jusqu'au 20/07 (contre 5 avant le fix, rien avant le 24/07 12:07). ~36s pour 20 items (acceptable, usage agent ponctuel).
  • GET /search?q=Dr. Nexum Veille&limit=8 : 8 resultats corrects en ~24s.
  • Test de non-regression : /inbox sans parametre reste identique a avant (retro-compatible avec l'usage existant de hermes-tt).

Incident collateral

Pendant le rebuild/redeploiement du conteneur, hermes-tt (via Nabil) a teste l'ancienne hypothese de parametre search= (au lieu de q=) sur /search, echouant avec une reponse vide -- rapporte comme "l'application ne fonctionne pas". Cause reelle : le skill mail-o365-tt.md n'avait pas encore ete mis a jour avec le bon contrat d'API au moment du test. Le skill a ete complete (sections "Naviguer dans les dossiers" et "Rechercher un mail avec precision") et hermes-agent-tt redemarre pour recharger le fichier -- healthy et skill a jour depuis.

Fichiers modifies

/volume1/docker/hermes-mail-browser/app/main.py (backup : main.py.bak_20260724_search_scroll et main.py.bak_20260724_folders). /volume1/docker/hermes-platform/hermes-tt/data/skills/mail-o365-tt.md (backup : mail-o365-tt.md.bak_20260724_final).