尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
SIH26068 — Ministry of Earth Sciences / IMD · Disaster Management
A conversational, multilingual, voice-enabled weather assistant that turns
forecast data into plain-language, actionable guidance for farmers, fishermen,
travellers and flood-prone communities across India.
One risk engine. Every feature that mentions risk calls
app/services/risk_engine.py. Nothing else computes a score. That is what makes
it impossible for the map to say Moderate while the alert says Severe for
the same place — there is no second implementation to drift.查看完整 README ↗SIH26068 — Ministry of Earth Sciences / IMD · Disaster Management
A conversational, multilingual, voice-enabled weather assistant that turns forecast data into plain-language, actionable guidance for farmers, fishermen, travellers and flood-prone communities across India.
Open-Meteo (live) Anthropic (claude-sonnet-4-6)
│ │
▼ ▼
┌──────────────┐ ┌────────────────────┐
│ Weather │ │ Structured │
│ provider │ │ extraction + │
└──────┬───────┘ │ grounded writing │
│ └─────────┬──────────┘
▼ │
╔═══════════════════════╗ │
║ WEATHER RISK ENGINE ║ ◄─────────────────────────┘
║ the only place risk ║
║ is ever computed ║
╚═══════╤═══════════════╝
│ { risk_score, risk_level, detected_hazard }
┌─────────┼───────────┬──────────────┬───────────────┐
▼ ▼ ▼ ▼ ▼
/chat /alerts 24h timeline India risk map emergency mode
One risk engine. Every feature that mentions risk calls
app/services/risk_engine.py. Nothing else computes a score. That is what makes
it impossible for the map to say Moderate while the alert says Severe for
the same place — there is no second implementation to drift.
Answers cannot invent numbers. Generated prose is scanned for measurement claims and each one is checked against the values the provider actually returned. A claim that matches nothing causes the whole answer to be discarded in favour of a template built from real values. The fallback for a hallucination is a correct answer, not an apology.
Degradation is designed, not accidental. No API key, no network, a failed
translation, a dead TTS service — each has a defined path. Quality drops;
availability does not. Whatever degraded is reported in the response's
degraded object rather than hidden.
Multilingual all the way down. Six languages end to end. Language detection runs offline on the Unicode script, which is exact for Telugu and separates Assamese from Bengali by two letters Bengali does not use. When the LLM is unavailable the assistant answers from localised templates — it never silently falls back to English.
vercel.json in the repo root declares both services and the routing, so the
repo imports into Vercel as-is. Read docs/DEPLOYMENT.md
first — three components (the alert scheduler, the /ws/alerts WebSocket and
the SQLite store) need a long-lived process, which serverless does not provide.
The app detects a serverless runtime and adapts rather than failing: the
in-process scheduler is disabled in favour of a platform cron, the database
moves to /tmp, the API is served at both /chat and /api/chat so it works
whether or not the platform strips the prefix, and the client switches the alert
feed from WebSocket to polling — reporting "Alerts updating periodically" rather
than pretending to be live. That guide covers what is degraded and the split
deploy (Vercel frontend, Render backend) that avoids all of it.
Two terminals. Neither step needs an API key to run.
# ── Backend ───────────────────────────────────────────────
cd backend
pip install -r requirements.txt
cp ../.env.example ../.env # optional; every value has a default
python run.py # http://127.0.0.1:8000 · docs at /docs
# ── Frontend ──────────────────────────────────────────────
cd frontend
npm install
npm run dev # http://127.0.0.1:5173
The Vite dev server proxies /api (WebSockets included) to FastAPI, so local
development never depends on CORS configuration.
Everything is environment-driven; see .env.example. The values
that change behaviour most:
| Variable | Default | Effect |
|---|---|---|
LLM_PROVIDER | auto | gemini, anthropic, or auto (prefers Gemini when its key is set) |
GEMINI_API_KEY | (unset) | Unset ⇒ rule-based understanding and templated answers |
GEMINI_MODEL | gemini-3.5-flash-lite | Answers in about a second; larger flash models return 503 under load |
ANTHROPIC_API_KEY | (unset) | The alternative provider; same pipeline, same guardrails |
ANTHROPIC_MODEL | claude-sonnet-4-6 | Model used for extraction and writing |
ELEVENLABS_API_KEY | (unset) | Hosted speech-to-text; needs no model download, so voice works on serverless |
WEATHER_DATA_MODE | live | fixture serves deterministic offline data for dev/CI |
ALERT_INTERVAL_MINUTES | 30 | Scan cadence for the single alert scheduler |
ALERT_MIN_RISK_SCORE | 61 | The "High" band; the floor for raising an alert |
TWILIO_* | (unset) | Unset ⇒ alerts log to the console instead of texting |
WEATHER_DATA_MODE=fixture is for offline development and tests. Fixture
responses are tagged data_source: "fixture" and the UI shows a SIMULATED
DATA badge at every breakpoint. Simulated data cannot appear in live mode.
| Method | Path | Purpose |
|---|---|---|
POST | /chat | Ask a question. Returns answer, explanation, actions, risk, impacts, raw data, verification |
POST | /voice-chat | Same, from an audio upload (or a browser-supplied transcript) |
GET | /weather/current | Current conditions plus risk and impact cards |
GET | /weather/timeline | Next N hours, each with its own risk level |
GET | /weather/forecast | 7-day forecast with per-day risk |
GET | /climate-trend | Historical anomaly summary for the month so far |
GET | /risk | Risk for one location |
GET | /risk-map | Per-location risk for the India map |
GET | /alerts | Active alerts, with localised hazard and severity labels |
POST | /alerts/subscribe | Subscribe a location and hazard set |
POST | /alerts/scan | Run the scan immediately (same job the scheduler runs) |
WS | /ws/alerts | Live alert push; sends a snapshot on connect |
GET | /health, /config | Capabilities, so the UI can hide what cannot work |
GET | /historical-events | Reference events used for context comparisons |
Interactive documentation at /docs.
Every risk-bearing response carries the same shape:
{ "risk_score": 76, "risk_level": "High", "detected_hazard": "Heavy Rainfall" }
Bands: 0–30 Low · 31–60 Moderate · 61–80 High · 81–100 Severe. Hazards: Heavy Rainfall, Flood Risk, Strong Wind, Extreme Heat, Lightning/Storm.
Thresholds follow IMD's published rainfall categories (7.6 / 35.6 / 64.5 / 115.6 / 204.5 mm per 24 h) and conventional wind and heat advisory breakpoints, so the numbers mean something to a domain expert.
backend/
app/
main.py FastAPI app, CORS, the single alert scheduler
config.py All configuration, environment-driven
schemas.py Wire contract shared with the frontend
db.py SQLite (PostgreSQL is a driver swap)
routes/ chat · weather · alerts · risk · meta
services/
risk_engine.py ◄── the single source of truth for risk
chat_engine.py Orchestration: detect → understand → fetch → score → verify
weather.py Open-Meteo client + offline fixture provider
llm.py Anthropic, forced tool use, isolated failures
verification.py Numeric grounding check
nlp_fallback.py Rule-based understanding when the LLM is unavailable
language.py Offline script-based detection; translation
i18n.py Localised templates for all six languages
advisory.py Plain-language explanation, impacts, emergency briefs
alerts.py Scan job, WebSocket hub, Twilio
climate.py Historical anomaly analysis
history.py Threshold-matched historical comparisons
memory.py Multi-turn session memory
speech.py Whisper transcription, gTTS synthesis
tests/ 101 tests: risk engine, eval harness, edge cases, API
frontend/
src/
App.jsx Splash → landing → dashboard
scene/ Three.js background that reacts to conditions
components/ Dashboard panels
api/client.js Typed-ish client; every failure becomes a safe message
docs/DEMO_SCRIPT.md Step-by-step live demo
cd backend && python -m pytest tests/ -q
101 tests, no network required — they run against the fixture provider with the LLM disabled, which means they exercise the degraded path by default. That is deliberate: the degraded path is the one that must never break.
Coverage includes the risk-engine band boundaries and hazard discrimination, a
20-case eval harness (varied phrasing, misspellings, five languages, multi-turn
follow-ups, off-topic queries), the eight edge cases from the brief, and a
cross-feature invariant test asserting that /chat, /risk, /risk-map and
stored alerts report identical scores for the same location.
To evaluate the LLM path instead, export GEMINI_API_KEY (or
ANTHROPIC_API_KEY) and unset LLM_ENABLED=false in tests/conftest.py.
Whichever provider answers, it reaches the same guardrails: the risk engine is
still the only thing that scores risk, and verification still discards an
answer that quotes a number the provider did not return — so a provider swap
changes the wording, never the facts.
Both are feature-detected at runtime and reported by /health; neither is
required for the app to start.
faster-whisper transcribes server side. The browser's own
SpeechRecognition is used when available and sent as client_transcript, so
voice still works on a deployment without the Whisper model installed.pyttsx3 path when installed. If
synthesis fails the text answer is still returned, with the reason in
degraded.tts_error.Assamese has no gTTS voice; the closest available voice is used and the substitution is stated in the response rather than passed off silently.
app/services/weather.py normalises provider output into a provider-agnostic
shape before anything else sees it. Pointing at a GFS/WRF feed from an IMD or
NOAA mirror means writing one new provider class — the routes, the risk engine
and the frontend are untouched. The Open-Meteo endpoints are already
environment-overridable for a drop-in mirror.