Spaces:
Sleeping
Sleeping
File size: 8,626 Bytes
3545685 9b5b26a c19d193 e636c57 8fe38ae 9b5b26a 5df72d6 9b5b26a 7110895 8fe38ae 7110895 9b5b26a 7110895 8fe38ae 9b5b26a 7110895 8fe38ae 7110895 8fe38ae 7110895 8fe38ae 7110895 8fe38ae 7110895 8fe38ae 7110895 8fe38ae 7110895 8fe38ae 7110895 8fe38ae 7110895 8fe38ae 7110895 9b5b26a 8c01ffb 6aae614 ae7a494 3545685 13d500a 8c01ffb 9b5b26a 8c01ffb 861422e 9b5b26a 8c01ffb 8fe992b 1feba8c 8c01ffb 8fe992b 9b5b26a e636c57 4977da9 b9a86b5 4977da9 997d15e 4977da9 e636c57 8fe38ae e636c57 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | 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() |