feat: menu + — Connecteurs (socle) — phase 5/8 (v7.55.0)
FlowDeck CI / lint (push) Successful in 2m11s
FlowDeck CI / test (push) Failing after 15m16s
FlowDeck CI / docker (push) Skipped

- 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.
This commit is contained in:
2026-10-06 23:26:19 -04:00
parent 64c85caffc
commit 18c72d77fe
16 changed files with 974 additions and 29 deletions
+31 -15
View File
@@ -284,7 +284,7 @@ Propriétés custom, AI keywords, sync API, 12 tables DB
---
## v7.51.0 → v7.58.0 — Menu + de l'assistant : hub de contexte (phases 1-4 ✅ 2026-10-06 · phases 5-8 planifiées)
## v7.51.0 → v7.58.0 — Menu + de l'assistant : hub de contexte (phases 1-5 ✅ 2026-10-06 · phases 6-8 planifiées)
> **Objectif** : faire du bouton **+** du panneau agent (à gauche de la zone d'édition)
> un menu à sections, tel que demandé :
@@ -416,19 +416,35 @@ CHANGELOG). Chiffrage : S < ½ j · M = 1–2 j · L = 3–5 j.
- [x] **Livraison** — `VERSION` + `app/main.py` = **7.54.0**, OpenAPI régénéré
(516 chemins), CHANGELOG, ce ROADMAP
### Phase 5 — v7.55.0 — Connecteurs : socle · effort L
### Phase 5 — v7.55.0 — Connecteurs : socle · effort L ✅ (livrée 2026-10-06)
- [ ] **Table `agent_connectors`** (`kind`, `name`, `config`, credentials chiffrés,
`enabled`, `status`)
- [ ] **`app/services/connectors/`** — interface commune `probe() / list_sources() / fetch()`
+ 3 adapters **natifs déjà présents** : Gitea, GitHub, Web (`web_search` / `fetch_url`, v7.46)
- [ ] **Menu « Connecteurs »** — « Parcourir les connecteurs » (catalogue + statut
connecté/déconnecté) et « Ajouter un connecteur personnalisé » (URL + clé + type
HTTP / MCP)
- [ ] **Tools agent** — un tool par connecteur exposé au LLM via `tool_registry`
- [ ] **Sécurité** — garde SSRF `_is_public_host` sur toute URL, credentials chiffrés,
session requise, CSRF sur les écritures
- [ ] **Tests** — CRUD, statut, vecteurs SSRF, schéma des tools
- [x] **Table `agent_connectors`** (migration **32**) — colonnes **plates**
(`name`, `url`, `secret_encrypted`, `enabled`, `status`, `detail`) ; le
`config_json` prévu est **remis** (YAGNI : rien ne le remplissait — les scopes
OAuth des phases 6-7 ajouteront le leur)
- [x] **`app/services/connectors.py`** — **1 fichier au lieu du package
`connectors/`** promis (3 probes + 1 fetch ne justifient pas une arborescence) ;
3 natifs `gitea`/`github`/`web` servis à la volée, statut **sans réseau**
(`native_state()`) ; `probe()` et `connector_fetch()` passent par `_get()`
(gardé SSRF + re-vérification après redirection, timeout 10 s, borne 20 000 car.)
- [x] **Menu « Connecteurs »** — « Parcourir » = catalogue avec badge
(✓ ok / ✗ error / ⚠ missing / ? inconnu) + fiche (Tester, Activer/Désactiver,
Supprimer — masqués pour les natifs) ; « Ajouter un connecteur personnalisé » =
formulaire nom + URL + clé (`type="password"`)
- [x] **Tool agent** — **un seul `connector_fetch`** (id/nom/kind + `path` +
`query`) au lieu d'un outil par connecteur : même capacité, moins de bruit de
schéma — l'outil dispatche vers Gitea/GitHub/web/personnalisé. Connecteur
désactivé ou inconnu = erreur outil, jamais une exception de run
- [x] **Sécurité** — `_validate_url` (SSRF) à la création **et** à chaque appel,
clé **chiffrée Fernet** et jamais renvoyée (`has_secret` seulement), 401 sans
session sur les 5 routes, CSRF global
- [x] **Tests** — `tests/test_v755_connectors.py` : **13 tests** (3 natifs, clé
chiffrée roundtrip, **5 URLs refusées** : localhost / 127.0.0.1 / metadata
cloud / ftp: / file:, toggle persisté, 401, probe OK + probe erreur persistée,
outil complet, câblage menu) ; 3 autres fichiers de phase adaptés (1 section
« bientôt » restante) ; **suite complète 1306 verts**, `ruff` 0, `eslint` 0
- [x] **Livraison** — `VERSION` + `app/main.py` = **7.55.0**, OpenAPI régénéré
(519 chemins), CHANGELOG, ce ROADMAP
### Phase 6 — v7.56.0 — Connecteurs : Google + Microsoft 365 · effort L
@@ -456,8 +472,8 @@ CHANGELOG). Chiffrage : S < ½ j · M = 1–2 j · L = 3–5 j.
---
*Plan produit le 2026-10-06 à partir du code réel — **phases 1 à 4 livrées le
2026-10-06 (v7.51.0 → v7.54.0)**, phases 5-8 à valider une par une avant « go ».
*Plan produit le 2026-10-06 à partir du code réel — **phases 1 à 5 livrées le
2026-10-06 (v7.51.0 → v7.55.0)**, phases 6-8 à valider une par une avant « go ».
Chaque phase se clôt par tests verts, bump de version, CHANGELOG et ROADMAP à jour.*
---