Files
ObsiGate/docs/features/ai-app-context.md
T
bruno c3e6841293
CI / lint (push) Successful in 1m16s
CI / security (push) Successful in 50s
CI / test (push) Successful in 2m24s
CI / build (push) Successful in 47s
CI / e2e (push) Successful in 10m35s
fix(ai): accents dans les chemins et resolution des chemins prefixes par le vault (BUG-042)
- accents : classes de caracteres Unicode (\p{L}\p{N}\p{M}) pour les motifs
  de liens et _looksLikePath (PATH_NAME_RE) -> les chemins/fichiers accentues
  produisent enfin un lien cliquable ; comparaison de chemins normalisee NFC
  (_normKey), donc une mention decomposee (e + accent combinant, style macOS)
  correspond a une entree d'index precomposee, et inversement.
- prefixe de vault : _splitVaultPrefix() retire un premier segment egal au nom
  d'un vault connu (TestVault/Recettes/Pizza Maison.md) ; _fetchPathsForVault()
  interroge l'index de CE vault sans ecraser le cache du vault actif ;
  _openFileLink/_revealPath recoivent le vault cible ; repli 'retirer le
  premier segment' si le prefixe ne correspond a aucun vault connu.

Tests : frontend IA 62/62 (+5), 9 suites JSDOM, validate-imports 36 modules,
pytest 963 passed / 6 skipped. Verifie aussi contre l'instance live sur donnees
reelles accentuees/espaces (Recettes/Preparation.md, Recettes/Pat... ) : 8/8.
2026-09-14 13:37:23 -04:00

5.4 KiB

#88 — Assistant IA : contexte applicatif & fiabilité des liens

Statut : 🟢 corrigé / livré (en attente de vérification utilisateur) Version : 2.3.0 Composants : frontend/js/bookslm.js, backend/bookslm.py, backend/bookslm_routes.py Bugs liés : BUG-041, BUG-042

Contexte

Trois troubles d'usage signalés sur l'Assistant IA (BooksLM) :

  1. Répertoire vide bloquant — ouvrir l'assistant sur un dossier ne contenant aucun fichier markdown renvoyait ⚠ Error: Aucun fichier markdown trouvé dans ce dossier (HTTP 404) au lieu de répondre à la question de l'utilisateur.
  2. Assistant Général aveugle — en mode Général, l'assistant ne savait que lister les vaults : il ne connaissait ni les documents ouverts, ni le répertoire courant, ni la page de résultats de recherche, ni les fichiers récemment modifiés.
  3. Liens de fichiers peu fiables — l'assistant produisait des liens vers des noms de fichiers qui échouaient avec File not found: …, sans règle claire (nom simple, dossier, chemin complet).

Conception

1. Dégradation gracieuse du dossier vide (BUG-041)

_resolve_system_prompt (backend/bookslm_routes.py) ne lève plus de 404 quand le contexte d'un dossier est vide. Il construit le prompt Général (aide applicative + actions), enrichi d'un bloc « Dossier vide », et prévient le modèle qu'aucun contexte documentaire n'est disponible — il répond quand même et propose une création de fichier si pertinent.

Le prompt Général reçoit en outre les fichiers récemment modifiés de l'utilisateur (backend/services/recent.list_recent, best-effort).

2. Contexte applicatif de l'assistant Général (#88)

Le frontend envoie un nouveau champ app_context dans les requêtes /chat et /agent (_buildAppContext()), contenant l'état vivant de l'interface :

Champ Contenu
open_documents Documents ouverts dans les onglets/panneaux (via collectOpenDocuments())
current_path Document affiché dans le viewer
directory Répertoire courant de l'assistant
vault Vault sélectionné
search_query / search_total Dernière recherche et nombre de résultats
search_results Fichiers affichés sur la page de résultats (max 20)

Côté backend, build_general_system_prompt(vaults, app_context, recent_files) rend un bloc « Contexte applicatif actuel » ajouté au prompt Général.

3. Liens de fichiers déterministes (BUG-042)

Classification des liens (_classifyPath) :

Forme data-kind Action au clic
Nom de fichier seul (readme.md) name Copie le nom dans le presse-papiers
Chemin de dossier (projets/2026) dir Révèle le dossier dans l'arborescence
Chemin de fichier (notes/a.md) file Ouvre le fichier dans le viewer

Avant d'agir, _activatePath() résout le chemin contre l'index du vault (_resolveExistingPath) : correspondance exacte, puis suffixe (segment de tête omis par le modèle), puis basename unique. Les chemins non résolus copient le nom au lieu d'ouvrir un lien mort — plus de File not found.

4. Espaces, accents et préfixe de vault dans les chemins (BUG-042)

Les noms de fichiers/dossiers pouvant contenir des espaces et des accents, la détection et la résolution sont adaptées :

  • Liens markdown : la cible peut contenir des espaces, être encadrée par <…> ou porter un "titre" ; les URL percent-encodées (%20) sont décodées.
  • Code inline : `Ma note.md` / `Recettes/Préparation.md` sont reconnus (_looksLikePath utilise PATH_NAME_RE, une classe Unicode \p{L}\p{N}\p{M} — les accents sont acceptés, le jeu de caractères reste strict pour rejeter extraits de code et commandes shell).
  • Mentions brutes : une mention avec espaces n'est liée que si elle existe réellement dans l'index du vault (_linkifySpacePaths + _confirmPathInCache), et l'acceptation se fait sur le plus long suffixe aligné sur un mot — ainsi « Ouvre Mon dossier/Ma note.md » ne crée pas de lien englobant « Ouvre » et la prose ordinaire n'est jamais liée à tort. Les chemins sans espace mais accentués sont liés par le motif PATH_WITH_DIR_RE, lui aussi Unicode-aware.
  • Normalisation Unicode : _normKey() compare en NFC + minuscules, donc une mention décomposée (e + accent combinant, comme sur macOS) correspond à une entrée d'index précomposée, et inversement.
  • Préfixe de vault : _splitVaultPrefix() retire un premier segment égal au nom d'un vault connu (TestVault/Recettes/Pizza Maison.md → Recettes/Pizza Maison.md). La résolution interroge l'index de ce vault (_fetchPathsForVault, fetch ponctuel sans écraser le cache du vault actif), puis _openFileLink/_revealPath reçoivent le vault cible. Si le préfixe ne correspond à aucun vault connu, _resolveExistingPath retente en retirant le premier segment.

Tests

  • tests/frontend/ai.test.mjs : classification (name/file/dir), routage _activatePath (ouvre/révèle/copie), clic d'un lien « nom » → presse-papiers, et prise en charge des espaces (code inline, liens markdown %20, mentions brutes liées uniquement si présentes dans l'index, résolution au clic).
  • tests/test_bookslm.py : build_general_system_prompt avec app_context + recent_files ; prompt inchangé sans contexte ; chat sur dossier vide ne renvoie plus 404.