- app/services/plugins.py + migration 35 : table plugins (slug, name,
description, enabled) pré-remplie avec 3 modules câblés — web-tools,
web-clipper, automations ; ligne absente = activé (défaut sûr)
- automations OFF → dépendance FastAPI posée à l'include_router dans main.py
(aucun router touché) → toutes les routes /workspace/automations* refusées +
garde de tick du scheduler en arrière-plan
- web-clipper OFF → GET /extensions et tout /api/v2/web-clipper/* refusés
- web-tools OFF → web_search et fetch_url retirés du schéma ET de execute()
via ToolRegistry._all() : le LLM ne les voit plus
- UI rendue côté serveur : global Jinja plugin_enabled(slug) — nav
« Extensions » / « Automations » en {% if %} (absentes du DOM), sections
conditionnées en x-show dans settings.html
- menu + : l'entrée « Add plugins » devient vivante (fini disabled:true) —
liste des 3 plugins avec bascule, GET/PATCH /api/agent/plugins[/slug]
(slug inconnu → 404, 401 sans session)
- tests : tests/test_v758_plugins.py (10 tests) — routes refusées (302 hors
/api, 404 JSON pour /api*), outils retirés, nav disparue, persistance,
câblage ; assertions disabled:true == 0 dans les tests des phases 1/3/4/5/7
- livraison : VERSION + app/main = 7.58.0, OpenAPI 525 chemins, CHANGELOG,
ROADMAP phase 8 cochée (menu + complet), avenant phase 8 (docs)
- Table agent_connectors (migration 32) : colonnes plates name, url,
secret_encrypted, enabled, status, detail — config_json remis (YAGNI, les
scopes OAuth des phases 6-7 ajouteront le leur).
- app/services/connectors.py : 1 fichier au lieu du package connectors/ —
3 natifs (gitea, github, web) servis à la volée avec statut sans réseau,
CRUD des personnels (URL validée par _validate_url = garde SSRF, clé chiffrée
Fernet et jamais renvoyée — seul has_secret), probe() qui persiste
status/detail, connector_fetch() borné à 20 000 car.
- API /api/agent/connectors : GET, POST (400 URL privée), PATCH, DELETE,
POST /connectors/probe — 401 sans session, CSRF global. OpenAPI 519 chemins.
- Outil LLM connector_fetch (26e outil) : un seul outil qui dispatche vers
Gitea/GitHub/web/personnalisé (id ou nom ou kind + path + query) au lieu d'un
outil par connecteur ; désactivé/inconnu = erreur outil, jamais de run cassé.
- Menu + : section « Connecteurs » (catalogue avec badge ✓/✗/⚠/?), fiche par
connecteur (Tester, Activer/Désactiver, Supprimer — masqués pour les natifs),
formulaire « Ajouter un connecteur personnalisé » (clé en type=password).
- Tests : tests/test_v755_connectors.py (13) — 3 natifs, roundtrip Fernet de la
clé, 5 URLs refusées (localhost, 127.0.0.1, metadata cloud, ftp:, file:),
toggle persisté, 401, probe OK/erreur, outil complet, câblage menu ;
test_v751/v753/v754 adaptés (1 seule section « bientôt » = plugins).
Suite complète 1306 verts (-n auto), ruff 0, eslint 0 problème.
- Le moteur n'envoie jamais l'historique (system + objectif courant seulement)
: chaque run repartait de zéro. Nouveau service app/services/agent_memory.py —
une ligne résumé par conversation (table agent_memory, migration 31),
écrite en fin de run et ré-injectée au contexte du run suivant.
- context_for() : bloc « ## Mémoire de la conversation », budget 4000 car.
(troncature gauche + marqueur). remember() : 1 note/échange (180 → 700 car.),
20 notes max, upsert, erreurs journalisées — un run ne peut pas échouer à
cause de la mémoire. Toggle OFF = ni lecture ni écriture.
- Toggle « Mémoire » dans le menu + : entrée racine à l'état réel (🧠/💭 +
libellé), PATCH /api/agent/conversations/{id} avec memory_enabled ajouté au
whitelist, état lu à l'ouverture et à la création, défaut AGENT_MEMORY_DEFAULT
(settings.agent_memory_default) + memory_enabled dans la réponse de création.
- Décision : mémoire d'espace (lignes workspace_id NULL) remise — YAGNI, rien
ne l'écrivait ; noté ponytail: dans le service avec le chemin de montée.
- Tests : tests/test_v754_memory.py (8) dont 2 runs réels du moteur (FakeLLM
capture le prompt : mémoire présente ON / absente OFF) ; test_v751 et
test_v753 adaptés (2 sections « bientôt » restantes). Suite complète 1293
verts (-n auto, 2e run ; 1 échec intermittent sur test_v56_import URL au
1er run, vert isolé + vert au run suivant = flake préexistant), ruff 0,
eslint 0 problème. OpenAPI 516 chemins / 7.54.0.