diff --git a/.gitignore b/.gitignore index 21d0b89..6a3a595 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .venv/ +memoire_agent.db diff --git a/agent-db.py b/agent-db.py new file mode 100644 index 0000000..25e8690 --- /dev/null +++ b/agent-db.py @@ -0,0 +1,83 @@ +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()) \ No newline at end of file diff --git a/requirements b/requirements index fc9542f..a735322 100644 --- a/requirements +++ b/requirements @@ -11,4 +11,6 @@ langchain-qdrant langchain-chain langchain_mcp_adapters docx2txt -mcp \ No newline at end of file +mcp +langgraph-checkpoint-sqlite +aiosqlite \ No newline at end of file