chore: versioning initial du systeme Context Continuity

Code du systeme de memoire multi-LLM sur Trilium :
- trilium_api.py : wrapper trilium-py (notes, labels, relations)
- mcp_server.py : serveur MCP Starlette (19 tools, OAuth + Bearer)
- api_context.py : API REST FastAPI
- trilium_context.py : workflow CLI
- watchdog.sh, start_*.sh : supervision et demarrage
- skills, docs et ontologie associes
Secrets (.env, oauth_state.json) exclus via .gitignore.
This commit is contained in:
2026-06-29 11:02:22 +02:00
commit 01629780f4
26 changed files with 5259 additions and 0 deletions
+180
View File
@@ -0,0 +1,180 @@
# SKILL — Référence technique : APIs Trilium & serveur MCP
Référence d'implémentation du système Context Continuity. À sortir pour
débugger, étendre ou appeler directement les APIs. Le « quand/pourquoi »
comportemental est dans le skill de réflexe de continuité ; ici c'est le
« comment » technique.
Trois voies d'accès à Trilium coexistent : **API REST FastAPI** (distante,
HTTPS), **ETAPI via wrapper Python** (locale, sur GrosseBertha), **MCP**
(pour agents Mistral).
---
## 1. API REST FastAPI — accès distant (recommandé pour un LLM)
Couche créée pour exposer Trilium en HTTPS (pallie l'absence d'accès direct).
| Paramètre | Valeur |
|---|---|
| Base URL | `https://api-trilium.bertha-cloud.fr` |
| Auth header | `Authorization: <API_KEY>` (clé brute, **sans** `Bearer`) |
| Clés | Clé Claude / clé Le Chat — demander à Bastien ou lire dans `.env` |
| Doc Swagger | `https://api-trilium.bertha-cloud.fr/api/docs` |
**Endpoints essentiels :**
| Action | Appel |
|---|---|
| Lire le contexte projet | `GET /api/contexte/{projet}?llm_cible=NomLLM` |
| Voir le backlog | `GET /api/backlog/{projet}` |
| Enregistrer une décision | `POST /api/decisions` |
| Enregistrer un historique | `POST /api/historique` |
| Créer une conversation | `POST /api/conversations` |
| Clôturer une session | `PATCH /api/conversations/{id}` |
| Marquer un backlog item | `PATCH /api/backlog/{id}` |
**Exemples curl :**
```bash
# Lire le briefing de reprise
curl -s -H "Authorization: CLE" \
"https://api-trilium.bertha-cloud.fr/api/contexte/SlidingAutomation?llm_cible=Le+Chat+Large" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['briefing'])"
# Enregistrer une décision
curl -s -X POST -H "Authorization: CLE" -H "Content-Type: application/json" \
-d '{"projet":"SlidingAutomation","enonce":"Décision prise","justification":"Raison"}' \
https://api-trilium.bertha-cloud.fr/api/decisions
# Marquer un backlog item comme fait
curl -s -X PATCH -H "Authorization: CLE" -H "Content-Type: application/json" \
-d '{"statut":"fait"}' \
https://api-trilium.bertha-cloud.fr/api/backlog/NOTE_ID
```
---
## 2. ETAPI via wrapper Python — accès local (sur GrosseBertha)
TriliumNext 0.95+ a restructuré ses routes : `POST /etapi/notes` retourne
*Router not found*. **Solution validée : `trilium-py 1.3.9`**, encapsulé dans
`~/App/Context_continuity/trilium_api.py`.
```
pip install trilium-py python-dotenv
```
`.env` :
```
TRILIUM_URL=http://localhost:4292
TRILIUM_TOKEN=<token généré dans Options > ETAPI>
```
Header d'auth : `Authorization: token` (**sans** `Bearer` ; Bearer accepté
depuis 0.93 mais non requis).
**Fonctions du wrapper `trilium_api.py` :**
| Fonction | Note |
|---|---|
| `check_api()` | Lève SystemExit si Trilium inaccessible |
| `create_note(parent_id, title, content=" ", note_type="text")` | `content=" "` obligatoire — jamais vide |
| `get_note_id(result)` | Extrait `noteId` du résultat de `create_note` |
| `get_note(note_id)` / `get_note_content(note_id)` | Récupère note / contenu HTML |
| `update_note_content(note_id, content)` | Met à jour le contenu |
| `search_notes(query, limit=50)` | Recherche **sans guillemets** autour du terme |
| `search_by_label(label, value="")` | Syntaxe interne `#label=value` |
| `find_note_by_title(title, parent_id="")` | Retourne `noteId` ou `None` |
| `set_label(note_id, name, value="")` | `isInheritable=False` requis en interne |
| `get_label_value(note_id, name)` | Retourne la valeur ou `None` |
**Erreurs connues et fixes :**
| Erreur | Cause | Fix |
|---|---|---|
| `Router not found POST /etapi/notes` | Routing TriliumNext 0.95 | Utiliser `trilium-py` |
| `missing argument isInheritable` | `create_attribute()` trilium-py | Passer `isInheritable=False` |
| `Note content must be set` | Contenu vide refusé | Passer `content=" "` |
| Recherche avec guillemets → `[]` | Parser 0.95 | Chercher sans guillemets |
| `{status,code,message}` sur create | Note existe déjà / contenu vide | `find_note_by_title` avant + `content=" "` |
IDs des dossiers : `trilium_ids.json` (généré par `trilium_init.py`). Clés :
`root, Projets, Conversations, Backlog, Decisions, Historique, Glossaire,
ContextesReprise`.
---
## 3. Serveur MCP — pour agents Mistral
`mcp_server.py` — serveur MCP pur Starlette (compatible Python 3.9), transport
Streamable HTTP sur `/mcp`, écoute `127.0.0.1:8766`, exposé via
`https://mcp-trilium.bertha-cloud.fr`. Protocole `2025-06-18`.
**Authentification : Bearer token statique** (`API_KEY_CLAUDE` /
`API_KEY_LECHAT` depuis `.env`). C'est ce qui le rend **utilisable par Le Chat
mais PAS par Claude** : les connecteurs distants de Claude.ai exigent OAuth
(endpoints de découverte `/.well-known/oauth-authorization-server`, flux
d'autorisation), absents de ce serveur. Pour activer Claude, il faudrait
ajouter une couche OAuth devant le serveur.
**11 tools exposés :** `get_backlog`, `get_decisions`, `get_historique`,
`get_glossaire`, `get_contexte`, `add_decision`, `add_history`, `add_backlog`,
`update_backlog`, `new_conversation`, `close_session`.
---
## 4. Structure des données Trilium
Note racine **Context Continuity** → 8 sous-dossiers : `Projets`,
`Conversations`, `Backlog`, `Decisions`, `Historique`, `Glossaire`,
`Contextes Reprise`, `Skills`.
**Types de notes et labels obligatoires :**
| Type (`type=`) | Labels obligatoires |
|---|---|
| `projet` | `projet` (sans espaces), `statut` (actif\|en-pause\|archive) |
| `conversation` | `projet`, `llm`, `statut` (en-cours\|clos), `date` (YYYY-MM-DD HH:MM) |
| `backlogItem` | `projet`, `statut` (a faire\|en cours\|bloque\|fait\|abandonne), `priorite` (haute\|moyenne\|basse) |
| `decision` | `projet`, `statut` (active\|revisee\|annulee) |
| `historiqueItem` | `projet`, `typeHistorique`, `encoreValide` (true\|false) |
| `termeGlossaire` | `projet`, `definition` |
| `contexteReprise` | `projet`, `llmCible`, `version` |
`typeHistorique` ∈ { `Fait etabli`, `Test effectue`, `Hypothese invalidee`,
`Contrainte decouverte` }.
**Filtres des briefings** (pièges) :
- `generate-context` n'inclut que les décisions `statut=active`.
- N'inclut que l'historique `encoreValide=true`.
- `list-backlog` exclut `statut` ∈ { `fait`, `abandonne` }.
- Pour retirer un élément du briefing : passer `statut=annulee` (décision) ou
`encoreValide=false` (historique) — ne pas supprimer la note.
**Pièges d'écriture récurrents :**
| Erreur | Conséquence | Fix |
|---|---|---|
| Statut avec majuscule (`Actif`) | Le filtre rate la note | Toujours minuscules |
| Nom projet avec espaces | `search_by_label` échoue | `SlidingAutomation` |
| `encoreValide="True"` | Filtre cherche `true` | Minuscules |
| `definition` absent sur glossaire | Briefing affiche « (voir note) » | Ajouter le label |
---
## 5. Workflow CLI (sur GrosseBertha)
```bash
cd ~/App/Context_continuity && source venv/bin/activate
# Début
python trilium_context.py new-conversation --projet SlidingAutomation --llm "Claude Sonnet" --titre "..."
# Reprise
python trilium_context.py generate-context --projet SlidingAutomation --llm-cible "Claude Sonnet" --note-id ID --version N
# Au fil de l'eau
python trilium_context.py add-decision --projet SlidingAutomation --enonce "..." --justification "..."
python trilium_context.py add-history --projet SlidingAutomation --type "Test effectue" --enonce "..." --detail "..."
# Clôture
python trilium_context.py close-session --note-id ID --summary "..."
# État
python trilium_context.py list-backlog --projet SlidingAutomation
python trilium_context.py list-projects
```
Fichiers du système : `trilium_api.py` (wrapper, ne pas modifier),
`trilium_init.py` (init unique), `trilium_context.py` (workflow quotidien),
`trilium_logger.py` (intégration pipeline Sliding), `trilium_ids.json`,
`mcp_server.py`, `api_context.py` (API FastAPI).