feat(ai): durcissement phase F (#79) - rate limit, redaction, OpenAPI/MCP, E2E

This commit is contained in:
2026-09-11 21:56:50 -04:00
parent 88eecd7671
commit 9dce341bc8
18 changed files with 854 additions and 27 deletions
+20 -6
View File
@@ -1,6 +1,6 @@
# #79 — Assistant IA — Outils (function calling) & serveur MCP
> **Statut :** 🔵 En cours — Phase 0 + A2 + B1/B2/B3/B4/B5/B6/B7 + C + D + E + G livrés (2026-09-11)
> **Statut :** ✅ Livré — Phase 0 + A2 + B1/B2/B3/B4/B5/B6/B7 + C + D + E + F + G livrés (2026-09-11)
> **Effort :** 10-15 jours | **Impact :** 🟡
> **Références :** [Roadmap](../ROADMAP.md) · [Guide d'architecture IA](../AI_ARCHITECTURE_GUIDE.md)
@@ -53,11 +53,25 @@
matcher `/mcp` exact, démarrage paresseux du manager pour les tests). Dépendances ajoutées :
`mcp==1.9.4`, `sse-starlette==2.1.3` (compatibles avec FastAPI 0.110 / starlette 0.37).
## F. Durcissement & documentation (1 jour)
- [ ] **F1.** Rate limiting par token/outil + quotas (`BOOKSLM_MAX_*`)
- [ ] **F2.** Redaction des secrets avant retour au LLM
- [ ] **F3.** Documentation OpenAPI (`backend/openapi_docs.py`) + guide MCP
- [ ] **F4.** Tests E2E de bout en bout
## F. Durcissement & documentation (1 jour) — ✅ livré (2026-09-11)
- [x] **F1.** Rate limiting par token/outil + quotas — `backend/tools/ratelimit.py`
(fenêtre glissante par identité **et** par outil ; identité = JTI du jeton
(`_token_jti`, ajouté par `backend/auth/middleware.py`) sinon id/username).
Env : `OBSIGATE_TOOL_RATE_LIMIT` (60), `OBSIGATE_TOOL_RATE_LIMIT_PER_TOOL`,
`OBSIGATE_TOOL_RATE_WINDOW` (60 s) ; erreur `ToolRateLimitError` (`rate_limited`).
Quotas `BOOKSLM_MAX_*` : `BOOKSLM_MAX_TOOL_CALLS` (25) plafonne les appels d'outils
par run d'agent (`backend/agent/loop.py`, `stopped="quota_exceeded"`) et
`BOOKSLM_MAX_TOOL_READ_BYTES` (200000) plafonne `read_file`.
- [x] **F2.** Redaction des secrets avant retour au LLM — `backend/tools/redaction.py`
(`redact_payload`, récursif) appliqué à **tout** résultat d'outil dans
`call_tool` (couvre les diffs, extraits de recherche et lectures non pré-redactées).
- [x] **F3.** Documentation OpenAPI + guide MCP — `backend/openapi_docs.py` : tag `MCP`,
règle `/mcp`, injection du path `/mcp` (Streamable HTTP, JSON-RPC) dans le schéma ;
nouveau [`docs/MCP_GUIDE.md`](../MCP_GUIDE.md) (endpoint, auth, config Claude Desktop /
Cursor, tools/resources/prompts, sécurité, variables, dépannage).
- [x] **F4.** Tests E2E de bout en bout — `tests/test_ai_e2e.py` : agent in-app
read→confirmation→write, quota d'outils, rate limiting, redaction, et flux MCP complet
`read` → `propose_edit_file` → `apply_edit_file` → `resources/read`.
## G. Sélection fournisseur/modèle par défaut — ✅ livré
- [x] **G1.** Persistance `ai_default_provider` + `ai_default_models` dans `data/config.json` (`_DEFAULT_CONFIG`)