fix: Deleted strategy Registry to register tools
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
from langgraph.graph import StateGraph, START, END
|
from langgraph.graph import StateGraph, START, END
|
||||||
from langchain_core.messages import SystemMessage, ToolMessage, BaseMessage
|
from langchain_core.messages import SystemMessage, ToolMessage, BaseMessage
|
||||||
from typing import Literal, Callable, Any, Union
|
from typing import Literal, Callable, Any
|
||||||
from .schemas import MessagesState
|
from .schemas import MessagesState
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from ..tools.tool_registry import ToolRegistry, BaseTool
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -20,15 +19,14 @@ class Agent:
|
|||||||
"""
|
"""
|
||||||
Agente conversacional basado en LangGraph.
|
Agente conversacional basado en LangGraph.
|
||||||
|
|
||||||
Soporta tools usando el patrón Registry para una gestión centralizada
|
Soporta tools pasadas como lista de instancias.
|
||||||
y extensible de herramientas.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
model: Any,
|
model: Any,
|
||||||
config: AgentConfig | None = None,
|
config: AgentConfig | None = None,
|
||||||
tools: Union[list, ToolRegistry, None] = None
|
tools: list | None = None
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Inicializa el agente.
|
Inicializa el agente.
|
||||||
@@ -36,18 +34,14 @@ class Agent:
|
|||||||
Args:
|
Args:
|
||||||
model: Modelo LLM a usar
|
model: Modelo LLM a usar
|
||||||
config: Configuración del agente (AgentConfig)
|
config: Configuración del agente (AgentConfig)
|
||||||
tools: Lista de tools, ToolRegistry, o None
|
tools: Lista de instancias de herramientas o None
|
||||||
- Si es None: sin herramientas
|
- Si es None: sin herramientas
|
||||||
- Si es list: lista de herramientas
|
- Si es list: lista de herramientas
|
||||||
- Si es ToolRegistry: se extrae la lista de herramientas
|
|
||||||
"""
|
"""
|
||||||
self._model = model
|
self._model = model
|
||||||
self._config = config or AgentConfig()
|
self._config = config or AgentConfig()
|
||||||
|
|
||||||
# Normalizar tools: convertir ToolRegistry a lista si es necesario
|
# Normalizar tools: usar la lista proporcionada o lista vacía
|
||||||
if isinstance(tools, ToolRegistry):
|
|
||||||
self._tools = tools.get_all_tools()
|
|
||||||
else:
|
|
||||||
self._tools = tools or []
|
self._tools = tools or []
|
||||||
|
|
||||||
self._tools_by_name: dict[str, Any] = {
|
self._tools_by_name: dict[str, Any] = {
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
"""
|
|
||||||
Módulo de herramientas para el agente.
|
|
||||||
|
|
||||||
Implementa el patrón Registry para registrar y gestionar herramientas
|
|
||||||
de forma centralizada y extensible.
|
|
||||||
|
|
||||||
Uso:
|
|
||||||
from src.naliiabot.bot.tools import ToolRegistry, BaseTool
|
|
||||||
|
|
||||||
registry = ToolRegistry()
|
|
||||||
registry.register(MiHerramienta())
|
|
||||||
tools = registry.get_all_tools_as_langchain()
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .tool_registry import ToolRegistry, BaseTool
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"ToolRegistry",
|
|
||||||
"BaseTool",
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -1,268 +0,0 @@
|
|||||||
"""
|
|
||||||
Patrón Registry para herramientas del agente.
|
|
||||||
|
|
||||||
Este módulo proporciona una forma centralizada y extensible de registrar
|
|
||||||
y gestionar herramientas usando el patrón Registry.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from abc import ABC, abstractmethod
|
|
||||||
from typing import Any, Callable, Optional, Dict, List
|
|
||||||
from langchain_core.tools import Tool
|
|
||||||
import json
|
|
||||||
|
|
||||||
|
|
||||||
class BaseTool(ABC):
|
|
||||||
"""
|
|
||||||
Clase base para todas las herramientas del agente.
|
|
||||||
|
|
||||||
Define la interfaz que deben implementar todas las tools.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@property
|
|
||||||
@abstractmethod
|
|
||||||
def name(self) -> str:
|
|
||||||
"""Nombre único de la herramienta."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@property
|
|
||||||
@abstractmethod
|
|
||||||
def description(self) -> str:
|
|
||||||
"""Descripción de qué hace la herramienta."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@property
|
|
||||||
@abstractmethod
|
|
||||||
def args_schema(self) -> Dict[str, Any]:
|
|
||||||
"""
|
|
||||||
Schema de argumentos esperados (JSON Schema).
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dict con format JSON Schema que describe los argumentos.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def invoke(self, **kwargs) -> Any:
|
|
||||||
"""
|
|
||||||
Ejecuta la herramienta.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
**kwargs: Argumentos específicos de la herramienta
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Resultado de la ejecución
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def to_langchain_tool(self) -> Tool:
|
|
||||||
"""
|
|
||||||
Convierte la herramienta a formato LangChain Tool.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Tool de LangChain lista para ser usada con el modelo
|
|
||||||
"""
|
|
||||||
return Tool(
|
|
||||||
name=self.name,
|
|
||||||
description=self.description,
|
|
||||||
func=self.invoke,
|
|
||||||
args_schema=self.args_schema
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ToolRegistry:
|
|
||||||
"""
|
|
||||||
Registro centralizado de herramientas.
|
|
||||||
|
|
||||||
Implementa el patrón Registry para:
|
|
||||||
- Registrar nuevas herramientas
|
|
||||||
- Recuperar herramientas por nombre
|
|
||||||
- Listar todas las herramientas
|
|
||||||
- Validar herramientas antes de registrar
|
|
||||||
|
|
||||||
Ejemplo de uso:
|
|
||||||
registry = ToolRegistry()
|
|
||||||
registry.register(CalculatorTool())
|
|
||||||
registry.register(GreeterTool())
|
|
||||||
|
|
||||||
tools = registry.get_all_tools()
|
|
||||||
calc_tool = registry.get_tool("calculator")
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""Inicializa el registro vacío."""
|
|
||||||
self._tools: Dict[str, BaseTool] = {}
|
|
||||||
|
|
||||||
def register(self, tool: BaseTool) -> None:
|
|
||||||
"""
|
|
||||||
Registra una nueva herramienta.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tool: Instancia de BaseTool a registrar
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError: Si la herramienta ya está registrada
|
|
||||||
TypeError: Si no es una instancia de BaseTool
|
|
||||||
"""
|
|
||||||
if not isinstance(tool, BaseTool):
|
|
||||||
raise TypeError(
|
|
||||||
f"Tool must be instance of BaseTool, got {type(tool).__name__}"
|
|
||||||
)
|
|
||||||
|
|
||||||
if tool.name in self._tools:
|
|
||||||
raise ValueError(
|
|
||||||
f"Tool with name '{tool.name}' is already registered"
|
|
||||||
)
|
|
||||||
|
|
||||||
self._tools[tool.name] = tool
|
|
||||||
|
|
||||||
def register_multiple(self, tools: List[BaseTool]) -> None:
|
|
||||||
"""
|
|
||||||
Registra múltiples herramientas de una vez.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tools: Lista de BaseTool a registrar
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError: Si alguna herramienta ya está registrada
|
|
||||||
TypeError: Si algún elemento no es BaseTool
|
|
||||||
"""
|
|
||||||
for tool in tools:
|
|
||||||
self.register(tool)
|
|
||||||
|
|
||||||
def unregister(self, tool_name: str) -> None:
|
|
||||||
"""
|
|
||||||
Desregistra una herramienta.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tool_name: Nombre de la herramienta a remover
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
KeyError: Si la herramienta no existe
|
|
||||||
"""
|
|
||||||
if tool_name not in self._tools:
|
|
||||||
raise KeyError(f"Tool '{tool_name}' not found in registry")
|
|
||||||
del self._tools[tool_name]
|
|
||||||
|
|
||||||
def get_tool(self, tool_name: str) -> Optional[BaseTool]:
|
|
||||||
"""
|
|
||||||
Obtiene una herramienta por nombre.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tool_name: Nombre de la herramienta
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
La herramienta si existe, None en caso contrario
|
|
||||||
"""
|
|
||||||
return self._tools.get(tool_name)
|
|
||||||
|
|
||||||
def get_all_tools(self) -> List[BaseTool]:
|
|
||||||
"""
|
|
||||||
Obtiene todas las herramientas registradas.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Lista de todas las herramientas
|
|
||||||
"""
|
|
||||||
return list(self._tools.values())
|
|
||||||
|
|
||||||
def get_langchain_tools(self) -> List[Tool]:
|
|
||||||
"""
|
|
||||||
Obtiene todas las herramientas en formato LangChain.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Lista de herramientas convertidas a LangChain Tool
|
|
||||||
"""
|
|
||||||
return [tool.to_langchain_tool() for tool in self._tools.values()]
|
|
||||||
|
|
||||||
def has_tool(self, tool_name: str) -> bool:
|
|
||||||
"""
|
|
||||||
Verifica si una herramienta está registrada.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tool_name: Nombre de la herramienta
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True si la herramienta existe, False en caso contrario
|
|
||||||
"""
|
|
||||||
return tool_name in self._tools
|
|
||||||
|
|
||||||
def list_tools(self) -> Dict[str, str]:
|
|
||||||
"""
|
|
||||||
Lista todas las herramientas con sus descripciones.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dict con nombre de herramienta como key y descripción como value
|
|
||||||
"""
|
|
||||||
return {
|
|
||||||
tool.name: tool.description
|
|
||||||
for tool in self._tools.values()
|
|
||||||
}
|
|
||||||
|
|
||||||
def clear(self) -> None:
|
|
||||||
"""Limpia el registro, removiendo todas las herramientas."""
|
|
||||||
self._tools.clear()
|
|
||||||
|
|
||||||
def __len__(self) -> int:
|
|
||||||
"""Retorna la cantidad de herramientas registradas."""
|
|
||||||
return len(self._tools)
|
|
||||||
|
|
||||||
def __contains__(self, tool_name: str) -> bool:
|
|
||||||
"""Permite usar 'in' para verificar si una herramienta existe."""
|
|
||||||
return tool_name in self._tools
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
"""Representación en string del registro."""
|
|
||||||
tool_names = ", ".join(self._tools.keys())
|
|
||||||
return f"ToolRegistry(tools=[{tool_names}])"
|
|
||||||
|
|
||||||
|
|
||||||
class ToolRegistryBuilder:
|
|
||||||
"""
|
|
||||||
Constructor fluido para ToolRegistry.
|
|
||||||
|
|
||||||
Permite una forma conveniente de crear y configurar un registro.
|
|
||||||
|
|
||||||
Ejemplo:
|
|
||||||
registry = (ToolRegistryBuilder()
|
|
||||||
.add(CalculatorTool())
|
|
||||||
.add(GreeterTool())
|
|
||||||
.build())
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""Inicializa el constructor."""
|
|
||||||
self._registry = ToolRegistry()
|
|
||||||
|
|
||||||
def add(self, tool: BaseTool) -> "ToolRegistryBuilder":
|
|
||||||
"""
|
|
||||||
Añade una herramienta al registro.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tool: Herramienta a añadir
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Self para permitir encadenamiento
|
|
||||||
"""
|
|
||||||
self._registry.register(tool)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def add_multiple(self, tools: List[BaseTool]) -> "ToolRegistryBuilder":
|
|
||||||
"""
|
|
||||||
Añade múltiples herramientas.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
tools: Lista de herramientas
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Self para permitir encadenamiento
|
|
||||||
"""
|
|
||||||
self._registry.register_multiple(tools)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def build(self) -> ToolRegistry:
|
|
||||||
"""
|
|
||||||
Construye y retorna el ToolRegistry.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
ToolRegistry configurado
|
|
||||||
"""
|
|
||||||
return self._registry
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
"""
|
|
||||||
Implementaciones concretas de herramientas del agente.
|
|
||||||
|
|
||||||
Este módulo contiene las herramientas concretas que extienden BaseTool
|
|
||||||
y pueden ser registradas en el ToolRegistry.
|
|
||||||
|
|
||||||
Ejemplo de cómo crear una herramienta personalizada:
|
|
||||||
|
|
||||||
from typing import Any, Dict
|
|
||||||
from .tool_registry import BaseTool
|
|
||||||
|
|
||||||
class MiHerramienta(BaseTool):
|
|
||||||
@property
|
|
||||||
def name(self) -> str:
|
|
||||||
return "mi_herramienta"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def description(self) -> str:
|
|
||||||
return "Descripción de qué hace mi herramienta"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def args_schema(self) -> Dict[str, Any]:
|
|
||||||
return {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"param1": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Descripción del parámetro"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["param1"]
|
|
||||||
}
|
|
||||||
|
|
||||||
def invoke(self, **kwargs) -> str:
|
|
||||||
param1 = kwargs.get("param1")
|
|
||||||
# Implementa la lógica de tu herramienta
|
|
||||||
return f"Resultado: {param1}"
|
|
||||||
|
|
||||||
Luego registra tu herramienta:
|
|
||||||
|
|
||||||
from .tool_registry import ToolRegistry
|
|
||||||
from .tools import MiHerramienta
|
|
||||||
|
|
||||||
registry = ToolRegistry()
|
|
||||||
registry.register(MiHerramienta())
|
|
||||||
tools = registry.get_all_tools_as_langchain()
|
|
||||||
"""
|
|
||||||
|
|
||||||
from typing import Any, Dict
|
|
||||||
from .tool_registry import BaseTool
|
|
||||||
|
|
||||||
|
|
||||||
# Define aquí tus herramientas personalizadas
|
|
||||||
# Ejemplo: class MiHerramienta(BaseTool): ...
|
|
||||||
Reference in New Issue
Block a user