import asyncio import os import sys from dotenv import load_dotenv from langchain_google_genai import ChatGoogleGenerativeAI from langchain_mcp_adapters.client import MultiServerMCPClient from langgraph.prebuilt import create_react_agent from langchain_core.messages import HumanMessage # 🧠 1. Le nouvel import pour la sauvegarde from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver # Chargement de la clé API load_dotenv() async def lancer_agent(): print("🤖 Initialisation de l'Agent Gemini...") llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash") print("🔌 Configuration de la connexion au serveur MCP local...") # NOUVELLE SYNTAXE : On passe la configuration directement dans le client client = MultiServerMCPClient({ "serveur_taches": { "command": sys.executable, # 🌟 LA MODIFICATION EST ICI "args": ["serveur_mcp.py"], "transport": "stdio" } }) # On récupère les outils (attention, c'est maintenant une fonction asynchrone qui nécessite 'await') outils = await client.get_tools() print(f"✅ Outils détectés : {[outil.name for outil in outils]}") # 🧠 2. Connexion à notre base de données locale (elle sera créée automatiquement) # 🧠 2. On utilise 'async with' pour ouvrir la mémoire proprement async with AsyncSqliteSaver.from_conn_string("memoire_agent.db") as checkpointer: # 🌟 Création de l'Agent LangGraph #agent = create_react_agent(llm, tools=outils) # 🧠 3. On donne le checkpointer à notre agent agent = create_react_agent(llm, tools=outils, checkpointer=checkpointer) # 🧠 4. Le Thread ID : C'est la clé de la mémoire ! # Toutes les requêtes avec ce même ID partageront la même mémoire. config_memoire = {"configurable": {"thread_id": "conversation_personnelle_01"}} #--- LE TEST DE L'AGENT --- #consigne = ( # "1. Ajoute la tâche 'Acheter du pain'. " # "2. Ajoute la tâche 'Appeler le client'. " # "3. Fais-moi un résumé de toutes mes tâches actuelles." #) consigne = ( "J'ai déjà demander d'acheter du pain ?" ) print(f"\n🗣️ Consigne donnée à l'Agent : {consigne}\n") print("⏳ Démarrage du flux de réflexion de l'Agent...\n") # 🌟 LA MODIFICATION EST ICI : On remplace ainvoke par astream # stream_mode="values" permet de récupérer l'état à chaque nouvelle étape async for etape in agent.astream( {"messages": [HumanMessage(content=consigne)]}, config=config_memoire, # 🧠 5. On n'oublie pas de passer la config ! stream_mode="values" ): # On récupère le tout dernier message généré à cette étape dernier_message = etape["messages"][-1] # pretty_print() formate le texte avec des couleurs dans le terminal ! dernier_message.pretty_print() # Déconnexion propre (cette ligne ne change pas, assurez-vous de l'avoir gardée) # await client.disconnect() if __name__ == "__main__": asyncio.run(lancer_agent())