From 14b86641065edba53e758285be1ca1c2f2416da3 Mon Sep 17 00:00:00 2001 From: LJ5O <75009579+LJ5O@users.noreply.github.com> Date: Fri, 6 Feb 2026 16:23:59 +0100 Subject: [PATCH] Nodes V1 --- AgentReact/utils/nodes.py | 55 +++++++++++++++++++++++++++++++++------ roadmap.md | 3 ++- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/AgentReact/utils/nodes.py b/AgentReact/utils/nodes.py index 00e7ef4..5703dc7 100644 --- a/AgentReact/utils/nodes.py +++ b/AgentReact/utils/nodes.py @@ -14,21 +14,18 @@ llm = ChatMistralAI( # LLM sans outils ) # NODES -def reponse_question(state: MessagesState): - """Noeud qui réponds à la question, en s'aidant si besoin des outils à disposition""" +def call_to_LLM(state: MessagesState): + """Noeud qui s'occupe de gérer les appels au LLM""" # Initialisation du LLM model = llm.bind_tools(getTools()) # Appel du LLM return {"messages": [model.invoke(state["messages"])]} -tool_node = ToolNode(tools=getTools()) # Node gérant les outils - -# fonction de routage : Après reponse_question, si le LLM veut appeler un outil, on va au tool_node, sinon on termine +# fonction de routage : Après reponse_question, si le LLM veut appeler un outil, on va au tool_node def should_continue(state: MessagesState): """ - Use in the conditional_edge to route to the ToolNode if the last message - has tool calls. Otherwise, route to the end. + Vérifier s'il y a un appel aux outils dans le dernier message """ if isinstance(state, list): ai_message = state[-1] @@ -39,4 +36,46 @@ def should_continue(state: MessagesState): if hasattr(ai_message, "tool_calls") and len(ai_message.tool_calls) > 0: return "tools" - return END \ No newline at end of file + return "no_tools" + +def task_ended(state: MessagesState): + """ + Vérifier si l'agent a terminé son cycle, ou s'il faut le relancer + """ + if isinstance(state, list): + ai_message = state[-1] + elif messages := state.get("messages", []): + ai_message = messages[-1] + else: + raise ValueError(f"No messages found in input state to tool_edge: {state}") + + if "terminé" in ai_message.content.lower(): + return END + return "continue" + + +class BasicToolNode: # De mon ancien projet, https://github.com/LJ5O/Assistant/blob/main/modules/Brain/src/LLM/graph/nodes/BasicToolNode.py + """A node that runs the tools requested in the last AIMessage.""" + + def __init__(self, tools: list) -> None: + self.tools_by_name = {tool.name: tool for tool in tools} + + def __call__(self, inputs: dict): + if messages := inputs.get("messages", []): + message = messages[-1] + else: + raise ValueError("No message found in input") + outputs = [] + for tool_call in message.tool_calls: + #print(tool_call["args"]) + tool_result = self.tools_by_name[tool_call["name"]].invoke( + tool_call["args"] + ) + outputs.append( + ToolMessage( + content=json.dumps(tool_result), + name=tool_call["name"], + tool_call_id=tool_call["id"], + ) + ) + return {"messages": outputs} \ No newline at end of file diff --git a/roadmap.md b/roadmap.md index a9eaf74..eefaeba 100644 --- a/roadmap.md +++ b/roadmap.md @@ -13,8 +13,9 @@ ## Mise en place de l'agent - [X] Préparation du `State` - [X] Développement des outils de l'agent -- [ ] Préparation des nœuds +- [X] Préparation des nœuds - [ ] Branchement des nœuds entre-eux +- [ ] Human in the loop ## Amélioration de l'agent - [ ] Cross-encoding sur la sortie du **RAG**