fix(ai): chaine de repli web_search (SearXNG -> DuckDuckGo -> Bing, BUG-051)
CI / lint (push) Successful in 1m32s
CI / security (push) Successful in 1m0s
CI / test (push) Successful in 3m8s
CI / build (push) Successful in 56s
CI / e2e (push) Successful in 10m44s

This commit is contained in:
2026-09-16 23:13:44 -04:00
parent 75b8d294b0
commit 56b46cde0e
15 changed files with 353 additions and 73 deletions
@@ -133,6 +133,11 @@
ne remonte aucun résultat (moteurs amont suspendus/CAPTCHA) : `warning` +
`unresponsive_engines` dans le résultat — sans ce signal, l'assistant relançait la
même recherche jusqu'au quota d'outils.
- [x] **G8.** **Chaîne de repli web (BUG-051)** : `web_search` interroge successivement
SearXNG, puis DuckDuckGo (HTML sans JS) puis Bing (HTML), et retient le premier
fournisseur non vide (`provider`) ; les replis se désactivent via
`OBSIGATE_WEB_FALLBACK=0`. Évite que l'assistant conclue « pas d'accès à internet »
quand l'instance SearXNG est bloquée par ses moteurs amont.
### Outils restants — documentés pour le futur (hors #91)
La catégorie Notion « étapes » peut s'étendre ; chaque futur outil devra être un
+5 -2
View File
@@ -37,8 +37,11 @@ réécriture de la boucle n'est nécessaire.
## 3. Phase 2 — catégories à implémenter
### 3.1 Recherche web étendue (`web_search`)
- **Fallback sans clé** : aujourd'hui SearXNG auto-hébergé (`OBSIGATE_SEARXNG_URL`).
Prévoir une chaîne de repli si l'instance est indisponible (DuckDuckGo HTML).
- **Fallback sans clé — ✅ livré (BUG-051)** : chaîne de fournisseurs dans
`backend/tools/web.py` — SearXNG auto-hébergé (`OBSIGATE_SEARXNG_URL`) puis, si
aucun résultat, DuckDuckGo (`html.duckduckgo.com/html/`) puis Bing
(`www.bing.com/search`). Le premier fournisseur non vide est retenu et exposé
(`provider`) ; replis désactivables via `OBSIGATE_WEB_FALLBACK=0`.
- **Fournisseurs optionnels** (clé dans Infisical, jamais en dur) : Tavily
(résultats orientés agents), Brave Search API, SerpAPI (Google), Exa.
Interface unifiée type `anysearch` pour un sélecteur de fournisseur unique.