Spaces:
Runtime error
Runtime error
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, | |
) | |
def save_scraped_data_as_markdown(scraped_data: dict, filename: str = None) -> str: | |
"""Convierte el contenido scrapeado en un archivo Markdown mejor estructurado. | |
Mejoras: | |
- Resumen automático del contenido con NLP. | |
- Uso de encabezados, listas y negritas en Markdown. | |
- Guardado con timestamp para evitar sobrescribir archivos. | |
Args: | |
scraped_data: Diccionario con la URL y los datos extraídos. | |
filename: Nombre del archivo de salida (si no se da, se genera con timestamp). | |
Returns: | |
Mensaje de confirmación o error. | |
""" | |
try: | |
url = scraped_data.get("url", "Desconocido") | |
content_list = scraped_data.get("scraped_data", []) | |
if not content_list: | |
return "No hay datos para guardar en Markdown." | |
# Tokenizar en oraciones | |
tokenized_sentences = [sent_tokenize(text) for text in content_list] | |
formatted_content = "\n\n".join([" ".join(sentences) for sentences in tokenized_sentences]) | |
# Hacer resumen del contenido (limitamos a 1024 tokens por si el texto es muy largo) | |
if len(formatted_content.split()) > 100: | |
summarized_text = model.query( | |
prompt=f"Resume el siguiente texto:\n\n{formatted_content[:1024]}", | |
max_length=150, | |
min_length=50, | |
) | |
else: | |
summarized_text = formatted_content | |
# Mejorar la estructura Markdown | |
markdown_content = f"# Contenido extraído de {url}\n\n" | |
markdown_content += f"## Resumen\n\n> {summarized_text}\n\n" | |
markdown_content += "## Contenido Completo\n\n" | |
for paragraph in formatted_content.split("\n\n"): | |
if len(paragraph.split()) > 10: # Si el párrafo es largo, lo tratamos como sección | |
markdown_content += f"### {paragraph[:50]}...\n\n{paragraph}\n\n" | |
else: | |
markdown_content += f"- **{paragraph}**\n\n" | |
# Generar nombre 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" | |
# Guardar en un archivo Markdown | |
with open(filename, "w", encoding="utf-8") as file: | |
file.write(markdown_content) | |
return f"El contenido scrapeado se ha guardado en {filename}" | |
except Exception as e: | |
return f"Error al generar el archivo Markdown: {str(e)}" | |
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: URL de la página a scrapear. | |
tag: Etiqueta HTML a extraer (por defecto <p>). | |
class_name: Clase CSS opcional para filtrar resultados. | |
Returns: | |
Un diccionario con el contenido extraído. | |
""" | |
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)}"} | |
def extract_metadata_from_url(url: str) -> dict: | |
"""Extrae todos los metadatos de una página web. | |
Args: | |
url: La URL de la página web a analizar. | |
Returns: | |
Un diccionario con los metadatos encontrados. | |
""" | |
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)}"} | |
def get_current_time_in_timezone(timezone: str) -> str: | |
"""Devuelve la hora actual en una zona horaria específica. | |
Args: | |
timezone: Una cadena que representa una zona horaria válida (ej. 'America/New_York'). | |
Returns: | |
La hora local actual en la zona horaria especificada. | |
""" | |
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() | |
# Import tool from 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 | |
], | |
max_steps=6, | |
verbosity_level=1, | |
grammar=None, | |
planning_interval=None, | |
name=None, | |
description=None, | |
prompt_templates=prompt_templates, | |
) | |
GradioUI(agent).launch() | |