JairoCesar commited on
Commit
26f6933
·
verified ·
1 Parent(s): 79f5bed

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +183 -93
app.py CHANGED
@@ -87,97 +87,124 @@ def get_foodb_lower_map(_foodb_index):
87
  foodb_lower_map = get_foodb_lower_map(foodb_index)
88
 
89
  # --- DICCIONARIOS DE CONOCIMIENTO EXTENDIDOS ---
 
90
  FOOD_TO_COMPOUND_MAP = {
91
- "pan": ["gluten", "fodmaps", "fructanos", "levadura", "aminas", "fitatos"],
92
- "trigo": ["gluten", "fodmaps", "fructanos", "lectinas", "aminas", "fitatos"],
93
- "harina": ["gluten", "fodmaps", "fructanos"],
94
- "pasta": ["gluten", "fodmaps", "fructanos"],
95
- "galletas": ["gluten", "azúcar", "fodmaps", "fructanos", "lácteos"],
96
- "pizza": ["gluten", "lácteos", "histamina", "aminas", "fodmaps", "fructanos", "solaninas"],
97
- "ravioles": ["gluten", "fructanos", "lácteos", "histamina", "oxalatos", "purinas", "solaninas"],
98
- "cebada": ["gluten", "fodmaps", "fructanos"],
99
- "centeno": ["gluten", "fodmaps", "fructanos"],
100
- "avena": ["gluten", "avenina", "níquel", "fitatos"],
101
- "maíz": ["lectinas", "aflatoxinas", "fodmaps", "fructosa"],
102
- "arroz": ["lectinas", "arsénico", "fitatos"],
103
- "arroz frito": ["lectinas", "gluten", "soja", "histamina", "fodmaps", "alérgenos", "glutamato"],
104
  "quinoa": ["saponinas", "oxalatos", "fitatos"],
105
- "leche": ["lácteos", "caseína", "lactosa", "fodmaps"],
106
- "queso": ["lácteos", "caseína", "lactosa", "histamina", "tiramina", "aminas"],
107
- "yogur": ["lácteos", "caseína", "lactosa", "histamina"],
108
- "mantequilla": ["lácteos", "caseína", "lactosa"],
109
- "helado": ["lácteos", "azúcar", "lactosa", "fodmaps"],
110
- "tomate": ["histamina", "solaninas", "lectinas", "salicilatos", "aminas"],
111
- "pimiento": ["solaninas", "lectinas", "capsaicina", "salicilatos"],
112
- "berenjena": ["solaninas", "lectinas", "histamina", "salicilatos"],
113
- "patata": ["solaninas", "lectinas", "almidón resistente"],
114
- "papas fritas": ["solaninas", "lectinas", "aminas", "acrilamida", "gluten"],
115
- "cebolla": ["fodmaps", "fructanos", "azufre", "quercetina"],
116
- "ajo": ["fodmaps", "fructanos", "azufre"],
117
- "brócoli": ["fodmaps", "fructanos", "goitrógenos", "azufre", "salicilatos"],
118
- "coliflor": ["fodmaps", "polioles", "goitrógenos", "azufre"],
119
- "repollo": ["fodmaps", "fructanos", "goitrógenos", "azufre", "histamina"],
120
- "espinaca": ["oxalatos", "histamina", "goitrógenos", "níquel", "nitratos"],
121
- "acelga": ["oxalatos"],
122
- "remolacha": ["oxalatos", "fodmaps", "gos", "nitratos"],
123
- "legumbres": ["fodmaps", "gos", "lectinas", "fitatos", "saponinas"],
124
- "lentejas": ["fodmaps", "gos", "lectinas", "fitatos", "níquel"],
125
- "garbanzos": ["fodmaps", "gos", "lectinas", "fitatos"],
126
- "frijoles": ["fodmaps", "gos", "lectinas", "fitatos"],
127
- "soja": ["alérgenos", "fitatos", "goitrógenos", "lectinas", "níquel"],
128
- "tofu": ["soja", "fitatos", "goitrógenos", "lectinas"],
129
- "aguacate": ["fodmaps", "polioles", "histamina", "salicilatos", "aminas"],
130
- "champiñón": ["fodmaps", "polioles"],
131
- "pepino": ["lectinas", "salicilatos"],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  "zanahoria": ["salicilatos"],
133
- "manzana": ["fodmaps", "fructosa", "polioles", "salicilatos", "quercetina"],
134
- "pera": ["fodmaps", "fructosa", "polioles"],
135
- "mango": ["fodmaps", "fructosa"],
136
- "cereza": ["fodmaps", "fructosa", "polioles", "salicilatos"],
137
- "sandía": ["fodmaps", "fructosa"],
138
- "miel": ["fodmaps", "fructosa"],
139
- "plátano": ["aminas", "tiramina", "histamina", "almidón resistente"],
140
- "fresa": ["histamina", "salicilatos", "goitrógenos"],
141
- "piña": ["histamina", "salicilatos", "ácidos", "bromelina"],
142
- "cítricos": ["ácidos", "salicilatos", "aminas"],
143
- "naranja": ["ácidos", "salicilatos", "aminas"],
144
- "limón": ["ácidos", "salicilatos", "aminas"],
145
- "papaya": ["histamina", "papaína"],
146
- "pasas": ["histamina", "salicilatos", "fructosa"],
147
- "uvas": ["salicilatos", "fructosa", "quercetina"],
148
- "arándano": ["salicilatos"],
149
- "frambuesa": ["salicilatos"],
150
- "carne": ["purinas", "histamina", "alfa-gal", "hierro hemo"],
151
- "carne roja": ["purinas", "alfa-gal", "hierro hemo", "histamina"],
152
- "carne procesada": ["nitritos", "histamina", "tiramina", "aminas", "fosfatos"],
153
- "embutidos": ["nitritos", "histamina", "tiramina", "aminas", "fosfatos"],
154
- "hamburguesa": ["gluten", "fructanos", "lácteos", "histamina", "aminas", "purinas", "azúcar", "fodmaps", "lectinas", "solaninas", "semillas de sésamo"],
155
- "huevo": ["alérgenos", "azufre"],
156
- "pescado": ["histamina", "purinas", "mercurio"],
157
- "pescado azul": ["histamina", "purinas", "omega-3"],
158
- "atún": ["histamina", "mercurio"],
159
- "salmón": ["histamina", "purinas"],
160
- "mariscos": ["alérgenos", "purinas", "yodo", "níquel"],
161
- "frutos secos": ["níquel", "fitatos", "oxalatos", "salicilatos", "arginina", "alérgenos"],
162
- "nueces": ["arginina", "salicilatos", "níquel", "oxalatos", "fitatos"],
163
- "almendras": ["salicilatos", "arginina", "oxalatos", "fitatos", "cianuro"],
164
- "maní": ["alérgenos", "arginina", "lectinas", "aflatoxinas"],
165
- "cacahuetes": ["alérgenos", "arginina", "lectinas", "aflatoxinas"],
166
- "chocolate": ["cafeína", "aminas", "tiramina", "níquel", "arginina", "oxalatos", "teobromina"],
167
- "café": ["cafeína", "ácidos", "histamina", "salicilatos", "aminas"],
168
  "té": ["cafeína", "taninos", "oxalatos", "salicilatos"],
169
- "vino": ["histamina", "tiramina", "sulfitos", "taninos", "alcohol", "quercetina"],
170
- "cerveza": ["gluten", "histamina", "tiramina", "alcohol"],
171
- "refresco de cola": ["azúcar", "fructosa", "cafeína", "ácidos", "colorantes"],
172
- "bebida gaseosa oscura": ["azúcar", "fructosa", "cafeína", "ácidos", "colorantes"],
173
- "bebida energética": ["cafeína", "azúcar", "edulcorantes", "ácidos", "estimulantes", "saborizantes"],
174
- "vinagre": ["histamina", "sulfitos", "ácido acético"],
175
- "alimentos fermentados": ["histamina", "tiramina"],
176
- "chucrut": ["histamina", "tiramina"],
177
- "sancocho": ["histamina", "purinas", "fodmaps", "fructanos", "lectinas", "solaninas", "almidón"],
178
- "ajiaco": ["solaninas", "lectinas", "purinas", "lácteos", "histamina"],
179
- "bandeja paisa": ["fodmaps", "gos", "lectinas", "histamina", "tiramina", "aminas", "nitritos", "purinas", "alérgenos", "polioles"],
180
- "cholado": ["azúcar", "fructosa", "lácteos", "lactosa", "histamina", "salicilatos", "colorantes"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  }
182
  # --- SEGURO LÓGICO DE INCOMPATIBILIDAD BIOQUÍMICA Y FÁRMACOS ---
183
  # --- SEGURO LÓGICO: MATRIZ AMPLIADA DE COMPUESTOS Y DESENCADENANTES ESTRICTOS ---
@@ -227,6 +254,7 @@ STRICT_COMPOUND_TRIGGERS = {
227
 
228
  DRUG_KEYWORDS = ["fármaco", "farmaco", "medicamento", "imao", "remedio", "pastilla", "tratamiento", "antidepresiv"]
229
 
 
230
  def validar_seguro_logico(entry, user_foods, user_query, food_compound_map):
231
  if not user_foods:
232
  return True
@@ -259,6 +287,7 @@ def validar_seguro_logico(entry, user_foods, user_query, food_compound_map):
259
 
260
  return True
261
 
 
262
  COMPOUND_SYNONYM_MAP = {
263
  "gluten": ["gluten", "gliadin"],
264
  "caseína": ["casein", "casomorphin"],
@@ -1536,8 +1565,25 @@ CONSEJO_GENERICO_DEFAULT = (
1536
  "Cada organismo posee una individualidad bioquímica única influenciada por su genética, perfil enzimático y microbiota intestinal. "
1537
  "Identificar tu umbral de tolerancia personal mediante un registro sistemático de síntomas te permitirá adaptar tu nutrición de forma segura."
1538
  )
1539
- CONSEJO_GENERICO_DEFAULT = "Cada organismo posee una individualidad bioquímica única según su perfil enzimático y digestivo. Monitorear tus respuestas personales te permitirá adaptar la dieta a tu umbral de tolerancia."
1540
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1541
  # --- GENERADOR DE INFORME LOCAL AUTOMÁTICO (SIN IA) ---
1542
  def generate_local_fallback_analysis(query, match, entities, food_compound_map, neuro_map):
1543
  saludo = "### 📋 Informe de Análisis Clínico-Nutricional (Modo Local / Alta Disponibilidad)\n"
@@ -1566,11 +1612,11 @@ def generate_local_fallback_analysis(query, match, entities, food_compound_map,
1566
  elif match.get('mecanismo_fisiologico'):
1567
  causa += f"\n**Mecanismo fisiológico:** {match.get('mecanismo_fisiologico')}\n"
1568
 
1569
- evitar = f"\n### 🛑 Alimentos a Moderar o Evitar\n- **Alimentos evaluados:** {', '.join(user_foods).capitalize()}\n- Alimentos ricos en **{compuestos_str}** o derivados que contengan los mismos componentes desencadenantes.\n"
1570
 
1571
  alternativas = "\n### 💡 Sugerencias y Alternativas\n- Llevar un diario de síntomas registrando alimentos, hora de consumo y aparición de molestias.\n- Reducir temporalmente la ingesta del alimento sospechoso para evaluar la remisión del síntoma.\n- Consultar con un nutricionista funcional o médico especialista si las molestias persisten.\n"
1572
 
1573
- # 1. Prioridad: Buscar consejo directo en el diccionario de compuestos (O(1))
1574
  consejo_texto = None
1575
  for comp in compuestos_detectados:
1576
  comp_clean = comp.lower().strip()
@@ -1578,18 +1624,62 @@ def generate_local_fallback_analysis(query, match, entities, food_compound_map,
1578
  consejo_texto = CONSEJOS_POR_COMPUESTO[comp_clean]
1579
  break
1580
 
1581
- # 2. Si no hay en el diccionario, usar la recomendación de tu JSON si existe
1582
  if not consejo_texto and match.get("recomendaciones_examenes"):
1583
  consejo_texto = f"Recomendación específica de la base de datos: {match.get('recomendaciones_examenes')}"
1584
 
1585
- # 3. Fallback genérico si no se encuentra ninguna específica
1586
  if not consejo_texto:
1587
  consejo_texto = CONSEJO_GENERICO_DEFAULT
1588
 
1589
  consejo = f"\n### 📌 Consejo Práctico Final\n{consejo_texto}\n"
1590
 
1591
  return saludo + hipotesis + causa + evitar + alternativas + consejo + TEXTO_BANDERAS_ROJAS
 
 
 
1592
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1593
  # --- FUNCIONES DE APOYO Y EXTRACCIÓN ---
1594
  @st.cache_data(show_spinner=False)
1595
  def generate_word_report_cached(report_text):
@@ -1711,7 +1801,6 @@ def find_best_matches_hybrid(entities, data, user_query="", food_compound_map=No
1711
 
1712
  results = []
1713
  for entry in data:
1714
- # SEGURO LÓGICO
1715
  if food_compound_map and not validar_seguro_logico(entry, user_foods_list, user_query, food_compound_map):
1716
  continue
1717
 
@@ -1779,6 +1868,7 @@ def build_local_hypothesis(entities, food_compound_map, neuro_map):
1779
  "es_hipotesis_local": True
1780
  }
1781
 
 
1782
  def find_best_foodb_matches(user_foods_es, _foodb_index, _foodb_lower_map, food_name_map, limit=3):
1783
  if not user_foods_es or not _foodb_index: return []
1784
 
 
87
  foodb_lower_map = get_foodb_lower_map(foodb_index)
88
 
89
  # --- DICCIONARIOS DE CONOCIMIENTO EXTENDIDOS ---
90
+ # --- DICCIONARIO COMPLETO FOOD_TO_COMPOUND_MAP (Basado en la química de FooDB.ca) ---
91
  FOOD_TO_COMPOUND_MAP = {
92
+ # --- 1. CEREALES, GRANOS Y HARINAS ---
93
+ "trigo": ["gluten", "fodmaps", "lectinas", "fitatos"],
94
+ "pan": ["gluten", "fodmaps", "lectinas"],
95
+ "pasta": ["gluten", "fodmaps"],
96
+ "galletas": ["gluten", "fodmaps", "azúcar refinado"],
97
+ "cebada": ["gluten", "fodmaps", "fitatos"],
98
+ "centeno": ["gluten", "fodmaps", "fitatos"],
99
+ "avena": ["fodmaps", "avenina", "fitatos"],
100
+ "arroz": ["fitatos", "lectinas"],
101
+ "maíz": ["zeína", "lectinas", "fitatos", "fodmaps"],
 
 
 
102
  "quinoa": ["saponinas", "oxalatos", "fitatos"],
103
+ "alforfón": ["oxalatos", "fagopirina"],
104
+ "arroz frito": ["lectinas", "gluten", "soja", "histamina", "fodmaps", "glutamato"],
105
+
106
+ # --- 2. LÁCTEOS Y DERIVADOS ---
107
+ "leche": ["caseína", "lactosa", "fodmaps"],
108
+ "queso": ["tiramina", "histamina", "caseína", "lactosa"],
109
+ "queso fresco": ["caseína", "lactosa"],
110
+ "queso maduro": ["tiramina", "histamina", "caseína"],
111
+ "yogur": ["histamina", "caseína", "lactosa"],
112
+ "mantequilla": ["caseína", "lactosa"],
113
+ "crema de leche": ["caseína", "lactosa"],
114
+ "helado": ["lactosa", "caseína", "azúcar refinado"],
115
+
116
+ # --- 3. FRUTAS Y JUGOS ---
117
+ "naranja": ["fructosa", "histamina", "salicilatos", "fenoles"],
118
+ "jugo de naranja": ["fructosa", "histamina", "salicilatos", "fenoles"],
119
+ "limón": ["salicilatos", "histamina", "fenoles", "ácido cítrico"],
120
+ "mandarina": ["fructosa", "histamina", "salicilatos", "fenoles"],
121
+ "manzana": ["fructosa", "sorbitol", "fodmaps", "salicilatos"],
122
+ "pera": ["fructosa", "sorbitol", "fodmaps", "salicilatos"],
123
+ "plátano": ["tiramina", "histamina", "salicilatos", "fenoles"],
124
+ "banano": ["tiramina", "histamina", "salicilatos", "fenoles"],
125
+ "aguacate": ["histamina", "tiramina", "salicilatos", "fodmaps"],
126
+ "fresa": ["histamina", "salicilatos", "oxalatos"],
127
+ "mora": ["salicilatos", "oxalatos", "histamina", "taninos"],
128
+ "uva": ["fructosa", "salicilatos", "histamina", "taninos"],
129
+ "piña": ["salicilatos", "histamina", "fructosa"],
130
+ "papaya": ["salicilatos", "histamina"],
131
+ "mango": ["fructosa", "salicilatos", "histamina"],
132
+ "kiwi": ["salicilatos", "oxalatos", "histamina"],
133
+ "durazno": ["fructosa", "sorbitol", "fodmaps", "salicilatos"],
134
+ "ciruela": ["sorbitol", "fodmaps", "salicilatos", "histamina"],
135
+ "higo": ["histamina", "fructosa", "salicilatos"],
136
+ "cholado": ["fructosa", "lactosa", "histamina", "azúcar refinado", "salicilatos", "fenoles"],
137
+
138
+ # --- 4. VERDURAS, HORTALIZAS Y TUBÉRCULOS ---
139
+ "tomate": ["histamina", "solanina", "salicilatos", "glutamato"],
140
+ "salsa de tomate": ["histamina", "solanina", "salicilatos", "glutamato"],
141
+ "patata": ["solanina", "oxalatos", "lectinas"],
142
+ "papa": ["solanina", "oxalatos", "lectinas"],
143
+ "berenjena": ["solanina", "histamina", "salicilatos"],
144
+ "pimiento": ["capsaicina", "solanina", "salicilatos"],
145
+ "espinaca": ["oxalatos", "nitratos", "histamina"],
146
+ "acelga": ["oxalatos", "nitratos"],
147
+ "remolacha": ["oxalatos", "nitratos", "fructosa"],
148
+ "cebolla": ["fodmaps", "compuestos azufrados", "salicilatos"],
149
+ "ajo": ["fodmaps", "compuestos azufrados"],
150
+ "brócoli": ["fodmaps", "compuestos azufrados", "salicilatos"],
151
+ "coliflor": ["fodmaps", "sorbitol", "compuestos azufrados"],
152
+ "repollo": ["fodmaps", "compuestos azufrados"],
153
+ "pepino": ["salicilatos"],
154
+ "calabaza": ["salicilatos", "fodmaps"],
155
  "zanahoria": ["salicilatos"],
156
+
157
+ # --- 5. LEGUMBRES Y PROTEÍNAS VEGETALES ---
158
+ "frijol": ["lectinas", "fitatos", "fodmaps", "saponinas"],
159
+ "frijoles": ["lectinas", "fitatos", "fodmaps", "saponinas"],
160
+ "lentejas": ["lectinas", "fitatos", "fodmaps"],
161
+ "garbanzos": ["lectinas", "fitatos", "fodmaps", "saponinas"],
162
+ "soja": ["soja", "lectinas", "fitatos", "fodmaps"],
163
+ "tofu": ["soja", "lectinas", "fitatos"],
164
+ "arvejas": ["fodmaps", "lectinas"],
165
+
166
+ # --- 6. FRUTOS SECOS, SEMILLAS Y ACEITES ---
167
+ "almendras": ["oxalatos", "salicilatos", "fitatos", "histamina"],
168
+ "nueces": ["histamina", "oxalatos", "salicilatos", "taninos"],
169
+ "maní": ["histamina", "lectinas", "fitatos", "salicilatos"],
170
+ "cacahuate": ["histamina", "lectinas", "fitatos", "salicilatos"],
171
+ "marañón": ["oxalatos", "fitatos", "fodmaps"],
172
+ "frutos secos": ["histamina", "oxalatos", "salicilatos", "fitatos"],
173
+ "semillas de chía": ["fitatos", "oxalatos"],
174
+ "ajonjolí": ["fitatos", "oxalatos"],
175
+
176
+ # --- 7. BEBIDAS, ESTIMULANTES Y EMBUTIDOS ---
177
+ "café": ["cafeína", "salicilatos", "oxalatos"],
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  "té": ["cafeína", "taninos", "oxalatos", "salicilatos"],
179
+ "té negro": ["cafeína", "taninos", "oxalatos", "salicilatos"],
180
+ "té verde": ["cafeína", "taninos", "oxalatos", "salicilatos"],
181
+ "chocolate": ["teobromina", "feniletilamina", "tiramina", "histamina", "oxalatos", "cafeína"],
182
+ "cacao": ["teobromina", "feniletilamina", "tiramina", "histamina", "oxalatos"],
183
+ "vino": ["histamina", "tiramina", "sulfitos", "taninos", "alcohol"],
184
+ "vino tinto": ["histamina", "tiramina", "sulfitos", "taninos", "alcohol"],
185
+ "vino blanco": ["sulfitos", "histamina", "alcohol"],
186
+ "cerveza": ["gluten", "histamina", "sulfitos", "alcohol", "purinas"],
187
+ "refresco": ["azúcar refinado", "cafeína"],
188
+ "gaseosa": ["azúcar refinado", "cafeína"],
189
+ "jamón": ["histamina", "tiramina", "nitritos"],
190
+ "salchicha": ["histamina", "tiramina", "nitritos", "glutamato"],
191
+ "embutidos": ["histamina", "tiramina", "nitritos", "glutamato"],
192
+ "pescado": ["histamina", "purinas", "albúmina"],
193
+ "atún": ["histamina", "purinas"],
194
+ "huevo": ["albúmina"],
195
+ "carne roja": ["purinas"],
196
+ "pollo": ["purinas", "histamina"],
197
+
198
+ # --- 8. CONDIMENTOS Y ESPECIAS ---
199
+ "pimienta": ["capsaicina", "salicilatos"],
200
+ "chile": ["capsaicina", "salicilatos", "solanina"],
201
+ "ají": ["capsaicina", "salicilatos", "solanina"],
202
+ "salsa de soja": ["glutamato", "histamina", "tiramina", "gluten", "soja"],
203
+ "vinagre": ["histamina", "sulfitos"],
204
+ "mostaza": ["salicilatos", "histamina"],
205
+ "canela": ["salicilatos"],
206
+ "cúrcuma": ["salicilatos", "oxalatos"],
207
+ "jengibre": ["salicilatos"]
208
  }
209
  # --- SEGURO LÓGICO DE INCOMPATIBILIDAD BIOQUÍMICA Y FÁRMACOS ---
210
  # --- SEGURO LÓGICO: MATRIZ AMPLIADA DE COMPUESTOS Y DESENCADENANTES ESTRICTOS ---
 
254
 
255
  DRUG_KEYWORDS = ["fármaco", "farmaco", "medicamento", "imao", "remedio", "pastilla", "tratamiento", "antidepresiv"]
256
 
257
+ # --- FUNCIONES DE SEGURO LÓGICO E HÍBRIDO ---
258
  def validar_seguro_logico(entry, user_foods, user_query, food_compound_map):
259
  if not user_foods:
260
  return True
 
287
 
288
  return True
289
 
290
+
291
  COMPOUND_SYNONYM_MAP = {
292
  "gluten": ["gluten", "gliadin"],
293
  "caseína": ["casein", "casomorphin"],
 
1565
  "Cada organismo posee una individualidad bioquímica única influenciada por su genética, perfil enzimático y microbiota intestinal. "
1566
  "Identificar tu umbral de tolerancia personal mediante un registro sistemático de síntomas te permitirá adaptar tu nutrición de forma segura."
1567
  )
 
1568
 
1569
+ # --- TRADUCTOR DE EFECTOS BIOACTIVOS DE FOODB ---
1570
+ FOODB_EFFECTS_TRANSLATION = {
1571
+ "flatugenic": "genera gases/flatulencia", "antioxidant": "antioxidante",
1572
+ "hypercholesterolemic": "puede elevar colesterol", "triglycerigenic": "puede elevar triglicéridos",
1573
+ "uricogenic": "puede elevar ácido úrico", "aggregant": "pro-agregante plaquetario",
1574
+ "preservative": "conservante natural", "sweetener": "edulcorante natural",
1575
+ "demulcent": "protector de mucosa digestiva", "vasodilator": "vasodilatador (posible migraña)",
1576
+ "vasoconstrictor": "vasoconstrictor", "histaminic": "actividad histaminérgica",
1577
+ "laxative": "efecto laxante", "diuretic": "efecto diurético",
1578
+ "stimulant": "estimulante del SNC", "sedative": "efecto sedante",
1579
+ "antiinflammatory": "antiinflamatorio", "ulcerogenic": "irritante gástrico"
1580
+ }
1581
+
1582
+
1583
+
1584
+
1585
+
1586
+ # --- GENERADOR DE INFORME LOCAL AUTOMÁTICO (SIN IA) ---
1587
  # --- GENERADOR DE INFORME LOCAL AUTOMÁTICO (SIN IA) ---
1588
  def generate_local_fallback_analysis(query, match, entities, food_compound_map, neuro_map):
1589
  saludo = "### 📋 Informe de Análisis Clínico-Nutricional (Modo Local / Alta Disponibilidad)\n"
 
1612
  elif match.get('mecanismo_fisiologico'):
1613
  causa += f"\n**Mecanismo fisiológico:** {match.get('mecanismo_fisiologico')}\n"
1614
 
1615
+ evitar = f"\n### 🛑 Alimentos a Moderar o Evitar\n- **Alimentos evaluados:** {', '.join(user_foods).capitalize()}\n- Alimentos ricos en **{compuestos_str}** o productos derivados que compartan los mismos componentes desencadenantes.\n"
1616
 
1617
  alternativas = "\n### 💡 Sugerencias y Alternativas\n- Llevar un diario de síntomas registrando alimentos, hora de consumo y aparición de molestias.\n- Reducir temporalmente la ingesta del alimento sospechoso para evaluar la remisión del síntoma.\n- Consultar con un nutricionista funcional o médico especialista si las molestias persisten.\n"
1618
 
1619
+ # Búsqueda dinámica por diccionario
1620
  consejo_texto = None
1621
  for comp in compuestos_detectados:
1622
  comp_clean = comp.lower().strip()
 
1624
  consejo_texto = CONSEJOS_POR_COMPUESTO[comp_clean]
1625
  break
1626
 
 
1627
  if not consejo_texto and match.get("recomendaciones_examenes"):
1628
  consejo_texto = f"Recomendación específica de la base de datos: {match.get('recomendaciones_examenes')}"
1629
 
 
1630
  if not consejo_texto:
1631
  consejo_texto = CONSEJO_GENERICO_DEFAULT
1632
 
1633
  consejo = f"\n### 📌 Consejo Práctico Final\n{consejo_texto}\n"
1634
 
1635
  return saludo + hipotesis + causa + evitar + alternativas + consejo + TEXTO_BANDERAS_ROJAS
1636
+
1637
+ def generate_detailed_analysis(query, match, entities=None, food_compound_map=None, neuro_map=None):
1638
+ gemini_client = get_gemini_client()
1639
 
1640
+ if not gemini_client:
1641
+ logger.info("Usando informe local por falta de cliente Gemini API.")
1642
+ return generate_local_fallback_analysis(query, match, entities, food_compound_map, neuro_map)
1643
+
1644
+ compound_context = ""
1645
+ if entities and food_compound_map and neuro_map:
1646
+ lines = []
1647
+ for food in entities.get("alimentos", []):
1648
+ for compound in food_compound_map.get(food, []):
1649
+ if compound in neuro_map:
1650
+ lines.append(f"- {food.capitalize()} contiene {compound}: {neuro_map[compound]['efecto_neuropsicologico']}")
1651
+ if lines:
1652
+ compound_context = "Compuestos moleculares relevantes detectados:\n" + "\n".join(lines)
1653
+
1654
+ prompt = f"""
1655
+ Rol: Nutricionista Funcional y experto en bioquímica de alimentos.
1656
+ Caso del paciente: {query}
1657
+ Hipótesis clínica: {match.get('condicion_asociada')}
1658
+ Mecanismo fisiológico: {match.get('mecanismo_fisiologico')}
1659
+ Alimentos/compuestos clave: {match.get('compuesto_alimento')}
1660
+ {compound_context}
1661
+
1662
+ Tarea: Escribe un análisis en Markdown estructurado:
1663
+ 1. Saludo breve y empático.
1664
+ 2. Frase inicial clara con la hipótesis probable.
1665
+ 3. Explicación de las moléculas responsables (ej: histamina, tiramina, sulfitos, fructosa, gluten, salicilatos, fenoles).
1666
+ 4. Mecanismo fisiológico en términos sencillos.
1667
+ 5. Alimentos a evitar o moderar.
1668
+ 6. Alternativas o reemplazos sugeridos.
1669
+ 7. Consejo práctico final.
1670
+ NO incluyas descargos de responsabilidad.
1671
+ """
1672
+ try:
1673
+ response = gemini_client.models.generate_content(
1674
+ model='gemini-2.5-flash-lite',
1675
+ contents=prompt
1676
+ )
1677
+ return response.text + TEXTO_BANDERAS_ROJAS
1678
+ except Exception as e:
1679
+ logger.warning(f"Error o timeout en Gemini API ({e}). Se activa la respuesta automática en modo local.")
1680
+ return generate_local_fallback_analysis(query, match, entities, food_compound_map, neuro_map)
1681
+
1682
+
1683
  # --- FUNCIONES DE APOYO Y EXTRACCIÓN ---
1684
  @st.cache_data(show_spinner=False)
1685
  def generate_word_report_cached(report_text):
 
1801
 
1802
  results = []
1803
  for entry in data:
 
1804
  if food_compound_map and not validar_seguro_logico(entry, user_foods_list, user_query, food_compound_map):
1805
  continue
1806
 
 
1868
  "es_hipotesis_local": True
1869
  }
1870
 
1871
+
1872
  def find_best_foodb_matches(user_foods_es, _foodb_index, _foodb_lower_map, food_name_map, limit=3):
1873
  if not user_foods_es or not _foodb_index: return []
1874