Compare commits

...

2 Commits

Author SHA1 Message Date
7449bbf10c Trace of bugfix 2025-06-14 21:49:24 +02:00
370b64b4e2 Fixing return to localAgi 2025-06-14 16:57:23 +02:00
3 changed files with 23 additions and 536 deletions

58
__env
View File

@@ -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

View File

@@ -3,6 +3,7 @@ package agent
import (
"context"
"encoding/json"
"strings"
"github.com/mark3labs/mcp-go/client"
"github.com/mark3labs/mcp-go/client/transport"
@@ -64,19 +65,37 @@ func (m *mcpAction) Run(ctx context.Context, sharedState *types.AgentSharedState
// Traiter le résultat
textResult := ""
if result.IsError {
return types.ActionResult{}, err
}
// 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 {
if textContent, ok := mcp.AsTextContent(content); 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
}
return types.ActionResult{
Result: textResult,
}, nil

View File

@@ -1,474 +0,0 @@
# Plan de migration détaillé : metoro-io/mcp-golang vers mark3labs/mcp-go
Ce document présente un plan de migration détaillé pour remplacer la bibliothèque metoro-io/mcp-golang par mark3labs/mcp-go dans le projet LocalAGI. Le plan est divisé en phases avec des exemples de code concrets pour chaque étape critique.
## Phase 1 : Préparation et analyse
### Étape 1.1 : Audit du code existant
```bash
# Identifier tous les fichiers qui utilisent la bibliothèque metoro-io/mcp-golang
grep -r "github.com/metoro-io/mcp-golang" --include="*.go" .
# Identifier les fonctionnalités spécifiques utilisées
grep -r "mcp\.Client" --include="*.go" .
grep -r "transport/http" --include="*.go" .
grep -r "transport/stdio" --include="*.go" .
```
### Étape 1.2 : Création d'un environnement de test
```bash
# Créer une branche pour la migration
git checkout -b mcp-migration
# Installer la nouvelle bibliothèque
go get github.com/mark3labs/mcp-go
```
## Phase 2 : Modification des importations et structures
### Étape 2.1 : Mise à jour des importations
```go
// Avant
import (
mcp "github.com/metoro-io/mcp-golang"
"github.com/metoro-io/mcp-golang/transport/http"
stdioTransport "github.com/metoro-io/mcp-golang/transport/stdio"
)
// Après
import (
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
```
### Étape 2.2 : Adaptation des structures
```go
// Avant
type mcpAction struct {
mcpClient *mcp.Client
inputSchema ToolInputSchema
toolName string
toolDescription string
}
// Après
type mcpAction struct {
// Nous devrons déterminer la structure équivalente dans mark3labs/mcp-go
// Basé sur la documentation, cela pourrait ressembler à:
mcpClient *mcp.Client // ou une structure équivalente
toolDefinition *mcp.Tool
toolName string
toolDescription string
}
// Avant
type ToolInputSchema struct {
Type string `json:"type"`
Properties map[string]interface{} `json:"properties,omitempty"`
Required []string `json:"required,omitempty"`
}
// Après
// Nous utiliserons directement les structures de schéma fournies par mark3labs/mcp-go
```
## Phase 3 : Migration des clients et transports
### Étape 3.1 : Clients HTTP
```go
// Avant
transport := http.NewHTTPClientTransport("/mcp")
transport.WithBaseURL(mcpServer.URL)
if mcpServer.Token != "" {
transport.WithHeader("Authorization", "Bearer "+mcpServer.Token)
}
client := mcp.NewClient(transport)
// Après
// Basé sur les exemples disponibles, nous pourrions avoir besoin de créer un client HTTP personnalisé
// Voici une approche possible:
httpClient := &http.Client{}
// Configurer un client HTTP pour se connecter au serveur MCP
// Note: L'API exacte dépendra de la façon dont mark3labs/mcp-go implémente les clients
```
### Étape 3.2 : Clients STDIO
```go
// Avant
client := stdio.NewClient(a.options.mcpBoxURL)
p, err := client.CreateProcess(a.context,
mcpStdioServer.Cmd,
mcpStdioServer.Args,
mcpStdioServer.Env,
a.Character.Name)
read, writer, err := client.GetProcessIO(p.ID)
transport := stdioTransport.NewStdioServerTransportWithIO(read, writer)
mcpClient := mcp.NewClient(transport)
// Après
// Basé sur les exemples, mark3labs/mcp-go utilise une approche différente pour STDIO
// Nous devrons adapter notre code pour utiliser l'API de mark3labs/mcp-go
// Exemple possible:
cmd := exec.Command(mcpStdioServer.Cmd, mcpStdioServer.Args...)
cmd.Env = append(os.Environ(), mcpStdioServer.Env...)
// Configurer les pipes stdin/stdout
// Créer un client qui utilise ces pipes
```
## Phase 4 : Migration des outils et actions
### Étape 4.1 : Définition des outils
```go
// Avant
// Les outils sont définis implicitement via les réponses du serveur MCP
var inputSchema ToolInputSchema
err = json.Unmarshal(dat, &inputSchema)
generatedActions = append(generatedActions, &mcpAction{
mcpClient: client,
toolName: t.Name,
inputSchema: inputSchema,
toolDescription: desc,
})
// Après
// Avec mark3labs/mcp-go, nous pouvons définir les outils plus explicitement
// Exemple basé sur la documentation:
calculatorTool := mcp.NewTool("calculate",
mcp.WithDescription("Perform basic arithmetic operations"),
mcp.WithString("operation",
mcp.Required(),
mcp.Description("The operation to perform"),
mcp.Enum("add", "subtract", "multiply", "divide"),
),
mcp.WithNumber("x",
mcp.Required(),
mcp.Description("First number"),
),
mcp.WithNumber("y",
mcp.Required(),
mcp.Description("Second number"),
),
)
```
### Étape 4.2 : Appel des outils
```go
// Avant
func (m *mcpAction) Run(ctx context.Context, sharedState *types.AgentSharedState, params types.ActionParams) (types.ActionResult, error) {
resp, err := m.mcpClient.CallTool(ctx, m.toolName, params)
if err != nil {
return types.ActionResult{}, err
}
textResult := ""
for _, c := range resp.Content {
switch c.Type {
case mcp.ContentTypeText:
textResult += c.TextContent.Text + "\n"
// ...
}
}
return types.ActionResult{
Result: textResult,
}, nil
}
// Après
// Basé sur la documentation, l'appel d'outil pourrait ressembler à:
func (m *mcpAction) Run(ctx context.Context, sharedState *types.AgentSharedState, params types.ActionParams) (types.ActionResult, error) {
// Convertir params en format attendu par mark3labs/mcp-go
args := make(map[string]interface{})
if err := params.Unmarshal(&args); err != nil {
return types.ActionResult{}, err
}
// Créer une requête d'appel d'outil
request := mcp.CallToolRequest{
Params: mcp.CallToolParams{
Name: m.toolName,
Arguments: args,
},
}
// Appeler l'outil
// Note: L'API exacte dépendra de la façon dont mark3labs/mcp-go implémente les appels d'outils
result, err := m.mcpClient.CallTool(ctx, request)
if err != nil {
return types.ActionResult{}, err
}
// Traiter le résultat
textResult := ""
// Extraire le texte du résultat selon le format de mark3labs/mcp-go
return types.ActionResult{
Result: textResult,
}, nil
}
```
## Phase 5 : Gestion des résultats
```go
// Avant
textResult := ""
for _, c := range resp.Content {
switch c.Type {
case mcp.ContentTypeText:
textResult += c.TextContent.Text + "\n"
case mcp.ContentTypeImage:
xlog.Error("Image content not supported yet")
case mcp.ContentTypeEmbeddedResource:
xlog.Error("Embedded resource content not supported yet")
}
}
// Après
// Basé sur la documentation, le traitement des résultats pourrait ressembler à:
textResult := ""
// Supposons que result est de type *mcp.CallToolResult
if result.Error != nil {
return types.ActionResult{}, fmt.Errorf("tool error: %s", result.Error)
}
// Traiter les différents types de contenu
for _, content := range result.Content {
switch content.Type {
case "text":
textContent, ok := content.Content.(mcp.TextContent)
if ok {
textResult += textContent.Text + "\n"
}
case "image":
xlog.Error("Image content not supported yet")
case "embedded_resource":
xlog.Error("Embedded resource content not supported yet")
}
}
```
## Phase 6 : Gestion des sessions
```go
// Avant
// La gestion des sessions est limitée dans la bibliothèque actuelle
// Après
// Implémentation d'une gestion de session plus avancée avec mark3labs/mcp-go
type MCPSession struct {
id string
notifChannel chan mcp.JSONRPCNotification
isInitialized bool
}
// Implémenter l'interface ClientSession
func (s *MCPSession) SessionID() string {
return s.id
}
func (s *MCPSession) NotificationChannel() chan<- mcp.JSONRPCNotification {
return s.notifChannel
}
func (s *MCPSession) Initialize() {
s.isInitialized = true
}
func (s *MCPSession) Initialized() bool {
return s.isInitialized
}
// Utilisation dans le code
session := &MCPSession{
id: mcpServer.SessionId,
notifChannel: make(chan mcp.JSONRPCNotification, 10),
}
if err := mcpServer.RegisterSession(context.Background(), session); err != nil {
xlog.Error("Failed to register session", "error", err.Error())
}
```
## Phase 7 : Adaptation de la fonction initMCPActions
```go
// Avant
func (a *Agent) initMCPActions() error {
a.mcpActions = nil
var err error
generatedActions := types.Actions{}
// MCP HTTP Servers
for _, mcpServer := range a.options.mcpServers {
transport := http.NewHTTPClientTransport("/mcp")
transport.WithBaseURL(mcpServer.URL)
if mcpServer.Token != "" {
transport.WithHeader("Authorization", "Bearer "+mcpServer.Token)
}
client := mcp.NewClient(transport)
actions, err := a.addTools(client)
if err != nil {
xlog.Error("Failed to add tools for MCP server", "error", err.Error())
}
generatedActions = append(generatedActions, actions...)
}
// MCP STDIO Servers
// ...
a.mcpActions = generatedActions
return err
}
// Après
func (a *Agent) initMCPActions() error {
a.mcpActions = nil
var err error
generatedActions := types.Actions{}
// MCP HTTP Servers
for _, mcpServer := range a.options.mcpServers {
// Créer un client HTTP pour se connecter au serveur MCP
// Note: L'implémentation exacte dépendra de l'API de mark3labs/mcp-go
httpClient := &http.Client{}
// Configurer les headers, l'URL, etc.
// Initialiser le client
// ...
// Lister et ajouter les outils
actions, err := a.addTools(client, &mcpServer)
if err != nil {
xlog.Error("Failed to add tools for MCP server", "error", err.Error())
}
generatedActions = append(generatedActions, actions...)
}
// MCP STDIO Servers
// Adapter pour utiliser l'API STDIO de mark3labs/mcp-go
// ...
a.mcpActions = generatedActions
return err
}
```
## Phase 8 : Tests et validation
### Étape 8.1 : Tests unitaires
```go
// Créer des tests unitaires pour chaque composant migré
func TestMCPClientInitialization(t *testing.T) {
// Tester l'initialisation du client avec mark3labs/mcp-go
}
func TestToolDefinition(t *testing.T) {
// Tester la définition des outils avec mark3labs/mcp-go
}
func TestToolExecution(t *testing.T) {
// Tester l'exécution des outils avec mark3labs/mcp-go
}
```
### Étape 8.2 : Tests d'intégration
```go
// Créer des tests d'intégration pour vérifier que tout fonctionne ensemble
func TestMCPServerIntegration(t *testing.T) {
// Tester l'intégration complète avec un serveur MCP
}
```
## Phase 9 : Déploiement progressif
### Étape 9.1 : Déploiement en environnement de test
```bash
# Déployer la version migrée en environnement de test
docker build -t localagi-mcp-migration:test .
docker run -d --name localagi-test localagi-mcp-migration:test
```
### Étape 9.2 : Surveillance et correction
```bash
# Surveiller les logs pour détecter d'éventuels problèmes
docker logs -f localagi-test
# Corriger les problèmes identifiés
# ...
# Redéployer
docker build -t localagi-mcp-migration:test-v2 .
docker run -d --name localagi-test-v2 localagi-mcp-migration:test-v2
```
### Étape 9.3 : Déploiement en production
```bash
# Une fois les tests validés, déployer en production
docker build -t localagi:latest .
# Déployer selon votre processus habituel
```
## Considérations supplémentaires
### Compatibilité avec les serveurs MCP existants
Il est important de vérifier que mark3labs/mcp-go est compatible avec les serveurs MCP existants auxquels votre application se connecte. Si des différences de protocole existent, des adaptations supplémentaires pourraient être nécessaires.
### Documentation
Documenter tous les changements effectués et les différences de comportement entre les deux bibliothèques. Cela facilitera la maintenance future et aidera les développeurs à comprendre les choix de migration.
### Formation
Prévoir une session de formation pour les développeurs afin de les familiariser avec la nouvelle bibliothèque et ses particularités.
## Diagramme de séquence de la migration
```mermaid
sequenceDiagram
participant Dev as Développeur
participant Git as Système de contrôle de version
participant Test as Environnement de test
participant Prod as Production
Dev->>Git: Créer branche de migration
Dev->>Git: Modifier importations
Dev->>Git: Adapter structures
Dev->>Git: Migrer clients HTTP
Dev->>Git: Migrer clients STDIO
Dev->>Git: Migrer définition des outils
Dev->>Git: Migrer appel des outils
Dev->>Git: Migrer gestion des résultats
Dev->>Git: Migrer gestion des sessions
Dev->>Git: Écrire tests unitaires
Dev->>Git: Écrire tests d'intégration
Git->>Test: Déployer en test
Test->>Dev: Retour d'erreurs
Dev->>Git: Corrections
Git->>Test: Redéployer en test
Test->>Dev: Validation
Git->>Prod: Déployer en production
```
## Conclusion
Ce plan de migration détaillé devrait vous guider efficacement à travers le processus de remplacement de metoro-io/mcp-golang par mark3labs/mcp-go. La migration nécessitera des modifications significatives du code existant, mais les avantages potentiels en termes de maintenance, de fonctionnalités et de robustesse justifient cet effort.
Les principales difficultés résident dans les différences d'API et la façon dont les transports et les outils sont configurés et utilisés. Une approche progressive, avec des tests approfondis à chaque étape, est recommandée pour minimiser les risques.
N'hésitez pas à adapter ce plan en fonction des spécificités de votre projet et des découvertes faites pendant la migration.