- Conversion `async def` → `def` de TOUTES les routes dont le corps ne contient
ni `await`, ni `async with`, ni `async for`, ni `asyncio` (scan automatique
corps par corps sur app/ : 352 converties, 0 dangereuses, vérifié
`asyncio`/`run_coroutine`/`.result()` absents). FastAPI exécute ces handlers
dans son threadpool → tout leur SQLite (`get_conn()` + `conn.execute`) quitte
l'event loop, sans changer une ligne de logique.
- Répartition : api_v2 60, dashboard 40, collections 25, board 23,
workspace 19, wiki 17, permissions 14, api 14, main.py 6, + 35 fichiers.
- Les 4 routers prioritaires de l'audit sont couverts par ce lot :
api_v2 60 + dashboard 40 + collections 25 + board 23 = 148 conversions
(le reste de leurs routes attend la phase 2 : elles ont de vrais `await`).
- Reste (phase 2) : les 311 routes avec de vrais `await` → enrouler les blocs
DB dans `await anyio.to_thread.run_sync(...)` ; pas de wrapper partagé livré
(rien ne l'appellerait — YAGNI jusqu'au premier usage).
suite **1037/1037** (233 s) · `ruff check app tests` OK · docs à jour
- A26 — champ `standalone` mort supprimé (0 lecteur) ; `sqlite:////data/…` ne
produit plus de chemin UNC sous Windows ; `.env.example` ne promet plus
PostgreSQL ; raise au boot si `APP_SECRET_KEY` vaut la valeur par défaut
- A33 — rate limit : préfixes manquants (`/scim/v2/`, `/workspace/`, `/db/` +
non-GET sur `/s/` et `/f/`), limite lue dans `settings.rate_limit_requests`
(60 annoncés / 100 codés en dur), clé `X-Forwarded-For` seulement derrière un
proxy local (anti-spoof), `_store` épuré (mémoire bornée) + test dédié
- A34 — `_spawn()` : les 10 schedulers loggent leur exception et redémarrent
après 10 s au lieu de mourir en silence ; 2 `logger.debug` de scheduler → warning
- A35 — OpenAPI régénéré 439 → 511 chemins (`info.version 7.3.9`), README
(était v6.7.0), compteur API_GUIDE, titre dupliqué retiré du ROADMAP ;
le drift Python 3.12/3.13 reste noté (rebuild d'image à valider)
- A36 — 4 dépendances mortes purgées de requirements.txt (aiosqlite, slowapi,
loguru, packaging = 0 import) ; pyproject reste sans [project] : Docker et la
CI installent requirements.txt, dupliquer les 22 deps créerait 2 sources
- A43 — 15 `datetime.utcnow()` → `now(UTC).replace(tzinfo=None)` (format ISO
naïf identique, warnings de dépréciation divisés : 2374 → 926)
suite **1029/1029** · `ruff check app tests` OK · docs/ROADMAP/CHANGELOG/WORKLOAD à jour
- `_current_user_id` : 401 sans session (24 sites) au lieu de retomber sur
`SELECT id FROM users WHERE login='admin'`
- `_current_admin` : suppression du même fallback — `PATCH /api/agent/providers`
et `POST /api/agent/providers/test` (donc `LLMClient.ping(api_base=…)`)
exigent une session admin : 401 sans session, 403 non-admin
- `_check_api_base()` sur les 2 routes : scheme http(s), pas d'identifiants
dans l'URL (400) ; hôtes privés maintenus — Ollama `localhost:11434` est le
provider par défaut du produit (commentaire `ponytail:` pour la fermeture)
- +1 test de non-régression → suite **1027/1027**, `ruff check app tests` OK
Un api_base stocke (ex. https://api.mistral.ai/v2) ecrasait l'URL par defaut corrigee et faisait echouer le test de connexion. Desormais: normalisation a l'ecriture (une base egale au defaut n'est pas stockee), possibilite de vider le champ (api_base='' vs None), et migration 14 qui efface les bases obsoletes/redondantes dans user_llm_keys et llm_config.
Tests de non-regression ajoutes.
tests/conftest.py: mutate the settings singleton (instead of rebinding) so DB + backup dir are isolated per test -> pytest-xdist safe.
Real backup tests (snapshot/prune/admin API) and OAuth mock tests (Gitea/GitHub/link) replace the previous skips.
init_db() now also creates webhook_subscriptions (full schema without the FastAPI lifespan).
ruff check is clean; .eslintrc.json migrated to eslint.config.mjs (flat config).
CI: lint job (ruff + eslint), parallel tests (-n auto), run on every branch push.
VERSION 5.11.1.
- Nouveau bouton « 🗑 Réinitialiser » dans Réglages → Agent & IA (réservé aux
admins) : bascule le fournisseur par défaut sur « hors-ligne » et efface la
clé API/base/état vérifié stockés (clear_keys dans set_llm_config).
- Confirmation avant suppression des clés API utilisateur (deleteUserKey).
- Correctif : chaîne JS de confirm("…") sur deux lignes provoquait une erreur
de syntaxe → le script alpine:init ne s'exécutait pas et la page paramètres
restait figée sur « Agent & AI » ; la chaîne est désormais sur une ligne.
- /api/agent/mentions : reponse en sections (fichiers de l'espace courant ouvert, collections, pages de collections, autres documents), workspace_id transmis par le frontend (localWsId) et prioritaire
- Navigation clavier up/down : la liste defile pour garder la selection visible (menus @ et /)
- Deduplication des propositions (meme type + meme titre affiches une seule fois)
- Skills : plus d'injection du texte du skill dans la boite d'edition; requete composee en arriere-plan (contexte + skills + texte) a l'envoi; les skills integres injectent leur template, les enregistres partent via skill_ids
- Tests : shape des mentions, dedup, scoping workspace
- Les skills (menu /, integres et enregistres) s'epinglent comme des bulles dans le composer, au meme titre que les mentions @; plusieurs peuvent coexister sur un meme post
- L'API /run accepte skill_ids (tableau) et l'engine injecte tous leurs prompts dans le system prompt (skill_id conserve pour retro-compat)
- Clic sur une bulle de contexte (@ document/page/base) ouvre l'element comme document courant (/pages/<id> ou /db/<id>); le bouton x retire sans ouvrir
- Envoi possible avec des skills seuls sans texte
- test_engine_multiple_skills_applied
- Composeur contenteditable : mentions inline (pastilles icône+nom), barre de contexte groupée documents/skills, sélecteur @ (icône+titre+chemin), skills intégrés + agent_skills + commandes admin via '/'
- Actions sous chaque réponse agent : copier, insérer dans la page, feedback 👍/👎
- Backend : table agent_feedback, GET /api/agent/mentions, POST /api/agent/feedback, contexte document:<id>/page:<id>/collection:<id> résolu en contenu réel
- Inclut le travail v4.14.0 (documents/espace de travail + outils + auto-titre de conversation)