refactor: move customer identification to agent node
- Add identify_customer_node to Agent class for customer lookup - Webhook now only passes customer_phone to agent state - Customer identification happens in agent flow: START -> identify_customer -> llm_call -> tool_node -> END
This commit is contained in:
@@ -6,6 +6,7 @@ from langchain_core.runnables import RunnableConfig
|
|||||||
from typing import Literal, Callable, Any, Union
|
from typing import Literal, Callable, Any, Union
|
||||||
from .schemas import MessagesState
|
from .schemas import MessagesState
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -134,10 +135,12 @@ class Agent:
|
|||||||
"""Construye el grafo de estado completo."""
|
"""Construye el grafo de estado completo."""
|
||||||
agent_builder = StateGraph(MessagesState)
|
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("llm_call", self._llm_call_node)
|
||||||
agent_builder.add_node("tool_node", self._tool_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(
|
agent_builder.add_conditional_edges(
|
||||||
"llm_call", self._should_continue, {"tool_node": "tool_node", END: END}
|
"llm_call", self._should_continue, {"tool_node": "tool_node", END: END}
|
||||||
)
|
)
|
||||||
@@ -145,6 +148,45 @@ class Agent:
|
|||||||
|
|
||||||
return agent_builder
|
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:
|
def _llm_call_node(self, state: MessagesState) -> dict:
|
||||||
"""
|
"""
|
||||||
Nodo LLM: Decide siguiente acción o responde.
|
Nodo LLM: Decide siguiente acción o responde.
|
||||||
|
|||||||
@@ -3,15 +3,12 @@ from langchain.messages import HumanMessage
|
|||||||
from ...dependencies import get_agent
|
from ...dependencies import get_agent
|
||||||
from ....logger import logger
|
from ....logger import logger
|
||||||
from ....schemes.chat_schemes import SendMessageScheme
|
from ....schemes.chat_schemes import SendMessageScheme
|
||||||
from naliiabot.bot.tools.naliia_tools import NaliiaTools
|
|
||||||
import httpx
|
import httpx
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
_TOOLS = NaliiaTools()
|
|
||||||
|
|
||||||
|
|
||||||
async def send_whatsapp_message(request_data: SendMessageScheme):
|
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)
|
existing_state = await agent.checkpointer.aget(config)
|
||||||
if existing_state is None:
|
if existing_state is None:
|
||||||
initial_state["customer_phone"] = customer_phone
|
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}")
|
logger.info(f"Nueva conversación iniciada con cliente: {customer_phone}")
|
||||||
|
|
||||||
agent_response = await agent.ainvoke(initial_state, config=config)
|
agent_response = await agent.ainvoke(initial_state, config=config)
|
||||||
|
|||||||
Reference in New Issue
Block a user