Spaces:
Sleeping
Sleeping
| title: AgroSense | |
| emoji: π± | |
| colorFrom: green | |
| colorTo: yellow | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| short_description: Offline-first AI farming advisor for India | |
| # π± AgroSense β RAG-Based Agriculture Farming Advisor | |
| A working implementation of the **AgroSense** concept from the project report: a | |
| Retrieval-Augmented Generation (RAG) advisor that answers farmer questions with | |
| **grounded, cited** guidance drawn from an agriculture knowledge base. | |
| This is the **Phase 1 MVP** (text interface, offline) β built as a full stack: | |
| ``` | |
| Knowledge Base (JSON) -> Embeddings -> Vector Store -> Retrieve + Re-rank -> Grounded Generation (cited) | |
| | | |
| Modern Web App (SPA) / Streamlit UI / CLI <---- FastAPI <---- RAGEngine | |
| ``` | |
| ## π₯οΈ Modern web app | |
| A responsive single-page dashboard (no build step β modern HTML/CSS/vanilla JS in | |
| [web/](web/)) is **served by FastAPI itself**. Start the API and open it: | |
| ```powershell | |
| uvicorn api.main:app --reload # then open: | |
| # http://127.0.0.1:8000/ui/ (the web app) | |
| # http://127.0.0.1:8000/docs (API docs) | |
| ``` | |
| It covers every feature via the API: the date/calendar/IST header, news + commodities | |
| tickers, the advisor chat with a **speaking avatar** ("AgroBot" β an animated SVG | |
| mascot that reads answers aloud via the browser's Web Speech API, keyless and | |
| multilingual, with an Auto-speak toggle), a **Location intel** dashboard (weather Β· satellite Β· NDVI Β· | |
| environment Β· sky Β· hazards Β· advisories), market prices, and the **Plant clinic** β | |
| AI image diagnosis + telemedicine that escalates to a **live verified plant doctor** | |
| (expert routing, video room, chat) in one tab. | |
| There is also a polished **marketing landing page** (the campaign destination) at | |
| **`/landing`** ([web/landing/index.html](web/landing/index.html)) β hero, features, | |
| how-it-works, audience segments, CTAs into the app, and the downloadable campaign kit. | |
| A headless render test lives at [web/smoke.mjs](web/smoke.mjs) (`node web/smoke.mjs`, | |
| needs `npm i jsdom`). The Streamlit UI (`streamlit run ui/app.py`) and CLI remain as | |
| alternatives. | |
| ### π Documentation & marketing kit (Word + PDF, downloadable) | |
| A full set of documents is provided in **both Word and PDF**, with download links in | |
| the web app header. They live in [docs/](docs/): | |
| | Document | What it covers | | |
| | --- | --- | | |
| | **User Manual** | End-user guide to every feature/tab | | |
| | **Technical Guide** | Architecture, modules, API, config, extending, deployment, security | | |
| | **Standard Operating Procedure (SOP)** | Operational runbook: start/stop, monitoring, KB + doctor admin, incident response, backup/recovery | | |
| | **Go-to-Market & Monetization Plan (India)** | Freemium tiers, pricing, monetization streams, 3-year financial projection, unit economics, GTM strategy | | |
| | **Instagram Campaign** | Reels/storyboards, voiceover + audio direction, captions, hashtags | | |
| | **Facebook Campaign** | Page, Groups, Meta Ads + Lead Ads, ad copy | | |
| | **LinkedIn (B2B) Campaign** | FPOs, agri-input partners, investors, enterprise/API | | |
| | **30-Day Content Calendar** | Post-launch monthly plan with recurring series | | |
| Served at `GET /downloads/{user-manual|technical-guide|sop|gtm-plan|instagram-campaign|` | |
| `facebook-campaign|linkedin-campaign|content-calendar}.{pdf|docx}`. All share a | |
| renderer ([scripts/docgen.py](scripts/docgen.py)) so the two formats never drift. | |
| **Regenerate everything with one command:** | |
| ```powershell | |
| pip install python-docx fpdf2 | |
| python scripts/build_docs.py | |
| ``` | |
| ### βοΈ Admin β configure the knowledge base | |
| The web app has an **Admin** tab to add / edit / delete knowledge-base entries. Saving | |
| persists to [data/knowledge_base.json](data/knowledge_base.json) and **rebuilds the | |
| live vector index**, so new guidance is retrievable immediately. Admin endpoints are | |
| token-gated (`X-Admin-Token` header): | |
| ``` | |
| GET /admin/kb Β· POST /admin/kb Β· PUT /admin/kb/{id} Β· DELETE /admin/kb/{id} | |
| ``` | |
| Set the token with `AGROSENSE_ADMIN_TOKEN` (defaults to `admin` for the local POC β | |
| **change it** for any shared deployment). Logic lives in | |
| [agrosense/kb_admin.py](agrosense/kb_admin.py); validation requires at least `crop` | |
| and `source`. | |
| ### Live local weather (optional, no API key) | |
| Provide a **location** and AgroSense attaches a real-time forecast + farming | |
| advisory from **[Open-Meteo](https://open-meteo.com/)** (free, **no API key**), | |
| implementing the report's Data Layer "dynamic (weather) data" source: | |
| ```powershell | |
| python cli.py --location Belagavi "I grow cotton on black soil β fertilizer and pest steps?" | |
| ``` | |
| The advisory is computed strictly from the forecast numbers (e.g. *"rain likely on | |
| 2026-05-30 β postpone foliar sprays and nitrogen top-dressing to avoid wash-off"*), | |
| so it stays as trustworthy as the KB-grounded advice. If there's no internet (or the | |
| place can't be resolved), weather is silently skipped and the KB answer is unaffected. | |
| ### Satellite monitoring (optional, no API key) | |
| Provide a location and AgroSense pulls **real satellite monitoring** from two free, | |
| keyless NASA sources: | |
| - **NASA GIBS** β MODIS **true-color** and **NDVI** (vegetation greenness) imagery | |
| for your area's bounding box, plus a one-click NASA Worldview link. | |
| - **NASA POWER** β satellite-derived **agroclimate** (solar radiation, temperature, | |
| rainfall) for the point, with number-grounded notes (e.g. *"ample solar radiation | |
| β good for growth"*, *"very little rainfall β check soil moisture"*). | |
| ```powershell | |
| python cli.py --location Belagavi --satellite "How is my paddy field doing?" | |
| ``` | |
| In the UI, set a location and tick **π°οΈ Show satellite monitoring** to see the | |
| imagery and agroclimate panel. | |
| ### Field-level numeric NDVI (optional, Google Earth Engine) | |
| For a true **per-field Sentinel-2 (~10 m) NDVI time series** β latest value, mean, | |
| trend, and a health status (`healthy/dense` Β· `moderate` Β· `sparse/stressed`) β | |
| AgroSense integrates **Google Earth Engine**. It is fully optional and **credential- | |
| gated**: with no credentials the app silently uses MODIS NDVI imagery + POWER | |
| agroclimate instead (see [agrosense/ndvi.py](agrosense/ndvi.py)). | |
| **Enable it:** | |
| ```powershell | |
| pip install earthengine-api | |
| # Option A β user / default credentials (after a one-time browser auth): | |
| earthengine authenticate | |
| $env:AGROSENSE_EE_PROJECT = "your-gcp-project-id" | |
| # Option B β service account (for servers / CI, no browser): | |
| $env:AGROSENSE_EE_SERVICE_ACCOUNT = "agro@your-project.iam.gserviceaccount.com" | |
| $env:AGROSENSE_EE_KEY_FILE = "C:\path\to\service-account-key.json" | |
| $env:AGROSENSE_EE_PROJECT = "your-gcp-project-id" | |
| ``` | |
| Then any satellite request (UI checkbox, `--satellite`, or `GET /satellite`) adds a | |
| `numeric_ndvi` block with the time series, trend, and number-grounded notes (e.g. | |
| *"NDVI is trending down β investigate for stress, senescence, or recent harvest"*). | |
| Tunables: `AGROSENSE_NDVI_DAYS` (60), `AGROSENSE_NDVI_BUFFER_M` (100 m field radius), | |
| `AGROSENSE_NDVI_MAX_CLOUD` (40%). The architecture is provider-agnostic β swap in | |
| Sentinel Hub by adding a sibling provider in [agrosense/ndvi.py](agrosense/ndvi.py). | |
| Cloud handling is two-layer: scenes are filtered by `CLOUDY_PIXEL_PERCENTAGE`, **and** | |
| clouds/shadows/cirrus/snow are masked **per pixel** via the Sentinel-2 SCL band | |
| (`build_scl_mask`), so cloud over the field can't skew the field-mean NDVI. | |
| ### Location environment profile | |
| Display a full environment readout for a place or lat/lon β **keyless** (Open-Meteo): | |
| | Field | Source | Notes | | |
| | --- | --- | --- | | |
| | Longitude, Latitude | geocoding | | | |
| | Altitude (sea level) | geocoding / elevation API | metres | | |
| | Local population | geocoding | of the resolved place | | |
| | Humidity | forecast `current` | % | | |
| | Sunlight | forecast | sunshine hours/day, UV-index max, live solar W/mΒ² | | |
| | Wind speed & direction | forecast `current` | km/h + 16-point compass | | |
| | Air quality | Air Quality API | US/EU AQI, PM2.5, PM10, ozone + category | | |
| | Pollen | Air Quality API | **Europe-only (CAMS)** β shows "not available for this region" elsewhere | | |
| | Ground water level | CGWB / data.gov.in (keyed) | real nearest-well water-table depth when `AGROSENSE_GROUNDWATER_RESOURCE` + `AGROSENSE_DATAGOV_API_KEY` are set ([agrosense/groundwater.py](agrosense/groundwater.py)); otherwise a labelled **soil-moisture proxy** (3β9 cm) | | |
| ```powershell | |
| python cli.py --location Belagavi --environment "..." | |
| ``` | |
| Endpoint: `GET /environment?location=β¦` or `?latitude=β¦&longitude=β¦`. UI: tick | |
| **π Show location environment**. See [agrosense/environment.py](agrosense/environment.py). | |
| **Real ground-water level (optional):** set a CGWB "depth to water level" resource id | |
| and a data.gov.in key to replace the proxy with an actual nearest-observation-well | |
| water-table depth: | |
| ```powershell | |
| $env:AGROSENSE_DATAGOV_API_KEY = "your-data.gov.in-key" | |
| $env:AGROSENSE_GROUNDWATER_RESOURCE = "<cgwb-resource-id>" | |
| $env:AGROSENSE_GROUNDWATER_STATE = "Karnataka" # optional server-side filter | |
| ``` | |
| The nearest-well geometry (haversine + parsing) is unit-tested; the live fetch is | |
| mock-tested. **Caveat:** CGWB data is station-based and ~quarterly (not real-time), | |
| and resource field names vary β confirm your resource's schema (see | |
| [agrosense/groundwater.py](agrosense/groundwater.py)). | |
| ### Natural-hazard events & active fires (NASA EONET + FIRMS) | |
| Shows natural-hazard events and active fires near the location: | |
| - **NASA EONET** β **keyless** open natural events (wildfires, severe storms, floods, | |
| drought, dust/hazeβ¦) filtered to a radius of the farm and sorted by distance. | |
| - **NASA FIRMS** β active fire / thermal anomalies (VIIRS/MODIS); needs a **free | |
| map-key** (`AGROSENSE_FIRMS_MAP_KEY`) β shows "set key to enable" otherwise. | |
| UI: tick **β οΈ Show hazards & fires**. `GET /hazards?location=β¦` (or lat/lon). | |
| See [agrosense/hazards.py](agrosense/hazards.py). | |
| ### Plant-disease, plant-ID & pest vision | |
| Upload a leaf/plant/insect photo (UI: **πΏ Plant image diagnosis**, or | |
| `POST /vision/classify?task=all`) to get three classifications β **disease/health**, | |
| **plant ID**, and **pest ID**: | |
| - With trained models configured (`AGROSENSE_VISION_DISEASE_MODEL` / `_PLANT_MODEL` / | |
| `_PEST_MODEL`) and TensorFlow installed, real CNN inference runs. | |
| - Without them, an **honest Pillow colour heuristic** gives a leaf-health indication | |
| (clearly labelled "not a diagnosis"); plant-ID and pest-ID report that a trained | |
| model is required. See [agrosense/vision.py](agrosense/vision.py). | |
| **Train the models** (needs TensorFlow + datasets β run outside this sandbox) with | |
| [scripts/train_plant_models.py](scripts/train_plant_models.py): | |
| - **disease** β PlantVillage (~54k images, 38 classes) | |
| - **plant** β any per-class leaf/plant folder dataset (Flavia, Oxford-102β¦) | |
| - **pest** β **IP102** (~75k images, 102 crop-pest classes) or the Kaggle | |
| "Agricultural Pests Image Dataset" (12 classes) | |
| Point the env vars at the resulting `.keras` + labels files to activate real inference. | |
| > Note: this Python 3.14 POC has Pillow + numpy but **not** TensorFlow/ONNX, so only | |
| > the heuristic path runs here; the model backend activates wherever TF is available. | |
| ### Plant telemedicine (diagnosis β prescription) | |
| A clinician-style consult that fuses the image diagnosis (disease/pest vision) + | |
| symptom intake + the KB's treatment fields + weather-aware timing into a structured | |
| **diagnosis β health assessment β prescription β follow-up**: | |
| - Intake: crop, free-text symptoms, optional leaf photo, location. | |
| - Assessment: diagnosis (from image and/or symptom keywords), health status, severity. | |
| - **Diagnosis-driven prescription**: a recognized disease/pest **class** β from the | |
| vision model's predicted label (e.g. PlantVillage `Tomato___Late_blight`) or from | |
| symptom text that names the condition β is mapped to a **targeted IPM prescription** | |
| via [agrosense/ipm.py](agrosense/ipm.py) + [data/ipm_prescriptions.json](data/ipm_prescriptions.json) | |
| (e.g. *"Late blight β spray Mancozeb 0.25%β¦"*). This specific treatment is listed | |
| first, then the crop's KB-grounded steps follow. | |
| - **Prescription**: treatment + nutrition + cultural/IPM steps composed **only** from | |
| the IPM lookup and retrieved KB fields (dosages verbatim, every line cited) β never invented. | |
| - Weather-aware timing (e.g. "rain likely β postpone foliar sprays") + a clear | |
| **safety disclaimer** (decision support, not a substitute for an expert). | |
| UI: sidebar **π©Ί Plant telemedicine** (crop + symptoms + the uploaded photo) β | |
| consultation card. `POST /telemedicine` (multipart: crop/symptoms/location + optional | |
| image). See [agrosense/telemedicine.py](agrosense/telemedicine.py). | |
| ### Farmers' digital clubs | |
| **Location-wise** and **commodity-wise** farmer communities (π₯ Clubs tab). Browse/filter | |
| clubs by location or commodity, **create** a club, **join**, post to a **discussion feed** | |
| and **share information/links**, and start a **live video meeting** (Jitsi room per club, | |
| keyless). Each club has members, a feed, and its own meeting room. Seeded with starter | |
| clubs (Karnataka/Maharashtra; Tomato/Cotton/Coffee/Paddy). API: `GET/POST /clubs`, | |
| `GET /clubs/{id}`, `POST /clubs/{id}/join`, `POST /clubs/{id}/post`. See | |
| [agrosense/clubs.py](agrosense/clubs.py) (persisted to `data/clubs.json`). | |
| ### Live agri-doctor consultation | |
| Escalate from the AI consult to a **human expert**: a consultation request is **routed | |
| to a matching available expert** (pest β entomologist, disease β pathologist, etc., | |
| honoring language), attaches the **AI telemedicine consult as context**, and opens a | |
| **live video room** (Jitsi, keyless) plus an in-app **chat thread**. | |
| UI: sidebar **π¨ββοΈ Live agri-doctor** (name + channel + language) β session card with | |
| the assigned expert, a *Join live video room* button, and chat. API: `GET /experts`, | |
| `POST /consult/request`, `GET /consult/{id}`, `POST /consult/{id}/message`. See | |
| [agrosense/consultation.py](agrosense/consultation.py) + [data/agri_experts.json](data/agri_experts.json). | |
| **Onboarding & verification:** anyone can **apply to become a plant doctor** | |
| (`POST /doctors/apply`, status `pending`); an **admin verifies** them | |
| (`POST /admin/doctors/{id}/verify`, token-gated) β and only **verified** doctors enter | |
| the consultation directory (`GET /experts`) and can be routed live consults. | |
| Applications require name, specialization, region, contact, languages, credentials, | |
| and a format-checked **ICAR / registration number**; routing tags are derived from the | |
| specialization. | |
| **Profiles & ratings:** each verified doctor has a public **profile page** | |
| (`GET /doctors/{id}`) showing specialization, region, languages, registration number, | |
| and an aggregate **star rating** with recent reviews; farmers rate a doctor | |
| (`POST /doctors/{id}/rate`, 1-5 stars + comment). Ratings show in the directory and on | |
| the profile. The web app has an *Apply as a plant doctor* form + *View profile* with a | |
| rating widget (in the Plant clinic tab's live-doctor section) and a *Plant doctor | |
| verification* panel (Admin tab). | |
| Backed by [agrosense/doctors.py](agrosense/doctors.py) (`data/plant_doctors.json`, | |
| seeded from [data/agri_experts.json](data/agri_experts.json)). | |
| **Expert notifications:** when a consult is routed, the assigned expert is notified β | |
| always recorded in an in-app **audit log** (`GET /notifications`), and, when | |
| configured, delivered via **webhook** (`AGROSENSE_NOTIFY_WEBHOOK` β Slack/Discord/ | |
| Zapier/custom, keyless) and/or **email** (`AGROSENSE_NOTIFY_EMAIL_TO` + SMTP env). See | |
| [agrosense/notifications.py](agrosense/notifications.py). | |
| > Honest scope: the experts are **demo/seed entries** β there are no real practitioners | |
| > on the other end in the POC. Connecting real experts means populating the directory | |
| > with availability + contact, and they'll be alerted via the notification channels | |
| > above; the video room, chat, and notifications are functional. The default Jitsi room | |
| > (meet.jit.si) may ask the first joiner to sign in as moderator β set | |
| > `AGROSENSE_VIDEO_BASE` to a self-hosted Jitsi for production. | |
| ### Traditional Advisor (traditional knowledge + Panchang) | |
| A **πͺ Traditional** advisor for daily farm activities that combines **Indian | |
| traditional/desi practices** with **Panchang (astrological) guidance**. For an activity | |
| (sowing, transplanting, harvesting, pest control, β¦) it gives: | |
| - an **astrological suitability** verdict from today's Panchang β favourable nakshatras | |
| for sowing, waxing vs waning moon (Shukla/Krishna paksha), Vishti (Bhadra) karana and | |
| Amavasya/Rikta-tithi cautions β with the reasons, and | |
| - relevant **traditional practices** (Beejamrit, Jeevamrit, lunar/nakshatra sowing, neem | |
| & panchagavya pest control, mixed croppingβ¦), **matched to the area/region**. | |
| `GET /traditional?activity=β¦&location=β¦` (keyless). See | |
| [agrosense/traditional.py](agrosense/traditional.py) + | |
| [data/traditional_knowledge.json](data/traditional_knowledge.json). | |
| ### Finance β bank assistance + government schemes & subsidies | |
| A single **π¦ Finance** tab combines two things a farmer needs money-wise: | |
| **Bank assistance & agri-loans.** A curated catalog of agri-credit products β KCC and | |
| crop/production loans, term/investment loans, farm-mechanization, allied | |
| (dairy/AH/fisheries), agri gold loans, warehouse-receipt finance, FPO & SHG credit, the | |
| Agriculture Infrastructure Fund, solar-pump (PM-KUSUM) and horticulture loans. Each lists | |
| **provider, interest, loan amount, tenure, benefits, eligibility, step-by-step application | |
| process, documents, portal and helpline**. Browse/filter by **category** or search, then | |
| **lodge a loan enquiry** (name + contact + requested amount) β applications are recorded | |
| and visible to an admin in the βοΈ Admin tab (`GET /admin/finance/applications`, | |
| token-gated). API: `GET /finance?category=&provider=&search=`, `GET /finance/{id}`, | |
| `POST /finance/{id}/apply`. See [agrosense/finance.py](agrosense/finance.py) + | |
| [data/finance.json](data/finance.json) (enquiries persist to the gitignored runtime | |
| `data/finance_applications.json`). | |
| **Government schemes & subsidies.** Central and state agricultural schemes with the full | |
| publication for each β **summary, benefits, eligibility, step-by-step application | |
| process, documents required, official portal, helpline** β plus an | |
| **announcements/updates** feed. Browse and filter by **level** (Central / State), | |
| **state** (the sidebar Location surfaces schemes that apply to you β central schemes | |
| always show), **category**, or free-text **search**; open any scheme for its full detail, | |
| and see a **latest-announcements** feed aggregated across all schemes (newest first). | |
| Seeded with 13 schemes β 10 central (PM-KISAN, PMFBY, KCC, PMKSY, Soil Health Card, SMAM, | |
| PKVY, eNAM, AIF, PM-KMY) and 3 state (Krishi Bhagya/Karnataka, Rythu Bandhu/Telangana, | |
| Magel Tyala Shettale/Maharashtra). Admins can **append updates** to a scheme | |
| (`POST /admin/subsidies/{id}/update`, token-gated). API: | |
| `GET /subsidies?level=&state=&category=&search=`, `GET /subsidies/{id}`, | |
| `GET /subsidies/updates`. See [agrosense/subsidies.py](agrosense/subsidies.py) + | |
| [data/subsidies.json](data/subsidies.json). | |
| > Honest scope: both are **curated knowledge bases** (no reliable keyless live | |
| > scheme/loan-rate feed exists). Interest rates, scheme amounts and rules are set by | |
| > RBI/NABARD/banks and governments and change over time; **"apply" lodges an enquiry in | |
| > AgroSense, not a bank/portal submission**. Each view carries a disclaimer to verify and | |
| > apply through the bank or official portal. | |
| ### Land record search & documents | |
| A **πΊοΈ Land records** tab to find your **State's official land-record system** and take | |
| the exact steps to view/download your record. Land is a State subject, so the tab is a | |
| **searchable directory** (15 states + an all-India fallback) giving, per state: the local | |
| **record name** (RTC/Pahani, 7/12 Saatbara, Khatauni, Jamabandi, Patta/Chitta, β¦), the | |
| official **portal** and **cadastral-map (Bhu-Naksha)** portal, **what to search by** | |
| (district, taluk/tehsil, village, survey/khasra/khata number), **step-by-step** search & | |
| download instructions, what the record **contains**, and the helpline. The sidebar | |
| **Location** is geocoded to its state (or pick a state explicitly). You can also | |
| **download a printable guide** (Word/PDF) for that state, generated on the fly. | |
| API: `GET /land-records?location=&state=`, `GET /land-records/guide.{pdf|docx}?location=&state=`. | |
| See [agrosense/land_records.py](agrosense/land_records.py) + | |
| [data/land_records.json](data/land_records.json) (PDF/Word via the shared | |
| [scripts/docgen.py](scripts/docgen.py) renderer). | |
| > Honest scope: AgroSense **does not fetch or store your actual land record** β those | |
| > live on each State's portal, usually behind a login/OTP/fee. This feature helps you | |
| > **find and download yours from the official source**; always rely on the State portal's | |
| > copy. | |
| > This is cultural, belief-based knowledge offered as **complementary to β not a | |
| > replacement for β scientific agronomy**, soil tests and local conditions. The | |
| > nakshatra/yoga rely on an approximate ayanamsa (see the Panchang note above). | |
| ### Decision-fusion advisories | |
| Fuse the live signals β **weather forecast + satellite agroclimate (NASA POWER) + | |
| field NDVI** β into **prioritized, cross-signal, actionable** advisories that no | |
| single source can give (e.g. *"NDVI trending down while rain is forecast β inspect | |
| drainage and scout disease"*). Works by place name **or** latitude/longitude: | |
| ```powershell | |
| python cli.py --location Belagavi --advisories "advice for my cotton field?" | |
| ``` | |
| Advisories are tagged by urgency (high/medium/low) and category (irrigation, spray, | |
| disease, protection, monitoring), each with the **rationale** (which signals drove | |
| it). The rule set lives in [agrosense/fusion.py](agrosense/fusion.py) as a pure | |
| function over the fetched signals, so it is fully unit-tested. | |
| **Crop- and stage-aware:** pass a `crop` and growth `stage` | |
| (seedling/vegetative/flowering/maturity) and the thresholds + urgencies adapt per | |
| [agrosense/crop_profiles.py](agrosense/crop_profiles.py) β e.g. tomato flags heat at | |
| 32Β°C while cotton tolerates 40Β°C, flowering/seedling stages escalate stress | |
| advisories, and rain near *maturity* raises a harvest-quality warning. | |
| ```powershell | |
| python cli.py --location Belagavi --advisories --stage flowering "advice for my tomato?" | |
| ``` | |
| Endpoint: `GET /advisories?location=β¦&crop=Tomato&stage=flowering` (or `latitude`/`longitude`). | |
| ### Planetary positions | |
| Show the **Sun, Moon (with phase) and classical planets** (MercuryβSaturn) for the | |
| location at the current time β altitude/azimuth, RA/Dec, and what's above the | |
| horizon β useful for sky context and traditional/Panchang-style scheduling. | |
| ```powershell | |
| python cli.py --location Belagavi --planets "..." | |
| ``` | |
| Computed locally with a pure-Python ephemeris (Schlyter's algorithm) β **keyless, | |
| offline, no dependencies** ([agrosense/planetary.py](agrosense/planetary.py)), | |
| validated in tests against known astronomy (solar declination β +23.4Β° at the June | |
| solstice). Endpoint: `GET /planetary?location=β¦` or `?latitude=β¦&longitude=β¦`. | |
| ### Multilingual answers (Phase 2) | |
| Ask in β or get answers in β the report's Phase 2 languages (Hindi, Kannada, | |
| Telugu, Tamil, Marathi, Bengali, Malayalam, Gujarati, Punjabi). The query is | |
| translated to English for retrieval and the grounded answer is translated back: | |
| ```powershell | |
| python cli.py --lang hi "What fertilizer should I use for maize?" | |
| ``` | |
| Backends (auto-selected, optional): **argostranslate** (fully offline) β **deep- | |
| translator** (online, no key) β identity (English passthrough). If no backend is | |
| installed, the answer simply stays English and the UI/CLI says so. See | |
| [agrosense/translation.py](agrosense/translation.py). | |
| ### Real-time market prices (closes the report's last pain point) | |
| Attach live mandi (Agmarknet) prices for the crop in a question β min/max/modal | |
| βΉ/quintal across markets, with a "compare mandis" note when prices spread widely: | |
| ```powershell | |
| python cli.py --prices "what's the price of tomato in Karnataka?" | |
| ``` | |
| Requires a **free data.gov.in api-key** (set `AGROSENSE_DATAGOV_API_KEY`); without | |
| it, prices degrade gracefully to "unavailable". See | |
| [agrosense/prices.py](agrosense/prices.py). | |
| ### π€ Farmer trading platform (in the Market tab) | |
| A peer-to-peer **produce marketplace** inside the Market tab: farmers post **sell** | |
| offers and buyers post **buy** requirements (commodity, quantity/unit, price, grade, | |
| location/state, description). Anyone can **browse/filter** by type (sell|buy), commodity | |
| or state, **open a listing**, **express interest** (an inquiry with contact + offer + | |
| quantity), **negotiate live** in a per-listing **video room** (Jitsi, keyless), and the | |
| poster can **mark it sold/closed** (closed listings drop out of the default browse). Live | |
| mandi prices and the commodity ticker sit alongside in the same tab as a pricing | |
| reference. Seeded with demo listings on first run. | |
| API: `GET/POST /market/listings`, `GET /market/listings/{id}`, | |
| `POST /market/listings/{id}/inquire`, `POST /market/listings/{id}/close`. See | |
| [agrosense/trading.py](agrosense/trading.py) (persisted to `data/market_listings.json`, | |
| gitignored runtime state). | |
| > Honest scope: a **POC marketplace** β listings and seed buyers/sellers are | |
| > demo/user-generated; there is **no payment, escrow, KYC or logistics**. Verify the | |
| > other party and agree terms independently before transacting (the UI carries this | |
| > disclaimer). | |
| ### π» Internet radio | |
| A **Radio** tab lists online radio stations for India (Vivid Bharti, Radio Mirchi, | |
| Red FM, AIR, regional/agriculture stationsβ¦) and plays them in an in-app audio player. | |
| Keyless via the **Radio Browser** community API. `GET /radio?country=IN&search=β¦`. See | |
| [agrosense/radio.py](agrosense/radio.py). | |
| > This is **internet radio**, not over-the-air FM tuning (a browser has no RF | |
| > hardware). Many FM/AIR stations stream online so the local station is often present, | |
| > but coverage of small stations varies and some streams may be temporarily offline | |
| > (filtered with `hidebroken=true` + popularity ordering). On an HTTPS deployment, | |
| > plain `http://` streams are blocked as mixed content β prefer https streams or proxy. | |
| ### Date/time header + Reuters news ticker | |
| The UI shows a top bar with the date in the **Gregorian (English)** calendar, the | |
| **Indian National (Saka)** calendar with a mini-**Panchang** β lunar day (tithi), | |
| nakshatra shown inline (e.g. "Shukla Purnima Β· Anuradha") and the full five limbs | |
| (vaara, tithi, nakshatra, yoga, karana) in a hover tooltip, computed from the | |
| ephemeris β and the current **IST** time, plus the Google News headline ticker. | |
| - Calendar/IST logic: [agrosense/calendars.py](agrosense/calendars.py) (pure, | |
| unit-tested β the GregorianβSaka conversion is exact). Endpoint `GET /datetime`. | |
| - Headlines: [agrosense/news.py](agrosense/news.py) β Google News RSS, **keyless**, | |
| graceful empty list on failure. The UI has **region** (India/US/UK/Australia/ | |
| Canada/Singapore) and **topic** (Top stories/Agriculture/Business/Technology/ | |
| Science/Health/Sports/World) selectors above the ticker. | |
| `GET /news?region=US&query=technology&limit=15` β `region` selects the locale, | |
| `query`=None gives general top stories, or pass a topic/keyword (or a | |
| `site:reuters.com` filter for the Reuters feed). | |
| Directly below the news scroll, a **slow-scrolling commodity ticker** shows | |
| **Gold, Silver, Crude Oil, Coffee** (Yahoo Finance futures, **keyless**, with day | |
| change %) and **Arecanut, Coconut** (Agmarknet via data.gov.in β show "n/a" until a | |
| key is set). See [agrosense/commodities.py](agrosense/commodities.py); `GET /commodities`. | |
| Below that, a **local weather strip** shows current conditions for the sidebar | |
| location (temperature, humidity, today's range, rain chance, top advisory) β driven | |
| by the same Open-Meteo forecast as the rest of the app. | |
| The displayed time reflects the page render (updates on refresh/interaction). | |
| ### Evaluation harness (RAGAS-style, offline) | |
| Measure the report's accuracy targets against a gold questionβexpected-source set: | |
| ```powershell | |
| $env:AGROSENSE_EMBEDDING_BACKEND="hashing"; python scripts/evaluate.py | |
| ``` | |
| Reports context relevance, citation MRR, faithfulness, hallucination rate, answer | |
| relevance, out-of-domain accuracy, and latency p50/p95 β each checked against the | |
| report's targets (β₯95% relevance/faithfulness, <5% hallucination, β€3 s). Exits | |
| non-zero if any target is missed (CI-friendly). Metrics are pure functions | |
| ([agrosense/evaluation.py](agrosense/evaluation.py)); the gold set is | |
| [data/eval_set.json](data/eval_set.json). | |
| > On the offline hashing-embedder POC the current set passes all targets (context | |
| > relevance 100%, faithfulness 100%, hallucination 0%, p95 < 1 ms). Faithfulness is | |
| > high by construction for the extractive generator; the harness's value is catching | |
| > regressions and re-measuring once a real embedder/LLM is plugged in. | |
| ### Runs fully offline, no API keys, no internet | |
| Every heavy dependency is **optional**. Out of the box the app uses: | |
| - a deterministic **hashing embedder** (no model download), and | |
| - a **numpy** cosine-similarity vector store (no FAISS), and | |
| - an **extractive grounded generator** that composes answers *only* from retrieved | |
| KB fields and attaches citations β so it cannot hallucinate agronomic facts. | |
| If you install the optional accelerators, the same code automatically upgrades: | |
| - `pip install sentence-transformers` β better semantic embeddings | |
| - `pip install faiss-cpu` β faster vector search | |
| --- | |
| ## Quick start | |
| ```powershell | |
| # 1. (optional) create a venv, then install core deps | |
| pip install -r requirements.txt | |
| # 2a. Try it on the command line (no server needed) | |
| python cli.py "My soil is sandy, rainfall 900 mm, I plan to grow maize. What fertilizer and pest steps?" | |
| # 2b. Or run the interactive REPL | |
| python cli.py | |
| # 3. Run the API | |
| uvicorn api.main:app --reload # http://127.0.0.1:8000/docs | |
| # 4. Run the chat UI (in another terminal) | |
| streamlit run ui/app.py # http://localhost:8501 | |
| ``` | |
| The Streamlit UI calls the FastAPI backend if it's running, and otherwise falls | |
| back to running the engine in-process β so the UI works on its own too. | |
| ### Run the tests | |
| ```powershell | |
| python tests/test_rag.py # or: python -m pytest | |
| ``` | |
| --- | |
| ## How it maps to the report | |
| | Report concept | Where it lives | | |
| | --- | --- | | |
| | Data Layer / Knowledge Base (structured JSON entries) | [data/knowledge_base.json](data/knowledge_base.json), [agrosense/knowledge_base.py](agrosense/knowledge_base.py) | | |
| | Knowledge Layer (vectorized documents) | [agrosense/embeddings.py](agrosense/embeddings.py), [agrosense/vector_store.py](agrosense/vector_store.py) | | |
| | Cognitive Layer β RAG pipeline (retrieval + re-ranking + generation) | [agrosense/retriever.py](agrosense/retriever.py), [agrosense/generator.py](agrosense/generator.py), [agrosense/rag.py](agrosense/rag.py) | | |
| | Cognitive Layer β decision fusion (multi-signal advisories) | [agrosense/fusion.py](agrosense/fusion.py), [agrosense/crop_profiles.py](agrosense/crop_profiles.py) | | |
| | Cognitive Layer β traditional advisor (Panchang + desi practices) | [agrosense/traditional.py](agrosense/traditional.py) | | |
| | Data Layer β government schemes & subsidies (central + state, updates) | [agrosense/subsidies.py](agrosense/subsidies.py), [data/subsidies.json](data/subsidies.json) | | |
| | Application Layer β agri finance (bank assistance / loans + apply) | [agrosense/finance.py](agrosense/finance.py), [data/finance.json](data/finance.json) | | |
| | Data Layer β land records (state RoR portal directory + generated guide) | [agrosense/land_records.py](agrosense/land_records.py), [data/land_records.json](data/land_records.json) | | |
| | Data Layer β planetary positions | [agrosense/planetary.py](agrosense/planetary.py) (pure-Python ephemeris) | | |
| | Data Layer β hazards & fires | [agrosense/hazards.py](agrosense/hazards.py) (NASA EONET keyless + FIRMS keyed) | | |
| | Cognitive Layer β plant vision | [agrosense/vision.py](agrosense/vision.py) (disease + plant ID + pest ID; Keras backend + heuristic) | | |
| | Cognitive Layer β plant telemedicine | [agrosense/telemedicine.py](agrosense/telemedicine.py) (diagnosis + grounded, cited prescription) | | |
| | Engagement Layer β live agri-doctor | [agrosense/consultation.py](agrosense/consultation.py) (expert routing + Jitsi video + chat) | | |
| | Engagement Layer β farmers' clubs | [agrosense/clubs.py](agrosense/clubs.py) (location/commodity communities: feed + video + sharing) | | |
| | RAG Workflow steps 1β7 (intake β preprocess β retrieve β re-rank β generate β cite) | [agrosense/rag.py](agrosense/rag.py) (`RAGEngine.answer`) | | |
| | **CARO** β Context-Aware Retrieval Optimizer (metadata-weighted re-ranking) | `Retriever._rerank_score` in [agrosense/retriever.py](agrosense/retriever.py) | | |
| | Data Layer β dynamic (weather) data | [agrosense/weather.py](agrosense/weather.py) (Open-Meteo, no key) | | |
| | Data Layer β location environment | [agrosense/environment.py](agrosense/environment.py) (elevation, AQ, pollen, wind, groundwater proxy) | | |
| | Data Layer β satellite / remote sensing | [agrosense/satellite.py](agrosense/satellite.py) (NASA GIBS + POWER, no key) | | |
| | Data Layer β field-level NDVI (keyed) | [agrosense/ndvi.py](agrosense/ndvi.py) (Sentinel-2 via Google Earth Engine) | | |
| | Data Layer β market prices | [agrosense/prices.py](agrosense/prices.py) (Agmarknet via data.gov.in) | | |
| | Application Layer β farmer trading platform (P2P produce marketplace) | [agrosense/trading.py](agrosense/trading.py), `data/market_listings.json` | | |
| | Engagement Layer β multilingual | [agrosense/translation.py](agrosense/translation.py) (argos / deep-translator) | | |
| | Interaction Layer (conversational UI) | [ui/app.py](ui/app.py) | | |
| | "Use only retrieved KB data. Include citations." system prompt | `SYSTEM_PROMPT` in [agrosense/generator.py](agrosense/generator.py) | | |
| | Faithfulness / low-hallucination targets | extractive generator + relevance gate β off-domain queries get a safe fallback, never fabricated advice | | |
| | Latency β€ 3 s target | every response reports `latency_ms` (sub-millisecond on the offline backends) | | |
| ### Sample knowledge base | |
| Covers paddy, maize, wheat, cotton, plus fertilizer schedules for aromatic | |
| (mint, citronella), vegetable (tomato), fruit (banana) and flower (marigold) crops, | |
| and a general soil-health entry β modeled on the report's KB design and the Azure | |
| assistant examples shown in the document. | |
| --- | |
| ## Configuration | |
| All tunable via environment variables (see [agrosense/config.py](agrosense/config.py)): | |
| | Variable | Default | Purpose | | |
| | --- | --- | --- | | |
| | `AGROSENSE_EMBEDDING_BACKEND` | `auto` | `auto` \| `sentence-transformers` \| `hashing` | | |
| | `AGROSENSE_GENERATION_BACKEND` | `extractive` | `extractive` (offline) \| `openai` (real LLM seam) | | |
| | `AGROSENSE_TOP_K` | `5` | candidates from vector search | | |
| | `AGROSENSE_RERANK_K` | `3` | kept after re-ranking | | |
| | `AGROSENSE_KB_PATH` | `data/knowledge_base.json` | knowledge base location | | |
| | `AGROSENSE_API_URL` | `http://127.0.0.1:8000` | API URL used by the UI | | |
| ### Plugging in a real LLM (production path) | |
| `OpenAIGenerator` in [agrosense/generator.py](agrosense/generator.py) shows the seam. | |
| Set `AGROSENSE_GENERATION_BACKEND=openai`, `pip install openai`, and provide | |
| `OPENAI_API_KEY`. The same pattern adapts to Azure OpenAI (the report's `gpt-5-mini` | |
| deployment). The retrieval context and the strict "use only the provided context, | |
| cite sources" instruction are already wired in. | |
| --- | |
| ## Project layout | |
| ``` | |
| AgroSense/ | |
| βββ data/knowledge_base.json # the agriculture KB (structured JSON) | |
| βββ agrosense/ # RAG core (the reusable library) | |
| β βββ config.py # env-driven configuration | |
| β βββ embeddings.py # hashing (offline) + sentence-transformers backends | |
| β βββ knowledge_base.py # KB loading + document construction | |
| β βββ vector_store.py # numpy fallback + FAISS backend | |
| β βββ retriever.py # vector search + CARO-style re-ranking + relevance gate | |
| β βββ generator.py # extractive grounded generator (+ OpenAI seam) | |
| β βββ weather.py # live local forecast + advisory (Open-Meteo, no key) | |
| β βββ satellite.py # satellite imagery + agroclimate (NASA GIBS + POWER) | |
| β βββ ndvi.py # field-level Sentinel-2 NDVI (Google Earth Engine, keyed) | |
| β βββ translation.py # multilingual layer (argos / deep-translator / identity) | |
| β βββ prices.py # mandi market prices (Agmarknet via data.gov.in, keyed) | |
| β βββ fusion.py # decision-fusion advisories (weather + satellite + NDVI) | |
| β βββ crop_profiles.py # per-crop thresholds + growth stages (crop-aware fusion) | |
| β βββ environment.py # location environment profile (Open-Meteo, keyless) | |
| β βββ planetary.py # Sun/Moon/planet positions (pure-Python ephemeris) | |
| β βββ groundwater.py # real water-table depth (CGWB/data.gov.in, keyed) | |
| β βββ evaluation.py # RAGAS-style eval metrics (pure) + evaluate() | |
| β βββ calendars.py # Gregorian + Indian National (Saka) calendars + IST | |
| β βββ news.py # Google News headlines (region/topic, keyless) | |
| β βββ radio.py # internet radio stations (Radio Browser, keyless) | |
| β βββ commodities.py # Gold/Silver/Oil/Coffee (Yahoo) + Arecanut/Coconut (Agmarknet) | |
| β βββ hazards.py # NASA EONET events (keyless) + FIRMS fires (keyed) | |
| β βββ vision.py # plant disease + ID + pest (Keras backend + Pillow heuristic) | |
| β βββ telemedicine.py # plant consult: diagnosis + grounded, cited prescription | |
| β βββ ipm.py # recognized class -> exact IPM prescription lookup | |
| β βββ consultation.py # live agri-doctor: expert routing + video + chat | |
| β βββ doctors.py # plant-doctor onboarding + verification registry | |
| β βββ notifications.py # expert alerts: in-app log + webhook + email | |
| β βββ kb_admin.py # knowledge-base CRUD store + validation (admin) | |
| β βββ rag.py # RAGEngine: end-to-end pipeline | |
| βββ api/main.py # FastAPI: /query /weather /satellite /environment /planetary /hazards /vision/classify /telemedicine /experts /doctors/apply /doctors/{id} /doctors/{id}/rate /admin/doctors /consult/* /notifications /admin/kb /advisories /prices /news /commodities /datetime /languages | |
| βββ scripts/evaluate.py # run the evaluation harness over data/eval_set.json | |
| βββ scripts/train_plant_models.py # train the disease + plant-ID CNNs (needs TF + datasets) | |
| βββ ui/app.py # Streamlit chat UI | |
| βββ cli.py # command-line interface | |
| βββ tests/test_rag.py # offline smoke + behavior tests | |
| βββ requirements.txt | |
| ``` | |
| --- | |
| ## Limitations & next steps (toward the report's later phases) | |
| - The offline hashing embedder is lexical-ish; install `sentence-transformers` for | |
| true semantic retrieval. | |
| - The extractive generator returns KB fields verbatim with citations rather than | |
| free-form prose β swap in the LLM backend for natural-language synthesis. | |
| - Phase 2+: voice/image input, multilingual responses, live weather/market data, | |
| and IoT signals (the data layer and `RAGEngine` are structured to accept them). | |