Files
context-continuity/trilium_automation_setup.md
T
Master 01629780f4 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.
2026-06-29 11:02:22 +02:00

316 lines
9.0 KiB
Markdown

# Trilium Automation Setup - Fichier Unique avec Tous les Scripts
# Projet : Context Continuity
# Date : 27 mai 2026
---
## Description
Ce fichier contient tous les scripts Python et configurations nécessaires pour automatiser la gestion de contexte multi-LLM avec Trilium.
---
## Structure des Fichiers
```
trilium_automation/
├── init_trilium_architecture.py # Initialise l'arborescence Trilium
├── trilium_api.py # Bibliothèque pour interagir avec l'API ETAPI
├── create_conversation.py # Crée des notes de conversation LLM
├── generate_context.py # Génère un contexte pour les LLM
└── .env.example # Exemple de fichier d'environnement
```
---
## 1. Fichier .env.example
```ini
# Fichier : .env
# À placer dans /volume1/homes/Master/App/Automation/
# Ne jamais commiter ce fichier dans Git !
TRILIUM_TOKEN=ton_token_etapi_ici
TRILIUM_API_URL=http://localhost:4292/etapi
ROOT_NOTE_ID=root
```
---
## 2. Script : init_trilium_architecture.py
```python
import requests
import json
import os
from dotenv import load_dotenv
# Charger les variables d'environnement depuis .env
load_dotenv()
# ===== CONFIGURATION =====
TRILIUM_API_URL = os.getenv("TRILIUM_API_URL", "http://localhost:4292/etapi")
TRILIUM_TOKEN = os.getenv("TRILIUM_TOKEN")
HEADERS = {
"Authorization": TRILIUM_TOKEN,
"Content-Type": "application/json"
}
# ID de la note racine (root) - à remplacer par le tien
ROOT_NOTE_ID = os.getenv("ROOT_NOTE_ID", "root")
# ===== FONCTIONS =====
def create_note(parent_id, title, note_type="book"):
"""Crée une note de type 'book' (dossier) ou 'text' dans Trilium."""
data = {
"parentNoteId": parent_id,
"title": title,
"type": note_type,
"content": f"# {title}\n\n*Dossier créé automatiquement via API ETAPI.*"
}
response = requests.post(
f"{TRILIUM_API_URL}/notes",
headers=HEADERS,
json=data
)
if response.status_code == 200:
note_id = response.json().get("noteId")
print(f"✅ Dossier créé : {title} (ID: {note_id})")
return note_id
else:
raise Exception(f"❌ Erreur {response.status_code} : {response.text}")
def get_note_id_by_title(title, parent_id):
"""Récupère l'ID d'une note par son titre (pour éviter les doublons)."""
search_url = f"{TRILIUM_API_URL}/search?q=title:{title}"
response = requests.get(search_url, headers=HEADERS)
if response.status_code == 200:
notes = response.json()
for note in notes:
if note.get("title") == title and note.get("parentNoteId") == parent_id:
return note.get("noteId")
return None
# ===== EXÉCUTION =====
def main():
print(" Initialisation de l'architecture Trilium pour 'Context Continuity'...")
# 1. Créer le dossier principal "Context Continuity" (s'il n'existe pas)
context_continuity_id = get_note_id_by_title("Context Continuity", ROOT_NOTE_ID)
if not context_continuity_id:
context_continuity_id = create_note(ROOT_NOTE_ID, "Context Continuity", "book")
else:
print(f"✅ Dossier existant : Context Continuity (ID: {context_continuity_id})")
# 2. Créer les sous-dossiers
subfolders = ["Conversations", "Backlog", "Décisions", "Glossaire", "Historique"]
folder_ids = {}
for folder in subfolders:
folder_id = get_note_id_by_title(folder, context_continuity_id)
if not folder_id:
folder_id = create_note(context_continuity_id, folder, "book")
else:
print(f"✅ Dossier existant : {folder} (ID: {folder_id})")
folder_ids[folder] = folder_id
# 3. Afficher les IDs pour référence
print("\n IDs des dossiers créés (à utiliser dans tes scripts) :")
for folder, folder_id in folder_ids.items():
print(f"{folder}: {folder_id}")
# 4. Sauvegarder les IDs dans un fichier JSON
with open("trilium_folder_ids.json", "w") as f:
json.dump({
"root_id": ROOT_NOTE_ID,
"context_continuity_id": context_continuity_id,
**folder_ids
}, f, indent=4)
print("\n IDs sauvegardés dans trilium_folder_ids.json")
if __name__ == "__main__":
main()
```
---
## 3. Script : trilium_api.py
```python
import requests
import os
from dotenv import load_dotenv
# Charger les variables d'environnement
load_dotenv()
TRILIUM_API_URL = os.getenv("TRILIUM_API_URL", "http://localhost:4292/etapi")
TRILIUM_TOKEN = os.getenv("TRILIUM_TOKEN")
HEADERS = {
"Authorization": TRILIUM_TOKEN,
"Content-Type": "application/json"
}
def create_note(parent_id, title, content, note_type="text"):
"""Crée une note dans Trilium."""
data = {
"parentNoteId": parent_id,
"title": title,
"type": note_type,
"content": content
}
response = requests.post(
f"{TRILIUM_API_URL}/notes",
headers=HEADERS,
json=data
)
if response.status_code == 200:
return response.json().get("noteId")
else:
raise Exception(f"Erreur {response.status_code} : {response.text}")
def get_note(note_id):
"""Récupère une note par son ID."""
response = requests.get(
f"{TRILIUM_API_URL}/notes/{note_id}",
headers=HEADERS
)
return response.json()
def update_note(note_id, content):
"""Met à jour une note existante."""
data = {"content": content}
response = requests.put(
f"{TRILIUM_API_URL}/notes/{note_id}",
headers=HEADERS,
json=data
)
return response.status_code == 200
def search_notes(query):
"""Recherche des notes par titre ou contenu."""
response = requests.get(
f"{TRILIUM_API_URL}/search?q={query}",
headers=HEADERS
)
return response.json()
```
---
## 4. Script : create_conversation.py
```python
from trilium_api import create_note
from datetime import datetime
import os
from dotenv import load_dotenv
load_dotenv()
# IDs des dossiers (à remplacer par les tiens)
CONVERSATIONS_ID = os.getenv("CONVERSATIONS_ID", "ID_DU_DOSSIER_CONVERSATIONS")
def create_conversation(llm, title, content):
"""Crée une note de conversation dans Trilium."""
date = datetime.now().strftime("%Y-%m-%d %H:%M")
note_title = f"[{llm}] - {date} - {title}"
note_content = f"""# {note_title}
**Projet** : [[Context Continuity]]
**LLM** : {llm}
**Date** : {date}
**Statut** : En cours
---
## Contexte
{content}
---
**Liens** :
- [[Backlog/]]
- [[Décisions/]]
"""
note_id = create_note(
parent_id=CONVERSATIONS_ID,
title=note_title,
content=note_content
)
print(f"Note créée : {note_id} ({note_title})")
return note_id
# Exemple d'utilisation
if __name__ == "__main__":
create_conversation(
llm="Le Chat",
title="Configuration Trilium pour Context Continuity",
content="Discussion sur la configuration de Trilium pour synchroniser les contextes entre LLM."
)
```
---
## 5. Script : generate_context.py
```python
from trilium_api import search_notes, get_note
from datetime import datetime
import os
from dotenv import load_dotenv
load_dotenv()
CONTEXT_CONTINUITY_ID = os.getenv("CONTEXT_CONTINUITY_ID", "ID_DU_DOSSIER_CONTEXT_CONTINUITY")
def generate_context(project_name, limit=10):
"""Génère un contexte pour un projet donné en agrégeant les notes Trilium."""
query = f"projet:{project_name}"
notes = search_notes(query)
context = f"# Contexte du projet : {project_name}\n\n"
context += "## Conversations récentes\n"
for note in notes[:limit]:
note_data = get_note(note["noteId"])
context += f"- **{note_data['title']}** (LLM: {note_data.get('llm', 'N/A')}, Date: {note_data.get('date', 'N/A')})\n"
context += f" {note_data['content'][:200]}...\n\n"
context += f"\n*Généré le {datetime.now().strftime('%Y-%m-%d %H:%M')}*"
return context
# Exemple d'utilisation
if __name__ == "__main__":
context = generate_context("Context Continuity")
print(context)
```
---
## Instructions d'Utilisation
### 1. Préparer l'environnement
```bash
# Installer les dépendances
pip install requests python-dotenv
# Créer le fichier .env
cd /volume1/homes/Master/App/Automation/
echo "TRILIUM_TOKEN=ton_token_etapi" > .env
echo "TRILIUM_API_URL=http://localhost:4292/etapi" >> .env
echo "ROOT_NOTE_ID=root" >> .env
```
### 2. Exécuter les scripts
```bash
# Initialiser l'arborescence Trilium
python3 init_trilium_architecture.py
# Créer une conversation
python3 create_conversation.py
# Générer un contexte
python3 generate_context.py > contexte.md
```
### 3. Vérifier les résultats
- Ouvre Trilium et vérifie que les dossiers et notes sont créés.
- Le fichier `trilium_folder_ids.json` contient les IDs des dossiers.
---
## Notes Importantes
- **Ne jamais partager le fichier .env** (il contient ton token ETAPI).
- Les scripts supposent que Trilium est accessible via `http://localhost:4292/etapi`.
- Si tu utilises le Reverse Proxy, remplace `TRILIUM_API_URL` par `https://trilium.bertha-cloud.fr/etapi`.