Les noms/paths de l'assistant peuvent contenir des espaces ; la detection et la resolution les prennent desormais en charge de bout en bout : - liens markdown : cible avec espaces, encadree par <...> ou avec un "titre", et URL percent-encodees (%20) decodees ; - code inline : `Ma note.md` / `Mon dossier/Ma note.md` reconnus (_looksLikePath accepte les espaces, jeu de caracteres strict pour rejeter extraits de code et commandes shell) ; - mentions brutes : liees uniquement si presentes dans l'index du vault (_linkifySpacePaths + _confirmPathInCache), avec acceptation du plus long suffixe aligne sur un mot -> le mot de prose precedent n'est pas avale ; - _normalizeLinkPath : trim ; _renderMdLink : decodage %20. Tests : frontend IA 57/57 (+5), 9 suites JSDOM, validate-imports 36 modules, pytest 963 passed / 6 skipped.
4.5 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.pyBugs liés : BUG-041, BUG-042
Contexte
Trois troubles d'usage signalés sur l'Assistant IA (BooksLM) :
- 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. - 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.
- 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 dans les noms de fichiers et les chemins (BUG-042)
Les noms de fichiers/dossiers pouvant contenir des espaces, la détection est adaptée :
- 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`/`Mon dossier/Ma note.md`sont reconnus (_looksLikePathaccepte les espaces en gardant un jeu de caractères strict, ce qui rejette les 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.
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_promptavecapp_context+recent_files; prompt inchangé sans contexte ; chat sur dossier vide ne renvoie plus 404.