diff --git a/src/naliiabot/bot/agent/agent.py b/src/naliiabot/bot/agent/agent.py index 1d3c55d..9d19a9a 100644 --- a/src/naliiabot/bot/agent/agent.py +++ b/src/naliiabot/bot/agent/agent.py @@ -6,6 +6,7 @@ from langchain_core.runnables import RunnableConfig from typing import Literal, Callable, Any, Union from .schemas import MessagesState from dataclasses import dataclass +import json @dataclass @@ -134,10 +135,12 @@ class Agent: """Construye el grafo de estado completo.""" agent_builder = StateGraph(MessagesState) + agent_builder.add_node("identify_customer", self._identify_customer_node) agent_builder.add_node("llm_call", self._llm_call_node) agent_builder.add_node("tool_node", self._tool_node) - agent_builder.add_edge(START, "llm_call") + agent_builder.add_edge(START, "identify_customer") + agent_builder.add_edge("identify_customer", "llm_call") agent_builder.add_conditional_edges( "llm_call", self._should_continue, {"tool_node": "tool_node", END: END} ) @@ -145,6 +148,45 @@ class Agent: return agent_builder + def _identify_customer_node(self, state: MessagesState) -> dict: + """ + Nodo de identificación del cliente. + Busca el cliente por teléfono y actualiza el estado. + """ + from ..logger import logger + + customer_phone = state.get("customer_phone", "") + if not customer_phone: + return {"customer_name": "Cliente Anónimo", "customer_id": 0} + + find_customer_tool = self._tools_by_name.get("find_customer_by_identifier") + if not find_customer_tool: + logger.warning("Tool find_customer_by_identifier not found") + return {"customer_name": "Cliente Final", "customer_id": 0} + + try: + result = find_customer_tool.invoke({"identifier": customer_phone}) + customer_data = json.loads(result) if result else {} + + if isinstance(customer_data, list): + customer_data = customer_data[0] if customer_data else {} + + if customer_data and customer_data.get("id"): + customer_name = customer_data.get("party", {}).get( + "name", "Cliente Final" + ) + customer_id = customer_data.get("id", 0) + logger.info( + f"Cliente identificado: {customer_name} (ID: {customer_id})" + ) + return {"customer_name": customer_name, "customer_id": customer_id} + else: + logger.info(f"Cliente no encontrado para teléfono: {customer_phone}") + return {"customer_name": "Cliente Nuevo", "customer_id": 0} + except Exception as e: + logger.error(f"Error identificando cliente: {e}") + return {"customer_name": "Cliente Final", "customer_id": 0} + def _llm_call_node(self, state: MessagesState) -> dict: """ Nodo LLM: Decide siguiente acción o responde. diff --git a/src/naliiabotapi/api/v1/webhooks/chat_hook.py b/src/naliiabotapi/api/v1/webhooks/chat_hook.py index eb07e90..d12638c 100644 --- a/src/naliiabotapi/api/v1/webhooks/chat_hook.py +++ b/src/naliiabotapi/api/v1/webhooks/chat_hook.py @@ -3,15 +3,12 @@ from langchain.messages import HumanMessage from ...dependencies import get_agent from ....logger import logger from ....schemes.chat_schemes import SendMessageScheme -from naliiabot.bot.tools.naliia_tools import NaliiaTools import httpx import json router = APIRouter() -_TOOLS = NaliiaTools() - async def send_whatsapp_message(request_data: SendMessageScheme): """ @@ -78,29 +75,6 @@ async def webhook_chat(request: Request, agent=Depends(get_agent)): existing_state = await agent.checkpointer.aget(config) if existing_state is None: initial_state["customer_phone"] = customer_phone - - find_customer_tool = _TOOLS.find_customer_by_identifier - customer_result = await find_customer_tool.ainvoke( - {"identifier": customer_phone} - ) - - try: - customer_data = json.loads(customer_result) - if isinstance(customer_data, list): - customer_data = customer_data[0] if customer_data else {} - if customer_data and customer_data.get("id"): - initial_state["customer_name"] = customer_data.get("party.", {}).get("name", "Cliente Final") - initial_state["customer_id"] = customer_data.get("id", 0) - logger.info( - f"Cliente registrado encontrado: {initial_state["customer_name"]} (ID: {initial_state["customer_id"]})" - ) - else: - logger.info( - f"Cliente no encontrado para el teléfono: {customer_phone}" - ) - except (json.JSONDecodeError, AttributeError) as e: - logger.error(f"Error al parsear datos del cliente: {e}") - logger.info(f"Nueva conversación iniciada con cliente: {customer_phone}") agent_response = await agent.ainvoke(initial_state, config=config)