AG-UI Weather Dashboard
April 4, 2026 · View on GitHub
An AI-powered weather dashboard that combines a Google ADK agent backend with a CopilotKit + Next.js frontend, connected via the AG-UI protocol. Ask about weather in any city and get rich, interactive card-based responses rendered inline in the chat sidebar and on a persistent dashboard.
Architecture
graph TB
subgraph Frontend ["Frontend (Next.js + CopilotKit)"]
UI[CopilotSidebar Chat UI]
FT[useFrontendTool Hooks]
Cards[Weather Card Components]
API[Open-Meteo API Client]
Dashboard[Dashboard Grid]
end
subgraph Backend ["Backend (Python + Google ADK)"]
Agent[LlmAgent - GPT-4o-mini]
AGUI[AGUIToolset Placeholder]
ADAPTER[ag_ui_adk Adapter]
FASTAPI[FastAPI Server]
end
subgraph External ["External APIs"]
METEO[Open-Meteo API]
end
UI -->|User message| FT
FT -->|Registers tools| UI
UI -->|AG-UI Protocol| FASTAPI
FASTAPI --> ADAPTER
ADAPTER -->|ClientProxyTool| Agent
Agent -->|Tool call event| ADAPTER
ADAPTER -->|SSE stream| UI
UI -->|Intercepts tool call| FT
FT -->|Fetches data| API
API -->|HTTP| METEO
FT -->|Renders| Cards
FT -->|Updates state| Dashboard
Cards -->|Displayed in| UI
Cards -->|Displayed in| Dashboard
Request Flow
sequenceDiagram
participant User
participant CopilotKit as CopilotKit (Frontend)
participant AGUI as AG-UI Adapter
participant ADK as ADK Agent (LLM)
participant OpenMeteo as Open-Meteo API
User->>CopilotKit: "What's the weather in Tokyo?"
CopilotKit->>AGUI: RunAgentInput (message + frontend tools)
AGUI->>AGUI: Replace AGUIToolset with ClientProxyTools
AGUI->>ADK: Forward message + tools to LLM
ADK->>AGUI: Tool call: get_current_weather({city: "Tokyo"})
AGUI->>CopilotKit: TOOL_CALL_START + TOOL_CALL_ARGS + TOOL_CALL_END
CopilotKit->>CopilotKit: Render loading card
CopilotKit->>OpenMeteo: Fetch weather data (frontend handler)
OpenMeteo-->>CopilotKit: Weather JSON
CopilotKit->>CopilotKit: Render weather card + update dashboard
CopilotKit->>AGUI: Tool result (JSON)
AGUI->>ADK: Forward tool result
ADK->>AGUI: Brief text response
AGUI->>CopilotKit: TEXT_MESSAGE events
CopilotKit->>User: Card + "It's sunny in Tokyo!"
Project Structure
agui-weather-dashboard/
├── agent/ # Python backend
│ ├── weather_dashboard/
│ │ ├── __main__.py # FastAPI + AG-UI server entry point
│ │ ├── agent.py # ADK LlmAgent with AGUIToolset
│ │ ├── agent_executor.py # Agent runner and session management
│ │ ├── prompt_builder.py # System prompt (no data repetition)
│ │ ├── tools.py # Backend tool definitions (reference)
│ │ └── weather_client.py # Python Open-Meteo client (httpx)
│ └── pyproject.toml # Python dependencies
├── frontend/ # Next.js frontend
│ ├── src/
│ │ ├── app/
│ │ │ ├── page.tsx # Main page: WeatherTools + Dashboard
│ │ │ ├── layout.tsx # Root layout
│ │ │ └── api/copilotkit/
│ │ │ └── route.ts # CopilotKit runtime + HttpAgent
│ │ ├── components/
│ │ │ └── weather-cards.tsx # CurrentWeather, Forecast, Historical cards
│ │ └── lib/
│ │ ├── weather-api.ts # Frontend Open-Meteo client (fetch)
│ │ └── theme.ts # Theme configuration
│ └── package.json # Node dependencies
├── tests/ # Python tests (pytest)
│ ├── test_weather_client.py
│ ├── test_tools.py
│ └── test_prompt_builder.py
├── package.json # Workspace root
└── pnpm-workspace.yaml # pnpm monorepo config
Tech Stack
| Layer | Technology | Purpose |
|---|---|---|
| LLM | GPT-4o-mini (via LiteLLM) | Agent reasoning and tool selection |
| Agent Framework | Google ADK | Agent lifecycle, session management |
| Agent-UI Protocol | AG-UI + ag_ui_adk | Standardized event streaming between agent and frontend |
| Frontend Framework | Next.js 16 (Turbopack) | React SSR, API routes |
| Chat UI | CopilotKit 1.54.1 | Sidebar chat, tool call rendering, frontend tool execution |
| Styling | Tailwind CSS 4 | Utility-first CSS for weather cards |
| Weather Data | Open-Meteo API | Free, no-auth geocoding + weather + forecast + historical |
| Backend Server | FastAPI + Uvicorn | Async Python HTTP server for AG-UI endpoint |
| Package Management | pnpm (JS) + uv (Python) | Dependency management |
Prerequisites
Setup
-
Clone and install dependencies:
git clone <repo-url> cd agui-weather-dashboard pnpm install cd agent && uv sync && cd .. -
Configure environment:
# agent/.env OPENAI_API_KEY=sk-your-key-here LITELLM_MODEL=openai/gpt-4o-mini AGENT_PORT=10002 -
Start both servers:
pnpm devThis runs concurrently:
- Agent:
http://localhost:10002(AG-UI protocol endpoint) - Frontend:
http://localhost:3000(Next.js app)
- Agent:
-
Open
http://localhost:3000and start chatting.
How It Works
Frontend Tools (useFrontendTool)
The key pattern that makes card rendering work is useFrontendTool from CopilotKit. Each weather tool is registered on the frontend with:
handler- Executes when the agent calls the tool. Fetches data from Open-Meteo directly in the browser.render- Returns a React component displayed inline in the chat. Shows a loading state while fetching, then the full weather card.
stateDiagram-v2
[*] --> Registered: useFrontendTool()
Registered --> InProgress: Agent calls tool
InProgress --> Executing: Handler starts
Executing --> Complete: Data fetched
Complete --> CardRendered: render() called
CardRendered --> DashboardUpdated: onResult callback
DashboardUpdated --> [*]
InProgress --> InProgress: Loading card shown
AGUIToolset Placeholder
The ADK agent is created with tools=[AGUIToolset()]. This empty placeholder is critical -- at runtime, ag_ui_adk replaces it with ClientProxyToolset, which wraps each frontend tool as an ADK-compatible ClientProxyTool. Without this placeholder, the agent never sees the frontend tools.
Dashboard State
When a tool handler completes, it calls onResult() which adds the weather data to the dashboard grid. The dashboard:
- Accumulates cards from multiple queries
- Updates in place if you ask about the same city + type again
- Displays in a responsive 1-2 column grid
Weather Cards
Three card types with distinct visual styles:
| Card | Gradient | Data |
|---|---|---|
| Current Weather | Blue | Temperature, feels like, humidity, wind, pressure, sunrise/sunset |
| Forecast | Indigo-Purple | Daily high/low, conditions, precipitation probability (1-7 days) |
| Historical | Emerald-Teal | Past daily data table + summary (avg high, total rain, trend) |
API Endpoints
Agent (AG-UI Protocol)
POST http://localhost:10002/- AG-UI run endpoint (SSE stream)
Frontend (Next.js)
POST /api/copilotkit- CopilotKit runtime proxy to AG-UI agent
External (Open-Meteo, no auth required)
GET https://geocoding-api.open-meteo.com/v1/search- City geocodingGET https://api.open-meteo.com/v1/forecast- Current weather + forecastGET https://archive-api.open-meteo.com/v1/archive- Historical weather
Testing
cd agent && uv run pytest ../tests/ -v
Tests cover:
- Weather client API calls (mocked with
respx) - Tool functions
- Prompt builder output
Example Queries
- "What's the weather in Tokyo?"
- "Show me a 5-day forecast for London"
- "Compare weather in New York, Paris, and Sydney"
- "What was the weather like in Berlin last week?"
License
MIT