Files
ObsiGate/docs/features/ai-app-context.md
T
bruno 12a53d647e
CI / lint (push) Successful in 1m17s
CI / security (push) Successful in 51s
CI / test (push) Successful in 2m30s
CI / build (push) Successful in 51s
CI / e2e (push) Successful in 10m29s
fix(ai): espaces dans les noms de fichiers et chemins des liens (BUG-042)
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.
2026-09-14 13:20:09 -04:00

92 lines
4.5 KiB
Markdown

# #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 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 (`_looksLikePath` accepte 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_prompt` avec `app_context` +
`recent_files` ; prompt inchangé sans contexte ; chat sur dossier vide ne
renvoie plus 404.