Agent_V3 #3
@@ -22,4 +22,4 @@ initial_input = {
|
||||
config={"configurable": {"thread_id": 'yes'}}
|
||||
|
||||
# Et je lance !
|
||||
streamGraph(initial_input, config, getGraph(), showSysMessages=False)
|
||||
streamGraph(initial_input, config, getGraph(), showSysMessages=True)
|
||||
@@ -57,6 +57,8 @@ class TodoElement():
|
||||
"""
|
||||
data = json.loads(json_str) if type(json_str) is str else json_str
|
||||
|
||||
if isinstance(data, TodoElement): return data
|
||||
|
||||
nom_ = data.get("name", "undefined")
|
||||
desc_ = data.get("desc", "undefined")
|
||||
state_ = data.get("state", TodoElement.STATE_NOT_STARTED)
|
||||
|
||||
@@ -111,7 +111,7 @@ def context_shortener(state: CustomState):
|
||||
lastSummarizedMessage = state['lastSummarizedMessage'] # Récupérer l'index du dernier message qui a été résumé
|
||||
else:
|
||||
# Premier passage, je supprime les anciens outils si besoin
|
||||
rmtree(reports_dir.as_posix()) # Supprimer le dossier
|
||||
rmtree(reports_dir.as_posix(), ignore_errors=True) # Supprimer le dossier
|
||||
reports_dir.mkdir(parents=True, exist_ok=False) # Créer le dossier
|
||||
|
||||
messages = [msg for msg in state['messages'][lastSummarizedMessage+1:]] # Récupérer tous les messages après lastSummarizedMessage sans l'inclure
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from langgraph.graph import StateGraph, MessagesState
|
||||
from typing import List
|
||||
from typing import List, Annotated
|
||||
import operator
|
||||
|
||||
|
||||
class CustomState(MessagesState):
|
||||
todo: List[str] # Les tâches en cours, au format JSON
|
||||
todo: Annotated[list, operator.add] # Les tâches en cours, au format JSON
|
||||
|
||||
ragQuery: str # Requête envoyée au RAG, pour le cross-encodeur
|
||||
ragDocuments: List[str] # Documents retrouvés par le RAG, pour le cross-encodeur
|
||||
|
||||
@@ -5,7 +5,7 @@ from langchain_core.messages import ToolMessage
|
||||
from langgraph.types import Command
|
||||
from tavily import TavilyClient
|
||||
from pathlib import Path
|
||||
from typing import List, Dict, Annotated
|
||||
from typing import List, Dict, Annotated, Tuple
|
||||
import sys
|
||||
import os
|
||||
from langgraph.types import interrupt
|
||||
@@ -25,26 +25,53 @@ def append_part_to_report(contenu:str)->str:
|
||||
Returns:
|
||||
str: Retour, une confirmation, ou un message d'erreur
|
||||
"""
|
||||
try:
|
||||
# Récupérer le chemin vers le point d'entrée
|
||||
base_dir: Path = Path(sys.argv[0]).resolve().parent
|
||||
full_path = reports_dir / "RAPPORT_STAGE.md"
|
||||
full_path = base_dir / "RAPPORT_STAGE.md"
|
||||
|
||||
query= interrupt(InterruptPayload({
|
||||
content: contenu
|
||||
'content': contenu
|
||||
}).toJSON())
|
||||
|
||||
response = InterruptPayload.fromJSON(query)
|
||||
if response.isAccepted():
|
||||
with open(full_path, "a", encoding="utf-8") as f: # Écrire le contenu
|
||||
f.write(response.get("content"))
|
||||
f.write("\n"+response.get("content"))
|
||||
|
||||
return "Requête acceptée et validée ! Tu peux considérer cette tâche comme complétée."
|
||||
else:
|
||||
return "ERREUR! L'utilisateur a refusé ta demande. Tu devrais lui demander pourquoi avoir refusé, et comment améliorer cette partie."
|
||||
|
||||
@tool
|
||||
def list_files(folder:str)->str:
|
||||
"""
|
||||
Retrouver la liste des fichiers dans un dossier
|
||||
|
||||
Args:
|
||||
folder (str): Le chemin relatif vers le dossier
|
||||
|
||||
Returns:
|
||||
str: La liste de tous les fichiers dans ce dossier
|
||||
"""
|
||||
try:
|
||||
base_dir: Path = Path(sys.argv[0]).resolve().parent
|
||||
full_path: Path = base_dir / folder
|
||||
|
||||
if not full_path.exists():
|
||||
return f"Le dossier '{folder}' n'existe pas."
|
||||
|
||||
if not full_path.is_dir():
|
||||
return f"Le chemin '{folder}' n'est pas un dossier."
|
||||
|
||||
files = [f.name for f in full_path.iterdir()]
|
||||
|
||||
if not files:
|
||||
return f"Le dossier '{folder}' est vide."
|
||||
|
||||
return "\n".join(files)
|
||||
|
||||
except Exception as e:
|
||||
return f"Erreur lors de l'écriture: {str(e)}"
|
||||
return f"Erreur lors de la lecture du dossier : {str(e)}"
|
||||
|
||||
|
||||
@tool
|
||||
@@ -99,40 +126,21 @@ def editTodo(index:int, todoState:int, state: Annotated[dict, InjectedState], to
|
||||
})
|
||||
|
||||
@tool
|
||||
def addTodo(name:str, description:str, state: Annotated[dict, InjectedState], tool_call_id: Annotated[str, InjectedToolCallId])->Command:
|
||||
def setTodo(todoList:List[Tuple[str, str]], state: Annotated[dict, InjectedState], tool_call_id: Annotated[str, InjectedToolCallId])->Command:
|
||||
"""
|
||||
Ajouter une nouvelle tâche/TODO
|
||||
Définir la liste des tâches à faire / TODO.
|
||||
Permet aussi de la supprimer en appelant avec une liste vide.
|
||||
|
||||
Args:
|
||||
name (str): Nom de cette tâche
|
||||
description (str): Une ou deux phrases pour décrire le travail à effectuer dans ce TODO
|
||||
todoList (List[Tuple[str, str]]): Une liste de tuples (str, str), donc le premier str est le nom de la tâche, et le second sa description, le travail à effectuer dans ce TODO
|
||||
"""
|
||||
if "todo" not in state.keys(): state["todo"] = []
|
||||
todo = []
|
||||
|
||||
state["todo"] = [TodoElement.fromJSON(e) for e in state["todo"]] # Convertion vers de vraies instances
|
||||
state["todo"].append(TodoElement(name, description))
|
||||
for t in todoList:
|
||||
todo.append(TodoElement(t[0], t[1]))
|
||||
return Command(update={
|
||||
"messages": [ToolMessage(content="Réussite!", tool_call_id=tool_call_id)],
|
||||
"todo": [x.toJSON() for x in state["todo"]] # Update du state, # medium.com/@o39joey/a-comprehensive-guide-to-langgraph-managing-agent-state-with-tools-ae932206c7d7
|
||||
})
|
||||
|
||||
@tool
|
||||
def removeTodo(index:int, state: Annotated[dict, InjectedState], tool_call_id: Annotated[str, InjectedToolCallId])->Command:
|
||||
"""
|
||||
Retirer une tâche/TODO de la liste des tâches
|
||||
|
||||
Args:
|
||||
index (int): Position de la tâche dans la liste, commence à 0 pour le premier TODO
|
||||
"""
|
||||
if "todo" not in state.keys(): return Command(update={"messages": [ToolMessage(content="Echec!", tool_call_id=tool_call_id)]})
|
||||
if len(state["todo"]) <= index:
|
||||
# Erreur, l'index est trop grand
|
||||
return Command(update={"messages": [ToolMessage(content="Index en dehors de la liste, echec!", tool_call_id=tool_call_id)]})
|
||||
|
||||
state['todo'].pop(index)
|
||||
return Command(update={
|
||||
"messages": [ToolMessage(content="Réussite!", tool_call_id=tool_call_id)],
|
||||
"todo": [x for x in state["todo"]] # Update du state, # medium.com/@o39joey/a-comprehensive-guide-to-langgraph-managing-agent-state-with-tools-ae932206c7d7
|
||||
"todo": [x.toJSON() for x in todo] # Update du state, # medium.com/@o39joey/a-comprehensive-guide-to-langgraph-managing-agent-state-with-tools-ae932206c7d7
|
||||
})
|
||||
|
||||
@tool
|
||||
@@ -284,7 +292,7 @@ def getTools()->List['Tools']:
|
||||
"""
|
||||
Récupérer la liste des tools
|
||||
"""
|
||||
return [internet_search, append_part_to_report, editTodo, read_file, search_in_files, addTodo, removeTodo, get_skill]
|
||||
return [internet_search, append_part_to_report, read_file, search_in_files, get_skill, list_files] # editTodo, setTodo
|
||||
|
||||
def getWeeklyReportTools()->List['Tools']:
|
||||
"""
|
||||
|
||||
25
readme.md
25
readme.md
@@ -25,3 +25,28 @@ Une fois le dossier **documents_projet** ajouté à la racine, il est possible d
|
||||
```
|
||||
python RAG/init.py
|
||||
```
|
||||
|
||||
Puis de lancer l'agent
|
||||
```
|
||||
python AgentReact/start.py
|
||||
```
|
||||
|
||||
### Exemple de prompt initial
|
||||
Il faut le coller comme une seule ligne dans l'input, produira des bugs lors de prompts sinon.
|
||||
|
||||
#### Sans TODO
|
||||
```
|
||||
Ton but est d'écrire un rapport de stage sur l'entreprise Diag'n Grow. Commence par préparer un plan avec ton skill "Creation_plan", tu peux rechercher des informations sur l'entreprise avec une recherche internet en utilisant "internet_search". Ensuite, rédige chacune des parties du plan, en utilisant l'outil "append_part_to_report".
|
||||
Tu as aussi des rapports de chaque semaine de stage dans le dossier `rapports_resumes`, tu peux en lister les fichiers avec l'outil "list_files".
|
||||
En plus de ces rapports, tu as une base de données de ce qui a été fait, en plus détaillé, avec l'outil "search_in_files".
|
||||
Bon couraj
|
||||
```
|
||||
|
||||
|
||||
#### Avec TODO
|
||||
```
|
||||
Ton but est d'écrire un rapport de stage sur l'entreprise Diag'n Grow. Commence par préparer un plan avec ton skill "Creation_plan", tu peux rechercher des informations sur l'entreprise avec une recherche internet en utilisant "internet_search". Ensuite, rédige chacune des parties du plan, en utilisant l'outil "append_part_to_report". En faisant cela, n'oublie pas de créer une liste de tâches(TODO), et de les garder à jour. A chaque fois qu'une partie du rapport est validée, mets à jour ta liste de tâches pour garder une trace de ta progression.
|
||||
Tu as aussi des rapports de chaque semaine de stage dans le dossier `rapports_resumes`, tu peux en lister les fichiers avec l'outil "list_files".
|
||||
En plus de ces rapports, tu as une base de données de ce qui a été fait, en plus détaillé, avec l'outil "search_in_files".
|
||||
Bon couraj
|
||||
```
|
||||
Reference in New Issue
Block a user