smolagents huggingface python ai-agents news-api

Real-Time News Tools for smolagents (HuggingFace, Python, 2025)

2026-05-19 ยท 7 min read

Tutorial: add live AI news to HuggingFace smolagents with the @tool decorator. Use wpnews as a CodeAgent or ToolCallingAgent data source โ€” search, entity tracking, morning briefing in under 30 lines.

Why smolagents + wpnews?

smolagents by HuggingFace is the minimalist agent framework โ€” just Python functions decorated with @tool, and the agent reasons about which to call. The entire framework fits in ~1000 lines of code.

wpnews gives smolagents real-time AI news in a single pip install. No custom HTTP code, no prompt engineering โ€” just import, decorate, run.

Two modes: ToolCallingAgent and CodeAgent

smolagents has two agent types:

  • ToolCallingAgent โ€” uses structured tool calls (like OpenAI function calling). Predictable, safe for production.
  • CodeAgent โ€” generates and executes Python code directly. More flexible, can chain tools in Python logic.

wpnews works with both. We'll show both patterns.

Step 1 โ€” Install

pip install smolagents wpnews

Get a free wpnews API key at wpnews.pro/api#get-key.

Step 2 โ€” Define wpnews tools with @tool

smolagents tools are plain Python functions with a docstring. The docstring becomes the tool description the LLM uses to decide when to call it:

import os
from smolagents import tool
from wpnews import WPNews

_news = WPNews(api_key=os.environ.get("WPNEWS_API_KEY", ""))


@tool
def search_ai_news(query: str, limit: int = 8) -> list[dict]:
    """Search for recent AI news articles matching the query.

    Args:
        query: Keyword or phrase to search for (e.g. "OpenAI GPT-5", "Gemini 2.0")
        limit: Maximum number of articles to return (1-20, default 8)

    Returns list of articles with title, summary, topics, entities, and URL.
    """
    articles = _news.search(q=query, limit=limit)
    return [
        {
            "title": a.get("title", ""),
            "summary": a.get("summary", "")[:200],
            "topics": a.get("topics", [])[:3],
            "entities": [e.get("name", e) if isinstance(e, dict) else e for e in a.get("entities", [])[:5]],
            "url": f"https://wpnews.pro/news/{a.get('slug', '')}",
            "published_at": a.get("published_at", ""),
        }
        for a in articles
    ]


@tool
def get_ai_news_briefing(hours: int = 6) -> dict:
    """Get current AI news situational awareness โ€” velocity status, breaking stories, trending entities.

    Args:
        hours: Look-back window in hours (1-24, default 6)

    Returns velocity_status (burst/normal/quiet), hot_articles[], trending_entities[],
    and context_text ready for injection into a system prompt.
    """
    data = _news.get_morning_briefing(hours=hours)
    return {
        "velocity_status": data.get("velocity", {}).get("status", "normal"),
        "velocity_ratio": data.get("velocity", {}).get("ratio", 1.0),
        "hot_articles": [
            {"title": a.get("title"), "hours_ago": round(a.get("hours_ago", 0), 1)}
            for a in data.get("hot_articles", [])[:5]
        ],
        "trending_entities": [e.get("name") for e in data.get("trending_entities", [])[:10]],
        "context_text": data.get("context_text", ""),
    }


@tool
def get_topic_news(topic: str, limit: int = 5) -> list[dict]:
    """Get recent AI news articles for a specific topic.

    Args:
        topic: Topic slug (e.g. 'llm', 'robotics', 'open-source', 'computer-vision', 'startups')
        limit: Maximum articles to return (1-20, default 5)

    Returns list of articles for the given topic.
    """
    articles = _news.get_news(topic=topic, limit=limit)
    return [{"title": a.get("title"), "summary": a.get("summary", "")[:150]} for a in articles]

Step 3 โ€” ToolCallingAgent (structured calls)

from smolagents import ToolCallingAgent, OpenAIServerModel

model = OpenAIServerModel(model_id="gpt-4o")

agent = ToolCallingAgent(
    tools=[search_ai_news, get_ai_news_briefing, get_topic_news],
    model=model,
    system_prompt="""You are an AI news analyst. Always start with get_ai_news_briefing
to understand the current news environment, then use search_ai_news or get_topic_news
to dive deeper on specific subjects. Cite article titles and publication times.""",
)

# Run the agent
result = agent.run("What's the most important AI news today? Any breaking stories?")
print(result)

Step 4 โ€” CodeAgent (generates Python to chain tools)

CodeAgent is unique to smolagents โ€” it writes Python code to chain your tools, then executes it in a sandboxed environment:

from smolagents import CodeAgent, OpenAIServerModel

model = OpenAIServerModel(model_id="gpt-4o")

code_agent = CodeAgent(
    tools=[search_ai_news, get_ai_news_briefing, get_topic_news],
    model=model,
)

# CodeAgent generates Python code like:
# briefing = get_ai_news_briefing(hours=6)
# entities = briefing["trending_entities"][:3]
# results = [search_ai_news(e, limit=3) for e in entities]
# return {entity: articles for entity, articles in zip(entities, results)}

result = code_agent.run(
    "Get the morning briefing, then search for news about each trending entity and "
    "return a dict mapping entity name to their 3 most recent articles."
)
print(result)

Full working example (under 60 lines)

"""
smolagents + wpnews news analyst
Run: WPNEWS_API_KEY=... OPENAI_API_KEY=... python smol_news.py
"""
import os
from smolagents import tool, ToolCallingAgent, OpenAIServerModel
from wpnews import WPNews

_news = WPNews(api_key=os.environ.get("WPNEWS_API_KEY", ""))


@tool
def search_ai_news(query: str, limit: int = 8) -> list[dict]:
    """Search recent AI news articles.
    Args:
        query: Keyword or phrase (e.g. "Anthropic Claude")
        limit: Max articles (1-20)
    """
    return [
        {"title": a.get("title"), "summary": a.get("summary", "")[:200],
         "url": f"https://wpnews.pro/news/{a.get('slug', '')}"}
        for a in _news.search(q=query, limit=limit)
    ]


@tool
def get_ai_news_briefing(hours: int = 6) -> dict:
    """Get current AI news status: velocity, hot articles, trending entities.
    Args:
        hours: Look-back window (1-24)
    """
    d = _news.get_morning_briefing(hours=hours)
    return {
        "status": d.get("velocity", {}).get("status", "normal"),
        "hot": [a.get("title") for a in d.get("hot_articles", [])[:3]],
        "entities": [e.get("name") for e in d.get("trending_entities", [])[:8]],
    }


agent = ToolCallingAgent(
    tools=[search_ai_news, get_ai_news_briefing],
    model=OpenAIServerModel(model_id="gpt-4o"),
)

print(agent.run("Give me a briefing on today's AI news and the top trending companies."))

Get your free wpnews API key

1,000 calls/day free. No credit card. smolagents integration in 5 minutes.

Get Free API Key โ†’

Or try keyless: curl https://api.wpnews.pro/api/v1/morning-briefing