zvl's picture
Update app.py
26814df verified
from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
import datetime
import requests
import pytz
import yaml
import os
import nltk
from bs4 import BeautifulSoup
from nltk.tokenize import sent_tokenize
from tools.final_answer import FinalAnswerTool
from Gradio_UI import GradioUI
# Descargar tokenizer de NLTK si no está disponible
nltk.download("punkt")
# Configurar el modelo de resumen desde Hugging Face en SmolAgents
model = HfApiModel(
max_tokens=2096,
temperature=0.5,
model_id="facebook/bart-large-cnn", # Modelo de resumen
custom_role_conversions=None,
)
@tool
def summarize_text(text: str) -> str:
"""
Resumir texto utilizando la API de Hugging Face.
Args:
text (str): El texto que se desea resumir.
Returns:
str: El resumen generado o un mensaje de error en caso de fallo.
"""
API_URL = "https://api-inference.huggingface.co/models/facebook/bart-large-cnn"
headers = {"Authorization": f"Bearer TU_HUGGINGFACE_API_KEY"}
payload = {
"inputs": text,
"parameters": {"max_length": 150, "min_length": 50, "do_sample": False},
}
response = requests.post(API_URL, headers=headers, json=payload)
if response.status_code == 200:
return response.json()[0]["summary_text"]
else:
return "Error en el resumen"
@tool
def scrape_webpage(url: str, tag: str = "p", class_name: str = None) -> dict:
"""
Extrae contenido de una página web según una etiqueta HTML y clase opcional.
Args:
url (str): URL de la página a scrapear.
tag (str): Etiqueta HTML a extraer (por defecto "p").
class_name (str, optional): Clase CSS opcional para filtrar resultados.
Returns:
dict: Diccionario con el contenido extraído. Contiene las claves:
- "url": La URL consultada.
- "scraped_data": Lista de fragmentos de texto extraídos (máximo 20).
En caso de error, devuelve una clave "error" con el mensaje correspondiente.
"""
try:
headers = {"User-Agent": "Mozilla/5.0"}
response = requests.get(url, headers=headers)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
if class_name:
elements = soup.find_all(tag, class_=class_name)
else:
elements = soup.find_all(tag)
extracted_data = [element.get_text(strip=True) for element in elements]
return {"url": url, "scraped_data": extracted_data[:20]} # Limita a 20 resultados
except requests.exceptions.RequestException as e:
return {"error": f"Error al acceder a la URL: {str(e)}"}
except Exception as e:
return {"error": f"Error inesperado: {str(e)}"}
@tool
def extract_metadata_from_url(url: str) -> dict:
"""
Extrae todos los metadatos de una página web.
Args:
url (str): La URL de la página web a analizar.
Returns:
dict: Diccionario con los metadatos encontrados. Si no se encuentran metadatos,
devuelve un diccionario con la clave "error" y el mensaje correspondiente.
"""
try:
headers = {"User-Agent": "Mozilla/5.0"}
response = requests.get(url, headers=headers)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
metadata = {}
for meta in soup.find_all("meta"):
if "name" in meta.attrs and "content" in meta.attrs:
metadata[meta["name"]] = meta["content"]
elif "property" in meta.attrs and "content" in meta.attrs:
metadata[meta["property"]] = meta["content"]
return metadata if metadata else {"error": "No se encontraron metadatos en la página."}
except requests.exceptions.RequestException as e:
return {"error": f"Error al acceder a la URL: {str(e)}"}
@tool
def save_scraped_data_as_markdown(scraped_data: dict, filename: str = None) -> str:
"""
Guarda el contenido scrapeado en un archivo Markdown bien formateado.
Args:
scraped_data (dict): Diccionario que contiene:
- "url" (str): La URL de la página de la cual se extrajo el contenido.
- "scraped_data" (list[str]): Lista de fragmentos de texto extraídos.
filename (str, optional): Nombre del archivo Markdown de salida. Si no se proporciona,
se genera uno usando la fecha y hora actual.
Returns:
str: Mensaje indicando si el archivo se guardó correctamente o si ocurrió algún error.
"""
try:
url = scraped_data.get("url", "Unknown")
content_list = scraped_data.get("scraped_data", [])
if not content_list:
return "No data available to save in Markdown."
formatted_content = "\n\n".join(content_list)
# Construir el contenido Markdown
markdown_content = f"# Content extracted from {url}\n\n"
markdown_content += "## Full Content\n\n"
markdown_content += formatted_content
# Generar un nombre de archivo con timestamp si no se proporciona
if not filename:
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"scraped_{timestamp}.md"
with open(filename, "w", encoding="utf-8") as file:
file.write(markdown_content)
return f"Scraped content has been saved in {filename}"
except Exception as e:
return f"Error generating Markdown file: {str(e)}"
@tool
def get_current_time_in_timezone(timezone: str) -> str:
"""
Devuelve la hora actual en una zona horaria específica.
Args:
timezone (str): Una cadena que representa una zona horaria válida (ej. "America/New_York").
Returns:
str: La hora local actual en la zona horaria especificada o un mensaje de error si falla.
"""
try:
tz = pytz.timezone(timezone)
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
return f"La hora local actual en {timezone} es: {local_time}"
except Exception as e:
return f"Error obteniendo la hora para la zona horaria '{timezone}': {str(e)}"
final_answer = FinalAnswerTool()
# Importar herramienta desde Hub
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
with open("prompts.yaml", "r") as stream:
prompt_templates = yaml.safe_load(stream)
agent = CodeAgent(
model=model,
tools=[
final_answer,
extract_metadata_from_url,
scrape_webpage,
save_scraped_data_as_markdown, # Se añade la nueva herramienta al agente
# Puedes añadir también otras herramientas como summarize_text si lo deseas
],
max_steps=6,
verbosity_level=1,
grammar=None,
planning_interval=None,
name=None,
description=None,
prompt_templates=prompt_templates,
)
GradioUI(agent).launch()