Shafagh99's picture
fix the capabilities of the model
b9a86b5 verified
from smolagents import CodeAgent, DuckDuckGoSearchTool, InferenceClientModel, load_tool, tool
import datetime
import requests
import pytz
import yaml
import gradio as gr
from tools.final_answer import FinalAnswerTool
# Below is an example of a tool that does nothing. Amaze us with your creativity !
@tool
def my_custom_tool(arg1: str, arg2: int) -> str: # it's important to specify the return type
# Keep this format for the description / args / args description but feel free to modify the tool
"""Fetch and nicely format top headlines from popular news sources for today.
Args:
arg1: Comma-separated list of sources to include (options: "bbc", "nyt", "guardian", "hn", "all").
Use "all" or empty string to fetch from all supported sources.
arg2: Maximum number of headlines per source (must be > 0).
This tool scrapes public RSS feeds (no API key needed) and returns a
markdown-formatted string grouped by source, with each headline on its own line
and linked to the original article when available.
"""
import xml.etree.ElementTree as ET
if arg2 <= 0:
return "Please provide a positive integer number of headlines per source for arg2."
# Normalize requested sources
requested = [s.strip().lower() for s in arg1.split(",")] if arg1 else []
if not requested or "all" in requested:
requested = ["bbc", "nyt", "guardian", "hn"]
# Supported sources and their RSS URLs
sources = {
"bbc": {
"name": "BBC News",
"url": "https://feeds.bbci.co.uk/news/rss.xml",
},
"nyt": {
"name": "The New York Times",
"url": "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml",
},
"guardian": {
"name": "The Guardian",
"url": "https://www.theguardian.com/world/rss",
},
"hn": {
"name": "Hacker News (Top)",
"url": "https://hnrss.org/frontpage",
},
}
picked_keys = [k for k in requested if k in sources]
if not picked_keys:
return (
"No valid news sources selected. Valid options: bbc, nyt, guardian, hn, all."
)
output_sections = []
for key in picked_keys:
meta = sources[key]
name = meta["name"]
url = meta["url"]
try:
resp = requests.get(url, timeout=8)
resp.raise_for_status()
root = ET.fromstring(resp.content)
# RSS structure: channel/item/title/link
items = []
for item in root.findall(".//item"):
title_el = item.find("title")
link_el = item.find("link")
if title_el is not None and title_el.text:
title = title_el.text.strip()
link = link_el.text.strip() if link_el is not None and link_el.text else ""
if title:
items.append((title, link))
if len(items) >= arg2:
break
if not items:
output_sections.append(f"### {name}\n\n_(no headlines found)_")
else:
lines = []
for idx, (title, link) in enumerate(items, start=1):
if link:
lines.append(f"{idx}. [{title}]({link})")
else:
lines.append(f"{idx}. {title}")
joined = "\n".join(lines)
output_sections.append(f"### {name} (top {len(items)})\n\n{joined}")
except Exception as e:
output_sections.append(f"### {name}\n\n_Error fetching headlines: {e}_")
header = "## Top headlines from popular news sources\n"
return header + "\n\n" + "\n\n".join(output_sections)
@tool
def get_current_time_in_timezone(timezone: str) -> str:
"""A tool that fetches the current local time in a specified timezone.
Args:
timezone: A string representing a valid timezone (e.g., 'America/New_York').
"""
try:
# Create timezone object
tz = pytz.timezone(timezone)
# Get current time in that timezone
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
return f"The current local time in {timezone} is: {local_time}"
except Exception as e:
return f"Error fetching time for timezone '{timezone}': {str(e)}"
final_answer = FinalAnswerTool()
# If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
# model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
model = InferenceClientModel(
max_tokens=2096,
temperature=0.5,
model_id='Qwen/Qwen2.5-Coder-32B-Instruct', # it is possible that this model may be overloaded
custom_role_conversions=None,
)
# 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, my_custom_tool, get_current_time_in_timezone, image_generation_tool], # don't remove final_answer
max_steps=6,
verbosity_level=1,
name=None,
description=None,
)
def chat_fn(message, history):
"""Chat handler for Gradio.
If the user is asking for headlines, we bypass the agent and call the
headlines tool directly so the nicely formatted markdown is returned
as-is. For other queries, we fall back to the CodeAgent.
"""
text = (message or "").lower().strip()
# Special handling for capability / "what can you do" questions
if any(phrase in text for phrase in ["what can you do", "what you can do", "help me", "how can you help"]):
return (
"I’m your **Daily Headlines Assistant**.\n\n"
"- I fetch today’s top headlines from **BBC**, **The New York Times**, "
"**The Guardian**, and **Hacker News** using live RSS feeds.\n"
"- I format them into a clean, grouped markdown view with **clickable links**.\n"
"- I can also tell you the **current time in any timezone** and generate images from text prompts.\n\n"
"Try asking things like:\n"
"- \"Show me today’s top 3 headlines from BBC, NYT and Hacker News.\"\n"
"- \"Give me the top 5 headlines from BBC only.\"\n"
"- \"What time is it now in America/New_York?\"\n"
)
wants_news = any(
kw in text
for kw in ["headline", "headlines", "bbc", "nyt", "new york times", "guardian", "hacker news", "hn"]
)
if wants_news:
# Simple heuristic: default to all sources and 3 headlines if user
# does not specify numbers; otherwise, try to extract a small integer.
import re
match = re.search(r"\b(\d{1,2})\b", text)
count = int(match.group(1)) if match else 3
# Map some common names to our source keys
sources = []
if "bbc" in text:
sources.append("bbc")
if "nyt" in text or "new york times" in text:
sources.append("nyt")
if "guardian" in text:
sources.append("guardian")
if "hacker news" in text or "hn" in text:
sources.append("hn")
# If nothing specific mentioned, use all
arg1 = ",".join(sources) if sources else "all"
try:
return my_custom_tool(arg1=arg1, arg2=count)
except Exception as e:
return f"Error while fetching headlines: {e}"
# Fallback: use the full agent for non-news tasks
try:
result = agent.run(task=message)
except Exception as e:
result = f"Error while running the agent: {e}"
if result is None:
result = (
"The agent did not produce a final answer (the upstream model may have "
"returned an error like 502). Please try again or with a simpler request."
)
return str(result)
demo = gr.ChatInterface(
fn=chat_fn,
title="Daily Headlines Assistant",
description=(
"Ask for today's top headlines from BBC, The New York Times, The Guardian, "
"and Hacker News. Results include clickable links and are grouped by source."
),
examples=[
"Show me today’s top 3 headlines from BBC, NYT and Hacker News.",
"Give me the top 5 headlines from BBC only.",
"Fetch today’s main stories from The Guardian and Hacker News.",
],
)
demo.launch()