Spaces:
Sleeping
Sleeping
| # 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 | |
| 1. **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. | |
| 2. **Agent — `agent/graph.py` and `agent/prompts.py`.** LangGraph owns conversation state, tool selection, looping, and the marketing-analysis instructions. It depends only on LangChain tools, not OpenWeatherMap. | |
| 3. **MCP client bridge — `agent/weather_client.py`.** The bridge starts the stdio server, discovers MCP tool metadata, translates JSON Schema to Pydantic models, and exposes `StructuredTool` instances to LangGraph. This protocol boundary allows another compatible MCP server to replace the current one. | |
| 4. **MCP server — `mcp_server/weather_server.py` and `weather_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 | |
| ```text | |
| 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. | |