Spaces:
Sleeping
Sleeping
File size: 8,554 Bytes
57daa1f 589f885 d0b57b8 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 57daa1f 589f885 b66033a 57daa1f b66033a 57daa1f b66033a 57daa1f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# Fichier: agent.py (Version Corrigée et Complète)
import os
import re
import json
import time
from typing import List, Dict, Any, Optional
from pathlib import Path
import tempfile
from smolagents import CodeAgent, MultiStepAgent, AgentError, PythonInterpreterTool
from models import ModelManager
from tools import search_web, scrape_website, read_file
# --- CLASSE ORCHESTRATEUR COMPLÈTE ---
class OrchestratorAgent(MultiStepAgent):
"""
Agent orchestrateur qui hérite de MultiStepAgent et implémente
les méthodes requises pour le prompt système et la réponse finale.
"""
def initialize_system_prompt(self) -> str:
"""Définit le prompt système pour l'agent orchestrateur."""
return (
"You are a world-class autonomous agent. Your goal is to fully answer the user's question. "
"To do so, you have access to a set of tools. "
"First, think step-by-step and lay out a plan to solve the problem. "
"Then, execute the plan by calling the tools in the required sequence. "
"Analyze the results of each tool call. If the plan is not working, reassess and create a new plan. "
"When you have the final answer, present it clearly to the user."
)
def render_final_answer(self, final_context: dict, final_response: str) -> str:
"""
Formate et retourne la réponse finale de l'agent.
"""
# Pour l'instant, nous retournons simplement la réponse brute du modèle.
return final_response
class UltraAgent:
"""
Agent ultra-puissant avec orchestration multi-modèles.
Utilise différents modèles spécialisés selon le type de tâche.
"""
def __init__(self, hf_token: Optional[str] = None):
"""Initialise l'UltraAgent et ses composants."""
print("🚀 Initialisation de l'UltraAgent...")
self.hf_token = hf_token or os.getenv("HF_TOKEN")
self.model_manager = ModelManager(self.hf_token)
self.tools = [search_web, scrape_website, read_file, PythonInterpreterTool()]
self._init_specialized_agents()
self.conversation_history = []
print("✅ UltraAgent initialisé avec succès!")
def _init_specialized_agents(self):
"""Initialise les agents spécialisés."""
try:
self.orchestrator = OrchestratorAgent(
model=self.model_manager.get_orchestrator(),
tools=self.tools,
max_steps=15,
planning_interval=3
)
self.code_agent = CodeAgent(
model=self.model_manager.get_code_agent(),
tools=[PythonInterpreterTool()],
additional_authorized_imports=["requests", "pandas", "numpy", "matplotlib", "seaborn", "scipy", "sklearn"]
)
print("✅ Agents spécialisés initialisés")
except Exception as e:
print(f"❌ Erreur lors de l'initialisation des agents: {e}")
raise
def __call__(self, question: str) -> str:
"""Point d'entrée principal de l'agent."""
print("\n" + "="*80)
print(f"🧠 ULTRA-AGENT - Nouvelle question reçue\nQuestion: {question[:200]}{'...' if len(question) > 200 else ''}")
print("="*80)
try:
self.conversation_history.append({"role": "user", "content": question, "timestamp": time.time()})
strategy = self._analyze_question(question)
print(f"📋 Stratégie sélectionnée: {strategy['type']}")
response = self._execute_strategy(question, strategy)
self.conversation_history.append({"role": "assistant", "content": response, "strategy": strategy, "timestamp": time.time()})
print(f"✅ Réponse générée avec succès ({len(response)} caractères)")
return response
except Exception as e:
error_msg = f"❌ Erreur critique dans l'UltraAgent: {e}"
print(error_msg)
try:
print("🔄 Tentative de récupération avec le modèle de raisonnement...")
fallback_response = self._fallback_reasoning(question, str(e))
return fallback_response
except Exception as fallback_e:
final_error = f"Je rencontre des difficultés techniques. Erreur: {str(fallback_e)[:200]}"
print(f"❌ La récupération a également échoué: {fallback_e}")
return final_error
def _analyze_question(self, question: str) -> Dict[str, Any]:
"""Analyse la question pour déterminer la meilleure stratégie."""
# Cette fonction de scoring simple reste la même
question_lower = question.lower()
vision_keywords = ['image', 'photo', 'picture', 'visual', 'voir', 'regarder', 'analyser l\'image', 'screenshot']
code_keywords = ['code', 'program', 'script', 'algorithm', 'python', 'javascript', 'sql', 'debug', 'programmer']
if any(kw in question_lower for kw in vision_keywords):
return {"type": "vision"}
if any(kw in question_lower for kw in code_keywords):
return {"type": "code"}
return {"type": "general"} # Simplification de la stratégie pour le débogage
def _execute_strategy(self, question: str, strategy: Dict[str, Any]) -> str:
"""Exécute la stratégie déterminée."""
strategy_type = strategy["type"]
try:
if strategy_type == "vision":
return self._handle_vision_task(question)
elif strategy_type == "code":
return self._handle_code_task(question)
else: # general, search_web, file_processing, reasoning
return self._handle_general_task(question)
except Exception as e:
print(f"❌ Erreur dans l'exécution de la stratégie {strategy_type}: {e}")
raise e # Fait remonter l'erreur pour la gestion centrale
def _handle_vision_task(self, question: str) -> str:
"""Gère les tâches de vision."""
print("👁️ Traitement avec le modèle de vision...")
response = self.model_manager.get_vision_model()(question)
return f"🔍 Analyse visuelle:\n{response}"
def _handle_code_task(self, question: str) -> str:
"""Gère les tâches de code."""
print("💻 Traitement avec l'agent de code...")
return self.code_agent.run(question)
def _handle_general_task(self, question: str) -> str:
"""Gère toutes les autres tâches avec l'orchestrateur."""
print("🎯 Traitement général avec l'orchestrateur...")
context = self._get_conversation_context()
enhanced_prompt = f"{context}\nQuestion actuelle: {question}"
return self.orchestrator.run(enhanced_prompt)
def _fallback_reasoning(self, question: str, error: str) -> str:
"""Fallback avec le modèle de raisonnement."""
fallback_prompt = f"An error occurred while processing the question. Question: '{question}'. Error: '{error}'. Provide the best possible answer, explaining the limitations due to the error."
return self.model_manager.get_reasoning_model()(fallback_prompt)
def _get_conversation_context(self, max_exchanges: int = 3) -> str:
"""Récupère le contexte des échanges récents."""
if not self.conversation_history: return ""
recent_history = self.conversation_history[-max_exchanges*2:]
context_parts = ["Contexte de la conversation récente:"]
for entry in recent_history:
role = "Utilisateur" if entry["role"] == "user" else "Assistant"
content = str(entry["content"])[:200]
context_parts.append(f"{role}: {content}")
return "\n".join(context_parts)
# La classe BasicAgent reste la même, elle ne fait qu'appeler UltraAgent
class BasicAgent:
def __init__(self):
try:
if not os.getenv("HF_TOKEN"):
print("⚠️ Attention: Le token Hugging Face (HF_TOKEN) n'est pas défini.")
self.ultra_agent = UltraAgent()
except Exception as e:
print(f"❌ Erreur critique lors de l'initialisation de l'UltraAgent: {e}")
self.ultra_agent = None
def __call__(self, question: str) -> str:
if self.ultra_agent is None:
return "Erreur: L'agent n'a pas pu être initialisé. Vérifiez les logs et la configuration (HF_TOKEN)."
return self.ultra_agent(question) |