This repository has been archived on 2025-11-27. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Fitz_Studio/llms/Agente.py
T
2025-05-05 02:21:55 +02:00

122 lines
4.2 KiB
Python

from llms.Modelos.Base_model import ModeloABC
from llms.Memory.Base_MemoryConv import MemoryConvABC
from datetime import datetime
from typing import Optional, List, Union
class AgenteAI:
def __init__(
self,
modelo: ModeloABC,
nombre: str,
descripcion: str,
system_prompt: str, # <- pertenece al agente
rol: str,
objetivos: List[str],
memoria: Optional[MemoryConvABC] = None,
version: str = "1.0.0",
tools: Optional[List] = None,
output_schema: Optional[dict] = None, # <- nuevo parámetro
):
self.modelo = modelo
self.memoria = memoria
self.tools = tools or []
self.output_schema = output_schema
self.nombre = nombre
self.descripcion = descripcion
self.system_prompt = system_prompt
self.rol = rol
self.objetivos = objetivos
self.version = version
self.created_at = datetime.now()
self.updated_at = self.created_at
self.numero_interacciones = 0
def actualizar_configuracion(self, **kwargs):
for clave, valor in kwargs.items():
if hasattr(self, clave):
setattr(self, clave, valor)
self.updated_at = datetime.now()
@property
def full_system_prompt(self) -> str:
partes = [
f"Tu nombre es: {self.nombre}",
f"Tu descripción: {self.descripcion}",
f"Tu Rol: {self.rol}",
f"Tus Objetivos: {', '.join(self.objetivos)}",
""
]
# Incluir herramientas disponibles
herramientas = self._obtener_descripcion_tools()
if herramientas:
partes.append("Estas son tus herramientas disponibles:\n")
partes.extend(herramientas)
partes.append("Úsalas cuando creas oportuno.\n")
partes.append(self.system_prompt)
if self.output_schema:
partes.append(
"SIEMPRE formatea la respuesta final siguiendo estrictamente el siguiente esquema JSON:"
)
partes.append(f"```json\n{self.output_schema}\n```")
return "\n".join(partes)
def _obtener_descripcion_tools(self) -> List[str]:
"""
Devuelve una lista de strings con el nombre y descripción de cada herramienta
recogida desde los servidores MCP conectados.
"""
descripciones = []
if not hasattr(self, "mcp_servers"):
return descripciones
for server in self.mcp_servers:
if hasattr(server, "tools") and server.tools:
for tool in server.tools:
# tool puede ser string o dict, depende cómo lo expongas
if isinstance(tool, str):
descripciones.append(f"- {tool}: [sin descripción]")
elif isinstance(tool, dict):
nombre = tool.get("name", "¿?")
descripcion = tool.get("description", "[sin descripción]")
descripciones.append(f"- {nombre}: {descripcion}")
elif hasattr(tool, "name"):
descripcion = getattr(tool, "description", "[sin descripción]")
descripciones.append(f"- {tool.name}: {descripcion}")
return descripciones
async def interactuar(self, prompt: str) -> str:
if not self.modelo:
raise ValueError("El agente no tiene un modelo asignado.")
historial = []
if self.memoria:
historial = self.memoria.cargar_historial_chat()
contexto = historial + [{"role": "user", "content": prompt}]
prompt_final = self._formatear_prompt(contexto)
# Espera la respuesta del modelo de forma asíncrona
respuesta = await self.modelo.responder(
prompt=prompt_final,
system_prompt=self.full_system_prompt
)
if self.memoria:
self.memoria.guardar_turno("user", prompt)
self.memoria.guardar_turno("assistant", respuesta)
self.numero_interacciones += 1
self.updated_at = datetime.now()
return respuesta
def _formatear_prompt(self, mensajes: List[dict]) -> str:
return "\n".join([f"{msg['role']}: {msg['content']}" for msg in mensajes])