diff --git a/BUGFIX_MCP_ERROR_HANDLING.md b/BUGFIX_MCP_ERROR_HANDLING.md new file mode 100644 index 0000000..0f22d06 --- /dev/null +++ b/BUGFIX_MCP_ERROR_HANDLING.md @@ -0,0 +1,127 @@ +# Correction du bug de gestion d'erreur MCP + +## Problème identifié + +L'agent Nabu entrait dans une boucle infinie en essayant d'accéder à une URL Wikipedia inexistante avec l'outil `web-search-web_url_read`. Le problème était dans le fichier `core/agent/mcp.go` à la ligne 68. + +### Symptômes observés dans les logs : +``` +mcphub-1 | [2025-06-14T13:51:11.649Z] [INFO] [web-search] [child] Error: Failed to fetch the URL: Not Found +localagi-1 | time=2025-06-14T13:51:11.649Z level=DEBUG msg="MCP response" response="&{Result:{Meta:map[]} Content:[{Annotated:{Annotations:} Type:text Text:Error: Failed to fetch the URL: Not Found}] IsError:true}" +``` + +### Code problématique : +```go +// Traiter le résultat +textResult := "" +if result.IsError { + return types.ActionResult{}, err // ❌ err est nil ici ! +} +``` + +Quand `result.IsError` était `true`, le code retournait `err` qui était `nil`, ce qui faisait que l'agent ne recevait aucune information sur l'erreur et continuait à essayer la même action. + +## Solution implémentée + +### 1. Correction de la gestion d'erreur +- Extraction du contenu de l'erreur avant de vérifier `result.IsError` +- Retour du message d'erreur comme résultat au lieu de faire échouer l'action +- Ajout de suggestions spécifiques selon le type d'erreur + +### 2. Code corrigé : +```go +// Traiter le résultat +textResult := "" + +// Extraire le texte du résultat selon le format de mark3labs/mcp-go +for _, content := range result.Content { + if textContent, ok := content.(*mcp.TextContent); ok { + textResult += textContent.Text + "\n" + } else { + xlog.Error("Unsupported content type", "type", content) + } +} + +// Si c'est une erreur, retourner le contenu de l'erreur comme résultat +// plutôt que de faire échouer complètement l'action +if result.IsError { + xlog.Error("MCP tool returned error", "tool", m.toolName, "error", textResult) + + // Fournir des suggestions spécifiques selon le type d'erreur + errorMessage := textResult + if strings.Contains(strings.ToLower(textResult), "not found") { + if m.toolName == "web-search-web_url_read" { + errorMessage = "L'URL spécifiée n'a pas pu être trouvée. Essayez plutôt d'utiliser l'outil de recherche web 'web-search-searxng_web_search' pour chercher des informations sur ce sujet." + } else { + errorMessage = "Ressource non trouvée: " + textResult + } + } + + // Retourner le message d'erreur comme résultat pour que l'agent puisse réagir + return types.ActionResult{ + Result: "Erreur: " + errorMessage, + }, nil +} +``` + +### 3. Améliorations apportées : +- ✅ L'agent reçoit maintenant le message d'erreur complet +- ✅ Suggestions intelligentes pour utiliser des outils alternatifs +- ✅ Logging approprié des erreurs MCP +- ✅ Prévention des boucles infinies sur les erreurs + +## Impact attendu + +Avec cette correction, quand l'agent Nabu rencontre une erreur "Not Found" avec `web-search-web_url_read`, il : + +1. Recevra le message d'erreur complet +2. Sera guidé vers l'utilisation de `web-search-searxng_web_search` comme alternative +3. Pourra adapter sa stratégie au lieu de répéter la même action échouée + +## Corrections supplémentaires + +### Problème de parsing des réponses MCP +Après le premier fix, un nouveau problème est apparu : LocalAGI n'arrivait pas à parser correctement les réponses MCP qui utilisent la structure : +```json +{ + "content": [ + { + "type": "text", + "text": "Title: Meteo Montjaux... [contenu complet]" + } + ], + "isError": false +} +``` + +### Solution : Utilisation de `mcp.AsTextContent()` +Le problème était dans la conversion de type à la ligne 71. Au lieu d'utiliser : +```go +if textContent, ok := content.(*mcp.TextContent); ok { +``` + +Il fallait utiliser la fonction appropriée de la bibliothèque `mark3labs/mcp-go` : +```go +if textContent, ok := mcp.AsTextContent(content); ok { +``` + +## Test de la correction + +La correction a été testée avec : +```bash +go build ./core/agent # ✅ Compilation réussie +docker build -f Dockerfile.webui -t localagi-fixed:v2 . # ✅ Image Docker construite +``` + +## Fichiers modifiés + +- `core/agent/mcp.go` : + - Correction de la gestion d'erreur MCP (ligne 68) + - Correction du parsing des réponses MCP (ligne 71) + - Ajout de l'import `strings` pour la détection de type d'erreur + +## Prochaines étapes recommandées + +1. Tester avec un déploiement Docker complet +2. Vérifier que l'agent utilise bien `web-search-searxng_web_search` après cette erreur +3. Surveiller les logs pour confirmer que les boucles infinies sont évitées \ No newline at end of file diff --git a/__env b/__env deleted file mode 100644 index d9f016f..0000000 --- a/__env +++ /dev/null @@ -1,58 +0,0 @@ -LOG_LEVEL=debug -# Modèles à utiliser -MODEL_NAME=gpt-alex -#MULTIMODAL_MODEL=minicpm-v-2_6 -#IMAGE_MODEL=sd-1.5-ggml -#EMBEDDING_MODEL=granite-embedding-107m-multilingual - -STT_ENGINE=STT_ENGINE=whisper - -# For Fast Whisper (GPU recommended) -STT_ENGINE=whisper-alex-fast - -CUDA_VISIBLE_DEVICES=0 -GGML_CUDA_FORCE_MMQ=0 -GGML_CUDA_FORCE_CUBLAS=1 - -# Home Assistant Configuration -HASS_HOST=https://jarvis.carriere.cloud -HASS_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjYjYzMTQwZjc4Njk0ZTdhODFiYTY2OGI4YzM1NWQzMSIsImlhdCI6MTc0OTM4ODkzMCwiZXhwIjoyMDY0NzQ4OTMwfQ.y6zC6fOk_d7COngm4QG-WatC8lQCYfltuvrJSDbZtk8 -HASS_SOCKET_URL=ws://jarvis.carriere.cloud/api/websocket - -# Server Configuration -PORT=3000 -NODE_ENV=production -DEBUG=false -# URLs des services -LOCALAGI_LLM_API_URL=http://localai:8080 -LOCALAGI_LOCALRAG_URL=http://localrecall:8080 - -# Configuration générale -LOCALAGI_TIMEOUT=5m -LOCALAGI_MCP_TIMEOUT=5m -LOCALAGI_STATE_DIR=/pool -LOCALAGI_ENABLE_CONVERSATIONS_LOGGING=false - -# Configuration LocalAI (basée sur votre instance Unraid) -DEBUG=true -MODELS_PATH=/models -THREADS=4 -COQUI_TOS_AGREED=1 -GALLERIES=[{"name":"localai","url":"github:mudler/LocalAI/gallery/index.yaml@master"}] -SINGLE_ACTIVE_BACKEND=false -LOCALAI_SINGLE_ACTIVE_BACKEND=false -PYTHON_GRPC_MAX_WORKERS=12 -LLAMACPP_PARALLEL=6 -PARALLEL_REQUESTS=true -WATCHDOG_IDLE=true -WATCHDOG_BUSY=true -WATCHDOG_IDLE_TIMEOUT=60m -WATCHDOG_BUSY_TIMEOUT=5m -LOCALAI_UPLOAD_LIMIT=256 -DISABLE_AUTODETECT=true -LOW_VRAM=true -MMAP=true -CONTEXT_SIZE=32768 -LOCALAI_P2P=true -LOCALAI_FEDERATED=true -LOCALAI_P2P_LOGLEVEL=info