feat: Add NaliiaTools
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from langgraph.graph import StateGraph, START, END
|
||||
from langchain_core.messages import SystemMessage, ToolMessage, BaseMessage
|
||||
import logging
|
||||
from typing import Literal, Callable, Any
|
||||
from .schemas import MessagesState
|
||||
from dataclasses import dataclass
|
||||
@@ -38,10 +39,9 @@ class Agent:
|
||||
- Si es None: sin herramientas
|
||||
- Si es list: lista de herramientas
|
||||
"""
|
||||
|
||||
self._model = model
|
||||
self._config = config or AgentConfig()
|
||||
|
||||
# Normalizar tools: usar la lista proporcionada o lista vacía
|
||||
self._tools = tools or []
|
||||
|
||||
self._tools_by_name: dict[str, Any] = {
|
||||
@@ -49,7 +49,6 @@ class Agent:
|
||||
}
|
||||
self._compiled_agent = self._compile_agent()
|
||||
|
||||
# Hooks para testing (monkey-patching friendly)
|
||||
self._pre_llm_hook: Callable | None = None
|
||||
self._post_tool_hook: Callable | None = None
|
||||
|
||||
@@ -92,26 +91,28 @@ class Agent:
|
||||
|
||||
def set_pre_llm_hook(self, hook: Callable[[dict], None]):
|
||||
"""Registra hook pre-llm para testing."""
|
||||
|
||||
self._pre_llm_hook = hook
|
||||
|
||||
def set_post_tool_hook(self, hook: Callable[[dict, Any], None]):
|
||||
"""Registra hook post-tool para testing."""
|
||||
|
||||
self._post_tool_hook = hook
|
||||
|
||||
def _compile_agent(self):
|
||||
"""Compila el grafo una sola vez."""
|
||||
|
||||
agent = self._build_agent()
|
||||
|
||||
return agent.compile()
|
||||
|
||||
def _build_agent(self) -> StateGraph:
|
||||
"""Construye el grafo de estado completo."""
|
||||
agent_builder = StateGraph(MessagesState)
|
||||
|
||||
# Nodos
|
||||
agent_builder.add_node("llm_call", self._llm_call_node)
|
||||
agent_builder.add_node("tool_node", self._tool_node)
|
||||
|
||||
# Flujo
|
||||
agent_builder.add_edge(START, "llm_call")
|
||||
agent_builder.add_conditional_edges(
|
||||
"llm_call",
|
||||
@@ -125,8 +126,6 @@ class Agent:
|
||||
|
||||
return agent_builder
|
||||
|
||||
# ============ Nodos del Grafo ============
|
||||
|
||||
def _llm_call_node(self, state: MessagesState) -> dict:
|
||||
"""
|
||||
Nodo LLM: Decide siguiente acción o responde.
|
||||
@@ -143,6 +142,7 @@ class Agent:
|
||||
] + state["messages"]
|
||||
|
||||
model_with_tools = self._model.bind_tools(self._tools)
|
||||
|
||||
response = model_with_tools.invoke(messages)
|
||||
|
||||
current_calls = state.get("llm_calls", 0)
|
||||
@@ -185,29 +185,30 @@ class Agent:
|
||||
Ejecuta una herramienta individual con manejo de errores.
|
||||
"""
|
||||
tool_name = tool_call.get("name")
|
||||
tool_id = tool_call.get("id", "unknown")
|
||||
tool_id = tool_call.get("id")
|
||||
tool_args = tool_call.get("args", {})
|
||||
|
||||
if tool_name not in self._tools_by_name:
|
||||
return ToolMessage(
|
||||
content=f"Error: Tool '{tool_name}' not found",
|
||||
tool_call_id=tool_id,
|
||||
status="error"
|
||||
name=tool_name,
|
||||
)
|
||||
|
||||
try:
|
||||
tool = self._tools_by_name[tool_name]
|
||||
observation = tool.invoke(tool_args)
|
||||
|
||||
return ToolMessage(
|
||||
content=str(observation),
|
||||
tool_call_id=tool_id,
|
||||
status="success"
|
||||
)
|
||||
name=tool_name)
|
||||
|
||||
except Exception as e:
|
||||
return ToolMessage(
|
||||
content=f"Error executing tool: {str(e)}",
|
||||
tool_call_id=tool_id,
|
||||
status="error"
|
||||
name=tool_name,
|
||||
)
|
||||
|
||||
def _should_continue(
|
||||
|
||||
Reference in New Issue
Block a user