Spaces:
Sleeping
A newer version of the Gradio SDK is available: 6.25.0
ClearCast Architecture
ClearCast uses 4 application layers plus an external weather provider. Each layer has one reason to change, which keeps the weather integration independently testable and makes the UI, model, and API provider replaceable.
Four Layers
- Frontend —
frontend/app.py. Gradio validates campaign fields, packages them into one structured user request, and renders the Markdown response. It has no weather or agent logic. - Agent —
agent/graph.pyandagent/prompts.py. LangGraph owns conversation state, tool selection, looping, and the marketing-analysis instructions. It depends only on LangChain tools, not OpenWeatherMap. - MCP client bridge —
agent/weather_client.py. The bridge starts the stdio server, discovers MCP tool metadata, translates JSON Schema to Pydantic models, and exposesStructuredToolinstances to LangGraph. This protocol boundary allows another compatible MCP server to replace the current one. - MCP server —
mcp_server/weather_server.pyandweather_api.py. FastMCP exposes a thin set of documented tools. The raw API module alone handles HTTP, authentication, response parsing, and useful error messages, so it can be tested without MCP.
The agent does not need to know OpenWeatherMap endpoints, authentication, or response formats. It only sees documented tools.
Tool-Calling Loop
tool call requested
START -> chatbot --------------------------------> ToolNode
^ |
| tool result |
+------------------------------------------+
|
+---- no tool call -> final response -> END
At startup, the bridge lists tools from FastMCP and creates a validated LangChain tool for each schema. During a request, the chatbot decides which tool to use. tools_condition routes a tool call to ToolNode; after execution, the result returns to the chatbot. A typical path is geocoding, forecast, current conditions, and optionally air quality before the model writes its campaign analysis.
State Flow
The graph-state contains a messages list annotated with LangGraph's add_messages reducer. Nodes return only their new messages; the reducer appends or updates them instead of discarding the conversation. This preserves user requests, assistant tool calls, and tool results through every super-step.
MemorySaver checkpoints state under configurable.thread_id, so repeated invocations with the same identifier share history and different identifiers remain isolated. It is appropriate for the local demo; a persistent checkpointer such as PostgresSaver is the production replacement.
Separation Benefits
- The MCP server can be launched and tested independently with
test_mcp.py. - Weather response-shape changes are isolated to
weather_api.py. - Prompt and campaign strategy can evolve without touching transport code.
- Gradio can be swapped for another client without changing tools or the graph.
- OpenWeatherMap could be replaced behind the same documented MCP contracts.