| """ |
| Curated knowledge base for the heat alert explanation RAG system. |
| |
| Contains real guidance from WHO, ILO, and East African occupational |
| health authorities, adapted for extreme heat contexts in Nairobi, |
| Dar es Salaam, Kampala, and Kigali. |
| """ |
|
|
| from __future__ import annotations |
|
|
| from typing import Dict, List |
|
|
|
|
| |
|
|
| HEAT_SAFETY_GUIDANCE: list[str] = [ |
| |
| "Drink water every 15-20 minutes even if you are not thirsty. " |
| "Do not wait until you feel thirsty — by then you are already dehydrated.", |
|
|
| "Carry at least 1 litre of clean water for every 2 hours of outdoor work. " |
| "Avoid alcohol, strong tea, and sugary drinks which increase dehydration.", |
|
|
| "Add a pinch of salt and sugar to drinking water to replace minerals " |
| "lost through sweating (oral rehydration solution).", |
|
|
| |
| "Take a 10-minute rest break in shade every 45 minutes when temperature " |
| "exceeds 35C. In extreme heat above 37C, rest 15 minutes every 30 minutes.", |
|
|
| "Schedule heavy physical work (carrying, digging, construction) for early " |
| "morning (before 10am) or late afternoon (after 4pm). Avoid peak heat hours.", |
|
|
| "If possible, rotate between outdoor and indoor tasks throughout the day " |
| "to reduce cumulative heat exposure.", |
|
|
| |
| "Wear loose, light-colored clothing that covers the skin. A wide-brimmed " |
| "hat or head covering protects against direct sun and reduces heat stroke risk.", |
|
|
| "Work in shade whenever possible. If shade is not available, create " |
| "temporary shade using tarps, umbrellas, or fabric canopies.", |
|
|
| |
| "DANGER SIGNS — seek medical help immediately if someone shows: confusion " |
| "or strange behavior, inability to sweat despite heat, hot dry red skin, " |
| "seizures, unconsciousness, or body temperature above 40C.", |
|
|
| "If a co-worker collapses from heat: move them to shade immediately, pour " |
| "cool water over their body, fan them, and call for emergency help. Do not " |
| "give water to an unconscious person.", |
|
|
| |
| "Employers should implement a heat action plan: shift start times earlier, " |
| "provide free drinking water stations, and designate shaded rest areas.", |
|
|
| "New workers and those returning after absence are at higher risk during " |
| "the first 1-2 weeks. Gradually increase workload over 7-14 days " |
| "(heat acclimatization).", |
| ] |
|
|
|
|
| |
|
|
| ZONE_HEAT_CONTEXT: Dict[str, str] = { |
| |
| "NBO-KIB": ( |
| "Kibera's informal structures have corrugated tin roofs that absorb and " |
| "re-radiate solar heat, creating indoor temperatures 10-15C above ambient. " |
| "Most workers are outdoor traders, jua kali artisans, and transport workers. " |
| "The zone's elevation (1720m) keeps ambient temperatures moderate, but the " |
| "urban heat island effect is significant in the densely packed settlement." |
| ), |
| "NBO-EAS": ( |
| "Eastleigh is a busy commercial district with thousands of street vendors " |
| "and market porters working outdoors on concrete and asphalt surfaces. " |
| "Heat radiating from buildings and pavement raises effective temperature. " |
| "Nairobi's highland climate provides some relief, but midday temperatures " |
| "during the dry season (Jan-Mar) can reach 28-30C." |
| ), |
| "NBO-MAT": ( |
| "Mathare valley traps heat due to its low-lying topography and dense " |
| "settlement. Air circulation is poor between tightly packed structures. " |
| "Many residents work as construction laborers, scrap collectors, and " |
| "informal transport operators — all with high outdoor exposure." |
| ), |
| "NBO-SBC": ( |
| "South B/C is a formal residential area where most workers commute to " |
| "indoor offices. Heat risk is lower but still affects outdoor guards, " |
| "gardeners, and maintenance workers during peak afternoon hours." |
| ), |
| "NBO-WES": ( |
| "Westlands commercial district has air-conditioned offices and shopping " |
| "centers. Heat risk is minimal for most workers but affects outdoor " |
| "security guards, construction crews, and delivery riders." |
| ), |
| "NBO-KAN": ( |
| "Kangemi has a large population of jua kali (literally 'fierce sun') " |
| "artisans — welders, carpenters, and mechanics who work outdoors with " |
| "heat-generating equipment. Combined with ambient heat, occupational " |
| "heat exposure can be significant." |
| ), |
|
|
| |
| "DAR-JAN": ( |
| "Jangwani is Dar es Salaam's most heat-vulnerable zone. Located at sea " |
| "level in an informal settlement with minimal shade and tin roofing, " |
| "ground-level temperatures regularly exceed 40C during hot months. " |
| "Humidity of 75-85% pushes WBGT into dangerous territory. Most workers " |
| "are outdoor laborers, market vendors, and waste collectors." |
| ), |
| "DAR-MSA": ( |
| "Msasani has a large fish market and coastal trading area where workers " |
| "are exposed to direct sun reflected off the ocean surface. Coastal " |
| "humidity compounds heat stress. Salt processing and fish drying are " |
| "outdoor occupations with extended sun exposure." |
| ), |
| "DAR-KIN": ( |
| "Kinondoni is more mixed with some tree cover, but humidity remains " |
| "consistently high (75-85%). Street vendors and bodaboda riders face " |
| "extended outdoor exposure. The concrete urban surface amplifies heat." |
| ), |
| "DAR-TEM": ( |
| "Temeke is Dar es Salaam's industrial zone. Port workers, construction " |
| "crews, and factory workers in poorly ventilated structures face extreme " |
| "heat exposure. Heavy physical labor combined with high humidity creates " |
| "the city's highest occupational heat stress." |
| ), |
| "DAR-KIG": ( |
| "Kigamboni peninsula has fishing, salt panning, and coastal construction " |
| "as primary outdoor occupations. Workers face combined heat from direct " |
| "sun, sea surface reflection, and high humidity. Limited shade on the " |
| "exposed peninsula." |
| ), |
|
|
| |
| "KLA-BWA": ( |
| "Bwaise is built on former wetland, creating humid conditions even by " |
| "Kampala standards. The low-lying settlement traps heat, and the high " |
| "water table increases humidity. Market traders and small manufacturers " |
| "work outdoors in congested conditions with poor air circulation." |
| ), |
| "KLA-NAT": ( |
| "Natete market area has high concentrations of outdoor workers — porters, " |
| "vendors, and boda-boda riders. Concrete market surfaces store and " |
| "re-radiate heat. Lake Victoria moderates temperatures but also " |
| "maintains high humidity." |
| ), |
| "KLA-NAK": ( |
| "Nakivubo commercial corridor includes the main taxi park where drivers " |
| "and conductors wait outdoors for extended periods. The concrete channel " |
| "and surrounding paved areas create a heat sink." |
| ), |
| "KLA-LUB": ( |
| "Lubaga is on higher ground with some hilltop breezes that provide relief. " |
| "Heat risk is moderate, mainly affecting construction workers and " |
| "outdoor service providers." |
| ), |
| "KLA-MAK": ( |
| "Makindye is elevated and has better tree cover than lower-lying areas. " |
| "Heat risk is lower, but outdoor security guards and gardeners in the " |
| "residential area still face extended exposure." |
| ), |
|
|
| |
| "KGL-NYA": ( |
| "Nyabugogo valley traps heat despite Kigali's highland elevation. The bus " |
| "terminal and surrounding market create a hot, congested environment. " |
| "Workers loading and unloading vehicles face combined heat stress from " |
| "sun exposure and vehicle exhaust." |
| ), |
| "KGL-KIC": ( |
| "Kicukiro is a growing residential area with moderate heat exposure. " |
| "Construction workers on new building sites are the primary at-risk group. " |
| "Kigali's elevation (1520m) keeps temperatures manageable most of the year." |
| ), |
| "KGL-GAS": ( |
| "Gasabo is the administrative district on higher ground. Air-conditioned " |
| "offices keep most workers comfortable. Outdoor workers (guards, cleaners, " |
| "construction) face moderate heat during dry season peaks." |
| ), |
| "KGL-NYM": ( |
| "Nyamirambo is a dense residential hillside neighborhood. Market traders " |
| "and informal workers face heat stress during the dry season, particularly " |
| "in the lower, more sheltered areas where air circulation is limited." |
| ), |
| } |
|
|
|
|
| |
|
|
| INSURANCE_PRODUCT_INFO: str = ( |
| "This is a parametric heat insurance product for outdoor workers in East Africa. " |
| "Unlike traditional insurance, payouts are triggered automatically when heat " |
| "conditions exceed pre-defined thresholds — there is no need to file a claim.\n\n" |
| "How it works:\n" |
| "1. We continuously monitor temperature and humidity for your work zone.\n" |
| "2. When heat conditions exceed the trigger threshold for the required number " |
| "of consecutive days, a payout is initiated automatically.\n" |
| "3. Payouts arrive via M-Pesa or mobile money within 48 hours of the trigger.\n\n" |
| "Trigger levels:\n" |
| "- WATCH: Temperature above 33C or WBGT above 28C for 1+ day. " |
| "Payout: $5 per worker. Take precautions.\n" |
| "- WARNING: Temperature above 35C or WBGT above 30C for 2+ consecutive days. " |
| "Payout: $10 per worker. Reduce outdoor work.\n" |
| "- CRITICAL: Temperature above 37C or WBGT above 32C for 3+ consecutive days. " |
| "Payout: $15 per worker. Stop outdoor work during peak hours.\n\n" |
| "Important: Parametric insurance pays based on the weather index, not on whether " |
| "you personally experienced heat illness. This means you may receive a payout " |
| "even if you felt fine (because conditions were dangerous), or you may not receive " |
| "a payout even if you felt unwell (if the index did not reach the threshold). " |
| "This gap is called 'basis risk' and we work continuously to minimize it." |
| ) |
|
|
|
|
| |
|
|
| EMERGENCY_CONTACTS: Dict[str, Dict[str, str]] = { |
| "Nairobi": { |
| "National Emergency": "999 or 112", |
| "Kenya Red Cross": "1199", |
| "Kenyatta National Hospital": "+254 20 272 6300", |
| "Kenya Meteorological Department": "+254 20 386 7880", |
| "Ambulance (St John)": "+254 20 221 0000", |
| "Police Emergency": "999", |
| }, |
| "Dar es Salaam": { |
| "Tanzania Emergency": "112 or 114", |
| "Tanzania Red Cross": "+255 22 215 0330", |
| "Muhimbili National Hospital": "+255 22 215 1599", |
| "Tanzania Meteorological Authority": "+255 22 246 0706", |
| "Ambulance": "114", |
| }, |
| "Kampala": { |
| "Uganda Emergency": "999 or 112", |
| "Uganda Red Cross": "+256 31 225 8701", |
| "Mulago National Hospital": "+256 41 425 4106", |
| "Uganda National Meteorological Authority": "+256 41 425 1798", |
| "Ambulance": "911", |
| }, |
| "Kigali": { |
| "Rwanda Emergency": "112", |
| "Rwanda Red Cross": "+250 78 830 0086", |
| "CHUK Hospital": "+250 78 830 1001", |
| "Rwanda Meteorology Agency": "+250 78 218 5230", |
| "Ambulance (SAMU)": "912", |
| }, |
| } |
|
|
|
|
| |
|
|
| SWAHILI_TERMS: Dict[str, str] = { |
| "heat": "joto", |
| "extreme heat": "joto kali", |
| "heat stroke": "kiharusi cha joto", |
| "heat stress": "msongo wa joto", |
| "temperature": "joto la hewa", |
| "humidity": "unyevunyevu", |
| "warning": "onyo", |
| "critical": "hali ya hatari", |
| "watch": "tahadhari", |
| "payout": "malipo", |
| "insurance": "bima", |
| "trigger": "kiwango cha hatari", |
| "shade": "kivuli", |
| "water": "maji", |
| "rest break": "mapumziko", |
| "dehydration": "upungufu wa maji mwilini", |
| "outdoor worker": "mfanyakazi wa nje", |
| "sun protection": "kinga ya jua", |
| "emergency": "dharura", |
| "ambulance": "gari la wagonjwa", |
| "M-Pesa": "M-Pesa", |
| "Red Cross": "Msalaba Mwekundu", |
| } |
|
|
|
|
| |
|
|
| PROTECTIVE_ACTIONS: Dict[str, list[str]] = { |
| "critical": [ |
| "STOP all outdoor work during peak heat hours (10am-4pm).", |
| "Move to shade or indoors immediately. Do not continue working in direct sun.", |
| "Drink water constantly — at least 250ml every 15 minutes.", |
| "Watch for danger signs: confusion, no sweating, hot dry skin, dizziness.", |
| "If someone collapses: move to shade, pour water on them, fan, call ambulance.", |
| "Your payout of $15 will arrive via mobile money within 48 hours.", |
| "Do not return to outdoor work until the heat alert is downgraded.", |
| ], |
| "warning": [ |
| "Reduce outdoor work to early morning (before 10am) and late afternoon (after 4pm).", |
| "Take 15-minute shade breaks every hour during outdoor work.", |
| "Drink at least 1 cup of water every 20 minutes.", |
| "Wear loose, light-colored clothing and a hat.", |
| "Your payout of $10 will arrive via mobile money within 48 hours.", |
| "Watch for heat illness signs in yourself and co-workers.", |
| "Set up shade structures if working outdoors is unavoidable.", |
| ], |
| "watch": [ |
| "Stay alert — heat conditions are developing.", |
| "Increase water intake beyond normal levels.", |
| "Plan your heavy work for cooler hours of the day.", |
| "Ensure shade and water are available at your work site.", |
| "Your payout of $5 will arrive via mobile money within 48 hours.", |
| ], |
| } |
|
|
|
|
| |
|
|
| def get_zone_context(zone_id: str) -> str: |
| """Assemble full knowledge base context for a zone. |
| |
| Returns a single text block suitable for injection into a Claude prompt. |
| """ |
| parts: list[str] = [] |
|
|
| |
| context = ZONE_HEAT_CONTEXT.get(zone_id, "No heat vulnerability data available for this zone.") |
| parts.append(f"ZONE HEAT VULNERABILITY:\n{context}") |
|
|
| |
| parts.append(f"INSURANCE PRODUCT:\n{INSURANCE_PRODUCT_INFO}") |
|
|
| |
| safety_text = "\n".join(f"- {s}" for s in HEAT_SAFETY_GUIDANCE[:8]) |
| parts.append(f"HEAT SAFETY GUIDANCE (WHO/ILO):\n{safety_text}") |
|
|
| return "\n\n---\n\n".join(parts) |
|
|
|
|
| def get_emergency_contacts(city: str) -> Dict[str, str]: |
| """Get emergency contacts for a city.""" |
| return EMERGENCY_CONTACTS.get(city, EMERGENCY_CONTACTS.get("Nairobi", {})) |
|
|
|
|
| def get_protective_actions(trigger_level: str) -> list[str]: |
| """Get recommended protective actions for a trigger level.""" |
| return PROTECTIVE_ACTIONS.get(trigger_level, PROTECTIVE_ACTIONS["watch"]) |
|
|