Build a News Agent with Google ADK + wpnews (Python, 2025)
2026-05-19 ยท 8 min read
Tutorial: wire wpnews into Google Agent Development Kit (ADK) โ Google's official multi-agent framework. Register 71 news tools as ADK FunctionTools, compose agents with sub-agents, and stream live AI news context.
Why Google ADK + wpnews?
Google Agent Development Kit (ADK) is Google's official framework for building production multi-agent systems. Unlike LangChain or CrewAI, ADK is designed ground-up for hierarchical agent orchestration โ agents compose other agents as sub-agents, passing typed state through structured flows.
wpnews provides 71 live AI news tools that plug directly into ADK's FunctionTool system โ giving every agent in your hierarchy real-time access to structured news data without building your own news pipeline.
What you'll build
- A NewsMonitorAgent โ registers all wpnews endpoints as ADK FunctionTools
- A BreakingNewsAgent sub-agent โ polls hot articles and triggers on bursts
- A DailyBriefingAgent โ orchestrates sub-agents to compile morning intelligence
Step 1 โ Install
pip install google-adk wpnews
Get a free wpnews API key at wpnews.pro/api#get-key.
Step 2 โ Register wpnews tools as ADK FunctionTools
ADK's FunctionTool wraps any Python callable. The simplest approach is to create thin wrapper functions that call the wpnews SDK:
import os
from google.adk.tools import FunctionTool
from wpnews import WPNews
_news = WPNews(api_key=os.environ.get("WPNEWS_API_KEY", ""))
def search_news(query: str, limit: int = 10, lang: str = "en") -> dict:
"""Search AI news by keyword or phrase. Returns articles with title, summary, topics, entities."""
return {"articles": _news.search(q=query, lang=lang, limit=limit)}
def get_morning_briefing(lang: str = "en", hours: int = 6) -> dict:
"""Get agent-ready morning briefing: velocity status, hot articles, trending entities.
Returns velocity_status (burst/normal/quiet), hot_articles[], trending_entities[]."""
return _news.get_morning_briefing(lang=lang, hours=hours)
def get_hot_articles(hours: int = 6, limit: int = 10, lang: str = "en") -> dict:
"""Fetch breaking news ranked by freshness x quality. Best for detecting bursts."""
return {"articles": _news.get_hot_articles(hours=hours, limit=limit, lang=lang)}
def get_topic_news(topic: str, limit: int = 10, lang: str = "en") -> dict:
"""Get articles for a specific topic slug (e.g. 'llm', 'robotics', 'open-source')."""
return {"articles": _news.get_news(topic=topic, lang=lang, limit=limit)}
# Wrap in ADK FunctionTool
search_tool = FunctionTool(func=search_news)
briefing_tool = FunctionTool(func=get_morning_briefing)
hot_articles_tool = FunctionTool(func=get_hot_articles)
topic_tool = FunctionTool(func=get_topic_news)
Step 3 โ Build the NewsMonitorAgent
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
news_agent = Agent(
name="news_monitor",
model=LiteLlm(model="openai/gpt-4o"),
description="Monitors live AI news and answers questions about current events.",
instruction="""You are an AI news analyst with access to live wpnews data.
Use search_news to find articles by keyword.
Use get_morning_briefing to get the current news status and hot articles.
Use get_hot_articles to detect breaking news (burst events).
Use get_topic_news to dive deep on a specific topic.
Always cite article titles and publication times in your answers.""",
tools=[search_tool, briefing_tool, hot_articles_tool, topic_tool],
)
Step 4 โ Build a BreakingNewsAgent sub-agent
ADK agents can orchestrate other agents as sub-agents. The BreakingNewsAgent focuses solely on burst detection:
def check_news_burst(threshold: float = 1.5, hours: int = 6) -> dict:
"""Check if AI news is in burst mode. threshold: ratio above baseline to consider burst."""
briefing = _news.get_morning_briefing(hours=hours)
vel = briefing.get("velocity", {})
ratio = vel.get("ratio", 1.0)
status = vel.get("status", "normal")
is_burst = status == "burst" or ratio >= threshold
return {
"is_burst": is_burst,
"velocity_status": status,
"ratio": ratio,
"hot_articles": briefing.get("hot_articles", [])[:3],
}
burst_tool = FunctionTool(func=check_news_burst)
breaking_news_agent = Agent(
name="breaking_news_detector",
model=LiteLlm(model="openai/gpt-4o-mini"),
description="Detects breaking news bursts and surfaces the top 3 stories.",
instruction="""Check if there's a breaking news burst using check_news_burst.
If is_burst is True, list the hot_articles with titles and why they matter.
If no burst, report that news activity is normal.""",
tools=[burst_tool],
)
Step 5 โ Orchestrate with DailyBriefingAgent
The orchestrator delegates to sub-agents and compiles the final briefing:
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
daily_briefing_agent = Agent(
name="daily_briefing",
model=LiteLlm(model="openai/gpt-4o"),
description="Orchestrates sub-agents to compile a daily AI news briefing.",
instruction="""Compile a comprehensive daily AI news briefing:
1. Ask breaking_news_detector if there are any burst events
2. Ask news_monitor for the morning briefing summary
3. Ask news_monitor to search for the top 3 trending topics from the briefing
4. Compile everything into a structured markdown briefing with:
- Velocity status (burst/normal/quiet) with ratio
- Breaking stories (if any)
- Top trending topics with representative articles
- Key entities making news today""",
sub_agents=[breaking_news_agent, news_agent],
)
Step 6 โ Run with ADK Runner
import asyncio
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
async def main():
session_service = InMemorySessionService()
runner = Runner(
agent=daily_briefing_agent,
app_name="wpnews_adk",
session_service=session_service,
)
session = await session_service.create_session(
app_name="wpnews_adk",
user_id="analyst_1",
)
message = types.Content(
role="user",
parts=[types.Part(text="Give me today's AI news briefing")]
)
async for event in runner.run_async(
user_id="analyst_1",
session_id=session.id,
new_message=message,
):
if event.is_final_response():
print(event.content.parts[0].text)
asyncio.run(main())
Full working example (under 80 lines)
"""
Google ADK + wpnews daily briefing agent
Run: WPNEWS_API_KEY=... OPENAI_API_KEY=... python adk_news.py
"""
import asyncio, os
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.adk.tools import FunctionTool
from google.genai import types
from wpnews import WPNews
_news = WPNews(api_key=os.environ.get("WPNEWS_API_KEY", ""))
def get_briefing(lang: str = "en", hours: int = 6) -> dict:
"""Get AI news situational awareness: velocity status + hot articles + entities."""
return _news.get_morning_briefing(lang=lang, hours=hours)
def search_news(query: str, limit: int = 8, lang: str = "en") -> dict:
"""Search live AI news by keyword. Returns articles with title, summary, topics."""
return {"articles": _news.search(q=query, lang=lang, limit=limit)}
agent = Agent(
name="ai_news_analyst",
model=LiteLlm(model="openai/gpt-4o"),
description="Live AI news analyst powered by wpnews",
instruction="""Use get_briefing first to understand current AI news status.
Use search_news to find articles on specific topics.
Always include velocity_status and cite article titles with dates.""",
tools=[FunctionTool(func=get_briefing), FunctionTool(func=search_news)],
)
async def main():
svc = InMemorySessionService()
runner = Runner(agent=agent, app_name="wpnews", session_service=svc)
session = await svc.create_session(app_name="wpnews", user_id="u1")
msg = types.Content(role="user", parts=[types.Part(text="What's the top AI news today?")])
async for event in runner.run_async(user_id="u1", session_id=session.id, new_message=msg):
if event.is_final_response():
print(event.content.parts[0].text)
asyncio.run(main())
Get your free wpnews API key
1,000 calls/day free. No credit card. Google ADK agent up in 10 minutes.
Get Free API Key โOr try keyless first: curl https://api.wpnews.pro/api/v1/morning-briefing