TODO liste avant LLM
Affichée juste avant dans un System message
This commit is contained in:
@@ -66,10 +66,17 @@ def user_prompt(state: CustomState):
|
|||||||
return {'messages': messages}# Je passe unen liste, devrait écraser tous les messages précédent au lieu d'ajouter à la liste du State
|
return {'messages': messages}# Je passe unen liste, devrait écraser tous les messages précédent au lieu d'ajouter à la liste du State
|
||||||
|
|
||||||
|
|
||||||
def LLM_central(state: MessagesState):
|
def LLM_central(state: CustomState):
|
||||||
"""Noeud qui s'occupe de gérer les appels au LLM"""
|
"""Noeud qui s'occupe de gérer les appels au LLM"""
|
||||||
# Initialisation du LLM
|
# Initialisation du LLM
|
||||||
model = llm.bind_tools(getTools())
|
model = llm.bind_tools(getTools())
|
||||||
|
#print(state)
|
||||||
|
|
||||||
|
if "todo" in state.keys(): # S'il y a des TODO, je l'ajoute avant le prompt au LLM
|
||||||
|
if len(state['todo'])>0:
|
||||||
|
sysmsg = SystemMessage(f"Voici la liste des tâches en cours : {str([f"{i}: {str(todo)}\n" for i,todo in enumerate(state['todo'])])}")
|
||||||
|
print(sysmsg.content)
|
||||||
|
return {"messages": [model.invoke(state["messages"] + [AIMessage('.'), sysmsg])]} # AIMessage pour que Msitrail ne refuse pas la requête avec un 400
|
||||||
|
|
||||||
# Appel du LLM
|
# Appel du LLM
|
||||||
return {"messages": [model.invoke(state["messages"])]}
|
return {"messages": [model.invoke(state["messages"])]}
|
||||||
@@ -142,7 +149,7 @@ def should_shorten(state: CustomState)->str:
|
|||||||
return 'réduire contexte'
|
return 'réduire contexte'
|
||||||
|
|
||||||
# fonction de routage : Après reponse_question, si le LLM veut appeler un outil, on va au tool_node
|
# fonction de routage : Après reponse_question, si le LLM veut appeler un outil, on va au tool_node
|
||||||
def should_continue(state: MessagesState):
|
def should_continue(state: CustomState):
|
||||||
"""
|
"""
|
||||||
Vérifier s'il y a un appel aux outils dans le dernier message
|
Vérifier s'il y a un appel aux outils dans le dernier message
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
from langchain.tools import tool
|
from langchain.tools import tool
|
||||||
from langgraph.prebuilt import InjectedState
|
from langgraph.prebuilt import InjectedState
|
||||||
|
from langchain_core.tools import InjectedToolCallId
|
||||||
|
from langchain_core.messages import ToolMessage
|
||||||
|
from langgraph.types import Command
|
||||||
from tavily import TavilyClient
|
from tavily import TavilyClient
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Dict, Annotated
|
from typing import List, Dict, Annotated
|
||||||
@@ -60,20 +63,18 @@ def write_file(file_path:str, content: str, append:bool=True) -> str:
|
|||||||
return f"Erreur lors de l'écriture: {str(e)}"
|
return f"Erreur lors de l'écriture: {str(e)}"
|
||||||
|
|
||||||
@tool
|
@tool
|
||||||
def editTodo(index:int, todoState:int, state: Annotated[dict, InjectedState])->bool: # https://stackoverflow.com/a/79525434
|
def editTodo(index:int, todoState:int, state: Annotated[dict, InjectedState], tool_call_id: Annotated[str, InjectedToolCallId])->Command: # https://stackoverflow.com/a/79525434
|
||||||
"""
|
"""
|
||||||
Modifier l'état d'une tâche (TODO)
|
Modifier l'état d'une tâche (TODO)
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
index (int): Index de la tâche à modifier, en commançant à 0 pour la première tâche.
|
index (int): Index de la tâche à modifier, en commançant à 0 pour la première tâche.
|
||||||
todoState (int): Nouvel état. 0 pour "non commencé, 1 pour "en cours", 2 pour "complété"
|
todoState (int): Nouvel état. 0 pour "non commencé, 1 pour "en cours", 2 pour "complété"
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: Réussite de l'opération, ou non.
|
|
||||||
"""
|
"""
|
||||||
|
if "todo" not in state.keys(): return Command(update={"messages": [ToolMessage(content="Echec!", tool_call_id=tool_call_id)]})
|
||||||
if len(state["todo"]) <= index:
|
if len(state["todo"]) <= index:
|
||||||
# Erreur, l'index est trop grand
|
# Erreur, l'index est trop grand
|
||||||
return False
|
return Command(update={"messages": [ToolMessage(content="Index en dehors de la liste, echec!", tool_call_id=tool_call_id)]})
|
||||||
|
|
||||||
state["todo"][index].state = todoState # Modification de l'état de cette tâche
|
state["todo"][index].state = todoState # Modification de l'état de cette tâche
|
||||||
|
|
||||||
@@ -85,42 +86,46 @@ def editTodo(index:int, todoState:int, state: Annotated[dict, InjectedState])->b
|
|||||||
break
|
break
|
||||||
|
|
||||||
if not found: state["todo"] = [] # Toutes les tâches terminées, je peux clear la TODO list du state
|
if not found: state["todo"] = [] # Toutes les tâches terminées, je peux clear la TODO list du state
|
||||||
return True
|
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
|
||||||
|
})
|
||||||
|
|
||||||
@tool
|
@tool
|
||||||
def addTodo(name:str, description:str, state: Annotated[dict, InjectedState])->bool:
|
def addTodo(name:str, description:str, state: Annotated[dict, InjectedState], tool_call_id: Annotated[str, InjectedToolCallId])->Command:
|
||||||
"""
|
"""
|
||||||
Ajouter une nouvelle tâche/TODO
|
Ajouter une nouvelle tâche/TODO
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name (str): Nom de cette tâche
|
name (str): Nom de cette tâche
|
||||||
description (str): Une ou deux phrases pour décrire le travail à effectuer dans ce TODO
|
description (str): Une ou deux phrases pour décrire le travail à effectuer dans ce TODO
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: Réussite de l'opération, ou non
|
|
||||||
"""
|
"""
|
||||||
if state["todo"] is None: state["todo"] = []
|
if "todo" not in state.keys(): state["todo"] = []
|
||||||
|
|
||||||
state["todo"].append(TodoElement(name, description))
|
state["todo"].append(TodoElement(name, description))
|
||||||
return True
|
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
|
||||||
|
})
|
||||||
|
|
||||||
@tool
|
@tool
|
||||||
def removeTodo(index:int, state: Annotated[dict, InjectedState])->bool:
|
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
|
Retirer une tâche/TODO de la liste des tâches
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
index (int): Position de la tâche dans la liste, commence à 0 pour le premier TODO
|
index (int): Position de la tâche dans la liste, commence à 0 pour le premier TODO
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: Réussite de l'opération, ou non
|
|
||||||
"""
|
"""
|
||||||
|
if "todo" not in state.keys(): return Command(update={"messages": [ToolMessage(content="Echec!", tool_call_id=tool_call_id)]})
|
||||||
if len(state["todo"]) <= index:
|
if len(state["todo"]) <= index:
|
||||||
# Erreur, l'index est trop grand
|
# Erreur, l'index est trop grand
|
||||||
return False
|
return Command(update={"messages": [ToolMessage(content="Index en dehors de la liste, echec!", tool_call_id=tool_call_id)]})
|
||||||
|
|
||||||
state['todo'].pop(index)
|
state['todo'].pop(index)
|
||||||
return True
|
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
|
||||||
|
})
|
||||||
|
|
||||||
@tool
|
@tool
|
||||||
def read_file(file_path: str) -> str:
|
def read_file(file_path: str) -> str:
|
||||||
|
|||||||
Reference in New Issue
Block a user