City-aware policy simulation platform for hackathons and rapid prototyping.
Tagline:See the impact before the decision.
FastAPI Pydantic Pytest React Vite Tailwind CSS Three.js Groq SDK Policy Simulation Multi-Agent Reasoning
CivitasX simulates how a city reacts to public-policy decisions such as:
- road closures
- bus route shutdowns
- fuel price increases
- police deployment changes
- internet restrictions
- public event controls
The simulation is designed to show ripple effects across:
- transport
- economy
- education
- digital work
- public sentiment
- protest risk
This repository now contains both:
- a FastAPI backend for simulation and agent reasoning
- a Vite/React frontend for visual policy simulation
| Area | What it does | Main files |
|---|---|---|
| Backend | Simulates the policy outcome and returns agent-by-agent reasoning | app/main.py, app/api.py, app/simulation.py |
| Frontend | Renders the city, metrics, agent flow, and comparison UI | frontend/src/App.jsx, frontend/src/components/City3D.jsx, frontend/src/components/AgentFlowPanel.jsx |
| AI Summary | Optionally upgrades the executive summary using Groq | app/llm.py |
| Validation | Protects the backend contract and simulation behavior | tests/test_simulation.py |
Implemented:
- FastAPI backend
- Vite/React frontend
- live frontend-to-backend integration
- 3D city visualization
- backend-driven zone stress visualization
- backend-driven agent network visualization
- city-aware simulation for
Islamabad,Lahore, andKarachi - interconnected agent logic
- conflict detection
- safer alternative policy generation
- comparison mode support
- optional Groq SDK integration for executive summaries
- backend Docker deployment scaffold for Hugging Face Spaces
- frontend Vercel deployment scaffold for SPA hosting
- backend live-context endpoint with RSS/fallback modes
- tests for core simulation flows
Not implemented yet:
- advanced caching or auth
- production monitoring
CivitasX/
|-- app/
| |-- api.py # API routes
| |-- city_profiles.py # City definitions and zone templates
| |-- llm.py # Optional Groq SDK integration
| |-- main.py # FastAPI app entrypoint
| |-- models.py # Request/response schemas
| `-- simulation.py # Core multi-agent simulation engine
|-- frontend/
| |-- src/
| |-- package.json
| |-- vite.config.js
| `-- .env.example
|-- tests/
| `-- test_simulation.py # Backend tests
|-- policypulse_ai_project_brief.md
|-- requirements.txt
`-- README.md
| Layer | Responsibility | Output |
|---|---|---|
| Backend | Scenario validation, city loading, agent simulation, conflict detection, alternative generation | Structured JSON for the dashboard |
| Frontend | Visual simulation, zone rendering, metrics, agent flow, scenario interaction, comparison display | Judge-facing interactive experience |
The project should feel visual-first.
The strongest frontend features arezone_impacts,agent_network,main_risks, andcomparison.
| Service | URL |
|---|---|
| Backend API | http://127.0.0.1:8000 |
| FastAPI Docs | http://127.0.0.1:8000/docs |
| Frontend Dev Server | http://127.0.0.1:5173 |
python -m venv .venv
.\.venv\Scripts\Activate.ps1python -m pip install -r requirements.txtThis now installs the Groq Python SDK as part of the normal backend setup.
python -m uvicorn app.main:app --reloadcd frontend
npm installCreate a frontend env file if needed:
copy .env.example .envcd frontend
npm run devpython -m compileall app tests
python -m pytest
cd frontend
npm run buildThe repository now includes:
Dockerfile.dockerignorerequirements-prod.txtHF_SPACE_README_TEMPLATE.mdDEPLOYMENT.md
Recommended backend environment variables:
BACKEND_CORS_ORIGINS=*
GROQ_API_KEY=...
GROQ_MODEL=llama-3.1-8b-instant
LIVE_CONTEXT_PROVIDER=fallback
LIVE_CONTEXT_TIMEOUT_SECONDS=3.5
LIVE_CONTEXT_MAX_ITEMS=5
Local container check:
docker build -t civitasx-backend .
docker run -p 7860:7860 civitasx-backendThe container serves FastAPI on port 7860, which is a good fit for a Docker-based Hugging Face Space.
For the exact hosted deployment sequence, use DEPLOYMENT.md.
The frontend now includes:
frontend/vercel.jsonfrontend/.env.example
Recommended Vercel project settings:
- Root Directory:
frontend - Build Command:
npm run build - Output Directory:
dist - Environment Variable:
VITE_API_BASE_URL=https://<your-space>.hf.space
The included vercel.json adds an SPA rewrite so browser refreshes and direct links continue to resolve correctly.
| Endpoint | Purpose |
|---|---|
GET / |
Basic service info |
GET /health |
Health check |
GET /cities |
Supported cities and summaries |
GET /metadata |
Default scenario and frontend control options |
GET /context/live |
Backend-fetched live or fallback operating context |
POST /simulate |
Main simulation endpoint |
POST /compare |
Before-vs-after scenario comparison |
Basic service info.
Health check.
Response:
{
"status": "ok"
}Returns the supported cities with summaries and highlights.
Frontend use:
- fill the city selector
- show city intro cards
Returns:
- default scenario values
- enum options for all controls
Frontend use:
- initialize the control panel
- avoid hardcoding dropdown values
Runs one policy scenario and returns the full dashboard payload.
Query param:
use_llm=true|false
Compares two scenarios:
currentproposed
Frontend use:
- before vs after mode
- AI recommendation comparison
The frontend should send this shape to /simulate:
{
"city": "Islamabad",
"scenario_type": "transport_restriction",
"fuel_price_increase_pct": 0,
"bus_routes_closed": 5,
"road_closure_level": "major",
"police_presence": "medium",
"internet_shutdown": "partial",
"public_transport_support": "normal",
"announcement_quality": "poor",
"duration_days": 2,
"exam_day": false,
"event_day": false
}IslamabadLahoreKarachi
transport_restrictionfuel_policypublic_eventemergencysecurity_restriction
noneminorpartialmajor
lowmediumhigh
offpartialfull
lownormalhigh
poorneutralclear
The /simulate response is designed for the frontend dashboard.
Top-level fields:
cityscenariocity_profilescoresagentsconflictsmain_riskszone_impactsagent_networkexecutive_summaryalternative_policycomparisongenerated_by
This section is the handoff for frontend development.
Frontend priority order:
city visualization->agent flow->metrics->conflict explanation->alternative policy
Use:
GET /metadatadefault_scenariooptions
Render controls for:
- city
- scenario type
- fuel price increase
- bus routes closed
- road closure level
- police presence
- internet shutdown
- public transport support
- announcement quality
- duration
- exam day
- event day
Use scores.
Render:
city_stabilitymobilityeconomic_impacteducation_continuityinternet_dependency_riskpublic_sentimentprotest_probability
Suggested UI rule:
- high positive metrics like
city_stabilityandmobility: bigger is better - disruption/risk metrics like
economic_impactandprotest_probability: bigger is worse
Use zone_impacts.
Each item already contains:
zone_idlabelzone_typexystatusrisk_scoreindicatorssummary
Suggested rendering:
- use
xandyas grid coordinates - color by
status - show small icons based on
indicators - show tooltip on hover using
summary
Status colors:
stable-> greenstressed-> yellowdisrupted-> orangecritical-> red
Indicator values currently used by backend:
road_closureeconomic_riskstudent_disruptioninternet_dependencyprotest_risk
Use agents.
Available keys:
transporteconomyeducationinternetsentimentadvisor
Each agent card includes:
scoreriskkey_reasonsummaryrecommendationdrivers
Recommended card layout:
- agent name
- score badge
- risk label
- one-line reason
- short summary
- recommendation
- top drivers list
Use agent_network.
It contains:
nodesedges
Each node includes:
idlabelkindactivityrisk
Each edge includes:
sourcetargetinfluencehighlightedlabel
Suggested frontend library:
- React Flow
Suggested rendering:
- larger or brighter nodes for high
activity - thicker edges for higher
influence - glow or pulse edges where
highlighted = true
Use:
conflictsmain_risks
Render:
- a conflict list
- a short "why this is risky" section
This should be visually separate from generic agent text because judges will look for cross-agent reasoning.
Use:
executive_summarygenerated_by
If generated_by = "groq", label it as AI-generated summary.
If generated_by = "rule_based", label it as system summary.
There are two ways to support this:
- use
/simulateand read itsalternative_policy+comparison - or call
/comparewith customcurrentandproposedscenarios
For quick hackathon delivery, the easiest path is:
- call
/simulate - show the current scenario
- show
alternative_policy - show
comparison.score_deltas - let the user apply the recommended scenario
Recommended simple UI flow:
- Load
/metadataand/citieson app start - Initialize form from
default_scenario - User changes policy controls
- Frontend sends
POST /simulate - Update:
- top metrics
- zone map
- agent cards
- network graph
- conflict list
- executive summary
- If
alternative_policyexists, show "Recommended Safer Policy" - If the user clicks compare, show
comparison
For the fastest handoff:
- React
- Vite
- Tailwind CSS
- Three.js / React Three Fiber
- React Flow
- Framer Motion
Current frontend workspace:
frontend/
|-- src/
| |-- components/
| |-- data/
| `-- lib/
|-- package.json
`-- .env.example
The frontend should mirror backend response models in TypeScript.
Suggested first types to create:
ScenarioRequestScoreBundleAgentResultZoneImpactAgentNetworkSimulationResponseComparisonResponse
Create a local .env using .env.example and add:
GROQ_API_KEY=your_key_here
GROQ_MODEL=llama-3.1-8b-instant
GROQ_BASE_URL=https://api.groq.comNotes:
GROQ_API_KEYis optional- if no Groq key is present, the backend still works
- only the executive summary falls back to deterministic text
- the current integration uses the official
groqPython SDK
| Resource | Link |
|---|---|
| Backend entrypoint | app/main.py |
| Backend API routes | app/api.py |
| Simulation engine | app/simulation.py |
| Groq wrapper | app/llm.py |
| Frontend shell | frontend/src/App.jsx |
| 3D city scene | frontend/src/components/City3D.jsx |
| Agent flow panel | frontend/src/components/AgentFlowPanel.jsx |
| Backend tests | tests/test_simulation.py |
- Do not hardcode option values; use
/metadata - Treat the backend as the source of truth for score calculations
- The city grid should be visual-first and text-second
zone_impactsandagent_networkare the strongest judge-facing visual features- The quickest demo path is to build
/simulatefirst and add/comparesecond
For the frontend developer, the best order is:
- build the control panel
- connect
/simulate - render the top metrics
- render the zone grid
- render the agent cards
- render the agent network
- add comparison mode
- Backend entry: app/main.py
- API routes: app/api.py
- Schemas: app/models.py
- Simulation engine: app/simulation.py
- Groq client wrapper: app/llm.py
- Frontend app shell: frontend/src/App.jsx
- Frontend 3D city view: frontend/src/components/City3D.jsx
- Frontend agent flow: frontend/src/components/AgentFlowPanel.jsx
- Tests: tests/test_simulation.py