"""Small, curated diabetes education knowledge base. The application uses deterministic keyword retrieval so the language model receives short summaries from reputable public-health sources. This is intentionally simple and transparent for a course project; it is not a clinical retrieval system. """ from __future__ import annotations from dataclasses import dataclass import re from typing import Iterable @dataclass(frozen=True) class Source: source_id: str title: str organization: str url: str summary: str keywords: tuple[str, ...] SOURCES: tuple[Source, ...] = ( Source( source_id="S1", title="What Is Diabetes?", organization="National Institute of Diabetes and Digestive and Kidney Diseases (NIDDK)", url="https://www.niddk.nih.gov/health-information/diabetes/overview/what-is-diabetes", summary=( "Diabetes occurs when blood glucose is too high because the body does not make " "enough insulin, makes no insulin, or does not use insulin properly. The main types " "include type 1, type 2, and gestational diabetes." ), keywords=( "diabetes", "type 1", "type one", "type 2", "type two", "gestational", "insulin", "blood sugar", "blood glucose", "glucose", "prediabetes", "diabetes tipo", "azúcar en la sangre", "glucosa", ), ), Source( source_id="S2", title="Diabetes Tests & Diagnosis", organization="NIDDK", url="https://www.niddk.nih.gov/health-information/diabetes/overview/tests-diagnosis", summary=( "Health professionals diagnose diabetes and prediabetes with blood tests. Home blood " "glucose meters cannot diagnose diabetes, and abnormal results may need confirmation." ), keywords=( "a1c", "hba1c", "test", "diagnosis", "diagnose", "screen", "fasting", "oral glucose", "lab", "laboratory", "prediabetes range", "prueba", "diagnóstico", ), ), Source( source_id="S3", title="About Insulin Resistance and Type 2 Diabetes", organization="Centers for Disease Control and Prevention (CDC)", url="https://www.cdc.gov/diabetes/about/insulin-resistance-type-2-diabetes.html", summary=( "Insulin resistance means cells do not respond well to insulin. The pancreas may make " "more insulin at first, but blood glucose can rise over time and lead to prediabetes " "or type 2 diabetes." ), keywords=( "insulin resistance", "resistant", "prediabetes", "type 2", "metabolic", "resistencia a la insulina", "prediabetes", ), ), Source( source_id="S4", title="Diabetes Meal Planning", organization="CDC", url="https://www.cdc.gov/diabetes/healthy-eating/diabetes-meal-planning.html", summary=( "Meal planning can support nutrition and blood glucose management. Common educational " "tools include carbohydrate awareness and the plate method. Individual plans should be " "created with a qualified clinician or diabetes educator." ), keywords=( "food", "meal", "diet", "carb", "carbohydrate", "plate method", "portion", "breakfast", "lunch", "dinner", "snack", "nutrition", "eat", "eating", "comida", "alimentación", "carbohidrato", "plato", "nutrición", ), ), Source( source_id="S5", title="Healthy Living with Diabetes", organization="NIDDK", url="https://www.niddk.nih.gov/health-information/diabetes/overview/healthy-living-with-diabetes", summary=( "Healthy living with diabetes may include balanced eating, physical activity, adequate " "sleep, stress management, and collaboration with a health care team. Plans should be " "adapted to the person's health status and treatment." ), keywords=( "exercise", "activity", "walking", "workout", "sleep", "stress", "lifestyle", "weight", "healthy living", "physical activity", "ejercicio", "actividad", "sueño", ), ), Source( source_id="S6", title="Low Blood Sugar (Hypoglycemia)", organization="CDC", url="https://www.cdc.gov/diabetes/about/low-blood-sugar-hypoglycemia.html", summary=( "Low blood glucose can be dangerous and requires prompt attention. People at risk should " "know their care plan, recognize warning signs, and discuss prevention and treatment with " "their health care team." ), keywords=( "low blood sugar", "low glucose", "hypoglycemia", "hypoglycaemia", "shaky", "sweating", "confused", "glucagon", "azúcar baja", "hipoglucemia", "temblor", ), ), Source( source_id="S7", title="Manage Blood Sugar", organization="CDC", url="https://www.cdc.gov/diabetes/treatment/index.html", summary=( "Blood glucose can become too high or too low for many reasons. Monitoring frequency and " "target ranges should be determined with a health professional, especially for people " "using insulin or medicines that can cause hypoglycemia." ), keywords=( "high blood sugar", "high glucose", "hyperglycemia", "ketone", "monitor", "meter", "cgm", "continuous glucose", "target range", "azúcar alta", "hiperglucemia", "cetona", ), ), Source( source_id="S8", title="Insulin, Medicines, & Other Diabetes Treatments", organization="NIDDK", url="https://www.niddk.nih.gov/health-information/diabetes/overview/insulin-medicines-treatments", summary=( "Diabetes treatment may involve lifestyle measures, oral medicines, injectable medicines, " "or insulin. The appropriate treatment depends on diabetes type, other health conditions, " "side effects, cost, access, and individual circumstances. Medication changes require a clinician." ), keywords=( "medicine", "medication", "drug", "insulin", "metformin", "glp-1", "glp1", "side effect", "dose", "dosage", "injection", "medicina", "medicamento", "dosis", ), ), Source( source_id="S9", title="Preventing Diabetes Problems", organization="NIDDK", url="https://www.niddk.nih.gov/health-information/diabetes/overview/preventing-problems", summary=( "Diabetes can affect the heart, blood vessels, kidneys, eyes, nerves, and feet. Routine " "care and management of blood glucose, blood pressure, cholesterol, and smoking status " "can help reduce complication risks." ), keywords=( "complication", "heart", "kidney", "eye", "vision", "nerve", "neuropathy", "foot", "feet", "stroke", "cholesterol", "blood pressure", "complicación", "riñón", "pie", ), ), ) def _tokenize(text: str) -> set[str]: return set(re.findall(r"[a-záéíóúñ0-9-]+", text.lower())) def retrieve_sources(query: str, limit: int = 3) -> list[Source]: """Return the most relevant curated sources for a user query. Scores use exact phrase matches plus token overlap. A general diabetes source is always available as a fallback. """ normalized = query.lower().strip() query_tokens = _tokenize(normalized) ranked: list[tuple[float, Source]] = [] for source in SOURCES: score = 0.0 for keyword in source.keywords: key = keyword.lower() if key in normalized: score += 4.0 if " " in key else 2.0 key_tokens = _tokenize(key) score += 0.35 * len(query_tokens.intersection(key_tokens)) ranked.append((score, source)) ranked.sort(key=lambda item: item[0], reverse=True) selected = [source for score, source in ranked if score > 0][:limit] if not selected: selected = [SOURCES[0], SOURCES[4]][:limit] elif SOURCES[0] not in selected and len(selected) < limit: selected.append(SOURCES[0]) return selected[:limit] def format_context(sources: Iterable[Source]) -> str: """Format source summaries for inclusion in the model prompt.""" blocks = [] for source in sources: blocks.append( f"[{source.source_id}] {source.title} — {source.organization}\n" f"Summary: {source.summary}\n" f"URL: {source.url}" ) return "\n\n".join(blocks) def format_reference_list(sources: Iterable[Source]) -> str: """Format deterministic Markdown references appended to each answer.""" items = [ f"- [{source.source_id}] [{source.title}]({source.url}) — {source.organization}" for source in sources ] return "\n".join(items)