Trace of bugfix
This commit is contained in:
127
BUGFIX_MCP_ERROR_HANDLING.md
Normal file
127
BUGFIX_MCP_ERROR_HANDLING.md
Normal file
@@ -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:<nil>} 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
|
||||||
58
__env
58
__env
@@ -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
|
|
||||||
Reference in New Issue
Block a user