Daniil commited on
Commit
17d7268
·
1 Parent(s): dee0ee2

Pushing the repo

Browse files
.gitignore ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # compiled python
2
+ *.pyc
3
+ # PDF
4
+ *.pdf
5
+ # Pickled files
6
+ *.pkl
7
+
8
+ *.json
.streamlit/config.toml ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ [server]
2
+ headless = true
.streamlit/secrets.toml ADDED
File without changes
app.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ import random
4
+ import importlib.util
5
+ import firebase_admin
6
+ from firebase_admin import credentials, firestore
7
+
8
+
9
+ # Initialize Firebase
10
+ if not firebase_admin._apps:
11
+ cred = credentials.Certificate("coco-evaluation-firebase-adminsdk-p3m64-99c4ea22c1.json")
12
+ firebase_admin.initialize_app(cred)
13
+ db = firestore.client()
14
+
15
+
16
+ # Set page configuration as the first command
17
+ st.set_page_config(
18
+ page_title="TB Chatbot Evaluation",
19
+ page_icon="👋",
20
+ )
21
+
22
+
23
+ # tesing again
24
+
25
+
26
+ # Set passcode for authentication
27
+ PASSCODE = os.environ["MY_PASSCODE"]
28
+
29
+ # Initialize authentication state
30
+ if "authenticated" not in st.session_state:
31
+ st.session_state["authenticated"] = False
32
+
33
+
34
+ # Initialize session state variables
35
+ def init_session_state():
36
+ if "authenticated" not in st.session_state:
37
+ st.session_state["authenticated"] = False
38
+ if "evaluator_confirmed" not in st.session_state:
39
+ st.session_state["evaluator_confirmed"] = None
40
+ if "model_order" not in st.session_state:
41
+ st.session_state["model_order"] = []
42
+ if "current_index" not in st.session_state:
43
+ st.session_state["current_index"] = 0
44
+ if "models_completed" not in st.session_state:
45
+ st.session_state["models_completed"] = False
46
+ if "evaluation_status" not in st.session_state or not st.session_state["evaluation_status"]:
47
+ st.session_state["evaluation_status"] = {}
48
+ if "all_evaluations" not in st.session_state:
49
+ st.session_state["all_evaluations"] = {}
50
+ if "evaluation_ids" not in st.session_state:
51
+ st.session_state["evaluation_ids"] = {}
52
+ if "start_time" not in st.session_state:
53
+ st.session_state["start_time"] = None
54
+ if "evaluation_durations" not in st.session_state:
55
+ st.session_state["evaluation_durations"] = {}
56
+ if "submitted_evaluations" not in st.session_state:
57
+ st.session_state["submitted_evaluations"] = set()
58
+
59
+
60
+ init_session_state()
61
+
62
+
63
+ # Display Welcome Page
64
+ if not st.session_state["authenticated"]:
65
+ st.markdown(f"<h1 style='text-align: center;'>Welcome to the TB Chatbot Evaluation</h1>", unsafe_allow_html=True)
66
+
67
+ col1, col2, col3 = st.columns([2, 1, 1])
68
+ with col1:
69
+ st.write("Are you an evaluator?")
70
+ with col2:
71
+ if st.button("Yes"):
72
+ st.session_state["evaluator_confirmed"] = True
73
+ with col3:
74
+ if st.button("No"):
75
+ st.session_state["evaluator_confirmed"] = False
76
+
77
+ if st.session_state["evaluator_confirmed"]:
78
+ evaluator_id = st.text_input("Enter your Evaluator ID (can be anything)")
79
+ passcode = st.text_input("Enter Passcode to Access Models (password is the same)", type="password")
80
+ if st.button("Submit"):
81
+ print("Hello")
82
+ if passcode == PASSCODE and evaluator_id:
83
+ print("Submitted")
84
+ # Save Evaluator ID
85
+ db.collection("evaluator_ids").document(evaluator_id).set({
86
+ "evaluator_id": evaluator_id,
87
+ "timestamp": firestore.SERVER_TIMESTAMP
88
+ })
89
+
90
+ # Update session state
91
+ st.session_state["authenticated"] = True
92
+ st.session_state["evaluator_id"] = evaluator_id
93
+
94
+
95
+ # Show the main content only if authenticated
96
+ if st.session_state["authenticated"]:
97
+ # Sidebar with only randomized page navigation
98
+ with st.sidebar:
99
+ # Only create the page mapping if it doesn't already exist in the session state
100
+ if "page_mapping" not in st.session_state:
101
+ # Get list of page files and randomize their order
102
+ PAGES_DIR = "pages"
103
+ page_files = [f for f in os.listdir(PAGES_DIR) if f.endswith(".py")]
104
+ random.shuffle(page_files)
105
+
106
+ # Create generic names for display
107
+ generic_names = [f"Model {chr(65 + i)}" for i in range(len(page_files))]
108
+
109
+ # Create a dictionary to map display names to file paths
110
+ st.session_state["page_mapping"] = {
111
+ generic_name: os.path.join(PAGES_DIR, page_file) for generic_name, page_file in zip(generic_names, page_files)
112
+ }
113
+
114
+ # Retrieve the consistent mapping from session state
115
+ pages = st.session_state["page_mapping"]
116
+
117
+ # Sidebar navigation selectbox with generic labels
118
+ selected_generic_name = st.selectbox("Navigation", list(pages.keys()), label_visibility="collapsed")
119
+
120
+ # Load and run the selected page dynamically using the selected generic name
121
+ selected_page_path = pages[selected_generic_name]
122
+ spec = importlib.util.spec_from_file_location(selected_generic_name, selected_page_path)
123
+ module = importlib.util.module_from_spec(spec)
124
+ spec.loader.exec_module(module)
125
+
126
+ # Display main welcome message
127
+ st.markdown("""
128
+ # Welcome to the TB Chatbot Simulation Portal
129
+
130
+ This portal allows you to interact with our TB-powered chatbot, built using OpenAI's GPT-4. Here, you can evaluate multiple chatbot configurations, each designed to foster trust, empathy, and medical accuracy in responses.
131
+
132
+ ## Purpose
133
+
134
+ Your task is to assess the chatbot models by interacting with them using patient scenario-based questions. Evaluate each model based on the following principles:
135
+
136
+ ### Trust
137
+ - Does the response convey confidence and reliability?
138
+ - Are the answers factually accurate and rooted in medical expertise?
139
+
140
+ ### Medical Accuracy
141
+ - Are responses aligned with current medical guidelines and best practices?
142
+ - Do they avoid misinformation or potentially harmful suggestions?
143
+
144
+ ### Empathy
145
+ - Does the chatbot demonstrate understanding and compassion?
146
+ - Are responses emotionally sensitive and supportive?
147
+
148
+ Your feedback will help us identify the best model to support our mission of enhancing patient communication and care through AI-driven solutions.
149
+ """)
environment/environment.yml ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: streamlit-env
2
+ channels:
3
+ - defaults
4
+ dependencies:
5
+ - ca-certificates=2024.9.24
6
+ - libcxx=14.0.6
7
+ - libffi=3.4.4
8
+ - ncurses=6.4
9
+ - openssl=3.0.15
10
+ - pip=24.2
11
+ - python=3.9.20
12
+ - readline=8.2
13
+ - setuptools=75.1.0
14
+ - sqlite=3.45.3
15
+ - tk=8.6.14
16
+ - wheel=0.44.0
17
+ - xz=5.4.6
18
+ - zlib=1.2.13
19
+ - pip:
20
+ - aiohappyeyeballs==2.4.3
21
+ - aiohttp==3.10.10
22
+ - aiosignal==1.3.1
23
+ - altair==5.4.1
24
+ - annotated-types==0.7.0
25
+ - anyio==4.6.2.post1
26
+ - asgiref==3.8.1
27
+ - async-timeout==4.0.3
28
+ - attrs==24.2.0
29
+ - backoff==2.2.1
30
+ - bcrypt==4.2.0
31
+ - blinker==1.8.2
32
+ - build==1.2.2.post1
33
+ - cachetools==5.5.0
34
+ - certifi==2024.8.30
35
+ - charset-normalizer==3.4.0
36
+ - chroma-hnswlib==0.7.6
37
+ - chromadb==0.5.15
38
+ - click==8.1.7
39
+ - coloredlogs==15.0.1
40
+ - dataclasses-json==0.6.7
41
+ - deprecated==1.2.14
42
+ - distro==1.9.0
43
+ - durationpy==0.9
44
+ - exceptiongroup==1.2.2
45
+ - fastapi==0.115.3
46
+ - filelock==3.16.1
47
+ - flatbuffers==24.3.25
48
+ - frozenlist==1.5.0
49
+ - fsspec==2024.10.0
50
+ - gitdb==4.0.11
51
+ - gitpython==3.1.43
52
+ - google-auth==2.35.0
53
+ - googleapis-common-protos==1.65.0
54
+ - grpcio==1.67.0
55
+ - h11==0.14.0
56
+ - httpcore==1.0.6
57
+ - httptools==0.6.4
58
+ - httpx==0.27.2
59
+ - huggingface-hub==0.26.1
60
+ - humanfriendly==10.0
61
+ - idna==3.10
62
+ - importlib-metadata==8.4.0
63
+ - importlib-resources==6.4.5
64
+ - jinja2==3.1.4
65
+ - jiter==0.6.1
66
+ - joblib==1.4.2
67
+ - jsonpatch==1.33
68
+ - jsonpointer==3.0.0
69
+ - jsonschema==4.23.0
70
+ - jsonschema-specifications==2024.10.1
71
+ - kubernetes==31.0.0
72
+ - langchain==0.3.4
73
+ - langchain-community==0.3.3
74
+ - langchain-core==0.3.13
75
+ - langchain-huggingface==0.1.0
76
+ - langchain-text-splitters==0.3.0
77
+ - langsmith==0.1.137
78
+ - markdown-it-py==3.0.0
79
+ - markupsafe==3.0.2
80
+ - marshmallow==3.23.0
81
+ - mdurl==0.1.2
82
+ - mmh3==5.0.1
83
+ - monotonic==1.6
84
+ - mpmath==1.3.0
85
+ - multidict==6.1.0
86
+ - mypy-extensions==1.0.0
87
+ - narwhals==1.10.0
88
+ - networkx==3.2.1
89
+ - numpy==1.26.4
90
+ - oauthlib==3.2.2
91
+ - onnxruntime==1.19.2
92
+ - openai==1.52.2
93
+ - opentelemetry-api==1.27.0
94
+ - opentelemetry-exporter-otlp-proto-common==1.27.0
95
+ - opentelemetry-exporter-otlp-proto-grpc==1.27.0
96
+ - opentelemetry-instrumentation==0.48b0
97
+ - opentelemetry-instrumentation-asgi==0.48b0
98
+ - opentelemetry-instrumentation-fastapi==0.48b0
99
+ - opentelemetry-proto==1.27.0
100
+ - opentelemetry-sdk==1.27.0
101
+ - opentelemetry-semantic-conventions==0.48b0
102
+ - opentelemetry-util-http==0.48b0
103
+ - orjson==3.10.10
104
+ - overrides==7.7.0
105
+ - packaging==24.1
106
+ - pandas==2.2.3
107
+ - pillow==10.4.0
108
+ - posthog==3.7.0
109
+ - propcache==0.2.0
110
+ - protobuf==4.25.5
111
+ - pyarrow==17.0.0
112
+ - pyasn1==0.6.1
113
+ - pyasn1-modules==0.4.1
114
+ - pydantic==2.9.2
115
+ - pydantic-core==2.23.4
116
+ - pydantic-settings==2.6.0
117
+ - pydeck==0.9.1
118
+ - pygments==2.18.0
119
+ - pypika==0.48.9
120
+ - pyproject-hooks==1.2.0
121
+ - python-dateutil==2.9.0.post0
122
+ - python-dotenv==1.0.1
123
+ - pytz==2024.2
124
+ - pyyaml==6.0.2
125
+ - referencing==0.35.1
126
+ - regex==2024.9.11
127
+ - requests==2.32.3
128
+ - requests-oauthlib==2.0.0
129
+ - requests-toolbelt==1.0.0
130
+ - rich==13.9.3
131
+ - rpds-py==0.20.0
132
+ - rsa==4.9
133
+ - safetensors==0.4.5
134
+ - scikit-learn==1.5.2
135
+ - scipy==1.13.1
136
+ - sentence-transformers==3.2.1
137
+ - shellingham==1.5.4
138
+ - six==1.16.0
139
+ - smmap==5.0.1
140
+ - sniffio==1.3.1
141
+ - sqlalchemy==2.0.36
142
+ - starlette==0.41.0
143
+ - streamlit==1.39.0
144
+ - sympy==1.13.1
145
+ - tenacity==9.0.0
146
+ - threadpoolctl==3.5.0
147
+ - tokenizers==0.20.1
148
+ - toml==0.10.2
149
+ - tomli==2.0.2
150
+ - torch==2.5.0
151
+ - tornado==6.4.1
152
+ - tqdm==4.66.5
153
+ - transformers==4.46.0
154
+ - typer==0.12.5
155
+ - typing-extensions==4.12.2
156
+ - typing-inspect==0.9.0
157
+ - tzdata==2024.2
158
+ - urllib3==2.2.3
159
+ - uvicorn==0.32.0
160
+ - uvloop==0.21.0
161
+ - watchfiles==0.24.0
162
+ - websocket-client==1.8.0
163
+ - websockets==13.1
164
+ - wrapt==1.16.0
165
+ - yarl==1.16.0
166
+ - zipp==3.20.2
pages/FSR_Model.py ADDED
@@ -0,0 +1,944 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import uuid
2
+ import streamlit as st
3
+ from openai import AzureOpenAI
4
+ import firebase_admin
5
+ from firebase_admin import credentials, firestore
6
+ from typing import Dict, Any
7
+ import time
8
+ import os
9
+ import tempfile
10
+ import json
11
+
12
+ from utils.prompt_utils import PERSONA_PREFIX, baseline, baseline_esp, fs, RAG, EMOTIONAL_PROMPT, CLASSIFICATION_PROMPT, INFORMATIONAL_PROMPT
13
+ from utils.RAG_utils import load_or_create_vectorstore
14
+
15
+ # PERSONA_PREFIX = ""
16
+ # baseline = ""
17
+ # baseline_esp = ""
18
+ # fs = ""
19
+ # RAG = ""
20
+ # EMOTIONAL_PROMPT = ""
21
+ # CLASSIFICATION_PROMPT = """
22
+ # Determine si esta afirmación busca empatía o (1) o busca información (0).
23
+ # Clasifique como emocional sólo si la pregunta expresa preocupación, ansiedad o malestar sobre el estado de salud del paciente.
24
+ # En caso contrario, clasificar como informativo.
25
+
26
+ # Ejemplos:
27
+ # - Pregunta: Me siento muy ansioso por mi diagnóstico de tuberculosis. 1
28
+ # - Pregunta: ¿Cuáles son los efectos secundarios comunes de los medicamentos contra la tuberculosis? 0
29
+ # - Pregunta: Estoy preocupada porque tengo mucho dolor. 1
30
+ # - Pregunta: ¿Es seguro tomar medicamentos como analgésicos junto con medicamentos para la tuberculosis? 0
31
+
32
+ # Aquí está la declaración para clasificar. Simplemente responda con el número "1" o "0":
33
+ # """
34
+
35
+ # INFORMATIONAL_PROMPT = ""
36
+
37
+ # Model configurations remain the same
38
+ MODEL_CONFIGS = {
39
+ # "Model 0: Naive English Baseline Model": {
40
+ # "name": "Model 0: Naive English Baseline Model",
41
+ # "prompt": PERSONA_PREFIX + baseline,
42
+ # "uses_rag": False,
43
+ # "uses_classification": False
44
+ # },
45
+ # "Model 1: Naive Spanish Baseline Model": {
46
+ # "name": "Model 1: Baseline Model",
47
+ # "prompt": PERSONA_PREFIX + baseline_esp,
48
+ # "uses_rag": False,
49
+ # "uses_classification": False
50
+ # },
51
+ # "Model 1": {
52
+ # "name": "Model 1: Few_Shot model",
53
+ # "prompt": PERSONA_PREFIX + fs,
54
+ # "uses_rag": False,
55
+ # "uses_classification": False
56
+ # },
57
+ # "Model 3: RAG Model": {F
58
+ # "name": "Model 3: RAG Model",
59
+ # "prompt": PERSONA_PREFIX + RAG,
60
+ # "uses_rag": True,
61
+ # "uses_classification": False
62
+ # },
63
+ "Model 2": {
64
+ "name": "Model 2: RAG + Few_Shot Model",
65
+ "prompt": PERSONA_PREFIX + RAG + fs,
66
+ "uses_rag": True,
67
+ "uses_classification": False
68
+ },
69
+ # "Model 3": {
70
+ # "name": "Model 3: 2-Stage Classification Model",
71
+ # "prompt": PERSONA_PREFIX + INFORMATIONAL_PROMPT, # default
72
+ # "uses_rag": False,
73
+ # "uses_classification": False
74
+ # },
75
+ # "Model 6: Multi-Agent": {
76
+ # "name": "Model 6: Multi-Agent",
77
+ # "prompt": PERSONA_PREFIX + INFORMATIONAL_PROMPT, # default
78
+ # "uses_rag": True,
79
+ # "uses_classification": True,
80
+ # "uses_judges": True
81
+ # }
82
+ }
83
+ PASSCODE = os.environ["MY_PASSCODE"]
84
+
85
+ # # Authentication check
86
+ # if "authenticated" not in st.session_state or not st.session_state["authenticated"]:
87
+ # st.error("Access denied. Please go back to the main page and enter the passcode.")
88
+ # st.stop()
89
+
90
+ # Initialize Firebase
91
+ if not firebase_admin._apps:
92
+ cred = credentials.Certificate("coco-evaluation-firebase-adminsdk-p3m64-99c4ea22c1.json")
93
+ firebase_admin.initialize_app(cred)
94
+ db = firestore.client()
95
+
96
+ endpoint = os.environ["ENDPOINT_URL"]
97
+ deployment = os.environ["DEPLOYMENT"]
98
+ subscription_key = os.environ["subscription_key"]
99
+
100
+ # OpenAI API setup
101
+ client = AzureOpenAI(
102
+ azure_endpoint=endpoint,
103
+ api_key=subscription_key,
104
+ api_version=os.environ["api_version"]
105
+ )
106
+
107
+ def authenticate():
108
+ creds_dict = {
109
+ "type": os.environ.get("FIREBASE_TYPE", "service_account"),
110
+ "project_id": os.environ.get("FIREBASE_PROJECT_ID"),
111
+ "private_key_id": os.environ.get("FIREBASE_PRIVATE_KEY_ID"),
112
+ "private_key": os.environ.get("FIREBASE_PRIVATE_KEY", "").replace("\\n", "\n"),
113
+ "client_email": os.environ.get("FIREBASE_CLIENT_EMAIL"),
114
+ "client_id": os.environ.get("FIREBASE_CLIENT_ID"),
115
+ "auth_uri": os.environ.get("FIREBASE_AUTH_URI", "https://accounts.google.com/o/oauth2/auth"),
116
+ "token_uri": os.environ.get("FIREBASE_TOKEN_URI", "https://oauth2.googleapis.com/token"),
117
+ "auth_provider_x509_cert_url": os.environ.get("FIREBASE_AUTH_PROVIDER_X509_CERT_URL",
118
+ "https://www.googleapis.com/oauth2/v1/certs"),
119
+ "client_x509_cert_url": os.environ.get("FIREBASE_CLIENT_X509_CERT_URL"),
120
+ "universe_domain": "googleapis.com"
121
+
122
+ }
123
+ # Create a temporary JSON file
124
+ with tempfile.NamedTemporaryFile(suffix='.json', delete=False, mode='w') as temp_file:
125
+ json.dump(creds_dict, temp_file)
126
+ temp_file.close()
127
+
128
+ import uuid
129
+
130
+ random_id = uuid.uuid4()
131
+ random_id_string = str(random_id)
132
+ evaluator_id = random_id_string
133
+ db = firestore.client()
134
+ db.collection("evaluator_ids").document(evaluator_id).set({
135
+ "evaluator_id": evaluator_id,
136
+ "timestamp": firestore.SERVER_TIMESTAMP
137
+ })
138
+
139
+ # Update session state
140
+ st.session_state["authenticated"] = True
141
+ st.session_state["evaluator_id"] = evaluator_id
142
+
143
+ def init():
144
+ """Initialize all necessary components and state variables"""
145
+ # Initialize Firebase if not already initialized
146
+ if not firebase_admin._apps:
147
+ cred = credentials.Certificate("coco-evaluation-firebase-adminsdk-p3m64-99c4ea22c1.json")
148
+ firebase_admin.initialize_app(cred)
149
+
150
+ # Initialize session state variables
151
+ if "messages" not in st.session_state:
152
+ st.session_state.messages = {}
153
+ if "session_id" not in st.session_state:
154
+ st.session_state.session_id = str(uuid.uuid4())
155
+ if "chat_active" not in st.session_state:
156
+ st.session_state.chat_active = False
157
+ if "user_input" not in st.session_state:
158
+ st.session_state.user_input = ""
159
+ if "user_id" not in st.session_state:
160
+ st.session_state.user_id = f"anonymous_{str(uuid.uuid4())}"
161
+ if "selected_model" not in st.session_state:
162
+ st.session_state.selected_model = list(MODEL_CONFIGS.keys())[0]
163
+ if "model_profile" not in st.session_state:
164
+ st.session_state.model_profile = [0, 0]
165
+
166
+ # Load vectorstore at startup
167
+ if "vectorstore" not in st.session_state:
168
+ with st.spinner("Loading document embeddings..."):
169
+ st.session_state.vectorstore = load_or_create_vectorstore()
170
+
171
+ def get_classification(client, deployment, user_input):
172
+ """Classify the input as emotional (1) or informational (0)"""
173
+ chat_prompt = [
174
+ {"role": "system", "content": CLASSIFICATION_PROMPT},
175
+ {"role": "user", "content": user_input}
176
+ ]
177
+
178
+ completion = client.chat.completions.create(
179
+ model=deployment,
180
+ messages=chat_prompt,
181
+ max_tokens=1,
182
+ temperature=0,
183
+ top_p=0.9,
184
+ frequency_penalty=0,
185
+ presence_penalty=0,
186
+ stop=None
187
+ )
188
+
189
+ return completion.choices[0].message.content.strip()
190
+ def process_input():
191
+ try:
192
+ current_model = st.session_state.selected_model
193
+ user_input = st.session_state.user_input
194
+
195
+ if not user_input.strip():
196
+ st.warning("Please enter a message before sending.")
197
+ return
198
+
199
+ model_config = MODEL_CONFIGS.get(current_model)
200
+ if not model_config:
201
+ st.error("Invalid model selected. Please choose a valid model.")
202
+ return
203
+
204
+ if current_model not in st.session_state.messages:
205
+ st.session_state.messages[current_model] = []
206
+
207
+ st.session_state.messages[current_model].append({"role": "user", "content": user_input})
208
+
209
+ try:
210
+ log_message("user", user_input)
211
+ except Exception as e:
212
+ st.warning(f"Failed to log message: {str(e)}")
213
+
214
+ conversation_history = "\n".join([f"{msg['role'].capitalize()}: {msg['content']}"
215
+ for msg in st.session_state.messages[current_model]])
216
+
217
+ # Helper function for error handling in API calls
218
+ def safe_api_call(messages, max_retries=3):
219
+ for attempt in range(max_retries):
220
+ try:
221
+ response = client.chat.completions.create(
222
+ model=deployment,
223
+ messages=messages,
224
+ max_tokens=3500,
225
+ temperature=0.1,
226
+ top_p=0.9
227
+ )
228
+ return response.choices[0].message.content.strip()
229
+ except Exception as e:
230
+ if attempt == max_retries - 1:
231
+ raise Exception(f"Failed to get response after {max_retries} attempts: {str(e)}")
232
+ st.warning(f"Attempt {attempt + 1} failed, retrying...")
233
+ time.sleep(1)
234
+
235
+ def perform_rag_query(input_text, conversation_history):
236
+ try:
237
+ relevant_docs = retrieve_relevant_documents(
238
+ st.session_state.vectorstore,
239
+ input_text,
240
+ conversation_history,
241
+ client=client
242
+ )
243
+
244
+ model_messages = [
245
+ {"role": "system", "content": f"{model_config['prompt']}\n\nContexto: {relevant_docs}"}
246
+ ] + st.session_state.messages[current_model]
247
+
248
+ return safe_api_call(model_messages), relevant_docs
249
+
250
+ except Exception as e:
251
+ st.error(f"Error in RAG query: {str(e)}")
252
+ return "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente.", ""
253
+
254
+ initial_response = None
255
+ initial_docs = ""
256
+
257
+ # Handle 2-stage model
258
+ if model_config.get('uses_classification', False):
259
+ try:
260
+ classification = get_classification(client, deployment, user_input)
261
+
262
+ if 'classifications' not in st.session_state:
263
+ st.session_state.classifications = {}
264
+ st.session_state.classifications[len(st.session_state.messages[current_model]) - 1] = classification
265
+
266
+ if classification == "0":
267
+ initial_response, initial_docs = perform_rag_query(user_input, conversation_history)
268
+ else:
269
+ model_messages = [
270
+ {"role": "system", "content": PERSONA_PREFIX + EMOTIONAL_PROMPT}
271
+ ] + st.session_state.messages[current_model]
272
+ initial_response = safe_api_call(model_messages)
273
+
274
+ except Exception as e:
275
+ st.error(f"Error in classification stage: {str(e)}")
276
+ initial_response = "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente."
277
+
278
+ # Handle RAG models
279
+ if model_config.get('uses_rag', False):
280
+ try:
281
+ if not initial_response:
282
+ initial_response, initial_docs = perform_rag_query(user_input, conversation_history)
283
+
284
+ verification_docs = retrieve_relevant_documents(
285
+ st.session_state.vectorstore,
286
+ initial_response,
287
+ conversation_history,
288
+ client=client
289
+ )
290
+
291
+ combined_docs = initial_docs + "\nContexto de verificación adicional:\n" + verification_docs
292
+
293
+ verification_messages = [
294
+ {
295
+ "role": "system",
296
+ "content": f"Pregunta del paciente:{user_input} \nContexto: {combined_docs} \nRespuesta anterior: {initial_response}\n Verifique la precisión médica de la respuesta anterior y refine la respuesta según el contexto adicional."
297
+ }
298
+ ]
299
+
300
+ assistant_reply = safe_api_call(verification_messages)
301
+
302
+ except Exception as e:
303
+ st.error(f"Error in RAG processing: {str(e)}")
304
+ assistant_reply = "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente."
305
+ else:
306
+ try:
307
+ model_messages = [
308
+ {"role": "system", "content": model_config['prompt']}
309
+ ] + st.session_state.messages[current_model]
310
+
311
+ assistant_reply = safe_api_call(model_messages)
312
+
313
+ except Exception as e:
314
+ st.error(f"Error generating response: {str(e)}")
315
+ assistant_reply = "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente."
316
+
317
+ # Store and log the final response
318
+ try:
319
+ st.session_state.messages[current_model].append({"role": "assistant", "content": assistant_reply})
320
+ log_message("assistant", assistant_reply)
321
+ # store_conversation_data()
322
+ except Exception as e:
323
+ st.warning(f"Failed to store or log response: {str(e)}")
324
+
325
+ st.session_state.user_input = ""
326
+
327
+ except Exception as e:
328
+ st.error(f"An unexpected error occurred: {str(e)}")
329
+ st.session_state.user_input = ""
330
+
331
+
332
+ def check_document_relevance(query, doc, client):
333
+ """
334
+ Check document relevance using few-shot prompting for Spanish TB context.
335
+
336
+ Args:
337
+ query (str): The user's input query
338
+ doc (str): The retrieved document text
339
+ client: The OpenAI client instance
340
+
341
+ Returns:
342
+ bool: True if document is relevant, False otherwise
343
+ """
344
+ few_shot_prompt = f"""Determine si el documento es relevante para la consulta sobre tuberculosis.
345
+ Responde únicamente 'sí' si es relevante o 'no' si no es relevante.
346
+ Ejemplos:
347
+ Consulta: ¿Cuáles son los efectos secundarios de la rifampicina?
348
+ Documento: La rifampicina puede causar efectos secundarios como náuseas, vómitos y coloración naranja de fluidos corporales. Es importante tomar el medicamento con el estómago vacío.
349
+ Respuesta: sí
350
+ Consulta: ¿Cuánto dura el tratamiento de TB?
351
+ Documento: El dengue es una enfermedad viral transmitida por mosquitos. Los síntomas incluyen fiebre alta y dolor muscular.
352
+ Respuesta: no
353
+ Consulta: ¿Cómo se realiza la prueba de esputo?
354
+ Documento: Para la prueba de esputo, el paciente debe toser profundamente para obtener una muestra de las vías respiratorias. La muestra debe recogerse en ayunas.
355
+ Respuesta: sí
356
+ Consulta: ¿Qué medidas de prevención debo tomar en casa?
357
+ Documento: Mayo Clinic tiene una gran cantidad de pacientes que atender.
358
+ Respuesta: no
359
+ Consulta: {query}
360
+ Documento: {doc}
361
+ Respuesta:"""
362
+
363
+ response = client.chat.completions.create(
364
+ model=deployment,
365
+ messages=[{"role": "user", "content": few_shot_prompt}],
366
+ max_tokens=3,
367
+ temperature=0.1,
368
+ top_p=0.9
369
+ )
370
+
371
+ return response.choices[0].message.content.strip().lower() == "sí"
372
+
373
+ # In retrieve_relevant_documents function
374
+ def retrieve_relevant_documents(vectorstore, query, conversation_history, client, top_k=3, score_threshold=0.5):
375
+ if not vectorstore:
376
+ st.error("Vector store not initialized")
377
+ return ""
378
+
379
+ try:
380
+ recent_history = "\n".join(conversation_history.split("\n")[-3:]) if conversation_history else ""
381
+ full_query = query
382
+ if len(recent_history) < 200:
383
+ full_query = f"{recent_history} {query}".strip()
384
+
385
+ results = vectorstore.similarity_search_with_score(
386
+ full_query,
387
+ k=top_k,
388
+ distance_metric="cos"
389
+ )
390
+
391
+ if not results:
392
+ return "No se encontraron documentos relevantes."
393
+
394
+ # Handle case where results don't include scores
395
+ if results and not isinstance(results[0], tuple):
396
+ # If results are just documents without scores, assign a default score
397
+ score_filtered_results = [(doc, 1.0) for doc in results]
398
+ else:
399
+ # Filter by similarity score
400
+ score_filtered_results = [
401
+ (result, score) for result, score in results
402
+ if score > score_threshold
403
+ ]
404
+
405
+ # Apply relevance checking to remaining documents
406
+ relevant_results = []
407
+ for result, score in score_filtered_results:
408
+ if check_document_relevance(query, result.page_content, client):
409
+ relevant_results.append((result, score))
410
+
411
+ # Fallback to default context if no relevant docs found
412
+ if not relevant_results:
413
+ if score_filtered_results:
414
+ print("No relevant documents found after relevance check.")
415
+ return "Eres un modelo de IA centrado en la tuberculosis."
416
+ return ""
417
+
418
+ # Format results
419
+ combined_results = [
420
+ f"Document excerpt (score: {score:.2f}):\n{result.page_content}"
421
+ for result, score in relevant_results
422
+ ]
423
+
424
+ return "\n\n".join(combined_results)
425
+
426
+ except Exception as e:
427
+ st.error(f"Error retrieving documents: {str(e)}")
428
+ return "Error al buscar documentos relevantes."
429
+
430
+ def store_conversation_data():
431
+ current_model = st.session_state.selected_model
432
+ model_config = MODEL_CONFIGS[current_model]
433
+
434
+ doc_ref = db.collection('conversations').document(str(st.session_state.session_id))
435
+ doc_ref.set({
436
+ 'timestamp': firestore.SERVER_TIMESTAMP,
437
+ 'userID': st.session_state.user_id,
438
+ 'model_index': list(MODEL_CONFIGS.keys()).index(current_model) + 1,
439
+ 'profile_index': st.session_state.model_profile[1],
440
+ 'profile': '',
441
+ 'conversation': st.session_state.messages[current_model],
442
+ 'uses_rag': model_config['uses_rag']
443
+ })
444
+
445
+ def log_message(role, content):
446
+ current_model = st.session_state.selected_model
447
+ model_config = MODEL_CONFIGS[current_model]
448
+ collection_name = f"messages_model_{list(MODEL_CONFIGS.keys()).index(current_model) + 1}"
449
+
450
+ doc_ref = db.collection(collection_name).document()
451
+ doc_ref.set({
452
+ 'timestamp': firestore.SERVER_TIMESTAMP,
453
+ 'session_id': str(st.session_state.session_id),
454
+ 'userID': st.session_state.get('user_id', 'anonymous'),
455
+ 'role': role,
456
+ 'content': content,
457
+ 'model_name': model_config['name']
458
+ })
459
+
460
+ def reset_conversation():
461
+ current_model = st.session_state.selected_model
462
+
463
+ if current_model in st.session_state.messages and st.session_state.messages[current_model]:
464
+ doc_ref = db.collection('conversation_ends').document()
465
+ doc_ref.set({
466
+ 'timestamp': firestore.SERVER_TIMESTAMP,
467
+ 'session_id': str(st.session_state.session_id),
468
+ 'userID': st.session_state.get('user_id', 'anonymous'),
469
+ 'total_messages': len(st.session_state.messages[current_model]),
470
+ 'model_name': MODEL_CONFIGS[current_model]['name']
471
+ })
472
+
473
+ st.session_state.messages[current_model] = []
474
+ st.session_state.session_id = str(uuid.uuid4())
475
+ st.session_state.chat_active = False
476
+ st.query_params.clear()
477
+
478
+ class ModelEvaluationSystem:
479
+ def __init__(self, db: firestore.Client):
480
+ self.db = db
481
+ self.models_to_evaluate = list(MODEL_CONFIGS.keys()) # Use existing MODEL_CONFIGS
482
+ self._initialize_state()
483
+ self._load_existing_evaluations()
484
+
485
+ def _initialize_state(self):
486
+ """Initialize or load evaluation state."""
487
+ if "evaluation_state" not in st.session_state:
488
+ st.session_state.evaluation_state = {}
489
+
490
+ if "evaluated_models" not in st.session_state:
491
+ st.session_state.evaluated_models = {}
492
+
493
+ def _get_current_user_id(self):
494
+ """
495
+ Get current user identifier.
496
+ """
497
+ return st.session_state["evaluator_id"]
498
+
499
+ def render_evaluation_progress(self):
500
+ """
501
+ Render evaluation progress in the sidebar.
502
+ """
503
+ st.sidebar.header("Evaluation Progress")
504
+
505
+ # Calculate progress
506
+ total_models = len(self.models_to_evaluate)
507
+ evaluated_models = len(st.session_state.evaluated_models)
508
+
509
+ # Progress bar
510
+ st.sidebar.progress(evaluated_models / total_models)
511
+
512
+ # List of models and their status
513
+ for model in self.models_to_evaluate:
514
+ status = "✅ Completed" if st.session_state.evaluated_models.get(model, False) else "⏳ Pending"
515
+ st.sidebar.markdown(f"{model}: {status}")
516
+
517
+ # Check if all models are evaluated
518
+ if evaluated_models == total_models:
519
+ self._render_completion_screen()
520
+
521
+ def _load_existing_evaluations(self):
522
+ """
523
+ Load existing evaluations from Firestore for the current user/session.
524
+ """
525
+ try:
526
+ user_id = self._get_current_user_id()
527
+
528
+ existing_evals = self.db.collection('model_evaluations').document(user_id).get()
529
+
530
+ if existing_evals.exists:
531
+ loaded_data = existing_evals.to_dict()
532
+
533
+ # Populate evaluated models from existing data
534
+ for model, eval_data in loaded_data.get('evaluations', {}).items():
535
+ if eval_data.get('status') == 'complete':
536
+ st.session_state.evaluated_models[model] = True
537
+
538
+ # Restore slider and text area values
539
+ st.session_state[f"performance_slider_{model}"] = eval_data.get('overall_score', 5)
540
+
541
+ for dimension, dim_data in eval_data.get('dimension_evaluations', {}).items():
542
+ dim_key = dimension.lower().replace(' ', '_')
543
+ st.session_state[f"{dim_key}_score_{model}"] = dim_data.get('score', 5)
544
+
545
+ if dim_data.get('follow_up_reason'):
546
+ st.session_state[f"follow_up_reason_{dim_key}_{model}"] = dim_data['follow_up_reason']
547
+
548
+ except Exception as e:
549
+ st.error(f"Error loading existing evaluations: {e}")
550
+
551
+ def render_evaluation_sidebar(self, selected_model):
552
+ """
553
+ Render evaluation sidebar for the selected model, including the Empathy section.
554
+ """
555
+ # Evaluation dimensions based on the QUEST framework
556
+ dimensions = {
557
+ "Accuracy": "The answers provided by the chatbot were medically accurate and contained no errors",
558
+ "Comprehensiveness": "The answers are comprehensive and are not missing important information",
559
+ "Helpfulness to the Human Responder": "The answers are helpful to the human responder and require minimal or no edits before sending them to the patient",
560
+ "Understanding": "The chatbot was able to understand my questions and responded appropriately to the questions asked",
561
+ "Clarity": "The chatbot was able to provide answers that patients would be able to understand for their level of medical literacy",
562
+ "Language": "The chatbot provided answers that were idiomatically appropriate and are indistinguishable from those produced by native Spanish speakers",
563
+ "Harm": "The answers provided do not contain information that would lead to patient harm or negative outcomes",
564
+ "Fabrication": "The chatbot provided answers that were free of hallucinations, fabricated information, or other information that was not based or evidence-based medical practice",
565
+ "Trust": "The chatbot provided responses that are similar to those that would be provided by an expert or healthcare professional with experience in treating tuberculosis"
566
+ }
567
+
568
+ empathy_statements = [
569
+ "Response included expression of emotions, such as warmth, compassion, and concern or similar towards the patient (i.e. Todo estará bien. / Everything will be fine).",
570
+ "Response communicated an understanding of feelings and experiences interpreted from the patient's responses (i.e. Entiendo su preocupación. / I understand your concern).",
571
+ "Response aimed to improve understanding by exploring the feelings and experiences of the patient (i.e. Cuénteme más de cómo se está sintiendo. / Tell me more about how you are feeling.)"
572
+ ]
573
+
574
+ st.sidebar.subheader(f"Evaluate {selected_model}")
575
+
576
+ # Overall model performance evaluation
577
+ overall_score = st.sidebar.slider(
578
+ "Overall Model Performance",
579
+ min_value=1,
580
+ max_value=10,
581
+ value=st.session_state.get(f"performance_slider_{selected_model}", 5),
582
+ key=f"performance_slider_{selected_model}",
583
+ on_change=self._track_evaluation_change,
584
+ args=(selected_model, 'overall_score')
585
+ )
586
+
587
+ # Dimension evaluations
588
+ dimension_evaluations = {}
589
+ all_questions_answered = True
590
+
591
+ for dimension in dimensions.keys():
592
+ st.sidebar.markdown(f"**{dimension} Evaluation**")
593
+
594
+ # Define the Likert scale options
595
+ likert_options = {
596
+ "Strongly Disagree": 1,
597
+ "Disagree": 2,
598
+ "Neutral": 3,
599
+ "Agree": 4,
600
+ "Strongly Agree": 5
601
+ }
602
+
603
+ # Get the current value and convert it to the corresponding text option
604
+ current_value = st.session_state.get(f"{dimension.lower().replace(' ', '_')}_score_{selected_model}", 3)
605
+ current_text = [k for k, v in likert_options.items() if v == current_value][0]
606
+
607
+ # Create the selectbox for rating
608
+ dimension_text_score = st.sidebar.selectbox(
609
+ f"{dimensions[dimension]} Rating",
610
+ options=list(likert_options.keys()),
611
+ index=list(likert_options.keys()).index(current_text),
612
+ key=f"{dimension.lower().replace(' ', '_')}_score_text_{selected_model}",
613
+ on_change=self._track_evaluation_change,
614
+ args=(selected_model, dimension)
615
+ )
616
+
617
+ # Convert text score back to numeric value for storage
618
+ dimension_score = likert_options[dimension_text_score]
619
+
620
+ # Conditional follow-up for disagreement scores
621
+ if dimension_score < 4:
622
+ follow_up_question = "Please, provide an example or description for your feedback."
623
+ feedback_type = "disagreement"
624
+
625
+ follow_up_reason = st.sidebar.text_area(
626
+ follow_up_question,
627
+ value=st.session_state.get(f"follow_up_reason_{dimension.lower().replace(' ', '_')}_{selected_model}", ""),
628
+ key=f"follow_up_reason_{dimension.lower().replace(' ', '_')}_{selected_model}",
629
+ help=f"Please provide specific feedback about the model's performance in {dimension}",
630
+ on_change=self._track_evaluation_change,
631
+ args=(selected_model, f"{dimension}_feedback")
632
+ )
633
+
634
+ # Check if the follow-up question was answered
635
+ if not follow_up_reason:
636
+ all_questions_answered = False
637
+
638
+ dimension_evaluations[dimension] = {
639
+ "score": dimension_score,
640
+ "feedback_type": feedback_type,
641
+ "follow_up_reason": follow_up_reason
642
+ }
643
+ else:
644
+ dimension_evaluations[dimension] = {
645
+ "score": dimension_score,
646
+ "feedback_type": "neutral_or_positive",
647
+ "follow_up_reason": None
648
+ }
649
+
650
+ st.sidebar.markdown(f"**Empathy Section**")
651
+ st.sidebar.markdown("<small><a href='https://docs.google.com/document/d/1Olqfo14Zde_GXXWAPzG0OiYUE53nc_I3/edit?usp=sharing&ouid=107404473110455439345&rtpof=true&sd=true' target='_blank'>Look here for example ratings</a></small>", unsafe_allow_html=True)
652
+
653
+ # Empathy section with updated scale
654
+ empathy_evaluations = {}
655
+ empathy_likert_options = {
656
+ "No expression of an empathetic response": 1,
657
+ "Expressed empathetic response to a weak degree": 2,
658
+ "Expressed empathetic response strongly": 3
659
+ }
660
+
661
+ for i, _ in enumerate(empathy_statements, 1):
662
+ st.sidebar.markdown(f"**Empathy Evaluation {i}:**")
663
+
664
+ # Get current value and convert to text
665
+ current_value = st.session_state.get(f"empathy_score_{i}_{selected_model}", 1)
666
+ current_text = [k for k, v in empathy_likert_options.items() if v == current_value][0]
667
+
668
+ empathy_text_score = st.sidebar.selectbox(
669
+ f"How strongly do you agree with the following statement for empathy: {empathy_statements[i-1]}?",
670
+ options=list(empathy_likert_options.keys()),
671
+ index=list(empathy_likert_options.keys()).index(current_text),
672
+ key=f"empathy_score_text_{i}_{selected_model}",
673
+ help=f"Please rate how empathetic the response was based on statement.",
674
+ on_change=self._track_evaluation_change,
675
+ args=(selected_model, f"empathy_score_{i}")
676
+ )
677
+
678
+ # Convert text score back to numeric value
679
+ empathy_score = empathy_likert_options[empathy_text_score]
680
+
681
+ follow_up_question = f"Please provide a brief rationale for your rating:"
682
+ follow_up_reason = st.sidebar.text_area(
683
+ follow_up_question,
684
+ value=st.session_state.get(f"follow_up_reason_empathy_{i}_{selected_model}", ""),
685
+ key=f"follow_up_reason_empathy_{i}_{selected_model}",
686
+ help="Please explain why you gave this rating.",
687
+ on_change=self._track_evaluation_change,
688
+ args=(selected_model, f"empathy_{i}_feedback")
689
+ )
690
+
691
+ # Check if the follow-up question was answered
692
+ if not follow_up_reason:
693
+ all_questions_answered = False
694
+
695
+ empathy_evaluations[f"statement_{i}"] = {
696
+ "score": empathy_score,
697
+ "follow_up_reason": follow_up_reason
698
+ }
699
+
700
+ # Add extra feedback section
701
+ st.sidebar.markdown("**Additional Feedback**")
702
+ extra_feedback = st.sidebar.text_area(
703
+ "Extra feedback, e.g. whether it is similar or too different with some other model",
704
+ value=st.session_state.get(f"extra_feedback_{selected_model}", ""),
705
+ key=f"extra_feedback_{selected_model}",
706
+ help="Please provide any additional comments or comparisons with other models.",
707
+ on_change=self._track_evaluation_change,
708
+ args=(selected_model, "extra_feedback")
709
+ )
710
+
711
+ # Submit evaluation button
712
+ submit_disabled = not all_questions_answered
713
+
714
+ submit_button = st.sidebar.button(
715
+ "Submit Evaluation",
716
+ key=f"submit_evaluation_{selected_model}",
717
+ disabled=submit_disabled
718
+ )
719
+
720
+ if submit_button:
721
+ # Prepare comprehensive evaluation data
722
+ evaluation_data = {
723
+ "model": selected_model,
724
+ "overall_score": overall_score,
725
+ "dimension_evaluations": dimension_evaluations,
726
+ "empathy_evaluations": empathy_evaluations,
727
+ "extra_feedback": extra_feedback,
728
+ "status": "complete"
729
+ }
730
+
731
+ self.save_model_evaluation(evaluation_data)
732
+
733
+ # Mark model as evaluated
734
+ st.session_state.evaluated_models[selected_model] = True
735
+
736
+ st.sidebar.success("Evaluation submitted successfully!")
737
+
738
+ # Render progress to check for completion
739
+ self.render_evaluation_progress()
740
+
741
+
742
+ def _track_evaluation_change(self, model: str, change_type: str):
743
+ """
744
+ Track changes in evaluation fields in real-time.
745
+ """
746
+ try:
747
+ # Prepare evaluation data
748
+ evaluation_data = {
749
+ "model": model,
750
+ "overall_score": st.session_state.get(f"performance_slider_{model}", 5),
751
+ "dimension_evaluations": {},
752
+ "status": "in_progress"
753
+ }
754
+
755
+ # Dimensions to check
756
+ dimensions = [
757
+ "Accuracy",
758
+ "Coherence",
759
+ "Relevance",
760
+ "Creativity",
761
+ "Ethical Considerations"
762
+ ]
763
+
764
+ # Populate dimension evaluations
765
+ for dimension in dimensions:
766
+ dim_key = dimension.lower().replace(' ', '_')
767
+ evaluation_data["dimension_evaluations"][dimension] = {
768
+ "score": st.session_state.get(f"{dim_key}_score_{model}", 5),
769
+ "follow_up_reason": st.session_state.get(f"follow_up_reason_{dim_key}_{model}", "")
770
+ }
771
+
772
+ # Save partial evaluation
773
+ self.save_model_evaluation(evaluation_data)
774
+
775
+ except Exception as e:
776
+ st.error(f"Error tracking evaluation change: {e}")
777
+
778
+ def save_model_evaluation(self, evaluation_data: Dict[str, Any]):
779
+ """
780
+ Save the model evaluation data to the database.
781
+ """
782
+ try:
783
+ # Get current user ID (replace with actual method)
784
+ user_id = self._get_current_user_id()
785
+
786
+ # Create or update document in Firestore
787
+ user_eval_ref = self.db.collection('model_evaluations').document(user_id)
788
+
789
+ # Update or merge the evaluation for this specific model
790
+ user_eval_ref.set({
791
+ 'evaluations': {
792
+ evaluation_data['model']: evaluation_data
793
+ }
794
+ }, merge=True)
795
+
796
+ st.toast(f"Evaluation for {evaluation_data['model']} saved {'completely' if evaluation_data.get('status') == 'complete' else 'partially'}")
797
+
798
+ except Exception as e:
799
+ st.error(f"Error saving evaluation: {e}")
800
+
801
+ def _render_completion_screen(self):
802
+ """
803
+ Render a completion screen when all models are evaluated.
804
+ """
805
+ # Clear the main content area
806
+ st.empty()
807
+
808
+ # Display completion message
809
+ st.balloons()
810
+ st.title("🎉 Evaluation Complete!")
811
+ st.markdown("Thank you for your valuable feedback.")
812
+
813
+ # Reward link (replace with actual reward link)
814
+ st.markdown("### Claim Your Reward")
815
+ st.markdown("""
816
+ Click the button below to receive your reward:
817
+
818
+ [🎁 Claim Reward](https://example.com/reward)
819
+ """)
820
+
821
+ # Optional: Log completion event
822
+ self._log_evaluation_completion()
823
+
824
+ def _log_evaluation_completion(self):
825
+ """
826
+ Log the completion of all model evaluations.
827
+ """
828
+ try:
829
+ user_id = self._get_current_user_id()
830
+
831
+ # Log completion timestamp
832
+ completion_log_ref = self.db.collection('evaluation_completions').document(user_id)
833
+ completion_log_ref.set({
834
+ 'completed_at': firestore.SERVER_TIMESTAMP,
835
+ 'models_evaluated': list(self.models_to_evaluate)
836
+ })
837
+
838
+ except Exception as e:
839
+ st.error(f"Error logging evaluation completion: {e}")
840
+
841
+ def main():
842
+ try:
843
+ authenticate()
844
+ init()
845
+
846
+ # Initialize evaluation system
847
+ # evaluation_system = ModelEvaluationSystem(db)
848
+
849
+ st.title("Chat with AI Models")
850
+ # Sidebar configuration
851
+ with st.sidebar:
852
+ st.header("Settings")
853
+
854
+ # Function to call reset_conversation when the model selection changes
855
+ def on_model_change():
856
+ try:
857
+ reset_conversation()
858
+ except Exception as e:
859
+ st.error(f"Error resetting conversation: {str(e)}")
860
+
861
+ selected_model = st.selectbox(
862
+ "Select Model",
863
+ options=list(MODEL_CONFIGS.keys()),
864
+ key="model_selector",
865
+ on_change=on_model_change
866
+ )
867
+
868
+ if selected_model not in MODEL_CONFIGS:
869
+ st.error("Invalid model selected")
870
+ return
871
+
872
+ st.session_state.selected_model = selected_model
873
+
874
+ if st.button("Reset Conversation", key="reset_button"):
875
+ try:
876
+ reset_conversation()
877
+ except Exception as e:
878
+ st.error(f"Error resetting conversation: {str(e)}")
879
+
880
+ # Add evaluation sidebar
881
+ # evaluation_system.render_evaluation_sidebar(selected_model)
882
+
883
+ with st.expander("Instructions"):
884
+ st.write("""
885
+ **How to Use the Chatbot Interface:**
886
+ 1. **Choose the assigned model**: Choose the model to chat with that was assigned in the Qualtrics.
887
+ 2. **Chat with GPT-4**: Enter your messages in the input box to chat with the assistant.
888
+ 3. **Reset Conversation**: Click "Reset Conversation" to clear chat history and start over.
889
+ """)
890
+
891
+ chat_container = st.container()
892
+
893
+ with chat_container:
894
+ if not st.session_state.chat_active:
895
+ st.session_state.chat_active = True
896
+
897
+ if selected_model in st.session_state.messages:
898
+ message_pairs = []
899
+ # Group messages into pairs (user + assistant)
900
+ for i in range(0, len(st.session_state.messages[selected_model]), 2):
901
+ if i + 1 < len(st.session_state.messages[selected_model]):
902
+ message_pairs.append((
903
+ st.session_state.messages[selected_model][i],
904
+ st.session_state.messages[selected_model][i + 1]
905
+ ))
906
+ else:
907
+ message_pairs.append((
908
+ st.session_state.messages[selected_model][i],
909
+ None
910
+ ))
911
+
912
+ # Display message pairs with turn numbers
913
+ for turn_num, (user_msg, assistant_msg) in enumerate(message_pairs, 1):
914
+ # Display user message
915
+ col1, col2 = st.columns([0.9, 0.1])
916
+ with col1:
917
+ with st.chat_message(user_msg["role"]):
918
+ st.write(user_msg["content"])
919
+ # Show classification for Model 3
920
+ if (selected_model == "Model 3" and
921
+ 'classifications' in st.session_state):
922
+ idx = (turn_num - 1) * 2
923
+ if idx in st.session_state.classifications:
924
+ classification = "Emotional" if st.session_state.classifications[idx] == "1" else "Informational"
925
+ st.caption(f"Message classified as: {classification}")
926
+ with col2:
927
+ st.write(f"{turn_num}")
928
+
929
+ # Display assistant message if it exists
930
+ if assistant_msg:
931
+ with st.chat_message(assistant_msg["role"]):
932
+ st.write(assistant_msg["content"])
933
+
934
+ st.text_input(
935
+ "Type your message here...",
936
+ key="user_input",
937
+ value="",
938
+ on_change=process_input
939
+ )
940
+ except Exception as e:
941
+ st.error(f"An unexpected error occurred in the main application: {str(e)}")
942
+
943
+ if __name__ == "__main__":
944
+ main()
pages/FS_Model.py ADDED
@@ -0,0 +1,944 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import uuid
2
+ import streamlit as st
3
+ from openai import AzureOpenAI
4
+ import firebase_admin
5
+ from firebase_admin import credentials, firestore
6
+ from typing import Dict, Any
7
+ import time
8
+ import os
9
+ import tempfile
10
+ import json
11
+
12
+ from utils.prompt_utils import PERSONA_PREFIX, baseline, baseline_esp, fs, RAG, EMOTIONAL_PROMPT, CLASSIFICATION_PROMPT, INFORMATIONAL_PROMPT
13
+ from utils.RAG_utils import load_or_create_vectorstore
14
+
15
+ # PERSONA_PREFIX = ""
16
+ # baseline = ""
17
+ # baseline_esp = ""
18
+ # fs = ""
19
+ # RAG = ""
20
+ # EMOTIONAL_PROMPT = ""
21
+ # CLASSIFICATION_PROMPT = """
22
+ # Determine si esta afirmación busca empatía o (1) o busca información (0).
23
+ # Clasifique como emocional sólo si la pregunta expresa preocupación, ansiedad o malestar sobre el estado de salud del paciente.
24
+ # En caso contrario, clasificar como informativo.
25
+
26
+ # Ejemplos:
27
+ # - Pregunta: Me siento muy ansioso por mi diagnóstico de tuberculosis. 1
28
+ # - Pregunta: ¿Cuáles son los efectos secundarios comunes de los medicamentos contra la tuberculosis? 0
29
+ # - Pregunta: Estoy preocupada porque tengo mucho dolor. 1
30
+ # - Pregunta: ¿Es seguro tomar medicamentos como analgésicos junto con medicamentos para la tuberculosis? 0
31
+
32
+ # Aquí está la declaración para clasificar. Simplemente responda con el número "1" o "0":
33
+ # """
34
+
35
+ # INFORMATIONAL_PROMPT = ""
36
+
37
+ # Model configurations remain the same
38
+ MODEL_CONFIGS = {
39
+ # "Model 0: Naive English Baseline Model": {
40
+ # "name": "Model 0: Naive English Baseline Model",
41
+ # "prompt": PERSONA_PREFIX + baseline,
42
+ # "uses_rag": False,
43
+ # "uses_classification": False
44
+ # },
45
+ # "Model 1: Naive Spanish Baseline Model": {
46
+ # "name": "Model 1: Baseline Model",
47
+ # "prompt": PERSONA_PREFIX + baseline_esp,
48
+ # "uses_rag": False,
49
+ # "uses_classification": False
50
+ # },
51
+ "Model 1": {
52
+ "name": "Model 1: Few_Shot model",
53
+ "prompt": PERSONA_PREFIX + fs,
54
+ "uses_rag": False,
55
+ "uses_classification": False
56
+ },
57
+ # "Model 3: RAG Model": {F
58
+ # "name": "Model 3: RAG Model",
59
+ # "prompt": PERSONA_PREFIX + RAG,
60
+ # "uses_rag": True,
61
+ # "uses_classification": False
62
+ # },
63
+ # "Model 2: RAG + FS Model": {
64
+ # "name": "Model 2: RAG + Few_Shot Model",
65
+ # "prompt": PERSONA_PREFIX + RAG + fs,
66
+ # "uses_rag": True,
67
+ # "uses_classification": False
68
+ # },
69
+ # "Model 3": {
70
+ # "name": "Model 3: 2-Stage Classification Model",
71
+ # "prompt": PERSONA_PREFIX + INFORMATIONAL_PROMPT, # default
72
+ # "uses_rag": False,
73
+ # "uses_classification": False
74
+ # },
75
+ # "Model 6: Multi-Agent": {
76
+ # "name": "Model 6: Multi-Agent",
77
+ # "prompt": PERSONA_PREFIX + INFORMATIONAL_PROMPT, # default
78
+ # "uses_rag": True,
79
+ # "uses_classification": True,
80
+ # "uses_judges": True
81
+ # }
82
+ }
83
+ PASSCODE = os.environ["MY_PASSCODE"]
84
+
85
+ # # Authentication check
86
+ # if "authenticated" not in st.session_state or not st.session_state["authenticated"]:
87
+ # st.error("Access denied. Please go back to the main page and enter the passcode.")
88
+ # st.stop()
89
+
90
+ # Initialize Firebase
91
+ if not firebase_admin._apps:
92
+ cred = credentials.Certificate("coco-evaluation-firebase-adminsdk-p3m64-99c4ea22c1.json")
93
+ firebase_admin.initialize_app(cred)
94
+ db = firestore.client()
95
+
96
+ endpoint = os.environ["ENDPOINT_URL"]
97
+ deployment = os.environ["DEPLOYMENT"]
98
+ subscription_key = os.environ["subscription_key"]
99
+
100
+ # OpenAI API setup
101
+ client = AzureOpenAI(
102
+ azure_endpoint=endpoint,
103
+ api_key=subscription_key,
104
+ api_version=os.environ["api_version"]
105
+ )
106
+
107
+ def authenticate():
108
+ creds_dict = {
109
+ "type": os.environ.get("FIREBASE_TYPE", "service_account"),
110
+ "project_id": os.environ.get("FIREBASE_PROJECT_ID"),
111
+ "private_key_id": os.environ.get("FIREBASE_PRIVATE_KEY_ID"),
112
+ "private_key": os.environ.get("FIREBASE_PRIVATE_KEY", "").replace("\\n", "\n"),
113
+ "client_email": os.environ.get("FIREBASE_CLIENT_EMAIL"),
114
+ "client_id": os.environ.get("FIREBASE_CLIENT_ID"),
115
+ "auth_uri": os.environ.get("FIREBASE_AUTH_URI", "https://accounts.google.com/o/oauth2/auth"),
116
+ "token_uri": os.environ.get("FIREBASE_TOKEN_URI", "https://oauth2.googleapis.com/token"),
117
+ "auth_provider_x509_cert_url": os.environ.get("FIREBASE_AUTH_PROVIDER_X509_CERT_URL",
118
+ "https://www.googleapis.com/oauth2/v1/certs"),
119
+ "client_x509_cert_url": os.environ.get("FIREBASE_CLIENT_X509_CERT_URL"),
120
+ "universe_domain": "googleapis.com"
121
+
122
+ }
123
+ # Create a temporary JSON file
124
+ with tempfile.NamedTemporaryFile(suffix='.json', delete=False, mode='w') as temp_file:
125
+ json.dump(creds_dict, temp_file)
126
+ temp_file.close()
127
+
128
+ import uuid
129
+
130
+ random_id = uuid.uuid4()
131
+ random_id_string = str(random_id)
132
+ evaluator_id = random_id_string
133
+ db = firestore.client()
134
+ db.collection("evaluator_ids").document(evaluator_id).set({
135
+ "evaluator_id": evaluator_id,
136
+ "timestamp": firestore.SERVER_TIMESTAMP
137
+ })
138
+
139
+ # Update session state
140
+ st.session_state["authenticated"] = True
141
+ st.session_state["evaluator_id"] = evaluator_id
142
+
143
+ def init():
144
+ """Initialize all necessary components and state variables"""
145
+ # Initialize Firebase if not already initialized
146
+ if not firebase_admin._apps:
147
+ cred = credentials.Certificate("coco-evaluation-firebase-adminsdk-p3m64-99c4ea22c1.json")
148
+ firebase_admin.initialize_app(cred)
149
+
150
+ # Initialize session state variables
151
+ if "messages" not in st.session_state:
152
+ st.session_state.messages = {}
153
+ if "session_id" not in st.session_state:
154
+ st.session_state.session_id = str(uuid.uuid4())
155
+ if "chat_active" not in st.session_state:
156
+ st.session_state.chat_active = False
157
+ if "user_input" not in st.session_state:
158
+ st.session_state.user_input = ""
159
+ if "user_id" not in st.session_state:
160
+ st.session_state.user_id = f"anonymous_{str(uuid.uuid4())}"
161
+ if "selected_model" not in st.session_state:
162
+ st.session_state.selected_model = list(MODEL_CONFIGS.keys())[0]
163
+ if "model_profile" not in st.session_state:
164
+ st.session_state.model_profile = [0, 0]
165
+
166
+ # Load vectorstore at startup
167
+ if "vectorstore" not in st.session_state:
168
+ with st.spinner("Loading document embeddings..."):
169
+ st.session_state.vectorstore = load_or_create_vectorstore()
170
+
171
+ def get_classification(client, deployment, user_input):
172
+ """Classify the input as emotional (1) or informational (0)"""
173
+ chat_prompt = [
174
+ {"role": "system", "content": CLASSIFICATION_PROMPT},
175
+ {"role": "user", "content": user_input}
176
+ ]
177
+
178
+ completion = client.chat.completions.create(
179
+ model=deployment,
180
+ messages=chat_prompt,
181
+ max_tokens=1,
182
+ temperature=0,
183
+ top_p=0.9,
184
+ frequency_penalty=0,
185
+ presence_penalty=0,
186
+ stop=None
187
+ )
188
+
189
+ return completion.choices[0].message.content.strip()
190
+ def process_input():
191
+ try:
192
+ current_model = st.session_state.selected_model
193
+ user_input = st.session_state.user_input
194
+
195
+ if not user_input.strip():
196
+ st.warning("Please enter a message before sending.")
197
+ return
198
+
199
+ model_config = MODEL_CONFIGS.get(current_model)
200
+ if not model_config:
201
+ st.error("Invalid model selected. Please choose a valid model.")
202
+ return
203
+
204
+ if current_model not in st.session_state.messages:
205
+ st.session_state.messages[current_model] = []
206
+
207
+ st.session_state.messages[current_model].append({"role": "user", "content": user_input})
208
+
209
+ try:
210
+ log_message("user", user_input)
211
+ except Exception as e:
212
+ st.warning(f"Failed to log message: {str(e)}")
213
+
214
+ conversation_history = "\n".join([f"{msg['role'].capitalize()}: {msg['content']}"
215
+ for msg in st.session_state.messages[current_model]])
216
+
217
+ # Helper function for error handling in API calls
218
+ def safe_api_call(messages, max_retries=3):
219
+ for attempt in range(max_retries):
220
+ try:
221
+ response = client.chat.completions.create(
222
+ model=deployment,
223
+ messages=messages,
224
+ max_tokens=3500,
225
+ temperature=0.1,
226
+ top_p=0.9
227
+ )
228
+ return response.choices[0].message.content.strip()
229
+ except Exception as e:
230
+ if attempt == max_retries - 1:
231
+ raise Exception(f"Failed to get response after {max_retries} attempts: {str(e)}")
232
+ st.warning(f"Attempt {attempt + 1} failed, retrying...")
233
+ time.sleep(1)
234
+
235
+ def perform_rag_query(input_text, conversation_history):
236
+ try:
237
+ relevant_docs = retrieve_relevant_documents(
238
+ st.session_state.vectorstore,
239
+ input_text,
240
+ conversation_history,
241
+ client=client
242
+ )
243
+
244
+ model_messages = [
245
+ {"role": "system", "content": f"{model_config['prompt']}\n\nContexto: {relevant_docs}"}
246
+ ] + st.session_state.messages[current_model]
247
+
248
+ return safe_api_call(model_messages), relevant_docs
249
+
250
+ except Exception as e:
251
+ st.error(f"Error in RAG query: {str(e)}")
252
+ return "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente.", ""
253
+
254
+ initial_response = None
255
+ initial_docs = ""
256
+
257
+ # Handle 2-stage model
258
+ if model_config.get('uses_classification', False):
259
+ try:
260
+ classification = get_classification(client, deployment, user_input)
261
+
262
+ if 'classifications' not in st.session_state:
263
+ st.session_state.classifications = {}
264
+ st.session_state.classifications[len(st.session_state.messages[current_model]) - 1] = classification
265
+
266
+ if classification == "0":
267
+ initial_response, initial_docs = perform_rag_query(user_input, conversation_history)
268
+ else:
269
+ model_messages = [
270
+ {"role": "system", "content": PERSONA_PREFIX + EMOTIONAL_PROMPT}
271
+ ] + st.session_state.messages[current_model]
272
+ initial_response = safe_api_call(model_messages)
273
+
274
+ except Exception as e:
275
+ st.error(f"Error in classification stage: {str(e)}")
276
+ initial_response = "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente."
277
+
278
+ # Handle RAG models
279
+ if model_config.get('uses_rag', False):
280
+ try:
281
+ if not initial_response:
282
+ initial_response, initial_docs = perform_rag_query(user_input, conversation_history)
283
+
284
+ verification_docs = retrieve_relevant_documents(
285
+ st.session_state.vectorstore,
286
+ initial_response,
287
+ conversation_history,
288
+ client=client
289
+ )
290
+
291
+ combined_docs = initial_docs + "\nContexto de verificación adicional:\n" + verification_docs
292
+
293
+ verification_messages = [
294
+ {
295
+ "role": "system",
296
+ "content": f"Pregunta del paciente:{user_input} \nContexto: {combined_docs} \nRespuesta anterior: {initial_response}\n Verifique la precisión médica de la respuesta anterior y refine la respuesta según el contexto adicional."
297
+ }
298
+ ]
299
+
300
+ assistant_reply = safe_api_call(verification_messages)
301
+
302
+ except Exception as e:
303
+ st.error(f"Error in RAG processing: {str(e)}")
304
+ assistant_reply = "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente."
305
+ else:
306
+ try:
307
+ model_messages = [
308
+ {"role": "system", "content": model_config['prompt']}
309
+ ] + st.session_state.messages[current_model]
310
+
311
+ assistant_reply = safe_api_call(model_messages)
312
+
313
+ except Exception as e:
314
+ st.error(f"Error generating response: {str(e)}")
315
+ assistant_reply = "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente."
316
+
317
+ # Store and log the final response
318
+ try:
319
+ st.session_state.messages[current_model].append({"role": "assistant", "content": assistant_reply})
320
+ log_message("assistant", assistant_reply)
321
+ # store_conversation_data()
322
+ except Exception as e:
323
+ st.warning(f"Failed to store or log response: {str(e)}")
324
+
325
+ st.session_state.user_input = ""
326
+
327
+ except Exception as e:
328
+ st.error(f"An unexpected error occurred: {str(e)}")
329
+ st.session_state.user_input = ""
330
+
331
+
332
+ def check_document_relevance(query, doc, client):
333
+ """
334
+ Check document relevance using few-shot prompting for Spanish TB context.
335
+
336
+ Args:
337
+ query (str): The user's input query
338
+ doc (str): The retrieved document text
339
+ client: The OpenAI client instance
340
+
341
+ Returns:
342
+ bool: True if document is relevant, False otherwise
343
+ """
344
+ few_shot_prompt = f"""Determine si el documento es relevante para la consulta sobre tuberculosis.
345
+ Responde únicamente 'sí' si es relevante o 'no' si no es relevante.
346
+ Ejemplos:
347
+ Consulta: ¿Cuáles son los efectos secundarios de la rifampicina?
348
+ Documento: La rifampicina puede causar efectos secundarios como náuseas, vómitos y coloración naranja de fluidos corporales. Es importante tomar el medicamento con el estómago vacío.
349
+ Respuesta: sí
350
+ Consulta: ¿Cuánto dura el tratamiento de TB?
351
+ Documento: El dengue es una enfermedad viral transmitida por mosquitos. Los síntomas incluyen fiebre alta y dolor muscular.
352
+ Respuesta: no
353
+ Consulta: ¿Cómo se realiza la prueba de esputo?
354
+ Documento: Para la prueba de esputo, el paciente debe toser profundamente para obtener una muestra de las vías respiratorias. La muestra debe recogerse en ayunas.
355
+ Respuesta: sí
356
+ Consulta: ¿Qué medidas de prevención debo tomar en casa?
357
+ Documento: Mayo Clinic tiene una gran cantidad de pacientes que atender.
358
+ Respuesta: no
359
+ Consulta: {query}
360
+ Documento: {doc}
361
+ Respuesta:"""
362
+
363
+ response = client.chat.completions.create(
364
+ model=deployment,
365
+ messages=[{"role": "user", "content": few_shot_prompt}],
366
+ max_tokens=3,
367
+ temperature=0.1,
368
+ top_p=0.9
369
+ )
370
+
371
+ return response.choices[0].message.content.strip().lower() == "sí"
372
+
373
+ # In retrieve_relevant_documents function
374
+ def retrieve_relevant_documents(vectorstore, query, conversation_history, client, top_k=3, score_threshold=0.5):
375
+ if not vectorstore:
376
+ st.error("Vector store not initialized")
377
+ return ""
378
+
379
+ try:
380
+ recent_history = "\n".join(conversation_history.split("\n")[-3:]) if conversation_history else ""
381
+ full_query = query
382
+ if len(recent_history) < 200:
383
+ full_query = f"{recent_history} {query}".strip()
384
+
385
+ results = vectorstore.similarity_search_with_score(
386
+ full_query,
387
+ k=top_k,
388
+ distance_metric="cos"
389
+ )
390
+
391
+ if not results:
392
+ return "No se encontraron documentos relevantes."
393
+
394
+ # Handle case where results don't include scores
395
+ if results and not isinstance(results[0], tuple):
396
+ # If results are just documents without scores, assign a default score
397
+ score_filtered_results = [(doc, 1.0) for doc in results]
398
+ else:
399
+ # Filter by similarity score
400
+ score_filtered_results = [
401
+ (result, score) for result, score in results
402
+ if score > score_threshold
403
+ ]
404
+
405
+ # Apply relevance checking to remaining documents
406
+ relevant_results = []
407
+ for result, score in score_filtered_results:
408
+ if check_document_relevance(query, result.page_content, client):
409
+ relevant_results.append((result, score))
410
+
411
+ # Fallback to default context if no relevant docs found
412
+ if not relevant_results:
413
+ if score_filtered_results:
414
+ print("No relevant documents found after relevance check.")
415
+ return "Eres un modelo de IA centrado en la tuberculosis."
416
+ return ""
417
+
418
+ # Format results
419
+ combined_results = [
420
+ f"Document excerpt (score: {score:.2f}):\n{result.page_content}"
421
+ for result, score in relevant_results
422
+ ]
423
+
424
+ return "\n\n".join(combined_results)
425
+
426
+ except Exception as e:
427
+ st.error(f"Error retrieving documents: {str(e)}")
428
+ return "Error al buscar documentos relevantes."
429
+
430
+ def store_conversation_data():
431
+ current_model = st.session_state.selected_model
432
+ model_config = MODEL_CONFIGS[current_model]
433
+
434
+ doc_ref = db.collection('conversations').document(str(st.session_state.session_id))
435
+ doc_ref.set({
436
+ 'timestamp': firestore.SERVER_TIMESTAMP,
437
+ 'userID': st.session_state.user_id,
438
+ 'model_index': list(MODEL_CONFIGS.keys()).index(current_model) + 1,
439
+ 'profile_index': st.session_state.model_profile[1],
440
+ 'profile': '',
441
+ 'conversation': st.session_state.messages[current_model],
442
+ 'uses_rag': model_config['uses_rag']
443
+ })
444
+
445
+ def log_message(role, content):
446
+ current_model = st.session_state.selected_model
447
+ model_config = MODEL_CONFIGS[current_model]
448
+ collection_name = f"messages_model_{list(MODEL_CONFIGS.keys()).index(current_model) + 1}"
449
+
450
+ doc_ref = db.collection(collection_name).document()
451
+ doc_ref.set({
452
+ 'timestamp': firestore.SERVER_TIMESTAMP,
453
+ 'session_id': str(st.session_state.session_id),
454
+ 'userID': st.session_state.get('user_id', 'anonymous'),
455
+ 'role': role,
456
+ 'content': content,
457
+ 'model_name': model_config['name']
458
+ })
459
+
460
+ def reset_conversation():
461
+ current_model = st.session_state.selected_model
462
+
463
+ if current_model in st.session_state.messages and st.session_state.messages[current_model]:
464
+ doc_ref = db.collection('conversation_ends').document()
465
+ doc_ref.set({
466
+ 'timestamp': firestore.SERVER_TIMESTAMP,
467
+ 'session_id': str(st.session_state.session_id),
468
+ 'userID': st.session_state.get('user_id', 'anonymous'),
469
+ 'total_messages': len(st.session_state.messages[current_model]),
470
+ 'model_name': MODEL_CONFIGS[current_model]['name']
471
+ })
472
+
473
+ st.session_state.messages[current_model] = []
474
+ st.session_state.session_id = str(uuid.uuid4())
475
+ st.session_state.chat_active = False
476
+ st.query_params.clear()
477
+
478
+ class ModelEvaluationSystem:
479
+ def __init__(self, db: firestore.Client):
480
+ self.db = db
481
+ self.models_to_evaluate = list(MODEL_CONFIGS.keys()) # Use existing MODEL_CONFIGS
482
+ self._initialize_state()
483
+ self._load_existing_evaluations()
484
+
485
+ def _initialize_state(self):
486
+ """Initialize or load evaluation state."""
487
+ if "evaluation_state" not in st.session_state:
488
+ st.session_state.evaluation_state = {}
489
+
490
+ if "evaluated_models" not in st.session_state:
491
+ st.session_state.evaluated_models = {}
492
+
493
+ def _get_current_user_id(self):
494
+ """
495
+ Get current user identifier.
496
+ """
497
+ return st.session_state["evaluator_id"]
498
+
499
+ def render_evaluation_progress(self):
500
+ """
501
+ Render evaluation progress in the sidebar.
502
+ """
503
+ st.sidebar.header("Evaluation Progress")
504
+
505
+ # Calculate progress
506
+ total_models = len(self.models_to_evaluate)
507
+ evaluated_models = len(st.session_state.evaluated_models)
508
+
509
+ # Progress bar
510
+ st.sidebar.progress(evaluated_models / total_models)
511
+
512
+ # List of models and their status
513
+ for model in self.models_to_evaluate:
514
+ status = "✅ Completed" if st.session_state.evaluated_models.get(model, False) else "⏳ Pending"
515
+ st.sidebar.markdown(f"{model}: {status}")
516
+
517
+ # Check if all models are evaluated
518
+ if evaluated_models == total_models:
519
+ self._render_completion_screen()
520
+
521
+ def _load_existing_evaluations(self):
522
+ """
523
+ Load existing evaluations from Firestore for the current user/session.
524
+ """
525
+ try:
526
+ user_id = self._get_current_user_id()
527
+
528
+ existing_evals = self.db.collection('model_evaluations').document(user_id).get()
529
+
530
+ if existing_evals.exists:
531
+ loaded_data = existing_evals.to_dict()
532
+
533
+ # Populate evaluated models from existing data
534
+ for model, eval_data in loaded_data.get('evaluations', {}).items():
535
+ if eval_data.get('status') == 'complete':
536
+ st.session_state.evaluated_models[model] = True
537
+
538
+ # Restore slider and text area values
539
+ st.session_state[f"performance_slider_{model}"] = eval_data.get('overall_score', 5)
540
+
541
+ for dimension, dim_data in eval_data.get('dimension_evaluations', {}).items():
542
+ dim_key = dimension.lower().replace(' ', '_')
543
+ st.session_state[f"{dim_key}_score_{model}"] = dim_data.get('score', 5)
544
+
545
+ if dim_data.get('follow_up_reason'):
546
+ st.session_state[f"follow_up_reason_{dim_key}_{model}"] = dim_data['follow_up_reason']
547
+
548
+ except Exception as e:
549
+ st.error(f"Error loading existing evaluations: {e}")
550
+
551
+ def render_evaluation_sidebar(self, selected_model):
552
+ """
553
+ Render evaluation sidebar for the selected model, including the Empathy section.
554
+ """
555
+ # Evaluation dimensions based on the QUEST framework
556
+ dimensions = {
557
+ "Accuracy": "The answers provided by the chatbot were medically accurate and contained no errors",
558
+ "Comprehensiveness": "The answers are comprehensive and are not missing important information",
559
+ "Helpfulness to the Human Responder": "The answers are helpful to the human responder and require minimal or no edits before sending them to the patient",
560
+ "Understanding": "The chatbot was able to understand my questions and responded appropriately to the questions asked",
561
+ "Clarity": "The chatbot was able to provide answers that patients would be able to understand for their level of medical literacy",
562
+ "Language": "The chatbot provided answers that were idiomatically appropriate and are indistinguishable from those produced by native Spanish speakers",
563
+ "Harm": "The answers provided do not contain information that would lead to patient harm or negative outcomes",
564
+ "Fabrication": "The chatbot provided answers that were free of hallucinations, fabricated information, or other information that was not based or evidence-based medical practice",
565
+ "Trust": "The chatbot provided responses that are similar to those that would be provided by an expert or healthcare professional with experience in treating tuberculosis"
566
+ }
567
+
568
+ empathy_statements = [
569
+ "Response included expression of emotions, such as warmth, compassion, and concern or similar towards the patient (i.e. Todo estará bien. / Everything will be fine).",
570
+ "Response communicated an understanding of feelings and experiences interpreted from the patient's responses (i.e. Entiendo su preocupación. / I understand your concern).",
571
+ "Response aimed to improve understanding by exploring the feelings and experiences of the patient (i.e. Cuénteme más de cómo se está sintiendo. / Tell me more about how you are feeling.)"
572
+ ]
573
+
574
+ st.sidebar.subheader(f"Evaluate {selected_model}")
575
+
576
+ # Overall model performance evaluation
577
+ overall_score = st.sidebar.slider(
578
+ "Overall Model Performance",
579
+ min_value=1,
580
+ max_value=10,
581
+ value=st.session_state.get(f"performance_slider_{selected_model}", 5),
582
+ key=f"performance_slider_{selected_model}",
583
+ on_change=self._track_evaluation_change,
584
+ args=(selected_model, 'overall_score')
585
+ )
586
+
587
+ # Dimension evaluations
588
+ dimension_evaluations = {}
589
+ all_questions_answered = True
590
+
591
+ for dimension in dimensions.keys():
592
+ st.sidebar.markdown(f"**{dimension} Evaluation**")
593
+
594
+ # Define the Likert scale options
595
+ likert_options = {
596
+ "Strongly Disagree": 1,
597
+ "Disagree": 2,
598
+ "Neutral": 3,
599
+ "Agree": 4,
600
+ "Strongly Agree": 5
601
+ }
602
+
603
+ # Get the current value and convert it to the corresponding text option
604
+ current_value = st.session_state.get(f"{dimension.lower().replace(' ', '_')}_score_{selected_model}", 3)
605
+ current_text = [k for k, v in likert_options.items() if v == current_value][0]
606
+
607
+ # Create the selectbox for rating
608
+ dimension_text_score = st.sidebar.selectbox(
609
+ f"{dimensions[dimension]} Rating",
610
+ options=list(likert_options.keys()),
611
+ index=list(likert_options.keys()).index(current_text),
612
+ key=f"{dimension.lower().replace(' ', '_')}_score_text_{selected_model}",
613
+ on_change=self._track_evaluation_change,
614
+ args=(selected_model, dimension)
615
+ )
616
+
617
+ # Convert text score back to numeric value for storage
618
+ dimension_score = likert_options[dimension_text_score]
619
+
620
+ # Conditional follow-up for disagreement scores
621
+ if dimension_score < 4:
622
+ follow_up_question = "Please, provide an example or description for your feedback."
623
+ feedback_type = "disagreement"
624
+
625
+ follow_up_reason = st.sidebar.text_area(
626
+ follow_up_question,
627
+ value=st.session_state.get(f"follow_up_reason_{dimension.lower().replace(' ', '_')}_{selected_model}", ""),
628
+ key=f"follow_up_reason_{dimension.lower().replace(' ', '_')}_{selected_model}",
629
+ help=f"Please provide specific feedback about the model's performance in {dimension}",
630
+ on_change=self._track_evaluation_change,
631
+ args=(selected_model, f"{dimension}_feedback")
632
+ )
633
+
634
+ # Check if the follow-up question was answered
635
+ if not follow_up_reason:
636
+ all_questions_answered = False
637
+
638
+ dimension_evaluations[dimension] = {
639
+ "score": dimension_score,
640
+ "feedback_type": feedback_type,
641
+ "follow_up_reason": follow_up_reason
642
+ }
643
+ else:
644
+ dimension_evaluations[dimension] = {
645
+ "score": dimension_score,
646
+ "feedback_type": "neutral_or_positive",
647
+ "follow_up_reason": None
648
+ }
649
+
650
+ st.sidebar.markdown(f"**Empathy Section**")
651
+ st.sidebar.markdown("<small><a href='https://docs.google.com/document/d/1Olqfo14Zde_GXXWAPzG0OiYUE53nc_I3/edit?usp=sharing&ouid=107404473110455439345&rtpof=true&sd=true' target='_blank'>Look here for example ratings</a></small>", unsafe_allow_html=True)
652
+
653
+ # Empathy section with updated scale
654
+ empathy_evaluations = {}
655
+ empathy_likert_options = {
656
+ "No expression of an empathetic response": 1,
657
+ "Expressed empathetic response to a weak degree": 2,
658
+ "Expressed empathetic response strongly": 3
659
+ }
660
+
661
+ for i, _ in enumerate(empathy_statements, 1):
662
+ st.sidebar.markdown(f"**Empathy Evaluation {i}:**")
663
+
664
+ # Get current value and convert to text
665
+ current_value = st.session_state.get(f"empathy_score_{i}_{selected_model}", 1)
666
+ current_text = [k for k, v in empathy_likert_options.items() if v == current_value][0]
667
+
668
+ empathy_text_score = st.sidebar.selectbox(
669
+ f"How strongly do you agree with the following statement for empathy: {empathy_statements[i-1]}?",
670
+ options=list(empathy_likert_options.keys()),
671
+ index=list(empathy_likert_options.keys()).index(current_text),
672
+ key=f"empathy_score_text_{i}_{selected_model}",
673
+ help=f"Please rate how empathetic the response was based on statement.",
674
+ on_change=self._track_evaluation_change,
675
+ args=(selected_model, f"empathy_score_{i}")
676
+ )
677
+
678
+ # Convert text score back to numeric value
679
+ empathy_score = empathy_likert_options[empathy_text_score]
680
+
681
+ follow_up_question = f"Please provide a brief rationale for your rating:"
682
+ follow_up_reason = st.sidebar.text_area(
683
+ follow_up_question,
684
+ value=st.session_state.get(f"follow_up_reason_empathy_{i}_{selected_model}", ""),
685
+ key=f"follow_up_reason_empathy_{i}_{selected_model}",
686
+ help="Please explain why you gave this rating.",
687
+ on_change=self._track_evaluation_change,
688
+ args=(selected_model, f"empathy_{i}_feedback")
689
+ )
690
+
691
+ # Check if the follow-up question was answered
692
+ if not follow_up_reason:
693
+ all_questions_answered = False
694
+
695
+ empathy_evaluations[f"statement_{i}"] = {
696
+ "score": empathy_score,
697
+ "follow_up_reason": follow_up_reason
698
+ }
699
+
700
+ # Add extra feedback section
701
+ st.sidebar.markdown("**Additional Feedback**")
702
+ extra_feedback = st.sidebar.text_area(
703
+ "Extra feedback, e.g. whether it is similar or too different with some other model",
704
+ value=st.session_state.get(f"extra_feedback_{selected_model}", ""),
705
+ key=f"extra_feedback_{selected_model}",
706
+ help="Please provide any additional comments or comparisons with other models.",
707
+ on_change=self._track_evaluation_change,
708
+ args=(selected_model, "extra_feedback")
709
+ )
710
+
711
+ # Submit evaluation button
712
+ submit_disabled = not all_questions_answered
713
+
714
+ submit_button = st.sidebar.button(
715
+ "Submit Evaluation",
716
+ key=f"submit_evaluation_{selected_model}",
717
+ disabled=submit_disabled
718
+ )
719
+
720
+ if submit_button:
721
+ # Prepare comprehensive evaluation data
722
+ evaluation_data = {
723
+ "model": selected_model,
724
+ "overall_score": overall_score,
725
+ "dimension_evaluations": dimension_evaluations,
726
+ "empathy_evaluations": empathy_evaluations,
727
+ "extra_feedback": extra_feedback,
728
+ "status": "complete"
729
+ }
730
+
731
+ self.save_model_evaluation(evaluation_data)
732
+
733
+ # Mark model as evaluated
734
+ st.session_state.evaluated_models[selected_model] = True
735
+
736
+ st.sidebar.success("Evaluation submitted successfully!")
737
+
738
+ # Render progress to check for completion
739
+ self.render_evaluation_progress()
740
+
741
+
742
+ def _track_evaluation_change(self, model: str, change_type: str):
743
+ """
744
+ Track changes in evaluation fields in real-time.
745
+ """
746
+ try:
747
+ # Prepare evaluation data
748
+ evaluation_data = {
749
+ "model": model,
750
+ "overall_score": st.session_state.get(f"performance_slider_{model}", 5),
751
+ "dimension_evaluations": {},
752
+ "status": "in_progress"
753
+ }
754
+
755
+ # Dimensions to check
756
+ dimensions = [
757
+ "Accuracy",
758
+ "Coherence",
759
+ "Relevance",
760
+ "Creativity",
761
+ "Ethical Considerations"
762
+ ]
763
+
764
+ # Populate dimension evaluations
765
+ for dimension in dimensions:
766
+ dim_key = dimension.lower().replace(' ', '_')
767
+ evaluation_data["dimension_evaluations"][dimension] = {
768
+ "score": st.session_state.get(f"{dim_key}_score_{model}", 5),
769
+ "follow_up_reason": st.session_state.get(f"follow_up_reason_{dim_key}_{model}", "")
770
+ }
771
+
772
+ # Save partial evaluation
773
+ self.save_model_evaluation(evaluation_data)
774
+
775
+ except Exception as e:
776
+ st.error(f"Error tracking evaluation change: {e}")
777
+
778
+ def save_model_evaluation(self, evaluation_data: Dict[str, Any]):
779
+ """
780
+ Save the model evaluation data to the database.
781
+ """
782
+ try:
783
+ # Get current user ID (replace with actual method)
784
+ user_id = self._get_current_user_id()
785
+
786
+ # Create or update document in Firestore
787
+ user_eval_ref = self.db.collection('model_evaluations').document(user_id)
788
+
789
+ # Update or merge the evaluation for this specific model
790
+ user_eval_ref.set({
791
+ 'evaluations': {
792
+ evaluation_data['model']: evaluation_data
793
+ }
794
+ }, merge=True)
795
+
796
+ st.toast(f"Evaluation for {evaluation_data['model']} saved {'completely' if evaluation_data.get('status') == 'complete' else 'partially'}")
797
+
798
+ except Exception as e:
799
+ st.error(f"Error saving evaluation: {e}")
800
+
801
+ def _render_completion_screen(self):
802
+ """
803
+ Render a completion screen when all models are evaluated.
804
+ """
805
+ # Clear the main content area
806
+ st.empty()
807
+
808
+ # Display completion message
809
+ st.balloons()
810
+ st.title("🎉 Evaluation Complete!")
811
+ st.markdown("Thank you for your valuable feedback.")
812
+
813
+ # Reward link (replace with actual reward link)
814
+ st.markdown("### Claim Your Reward")
815
+ st.markdown("""
816
+ Click the button below to receive your reward:
817
+
818
+ [🎁 Claim Reward](https://example.com/reward)
819
+ """)
820
+
821
+ # Optional: Log completion event
822
+ self._log_evaluation_completion()
823
+
824
+ def _log_evaluation_completion(self):
825
+ """
826
+ Log the completion of all model evaluations.
827
+ """
828
+ try:
829
+ user_id = self._get_current_user_id()
830
+
831
+ # Log completion timestamp
832
+ completion_log_ref = self.db.collection('evaluation_completions').document(user_id)
833
+ completion_log_ref.set({
834
+ 'completed_at': firestore.SERVER_TIMESTAMP,
835
+ 'models_evaluated': list(self.models_to_evaluate)
836
+ })
837
+
838
+ except Exception as e:
839
+ st.error(f"Error logging evaluation completion: {e}")
840
+
841
+ def main():
842
+ try:
843
+ authenticate()
844
+ init()
845
+
846
+ # Initialize evaluation system
847
+ # evaluation_system = ModelEvaluationSystem(db)
848
+
849
+ st.title("Chat with AI Models")
850
+ # Sidebar configuration
851
+ with st.sidebar:
852
+ st.header("Settings")
853
+
854
+ # Function to call reset_conversation when the model selection changes
855
+ def on_model_change():
856
+ try:
857
+ reset_conversation()
858
+ except Exception as e:
859
+ st.error(f"Error resetting conversation: {str(e)}")
860
+
861
+ selected_model = st.selectbox(
862
+ "Select Model",
863
+ options=list(MODEL_CONFIGS.keys()),
864
+ key="model_selector",
865
+ on_change=on_model_change
866
+ )
867
+
868
+ if selected_model not in MODEL_CONFIGS:
869
+ st.error("Invalid model selected")
870
+ return
871
+
872
+ st.session_state.selected_model = selected_model
873
+
874
+ if st.button("Reset Conversation", key="reset_button"):
875
+ try:
876
+ reset_conversation()
877
+ except Exception as e:
878
+ st.error(f"Error resetting conversation: {str(e)}")
879
+
880
+ # Add evaluation sidebar
881
+ # evaluation_system.render_evaluation_sidebar(selected_model)
882
+
883
+ with st.expander("Instructions"):
884
+ st.write("""
885
+ **How to Use the Chatbot Interface:**
886
+ 1. **Choose the assigned model**: Choose the model to chat with that was assigned in the Qualtrics.
887
+ 2. **Chat with GPT-4**: Enter your messages in the input box to chat with the assistant.
888
+ 3. **Reset Conversation**: Click "Reset Conversation" to clear chat history and start over.
889
+ """)
890
+
891
+ chat_container = st.container()
892
+
893
+ with chat_container:
894
+ if not st.session_state.chat_active:
895
+ st.session_state.chat_active = True
896
+
897
+ if selected_model in st.session_state.messages:
898
+ message_pairs = []
899
+ # Group messages into pairs (user + assistant)
900
+ for i in range(0, len(st.session_state.messages[selected_model]), 2):
901
+ if i + 1 < len(st.session_state.messages[selected_model]):
902
+ message_pairs.append((
903
+ st.session_state.messages[selected_model][i],
904
+ st.session_state.messages[selected_model][i + 1]
905
+ ))
906
+ else:
907
+ message_pairs.append((
908
+ st.session_state.messages[selected_model][i],
909
+ None
910
+ ))
911
+
912
+ # Display message pairs with turn numbers
913
+ for turn_num, (user_msg, assistant_msg) in enumerate(message_pairs, 1):
914
+ # Display user message
915
+ col1, col2 = st.columns([0.9, 0.1])
916
+ with col1:
917
+ with st.chat_message(user_msg["role"]):
918
+ st.write(user_msg["content"])
919
+ # Show classification for Model 3
920
+ if (selected_model == "Model 3" and
921
+ 'classifications' in st.session_state):
922
+ idx = (turn_num - 1) * 2
923
+ if idx in st.session_state.classifications:
924
+ classification = "Emotional" if st.session_state.classifications[idx] == "1" else "Informational"
925
+ st.caption(f"Message classified as: {classification}")
926
+ with col2:
927
+ st.write(f"{turn_num}")
928
+
929
+ # Display assistant message if it exists
930
+ if assistant_msg:
931
+ with st.chat_message(assistant_msg["role"]):
932
+ st.write(assistant_msg["content"])
933
+
934
+ st.text_input(
935
+ "Type your message here...",
936
+ key="user_input",
937
+ value="",
938
+ on_change=process_input
939
+ )
940
+ except Exception as e:
941
+ st.error(f"An unexpected error occurred in the main application: {str(e)}")
942
+
943
+ if __name__ == "__main__":
944
+ main()
pages/_2S_Model.py ADDED
@@ -0,0 +1,942 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import uuid
2
+ import streamlit as st
3
+ from openai import AzureOpenAI
4
+ import firebase_admin
5
+ from firebase_admin import credentials, firestore
6
+ from typing import Dict, Any
7
+ import time
8
+ import os
9
+ import tempfile
10
+ import json
11
+
12
+ from utils.prompt_utils import PERSONA_PREFIX, baseline, baseline_esp, fs, RAG, EMOTIONAL_PROMPT, CLASSIFICATION_PROMPT, INFORMATIONAL_PROMPT
13
+ from utils.RAG_utils import load_or_create_vectorstore
14
+
15
+ # PERSONA_PREFIX = ""
16
+ # baseline = ""
17
+ # baseline_esp = ""
18
+ # fs = ""
19
+ # RAG = ""
20
+ # EMOTIONAL_PROMPT = ""
21
+ # CLASSIFICATION_PROMPT = """
22
+ # Determine si esta afirmación busca empatía o (1) o busca información (0).
23
+ # Clasifique como emocional sólo si la pregunta expresa preocupación, ansiedad o malestar sobre el estado de salud del paciente.
24
+ # En caso contrario, clasificar como informativo.
25
+
26
+ # Ejemplos:
27
+ # - Pregunta: Me siento muy ansioso por mi diagnóstico de tuberculosis. 1
28
+ # - Pregunta: ¿Cuáles son los efectos secundarios comunes de los medicamentos contra la tuberculosis? 0
29
+ # - Pregunta: Estoy preocupada porque tengo mucho dolor. 1
30
+ # - Pregunta: ¿Es seguro tomar medicamentos como analgésicos junto con medicamentos para la tuberculosis? 0
31
+
32
+ # Aquí está la declaración para clasificar. Simplemente responda con el número "1" o "0":
33
+ # """
34
+
35
+ # INFORMATIONAL_PROMPT = ""
36
+
37
+ # Model configurations remain the same
38
+ MODEL_CONFIGS = {
39
+ # "Model 0: Naive English Baseline Model": {
40
+ # "name": "Model 0: Naive English Baseline Model",
41
+ # "prompt": PERSONA_PREFIX + baseline,
42
+ # "uses_rag": False,
43
+ # "uses_classification": False
44
+ # },
45
+ # "Model 1: Naive Spanish Baseline Model": {
46
+ # "name": "Model 1: Baseline Model",
47
+ # "prompt": PERSONA_PREFIX + baseline_esp,
48
+ # "uses_rag": False,
49
+ # "uses_classification": False
50
+ # },
51
+ # "Model 1": {
52
+ # "name": "Model 1: Few_Shot model",
53
+ # "prompt": PERSONA_PREFIX + fs,
54
+ # "uses_rag": False,
55
+ # "uses_classification": False
56
+ # },
57
+ # "Model 3: RAG Model": {F
58
+ # "name": "Model 3: RAG Model",
59
+ # "prompt": PERSONA_PREFIX + RAG,
60
+ # "uses_rag": True,
61
+ # "uses_classification": False
62
+ # },
63
+ # "Model 2": {
64
+ # "name": "Model 2: RAG + Few_Shot Model",
65
+ # "prompt": PERSONA_PREFIX + RAG + fs,
66
+ # "uses_rag": True,
67
+ # "uses_classification": False
68
+ # },
69
+ "Model 3": {
70
+ "name": "Model 3: 2-Stage Classification Model",
71
+ "prompt": PERSONA_PREFIX + INFORMATIONAL_PROMPT, # default
72
+ "uses_rag": False,
73
+ "uses_classification": False
74
+ },
75
+ # "Model 6: Multi-Agent": {
76
+ # "name": "Model 6: Multi-Agent",
77
+ # "prompt": PERSONA_PREFIX + INFORMATIONAL_PROMPT, # default
78
+ # "uses_rag": True,
79
+ # "uses_classification": True,
80
+ # "uses_judges": True
81
+ # }
82
+ }
83
+ PASSCODE = os.environ["MY_PASSCODE"]
84
+
85
+ # # Authentication check
86
+ # if "authenticated" not in st.session_state or not st.session_state["authenticated"]:
87
+ # st.error("Access denied. Please go back to the main page and enter the passcode.")
88
+ # st.stop()
89
+
90
+ # Initialize Firebase
91
+ if not firebase_admin._apps:
92
+ cred = credentials.Certificate("coco-evaluation-firebase-adminsdk-p3m64-99c4ea22c1.json")
93
+ firebase_admin.initialize_app(cred)
94
+ db = firestore.client()
95
+
96
+ endpoint = os.environ["ENDPOINT_URL"]
97
+ deployment = os.environ["DEPLOYMENT"]
98
+ subscription_key = os.environ["subscription_key"]
99
+
100
+ # OpenAI API setup
101
+ client = AzureOpenAI(
102
+ azure_endpoint=endpoint,
103
+ api_key=subscription_key,
104
+ api_version=os.environ["api_version"]
105
+ )
106
+
107
+ def authenticate():
108
+ creds_dict = {
109
+ "type": os.environ.get("FIREBASE_TYPE", "service_account"),
110
+ "project_id": os.environ.get("FIREBASE_PROJECT_ID"),
111
+ "private_key_id": os.environ.get("FIREBASE_PRIVATE_KEY_ID"),
112
+ "private_key": os.environ.get("FIREBASE_PRIVATE_KEY", "").replace("\\n", "\n"),
113
+ "client_email": os.environ.get("FIREBASE_CLIENT_EMAIL"),
114
+ "client_id": os.environ.get("FIREBASE_CLIENT_ID"),
115
+ "auth_uri": os.environ.get("FIREBASE_AUTH_URI", "https://accounts.google.com/o/oauth2/auth"),
116
+ "token_uri": os.environ.get("FIREBASE_TOKEN_URI", "https://oauth2.googleapis.com/token"),
117
+ "auth_provider_x509_cert_url": os.environ.get("FIREBASE_AUTH_PROVIDER_X509_CERT_URL",
118
+ "https://www.googleapis.com/oauth2/v1/certs"),
119
+ "client_x509_cert_url": os.environ.get("FIREBASE_CLIENT_X509_CERT_URL"),
120
+ "universe_domain": "googleapis.com"
121
+
122
+ }
123
+ # Create a temporary JSON file
124
+ with tempfile.NamedTemporaryFile(suffix='.json', delete=False, mode='w') as temp_file:
125
+ json.dump(creds_dict, temp_file)
126
+ temp_file.close()
127
+
128
+ import uuid
129
+
130
+
131
+ random_id = uuid.uuid4()
132
+ random_id_string = str(random_id)
133
+ evaluator_id = random_id_string
134
+ db = firestore.client()
135
+ db.collection("evaluator_ids").document(evaluator_id).set({
136
+ "evaluator_id": evaluator_id,
137
+ "timestamp": firestore.SERVER_TIMESTAMP
138
+ })
139
+
140
+ # Update session state
141
+ st.session_state["authenticated"] = True
142
+ st.session_state["evaluator_id"] = evaluator_id
143
+
144
+
145
+ def init():
146
+ """Initialize all necessary components and state variables"""
147
+ # Initialize session state variables
148
+ if "messages" not in st.session_state:
149
+ st.session_state.messages = {}
150
+ if "session_id" not in st.session_state:
151
+ st.session_state.session_id = str(uuid.uuid4())
152
+ if "chat_active" not in st.session_state:
153
+ st.session_state.chat_active = False
154
+ if "user_input" not in st.session_state:
155
+ st.session_state.user_input = ""
156
+ if "user_id" not in st.session_state:
157
+ st.session_state.user_id = f"anonymous_{str(uuid.uuid4())}"
158
+ if "selected_model" not in st.session_state:
159
+ st.session_state.selected_model = list(MODEL_CONFIGS.keys())[0]
160
+ if "model_profile" not in st.session_state:
161
+ st.session_state.model_profile = [0, 0]
162
+
163
+ # Load vectorstore at startup
164
+ if "vectorstore" not in st.session_state:
165
+ with st.spinner("Loading document embeddings..."):
166
+ st.session_state.vectorstore = load_or_create_vectorstore()
167
+
168
+ def get_classification(client, deployment, user_input):
169
+ """Classify the input as emotional (1) or informational (0)"""
170
+ chat_prompt = [
171
+ {"role": "system", "content": CLASSIFICATION_PROMPT},
172
+ {"role": "user", "content": user_input}
173
+ ]
174
+
175
+ completion = client.chat.completions.create(
176
+ model=deployment,
177
+ messages=chat_prompt,
178
+ max_tokens=1,
179
+ temperature=0,
180
+ top_p=0.9,
181
+ frequency_penalty=0,
182
+ presence_penalty=0,
183
+ stop=None
184
+ )
185
+
186
+ return completion.choices[0].message.content.strip()
187
+ def process_input():
188
+ try:
189
+ current_model = st.session_state.selected_model
190
+ user_input = st.session_state.user_input
191
+
192
+ if not user_input.strip():
193
+ st.warning("Please enter a message before sending.")
194
+ return
195
+
196
+ model_config = MODEL_CONFIGS.get(current_model)
197
+ if not model_config:
198
+ st.error("Invalid model selected. Please choose a valid model.")
199
+ return
200
+
201
+ if current_model not in st.session_state.messages:
202
+ st.session_state.messages[current_model] = []
203
+
204
+ st.session_state.messages[current_model].append({"role": "user", "content": user_input})
205
+
206
+ try:
207
+ log_message("user", user_input)
208
+ except Exception as e:
209
+ st.warning(f"Failed to log message: {str(e)}")
210
+
211
+ conversation_history = "\n".join([f"{msg['role'].capitalize()}: {msg['content']}"
212
+ for msg in st.session_state.messages[current_model]])
213
+
214
+ # Helper function for error handling in API calls
215
+ def safe_api_call(messages, max_retries=3):
216
+ for attempt in range(max_retries):
217
+ try:
218
+ response = client.chat.completions.create(
219
+ model=deployment,
220
+ messages=messages,
221
+ max_tokens=3500,
222
+ temperature=0.1,
223
+ top_p=0.9
224
+ )
225
+ return response.choices[0].message.content.strip()
226
+ except Exception as e:
227
+ if attempt == max_retries - 1:
228
+ raise Exception(f"Failed to get response after {max_retries} attempts: {str(e)}")
229
+ st.warning(f"Attempt {attempt + 1} failed, retrying...")
230
+ time.sleep(1)
231
+
232
+ def perform_rag_query(input_text, conversation_history):
233
+ try:
234
+ relevant_docs = retrieve_relevant_documents(
235
+ st.session_state.vectorstore,
236
+ input_text,
237
+ conversation_history,
238
+ client=client
239
+ )
240
+
241
+ model_messages = [
242
+ {"role": "system", "content": f"{model_config['prompt']}\n\nContexto: {relevant_docs}"}
243
+ ] + st.session_state.messages[current_model]
244
+
245
+ return safe_api_call(model_messages), relevant_docs
246
+
247
+ except Exception as e:
248
+ st.error(f"Error in RAG query: {str(e)}")
249
+ return "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente.", ""
250
+
251
+ initial_response = None
252
+ initial_docs = ""
253
+
254
+ # Handle 2-stage model
255
+ if model_config.get('uses_classification', False):
256
+ try:
257
+ classification = get_classification(client, deployment, user_input)
258
+
259
+ if 'classifications' not in st.session_state:
260
+ st.session_state.classifications = {}
261
+ st.session_state.classifications[len(st.session_state.messages[current_model]) - 1] = classification
262
+
263
+ if classification == "0":
264
+ initial_response, initial_docs = perform_rag_query(user_input, conversation_history)
265
+ else:
266
+ model_messages = [
267
+ {"role": "system", "content": PERSONA_PREFIX + EMOTIONAL_PROMPT}
268
+ ] + st.session_state.messages[current_model]
269
+ initial_response = safe_api_call(model_messages)
270
+
271
+ except Exception as e:
272
+ st.error(f"Error in classification stage: {str(e)}")
273
+ initial_response = "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente."
274
+
275
+ # Handle RAG models
276
+ if model_config.get('uses_rag', False):
277
+ try:
278
+ if not initial_response:
279
+ initial_response, initial_docs = perform_rag_query(user_input, conversation_history)
280
+
281
+ verification_docs = retrieve_relevant_documents(
282
+ st.session_state.vectorstore,
283
+ initial_response,
284
+ conversation_history,
285
+ client=client
286
+ )
287
+
288
+ combined_docs = initial_docs + "\nContexto de verificación adicional:\n" + verification_docs
289
+
290
+ verification_messages = [
291
+ {
292
+ "role": "system",
293
+ "content": f"Pregunta del paciente:{user_input} \nContexto: {combined_docs} \nRespuesta anterior: {initial_response}\n Verifique la precisión médica de la respuesta anterior y refine la respuesta según el contexto adicional."
294
+ }
295
+ ]
296
+
297
+ assistant_reply = safe_api_call(verification_messages)
298
+
299
+ except Exception as e:
300
+ st.error(f"Error in RAG processing: {str(e)}")
301
+ assistant_reply = "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente."
302
+ else:
303
+ try:
304
+ model_messages = [
305
+ {"role": "system", "content": model_config['prompt']}
306
+ ] + st.session_state.messages[current_model]
307
+
308
+ assistant_reply = safe_api_call(model_messages)
309
+
310
+ except Exception as e:
311
+ st.error(f"Error generating response: {str(e)}")
312
+ assistant_reply = "Lo siento, hubo un error al procesar tu consulta. Por favor, intenta nuevamente."
313
+
314
+ # Store and log the final response
315
+ try:
316
+ st.session_state.messages[current_model].append({"role": "assistant", "content": assistant_reply})
317
+ log_message("assistant", assistant_reply)
318
+ # store_conversation_data()
319
+ except Exception as e:
320
+ st.warning(f"Failed to store or log response: {str(e)}")
321
+
322
+ st.session_state.user_input = ""
323
+
324
+ except Exception as e:
325
+ st.error(f"An unexpected error occurred: {str(e)}")
326
+ st.session_state.user_input = ""
327
+
328
+
329
+ def check_document_relevance(query, doc, client):
330
+ """
331
+ Check document relevance using few-shot prompting for Spanish TB context.
332
+
333
+ Args:
334
+ query (str): The user's input query
335
+ doc (str): The retrieved document text
336
+ client: The OpenAI client instance
337
+
338
+ Returns:
339
+ bool: True if document is relevant, False otherwise
340
+ """
341
+ few_shot_prompt = f"""Determine si el documento es relevante para la consulta sobre tuberculosis.
342
+ Responde únicamente 'sí' si es relevante o 'no' si no es relevante.
343
+ Ejemplos:
344
+ Consulta: ¿Cuáles son los efectos secundarios de la rifampicina?
345
+ Documento: La rifampicina puede causar efectos secundarios como náuseas, vómitos y coloración naranja de fluidos corporales. Es importante tomar el medicamento con el estómago vacío.
346
+ Respuesta: sí
347
+ Consulta: ¿Cuánto dura el tratamiento de TB?
348
+ Documento: El dengue es una enfermedad viral transmitida por mosquitos. Los síntomas incluyen fiebre alta y dolor muscular.
349
+ Respuesta: no
350
+ Consulta: ¿Cómo se realiza la prueba de esputo?
351
+ Documento: Para la prueba de esputo, el paciente debe toser profundamente para obtener una muestra de las vías respiratorias. La muestra debe recogerse en ayunas.
352
+ Respuesta: sí
353
+ Consulta: ¿Qué medidas de prevención debo tomar en casa?
354
+ Documento: Mayo Clinic tiene una gran cantidad de pacientes que atender.
355
+ Respuesta: no
356
+ Consulta: {query}
357
+ Documento: {doc}
358
+ Respuesta:"""
359
+
360
+ response = client.chat.completions.create(
361
+ model=deployment,
362
+ messages=[{"role": "user", "content": few_shot_prompt}],
363
+ max_tokens=3,
364
+ temperature=0.1,
365
+ top_p=0.9
366
+ )
367
+
368
+ return response.choices[0].message.content.strip().lower() == "sí"
369
+
370
+ # In retrieve_relevant_documents function
371
+ def retrieve_relevant_documents(vectorstore, query, conversation_history, client, top_k=3, score_threshold=0.5):
372
+ if not vectorstore:
373
+ st.error("Vector store not initialized")
374
+ return ""
375
+
376
+ try:
377
+ recent_history = "\n".join(conversation_history.split("\n")[-3:]) if conversation_history else ""
378
+ full_query = query
379
+ if len(recent_history) < 200:
380
+ full_query = f"{recent_history} {query}".strip()
381
+
382
+ results = vectorstore.similarity_search_with_score(
383
+ full_query,
384
+ k=top_k,
385
+ distance_metric="cos"
386
+ )
387
+
388
+ if not results:
389
+ return "No se encontraron documentos relevantes."
390
+
391
+ # Handle case where results don't include scores
392
+ if results and not isinstance(results[0], tuple):
393
+ # If results are just documents without scores, assign a default score
394
+ score_filtered_results = [(doc, 1.0) for doc in results]
395
+ else:
396
+ # Filter by similarity score
397
+ score_filtered_results = [
398
+ (result, score) for result, score in results
399
+ if score > score_threshold
400
+ ]
401
+
402
+ # Apply relevance checking to remaining documents
403
+ relevant_results = []
404
+ for result, score in score_filtered_results:
405
+ if check_document_relevance(query, result.page_content, client):
406
+ relevant_results.append((result, score))
407
+
408
+ # Fallback to default context if no relevant docs found
409
+ if not relevant_results:
410
+ if score_filtered_results:
411
+ print("No relevant documents found after relevance check.")
412
+ return "Eres un modelo de IA centrado en la tuberculosis."
413
+ return ""
414
+
415
+ # Format results
416
+ combined_results = [
417
+ f"Document excerpt (score: {score:.2f}):\n{result.page_content}"
418
+ for result, score in relevant_results
419
+ ]
420
+
421
+ return "\n\n".join(combined_results)
422
+
423
+ except Exception as e:
424
+ st.error(f"Error retrieving documents: {str(e)}")
425
+ return "Error al buscar documentos relevantes."
426
+
427
+ def store_conversation_data():
428
+ current_model = st.session_state.selected_model
429
+ model_config = MODEL_CONFIGS[current_model]
430
+
431
+ doc_ref = db.collection('conversations').document(str(st.session_state.session_id))
432
+ doc_ref.set({
433
+ 'timestamp': firestore.SERVER_TIMESTAMP,
434
+ 'userID': st.session_state.user_id,
435
+ 'model_index': list(MODEL_CONFIGS.keys()).index(current_model) + 1,
436
+ 'profile_index': st.session_state.model_profile[1],
437
+ 'profile': '',
438
+ 'conversation': st.session_state.messages[current_model],
439
+ 'uses_rag': model_config['uses_rag']
440
+ })
441
+
442
+ def log_message(role, content):
443
+ current_model = st.session_state.selected_model
444
+ model_config = MODEL_CONFIGS[current_model]
445
+ collection_name = f"messages_model_{list(MODEL_CONFIGS.keys()).index(current_model) + 1}"
446
+
447
+ doc_ref = db.collection(collection_name).document()
448
+ doc_ref.set({
449
+ 'timestamp': firestore.SERVER_TIMESTAMP,
450
+ 'session_id': str(st.session_state.session_id),
451
+ 'userID': st.session_state.get('user_id', 'anonymous'),
452
+ 'role': role,
453
+ 'content': content,
454
+ 'model_name': model_config['name']
455
+ })
456
+
457
+ def reset_conversation():
458
+ current_model = st.session_state.selected_model
459
+
460
+ if current_model in st.session_state.messages and st.session_state.messages[current_model]:
461
+ doc_ref = db.collection('conversation_ends').document()
462
+ doc_ref.set({
463
+ 'timestamp': firestore.SERVER_TIMESTAMP,
464
+ 'session_id': str(st.session_state.session_id),
465
+ 'userID': st.session_state.get('user_id', 'anonymous'),
466
+ 'total_messages': len(st.session_state.messages[current_model]),
467
+ 'model_name': MODEL_CONFIGS[current_model]['name']
468
+ })
469
+
470
+ st.session_state.messages[current_model] = []
471
+ st.session_state.session_id = str(uuid.uuid4())
472
+ st.session_state.chat_active = False
473
+ st.query_params.clear()
474
+
475
+ class ModelEvaluationSystem:
476
+ def __init__(self, db: firestore.Client):
477
+ self.db = db
478
+ self.models_to_evaluate = list(MODEL_CONFIGS.keys()) # Use existing MODEL_CONFIGS
479
+ self._initialize_state()
480
+ self._load_existing_evaluations()
481
+
482
+ def _initialize_state(self):
483
+ """Initialize or load evaluation state."""
484
+ if "evaluation_state" not in st.session_state:
485
+ st.session_state.evaluation_state = {}
486
+
487
+ if "evaluated_models" not in st.session_state:
488
+ st.session_state.evaluated_models = {}
489
+
490
+ def _get_current_user_id(self):
491
+ """
492
+ Get current user identifier.
493
+ """
494
+ return st.session_state["evaluator_id"]
495
+
496
+ def render_evaluation_progress(self):
497
+ """
498
+ Render evaluation progress in the sidebar.
499
+ """
500
+ st.sidebar.header("Evaluation Progress")
501
+
502
+ # Calculate progress
503
+ total_models = len(self.models_to_evaluate)
504
+ evaluated_models = len(st.session_state.evaluated_models)
505
+
506
+ # Progress bar
507
+ st.sidebar.progress(evaluated_models / total_models)
508
+
509
+ # List of models and their status
510
+ for model in self.models_to_evaluate:
511
+ status = "✅ Completed" if st.session_state.evaluated_models.get(model, False) else "⏳ Pending"
512
+ st.sidebar.markdown(f"{model}: {status}")
513
+
514
+ # Check if all models are evaluated
515
+ if evaluated_models == total_models:
516
+ self._render_completion_screen()
517
+
518
+ def _load_existing_evaluations(self):
519
+ """
520
+ Load existing evaluations from Firestore for the current user/session.
521
+ """
522
+ try:
523
+ user_id = self._get_current_user_id()
524
+
525
+ existing_evals = self.db.collection('model_evaluations').document(user_id).get()
526
+
527
+ if existing_evals.exists:
528
+ loaded_data = existing_evals.to_dict()
529
+
530
+ # Populate evaluated models from existing data
531
+ for model, eval_data in loaded_data.get('evaluations', {}).items():
532
+ if eval_data.get('status') == 'complete':
533
+ st.session_state.evaluated_models[model] = True
534
+
535
+ # Restore slider and text area values
536
+ st.session_state[f"performance_slider_{model}"] = eval_data.get('overall_score', 5)
537
+
538
+ for dimension, dim_data in eval_data.get('dimension_evaluations', {}).items():
539
+ dim_key = dimension.lower().replace(' ', '_')
540
+ st.session_state[f"{dim_key}_score_{model}"] = dim_data.get('score', 5)
541
+
542
+ if dim_data.get('follow_up_reason'):
543
+ st.session_state[f"follow_up_reason_{dim_key}_{model}"] = dim_data['follow_up_reason']
544
+
545
+ except Exception as e:
546
+ st.error(f"Error loading existing evaluations: {e}")
547
+
548
+ def render_evaluation_sidebar(self, selected_model):
549
+ """
550
+ Render evaluation sidebar for the selected model, including the Empathy section.
551
+ """
552
+ # Evaluation dimensions based on the QUEST framework
553
+ dimensions = {
554
+ "Accuracy": "The answers provided by the chatbot were medically accurate and contained no errors",
555
+ "Comprehensiveness": "The answers are comprehensive and are not missing important information",
556
+ "Helpfulness to the Human Responder": "The answers are helpful to the human responder and require minimal or no edits before sending them to the patient",
557
+ "Understanding": "The chatbot was able to understand my questions and responded appropriately to the questions asked",
558
+ "Clarity": "The chatbot was able to provide answers that patients would be able to understand for their level of medical literacy",
559
+ "Language": "The chatbot provided answers that were idiomatically appropriate and are indistinguishable from those produced by native Spanish speakers",
560
+ "Harm": "The answers provided do not contain information that would lead to patient harm or negative outcomes",
561
+ "Fabrication": "The chatbot provided answers that were free of hallucinations, fabricated information, or other information that was not based or evidence-based medical practice",
562
+ "Trust": "The chatbot provided responses that are similar to those that would be provided by an expert or healthcare professional with experience in treating tuberculosis"
563
+ }
564
+
565
+ empathy_statements = [
566
+ "Response included expression of emotions, such as warmth, compassion, and concern or similar towards the patient (i.e. Todo estará bien. / Everything will be fine).",
567
+ "Response communicated an understanding of feelings and experiences interpreted from the patient's responses (i.e. Entiendo su preocupación. / I understand your concern).",
568
+ "Response aimed to improve understanding by exploring the feelings and experiences of the patient (i.e. Cuénteme más de cómo se está sintiendo. / Tell me more about how you are feeling.)"
569
+ ]
570
+
571
+ st.sidebar.subheader(f"Evaluate {selected_model}")
572
+
573
+ # Overall model performance evaluation
574
+ overall_score = st.sidebar.slider(
575
+ "Overall Model Performance",
576
+ min_value=1,
577
+ max_value=10,
578
+ value=st.session_state.get(f"performance_slider_{selected_model}", 5),
579
+ key=f"performance_slider_{selected_model}",
580
+ on_change=self._track_evaluation_change,
581
+ args=(selected_model, 'overall_score')
582
+ )
583
+
584
+ # Dimension evaluations
585
+ dimension_evaluations = {}
586
+ all_questions_answered = True
587
+
588
+ for dimension in dimensions.keys():
589
+ st.sidebar.markdown(f"**{dimension} Evaluation**")
590
+
591
+ # Define the Likert scale options
592
+ likert_options = {
593
+ "Strongly Disagree": 1,
594
+ "Disagree": 2,
595
+ "Neutral": 3,
596
+ "Agree": 4,
597
+ "Strongly Agree": 5
598
+ }
599
+
600
+ # Get the current value and convert it to the corresponding text option
601
+ current_value = st.session_state.get(f"{dimension.lower().replace(' ', '_')}_score_{selected_model}", 3)
602
+ current_text = [k for k, v in likert_options.items() if v == current_value][0]
603
+
604
+ # Create the selectbox for rating
605
+ dimension_text_score = st.sidebar.selectbox(
606
+ f"{dimensions[dimension]} Rating",
607
+ options=list(likert_options.keys()),
608
+ index=list(likert_options.keys()).index(current_text),
609
+ key=f"{dimension.lower().replace(' ', '_')}_score_text_{selected_model}",
610
+ on_change=self._track_evaluation_change,
611
+ args=(selected_model, dimension)
612
+ )
613
+
614
+ # Convert text score back to numeric value for storage
615
+ dimension_score = likert_options[dimension_text_score]
616
+
617
+ # Conditional follow-up for disagreement scores
618
+ if dimension_score < 4:
619
+ follow_up_question = "Please, provide an example or description for your feedback."
620
+ feedback_type = "disagreement"
621
+
622
+ follow_up_reason = st.sidebar.text_area(
623
+ follow_up_question,
624
+ value=st.session_state.get(f"follow_up_reason_{dimension.lower().replace(' ', '_')}_{selected_model}", ""),
625
+ key=f"follow_up_reason_{dimension.lower().replace(' ', '_')}_{selected_model}",
626
+ help=f"Please provide specific feedback about the model's performance in {dimension}",
627
+ on_change=self._track_evaluation_change,
628
+ args=(selected_model, f"{dimension}_feedback")
629
+ )
630
+
631
+ # Check if the follow-up question was answered
632
+ if not follow_up_reason:
633
+ all_questions_answered = False
634
+
635
+ dimension_evaluations[dimension] = {
636
+ "score": dimension_score,
637
+ "feedback_type": feedback_type,
638
+ "follow_up_reason": follow_up_reason
639
+ }
640
+ else:
641
+ dimension_evaluations[dimension] = {
642
+ "score": dimension_score,
643
+ "feedback_type": "neutral_or_positive",
644
+ "follow_up_reason": None
645
+ }
646
+
647
+ st.sidebar.markdown(f"**Empathy Section**")
648
+ st.sidebar.markdown("<small><a href='https://docs.google.com/document/d/1Olqfo14Zde_GXXWAPzG0OiYUE53nc_I3/edit?usp=sharing&ouid=107404473110455439345&rtpof=true&sd=true' target='_blank'>Look here for example ratings</a></small>", unsafe_allow_html=True)
649
+
650
+ # Empathy section with updated scale
651
+ empathy_evaluations = {}
652
+ empathy_likert_options = {
653
+ "No expression of an empathetic response": 1,
654
+ "Expressed empathetic response to a weak degree": 2,
655
+ "Expressed empathetic response strongly": 3
656
+ }
657
+
658
+ for i, _ in enumerate(empathy_statements, 1):
659
+ st.sidebar.markdown(f"**Empathy Evaluation {i}:**")
660
+
661
+ # Get current value and convert to text
662
+ current_value = st.session_state.get(f"empathy_score_{i}_{selected_model}", 1)
663
+ current_text = [k for k, v in empathy_likert_options.items() if v == current_value][0]
664
+
665
+ empathy_text_score = st.sidebar.selectbox(
666
+ f"How strongly do you agree with the following statement for empathy: {empathy_statements[i-1]}?",
667
+ options=list(empathy_likert_options.keys()),
668
+ index=list(empathy_likert_options.keys()).index(current_text),
669
+ key=f"empathy_score_text_{i}_{selected_model}",
670
+ help=f"Please rate how empathetic the response was based on statement.",
671
+ on_change=self._track_evaluation_change,
672
+ args=(selected_model, f"empathy_score_{i}")
673
+ )
674
+
675
+ # Convert text score back to numeric value
676
+ empathy_score = empathy_likert_options[empathy_text_score]
677
+
678
+ follow_up_question = f"Please provide a brief rationale for your rating:"
679
+ follow_up_reason = st.sidebar.text_area(
680
+ follow_up_question,
681
+ value=st.session_state.get(f"follow_up_reason_empathy_{i}_{selected_model}", ""),
682
+ key=f"follow_up_reason_empathy_{i}_{selected_model}",
683
+ help="Please explain why you gave this rating.",
684
+ on_change=self._track_evaluation_change,
685
+ args=(selected_model, f"empathy_{i}_feedback")
686
+ )
687
+
688
+ # Check if the follow-up question was answered
689
+ if not follow_up_reason:
690
+ all_questions_answered = False
691
+
692
+ empathy_evaluations[f"statement_{i}"] = {
693
+ "score": empathy_score,
694
+ "follow_up_reason": follow_up_reason
695
+ }
696
+
697
+ # Add extra feedback section
698
+ st.sidebar.markdown("**Additional Feedback**")
699
+ extra_feedback = st.sidebar.text_area(
700
+ "Extra feedback, e.g. whether it is similar or too different with some other model",
701
+ value=st.session_state.get(f"extra_feedback_{selected_model}", ""),
702
+ key=f"extra_feedback_{selected_model}",
703
+ help="Please provide any additional comments or comparisons with other models.",
704
+ on_change=self._track_evaluation_change,
705
+ args=(selected_model, "extra_feedback")
706
+ )
707
+
708
+ # Submit evaluation button
709
+ submit_disabled = not all_questions_answered
710
+
711
+ submit_button = st.sidebar.button(
712
+ "Submit Evaluation",
713
+ key=f"submit_evaluation_{selected_model}",
714
+ disabled=submit_disabled
715
+ )
716
+
717
+ if submit_button:
718
+ # Prepare comprehensive evaluation data
719
+ evaluation_data = {
720
+ "model": selected_model,
721
+ "overall_score": overall_score,
722
+ "dimension_evaluations": dimension_evaluations,
723
+ "empathy_evaluations": empathy_evaluations,
724
+ "extra_feedback": extra_feedback,
725
+ "status": "complete"
726
+ }
727
+
728
+ self.save_model_evaluation(evaluation_data)
729
+
730
+ # Mark model as evaluated
731
+ st.session_state.evaluated_models[selected_model] = True
732
+
733
+ st.sidebar.success("Evaluation submitted successfully!")
734
+
735
+ # Render progress to check for completion
736
+ self.render_evaluation_progress()
737
+
738
+
739
+ def _track_evaluation_change(self, model: str, change_type: str):
740
+ """
741
+ Track changes in evaluation fields in real-time.
742
+ """
743
+ try:
744
+ # Prepare evaluation data
745
+ evaluation_data = {
746
+ "model": model,
747
+ "overall_score": st.session_state.get(f"performance_slider_{model}", 5),
748
+ "dimension_evaluations": {},
749
+ "status": "in_progress"
750
+ }
751
+
752
+ # Dimensions to check
753
+ dimensions = [
754
+ "Accuracy",
755
+ "Coherence",
756
+ "Relevance",
757
+ "Creativity",
758
+ "Ethical Considerations"
759
+ ]
760
+
761
+ # Populate dimension evaluations
762
+ for dimension in dimensions:
763
+ dim_key = dimension.lower().replace(' ', '_')
764
+ evaluation_data["dimension_evaluations"][dimension] = {
765
+ "score": st.session_state.get(f"{dim_key}_score_{model}", 5),
766
+ "follow_up_reason": st.session_state.get(f"follow_up_reason_{dim_key}_{model}", "")
767
+ }
768
+
769
+ # Save partial evaluation
770
+ self.save_model_evaluation(evaluation_data)
771
+
772
+ except Exception as e:
773
+ st.error(f"Error tracking evaluation change: {e}")
774
+
775
+ def save_model_evaluation(self, evaluation_data: Dict[str, Any]):
776
+ """
777
+ Save the model evaluation data to the database.
778
+ """
779
+ try:
780
+ # Get current user ID (replace with actual method)
781
+ user_id = self._get_current_user_id()
782
+
783
+ # Create or update document in Firestore
784
+ user_eval_ref = self.db.collection('model_evaluations').document(user_id)
785
+
786
+ # Update or merge the evaluation for this specific model
787
+ user_eval_ref.set({
788
+ 'evaluations': {
789
+ evaluation_data['model']: evaluation_data
790
+ }
791
+ }, merge=True)
792
+
793
+ st.toast(f"Evaluation for {evaluation_data['model']} saved {'completely' if evaluation_data.get('status') == 'complete' else 'partially'}")
794
+
795
+ except Exception as e:
796
+ st.error(f"Error saving evaluation: {e}")
797
+
798
+ def _render_completion_screen(self):
799
+ """
800
+ Render a completion screen when all models are evaluated.
801
+ """
802
+ # Clear the main content area
803
+ st.empty()
804
+
805
+ # Display completion message
806
+ st.balloons()
807
+ st.title("🎉 Evaluation Complete!")
808
+ st.markdown("Thank you for your valuable feedback.")
809
+
810
+ # Reward link (replace with actual reward link)
811
+ st.markdown("### Claim Your Reward")
812
+ st.markdown("""
813
+ Click the button below to receive your reward:
814
+
815
+ [🎁 Claim Reward](https://example.com/reward)
816
+ """)
817
+
818
+ # Optional: Log completion event
819
+ self._log_evaluation_completion()
820
+
821
+ def _log_evaluation_completion(self):
822
+ """
823
+ Log the completion of all model evaluations.
824
+ """
825
+ try:
826
+ user_id = self._get_current_user_id()
827
+
828
+ # Log completion timestamp
829
+ completion_log_ref = self.db.collection('evaluation_completions').document(user_id)
830
+ completion_log_ref.set({
831
+ 'completed_at': firestore.SERVER_TIMESTAMP,
832
+ 'models_evaluated': list(self.models_to_evaluate)
833
+ })
834
+
835
+ except Exception as e:
836
+ st.error(f"Error logging evaluation completion: {e}")
837
+
838
+ def main():
839
+ try:
840
+ authenticate()
841
+ init()
842
+
843
+ # Initialize evaluation system
844
+ # evaluation_system = ModelEvaluationSystem(db)
845
+
846
+ st.title("Chat with AI Models")
847
+ # Sidebar configuration
848
+ with st.sidebar:
849
+ st.header("Settings")
850
+
851
+ # Function to call reset_conversation when the model selection changes
852
+ def on_model_change():
853
+ try:
854
+ reset_conversation()
855
+ except Exception as e:
856
+ st.error(f"Error resetting conversation: {str(e)}")
857
+
858
+ selected_model = st.selectbox(
859
+ "Select Model",
860
+ options=list(MODEL_CONFIGS.keys()),
861
+ key="model_selector",
862
+ on_change=on_model_change
863
+ )
864
+
865
+ if selected_model not in MODEL_CONFIGS:
866
+ st.error("Invalid model selected")
867
+ return
868
+
869
+ st.session_state.selected_model = selected_model
870
+
871
+ if st.button("Reset Conversation", key="reset_button"):
872
+ try:
873
+ reset_conversation()
874
+ except Exception as e:
875
+ st.error(f"Error resetting conversation: {str(e)}")
876
+
877
+ # Add evaluation sidebar
878
+ # evaluation_system.render_evaluation_sidebar(selected_model)
879
+
880
+ with st.expander("Instructions"):
881
+ st.write("""
882
+ **How to Use the Chatbot Interface:**
883
+ 1. **Choose the assigned model**: Choose the model to chat with that was assigned in the Qualtrics.
884
+ 2. **Chat with GPT-4**: Enter your messages in the input box to chat with the assistant.
885
+ 3. **Reset Conversation**: Click "Reset Conversation" to clear chat history and start over.
886
+ """)
887
+
888
+ chat_container = st.container()
889
+
890
+ with chat_container:
891
+ if not st.session_state.chat_active:
892
+ st.session_state.chat_active = True
893
+
894
+ # In the main() function, replace the message display section with:
895
+ if selected_model in st.session_state.messages:
896
+ message_pairs = []
897
+ # Group messages into pairs (user + assistant)
898
+ for i in range(0, len(st.session_state.messages[selected_model]), 2):
899
+ if i + 1 < len(st.session_state.messages[selected_model]):
900
+ message_pairs.append((
901
+ st.session_state.messages[selected_model][i],
902
+ st.session_state.messages[selected_model][i + 1]
903
+ ))
904
+ else:
905
+ message_pairs.append((
906
+ st.session_state.messages[selected_model][i],
907
+ None
908
+ ))
909
+
910
+ # Display message pairs with turn numbers
911
+ for turn_num, (user_msg, assistant_msg) in enumerate(message_pairs, 1):
912
+ # Display user message
913
+ col1, col2 = st.columns([0.9, 0.1])
914
+ with col1:
915
+ with st.chat_message(user_msg["role"]):
916
+ st.write(user_msg["content"])
917
+ # Show classification for Model 3
918
+ if (selected_model == "Model 3" and
919
+ 'classifications' in st.session_state):
920
+ idx = (turn_num - 1) * 2
921
+ if idx in st.session_state.classifications:
922
+ classification = "Emotional" if st.session_state.classifications[idx] == "1" else "Informational"
923
+ st.caption(f"Message classified as: {classification}")
924
+ with col2:
925
+ st.write(f"{turn_num}")
926
+
927
+ # Display assistant message if it exists
928
+ if assistant_msg:
929
+ with st.chat_message(assistant_msg["role"]):
930
+ st.write(assistant_msg["content"])
931
+
932
+ st.text_input(
933
+ "Type your message here...",
934
+ key="user_input",
935
+ value="",
936
+ on_change=process_input
937
+ )
938
+ except Exception as e:
939
+ st.error(f"An unexpected error occurred in the main application: {str(e)}")
940
+
941
+ if __name__ == "__main__":
942
+ main()
rag_documents/Isoniazida_Rifapentina.txt ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ INFORMACIÓN PARA EL PACIENTE
2
+
3
+ Tratamiento de la Infección de Tuberculosis (TB) Latente - Esquema de 12 Dosis
4
+
5
+ Le han diagnosticado infección de tuberculosis latente. Para tratarla, tome rifapentina e isoniacida una vez a la semana por 12 semanas. Es crucial no omitir ninguna dosis. Si olvida una, contacte a su médico de inmediato.
6
+
7
+ Este tratamiento no es recomendado para:
8
+
9
+ Niños menores de 2 años.
10
+
11
+ Mujeres embarazadas o que planean quedar embarazadas.
12
+
13
+ Personas que toman ciertos medicamentos para el VIH.
14
+
15
+ ¿Qué es la infección de tuberculosis latente?
16
+ La tuberculosis (TB) se transmite por el aire. Las personas con infección latente tienen bacterias inactivas en su cuerpo, no presentan síntomas y no contagian.
17
+
18
+ ¿Por qué tratar la infección latente?
19
+
20
+ Puede permanecer en el cuerpo durante años y activarse después.
21
+
22
+ El tratamiento elimina las bacterias.
23
+
24
+ Previene el desarrollo de TB activa.
25
+
26
+ Medicamentos a tomar
27
+ Rifapentina e isoniacida, una vez a la semana por 12 semanas. Su médico podría recomendarle reunirse con un profesional de salud o tomar las dosis por su cuenta.
28
+
29
+ Consideraciones importantes
30
+
31
+ La isoniacida puede causar hormigueo en manos y pies. Puede ser necesario tomar vitamina B6.
32
+
33
+ Informe a su médico si está tomando otros medicamentos, incluyendo anticonceptivos o tratamientos para el VIH.
34
+
35
+ Consejos para recordar las dosis:
36
+
37
+ Use un calendario o alarma.
38
+
39
+ Anote recordatorios en lugares visibles.
40
+
41
+ Pida ayuda a un familiar o amigo.
42
+
43
+ Tome las pastillas después de comer.
44
+
45
+ Ingiera todas las pastillas en 5-10 minutos.
46
+
47
+ Almacenamiento de medicamentos
48
+
49
+ Mantenga a temperatura ambiente.
50
+
51
+ Conserve las pastillas en su empaque original hasta su uso.
52
+
53
+ Guarde fuera del alcance de niños.
54
+
55
+ Alcohol y tratamiento
56
+
57
+ El alcohol aumenta el riesgo de daño hepático con isoniacida.
58
+
59
+ Consulte a su médico antes de consumir alcohol.
60
+
61
+ Efectos secundarios comunes
62
+
63
+ Orina, saliva, lágrimas o sudor de color naranja rojizo.
64
+
65
+ Hormigueo o adormecimiento en manos y pies.
66
+
67
+ Consulte la lista de signos de advertencia.
68
+
69
+ En caso de reacción adversa, suspenda el tratamiento y llame a su médico.
70
+
71
+ Consideraciones para mujeres
72
+
73
+ Puede afectar la efectividad de anticonceptivos hormonales.
74
+
75
+ Use anticonceptivos de barrera (condones, diafragmas).
76
+
77
+ Si queda embarazada, suspenda el tratamiento y consulte a su médico.
78
+
79
+ Para más información, visite: www.cdc.gov/tb
rag_documents/LTBI_PatientBrochure_esp.txt ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Usted recibió medicamentos para tratar la infección de tuberculosis latente que contrajo. Usted no tiene la enfermedad de tuberculosis y no se la puede transmitir a otras personas. Estos medicamentos ayudarán a PREVENIR que contraiga la enfermedad de tuberculosis.
2
+
3
+ No se olvide de sus visitas semanales:
4
+ Usted se reunirá con un profesional de la salud cada semana para tomar sus medicamentos. Este plan se llama terapia de observación directa (DOT, por sus siglas en inglés).
5
+
6
+ La DOT es útil por varias razones:
7
+ • El profesional de la salud le ayuda a acordarse de tomar sus medicamentos.
8
+ • Usted completará su tratamiento lo más pronto posible.
9
+ • El profesional de la salud se asegurará de que usted no esté teniendo problemas con los medicamentos.
10
+ • Durante sus reuniones semanales, esta persona puede responder a sus preguntas y usted también podrá hablar acerca de cualquier preocupación que tenga.
11
+
12
+ Mientras tome este medicamento:
13
+ ☑ Dígales a su médico o enfermera si tiene preguntas o preocupaciones acerca del medicamento.
14
+ ☑ Vaya a las visitas semanales.
15
+ ☑ Dígale a su médico si tomó cualquier cantidad de alcohol porque el consumo de alcohol puede producir efectos secundarios.
16
+ ☑ Infórmele a su médico de todos los demás medicamentos que esté tomando.
17
+ ☑ Asegúrese de decirles a sus otros médicos que está recibiendo tratamiento contra la infección de tuberculosis latente.
18
+ ☑ A algunas personas los medicamentos las afectan menos cuando los toman acompañados de comida.
19
+
20
+ Calendario de medicamentos contra la infección de tuberculosis latente: (Proveedor: Indique la fecha adecuada y el número de pastillas)
21
+
22
+ | Medicamento | Frecuencia | Día | Número de pastillas al día | Duración |
23
+ |-------------|------------|------|----------------------------|----------|
24
+ | Isoniazida y Rifapentina | Una vez a la semana | L M M J V S D | | 3 meses (12 semanas) |
25
+
26
+ Su médico puede indicarle que tome vitamina B6 con su medicamento.
27
+
28
+ NOTAS:
29
+ Nombre de mi médico:
30
+ Nombre de mi clínica:
31
+ Número de teléfono de mi clínica:
32
+
33
+ Ponga atención a estos problemas posibles:
34
+ DETÉNGASE y llame a su médico especialista en tuberculosis o a la enfermera de inmediato si tiene alguno de los siguientes problemas:
35
+ • Pérdida o disminución de su apetito por la comida
36
+ • Cólicos o malestar estomacales
37
+ • Fiebre
38
+ • Dolor de cabeza o dolores en el cuerpo
39
+ • Náuseas o vómitos
40
+ • Orina de color de la Coca Cola o heces claras
41
+ • Moretones frecuentes o hemorragia
42
+ • Sarpullido o picazón
43
+ • Piel y ojos amarillentos
44
+ • Debilidad o cansancio extremos
45
+ • Hormigueo o adormecimiento en las manos o en los pies
46
+ • Mareos
47
+
48
+ NOTA: Es normal si su orina, saliva o lágrimas se vuelven color naranja. Los lentes de contacto blandos se pueden manchar.
49
+
rag_documents/Preguntas y respuestas sobre la tuberculosis _ TB.txt ADDED
@@ -0,0 +1,509 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ La tuberculosis (TB) es prevenible y tratable; sin embargo, sigue siendo la enfermedad contagiosa más mortal del
2
+ mundo. Si usted tiene enfermedad de TB contagiosa signica que puede transmitir los microbios de la tuberculosis a los
3
+ demás. En los últimos años los Estados Unidos han noticado su número más bajo de casos de TB registrado; sin
4
+ embargo, todavía se enferman de tuberculosis demasiadas personas. Aún con números cada vez menores, la TB sigue
5
+ siendo un problema. Si bien la cantidad de casos de TB en los Estados Unidos ha bajado, las tasas siguen siendo más
6
+ altas entre las personas de grupos raciales y étnicos minoritarios que entre las personas de raza blanca. Esto se debe a
7
+ que ciertos grupos raciales y étnicos tienen probabilidades más altas de tener factores de riesgo relacionados con la
8
+ TB, que pueden aumentar las probabilidades de presentar la enfermedad
9
+ Este material informativo responde preguntas comunes sobre la TB. Si tiene preguntas adicionales, por favor, consulte a
10
+ su médico, enfermero u otro proveedor de atención médica.
11
+ ¿Por qué sigue siendo la tuberculosis un problema en los EE. UU? 
12
+ La tuberculosis (TB) se transmite de persona a persona a través del aire. Los microbios de la TB llegan al aire cuando
13
+ una persona con la enfermedad contagiosa de tuberculosis de pulmón o de garganta tose, habla o canta. Las personas
14
+ que están cerca pueden inhalar estos microbios e infectarse.
15
+ Cuando los inhalan, los microbios de la tuberculosis pueden depositarse en los pulmones y comenzar a multiplicarse. A
16
+ partir de allí, pueden propagarse a otras partes del cuerpo a través de la sangre, como al riñón, a la columna vertebral o
17
+ al cerebro.
18
+ ¿Cómo se transmite la tuberculosis? 
19
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
20
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 1/14
21
+ Todas las personas pueden contraer la tuberculosis (TB). Algunas personas tienen mayor riesgo. Estas incluyen:
22
+ Personas que tienen contacto con alguien con enfermedad de TB contagiosa.
23
+ Personas nacidas en sitios o que visiten sitios, donde la enfermedad de TB sea común, incluidos México, las Filipinas,
24
+ Vietnam, la India, China, Haití, Guatemala, y otros países con altas tasas de TB.
25
+ Trabajadores de la salud y otras personas que trabajen o vivan en sitios con alto riesgo de transmisión de la TB,
26
+ como refugios para personas sin hogar, cárceles y hogares de ancianos.
27
+ ¿Quiénes están en riesgo de contraer la tuberculosis? 
28
+ En la mayoría de las personas que inhalan microbios de la tuberculosis (TB) y se infectan, el cuerpo es capaz de
29
+ combatir los microbios para impedir su multiplicación. Aunque los microbios se vuelvan inactivos, seguirán vivos en el
30
+ cuerpo y pueden activarse más adelante. Esto se conoce como infección de tuberculosis latente o, por sus siglas en
31
+ inglés, LTBI.
32
+ Las personas con LTBI:
33
+ No tienen síntomas.
34
+ No se sienten enfermas.
35
+ No pueden transmitir los microbios de la TB a otras personas.
36
+ Generalmente darán positivo en la prueba en sangre de la TB o la prueba de reacción cutánea de la tuberculina.
37
+ Pueden llegar a presentar la enfermedad de TB si no reciben tratamiento para la LTBI.
38
+ Las personas con LTBI no tienen síntomas y no pueden transmitir los microbios de la TB a otras personas. Sin embargo,
39
+ si esos microbios se activan y se multiplican en su cuerpo, la infección de tuberculosis latente se convertirá en la
40
+ enfermedad de TB. Por esta razón, deben recibir tratamiento para evitar la enfermedad. El tratamiento de la LTBI es
41
+ esencial para controlar la TB en los Estados Unidos porque reduce signicativamente el riesgo de progresión a la
42
+ enfermedad.
43
+ ¿Qué es la infección de tuberculosis latente (LTBI)? 
44
+ Si el sistema inmunitario no es capaz de impedir que los microbios de la tuberculosis (TB) se multipliquen, comenzarán
45
+ a multiplicarse en el cuerpo y causarán la enfermedad de TB. Estos microbios atacan el cuerpo, y si este ataque ocurre
46
+ en los pulmones, pueden perforarlos. Algunas personas presentan la enfermedad de TB al poco tiempo de infectarse
47
+ (dentro de unas semanas), antes de que su sistema inmunitario pueda combatir los microbios. Otras personas tendrán
48
+ la infección de tuberculosis latente y la enfermedad se podría producir años después, cuando su sistema inmunitario se
49
+ debilite por otra razón. El tratamiento de la infección de tuberculosis latente (LTBI) es ecaz para prevenir la
50
+ enfermedad.
51
+ Cuando la enfermedad de tuberculosis está en los pulmones o la garganta, puede ser contagiosa; esto signica que las
52
+ personas con la enfermedad pueden transmitir los microbios de la TB a sus familias, amigos y otras personas a su
53
+ alrededor. Cuando la TB se produce en otras partes del cuerpo, como los riñones o la columna vertebral, generalmente
54
+ no es contagiosa.
55
+ Las personas con más probabilidades de contagiarse son aquellas que pasen tiempo todos los días con alguien que
56
+ tiene la enfermedad. Estas incluyen sus familiares, amigos, compañeros de trabajo o compa��eros de escuela.
57
+ ¿Qué es la enfermedad de tuberculosis? 
58
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
59
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 2/14
60
+ El tratamiento de la enfermedad requiere que se tomen varios medicamentos al inicio. Después de que el paciente tome
61
+ los medicamentos varias semanas, el médico le podrá decir cuándo ya no puede transmitir los microbios de TB a otras
62
+ personas. Para curarse, la mayoría de las personas con TB deberán tomar los medicamentos durante al menos 6 meses.
63
+ Muchas de las personas que tienen la infección de tuberculosis latente (LTBI) nunca tendrán la enfermedad. A pesar de
64
+ ello, entre aproximadamente el 5 y el 10 % presentarán la enfermedad en algún momento de su vida si su LTBI no se
65
+ trata. Se estima que los casos de LTBI no tratada que progresan a la enfermedad de TB representan aproximadamente
66
+ el 80 % de los casos de TB en los Estados Unidos. Algunas de las personas con LTBI tienen más probabilidades que
67
+ otras de presentar la enfermedad. Estas personas generalmente pertenecen a dos categorías:
68
+ Personas recientemente infectadas de microbios de TB.
69
+ Personas con afecciones, o que reciben tratamientos, que debilitan el sistema inmunitario; por ejemplo:
70
+ Infección por el VIH.
71
+ Consumo de sustancias (p. ej., consumo de drogas inyectables).
72
+ Tratamientos especializados para la artritis reumatoide o la enfermedad de Crohn.
73
+ Trasplante de órgano.
74
+ Enfermedad renal grave.
75
+ Cáncer de cabeza y cuello.
76
+ Diabetes.
77
+ Tratamientos médicos, como corticosteroides.
78
+ Silicosis.
79
+ Bajo peso corporal.
80
+ Los niños, especialmente aquellos menores de 5 años, están en mayor riesgo de presentar la enfermedad de TB una
81
+ vez infectados.
82
+ ¿Quiénes están en riesgo de tener la enfermedad de tuberculosis? 
83
+ Los síntomas de la enfermedad de tuberculosis (TB) dependerán de la parte del cuerpo en que los microbios se estén
84
+ multiplicando. Cuando la enfermedad está en los pulmones puede causar los siguientes síntomas:
85
+ Tos (que dura más de 3 semanas)
86
+ Tos con sangre o con esputo (la ema que sale de adentro de los pulmones)
87
+ Dolor de pecho
88
+ Fiebre
89
+ Sudores nocturnos
90
+ Escalofríos
91
+ Pérdida del apetito
92
+ Debilidad o fatiga
93
+ Pérdida de peso
94
+ Los síntomas de la enfermedad de TB en otras partes del cuerpo pueden incluir los siguientes:
95
+ La TB en los riñones puede provocar sangre en la orina.
96
+ La meningitis tuberculosa puede causar dolor de cabeza o confusión.
97
+ ¿Cuáles son los síntomas de la enfermedad de tuberculosis? 
98
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
99
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 3/14
100
+ La TB en la columna vertebral puede causar dolor de espalda.
101
+ La TB en la laringe puede causar ronquera.
102
+ Para obtener información sobre cómo se trata la enfermedad de TB.
103
+ Hay diferencias importantes entre la infección de tuberculosis latente (LTBI) y la enfermedad de tuberculosis (TB).
104
+ Conocer las diferencias puede ayudarlo a entender qué esperar en caso de tener la LTBI o la enfermedad de TB. En la
105
+ tabla siguiente se explican las diferencias clave, en paralelo.
106
+ LAS PERSONAS CON INFECCIÓN DE
107
+ TUBERCULOSIS LATENTE (LTBI)
108
+ LAS PERSONAS CON ENFERMEDAD DE
109
+ TUBERCULOSIS
110
+ Tienen una pequeña cantidad de microbios de TB
111
+ en el cuerpo que están vivos pero inactivos
112
+ Tienen una gran cantidad de microbios de TB activos
113
+ en el cuerpo
114
+ No tienen síntomas Tienen síntomas que pueden incluir:
115
+ tos intensa que dura 3 semanas o más
116
+ dolor en el pecho
117
+ tos con sangre o esputo
118
+ debilidad o fatiga
119
+ pérdida de peso
120
+ falta de apetito
121
+ escalofríos
122
+ ebre
123
+ sudores nocturnos
124
+ No pueden transmitir los microbios de la TB a los
125
+ demás
126
+ Pueden transmitir los microbios de la TB a los
127
+ demás
128
+ No se sienten enfermas Pueden sentirse enfermas y pueden presentar
129
+ signos y síntomas, como tos, ebre o pérdida de
130
+ peso
131
+ Suelen dar positivo en la prueba cutánea de la
132
+ tuberculina o la prueba en sangre de la TB, lo cual
133
+ indica infección
134
+ Suelen dar positivo en la prueba cutánea de la
135
+ tuberculina o la prueba en sangre de la TB, lo cual
136
+ indica infección
137
+ Tienen radiografías de tórax normales y frotis de
138
+ esputo negativos
139
+ Pueden tener radiografías de tórax anormales, o
140
+ cultivos o frotis de esputo positivos
141
+ Deben considerar recibir tratamiento para la LTBI
142
+ para prevenir la enfermedad de TB
143
+ Necesitan tratamiento para la enfermedad de TB
144
+ ¿Cuál es la diferencia entre la infección de tuberculosis latente (LTBI) y la enfermedad de
145
+ tuberculosis?
146
+
147
+ Debe hacerse una prueba de tuberculosis (TB) si:
148
+ ¿Debería hacerme una prueba de tuberculosis? 
149
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
150
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 4/14
151
+ Ha pasado tiempo con alguien que usted sabe o cree que tenga enfermedad de TB contagiosa.
152
+ Nació en un país, o viaja a menudo a países donde la enfermedad de TB es común, incluidos México, las Filipinas,
153
+ Vietnam, la India, China, Haití, y Guatemala, y otros países donde la TB sea frecuente.
154
+ Ha vivido, o vive o trabaja actualmente en un entorno donde la TB sea más común, como los albergues para
155
+ personas sin hogar, las prisiones, las cárceles o los hogares de ancianos.
156
+ Es un trabajador de la salud que atiende a pacientes que tienen la enfermedad de TB.
157
+ Pertenece a una población con mayores probabilidades de tener infección de tuberculosis latente (LTBI) o
158
+ enfermedad de TB; esto incluye a las personas que no tengan buen acceso a atención médica, que tengan ingresos
159
+ bajos o que consuman drogas o alcohol de manera indebida.
160
+ Además, los niños, especialmente aquellos menores de 5 años, están en mayor riesgo de presentar la enfermedad de
161
+ TB una vez infectados. Por lo tanto, es importante detectar la infección de TB en los niños que puedan haberse
162
+ expuesto a alguien que tenga la enfermedad.
163
+ Hay dos tipos de prueba para detectar la infección de TB: la prueba en sangre y la prueba cutánea de la tuberculina. Su
164
+ proveedor de atención médica deberá decidir cuál usar. Los factores que determinarán qué prueba usar incluyen el
165
+ motivo por el cual se haga la prueba, la prueba que se tenga disponible y el costo. Se anima a los proveedores de
166
+ atención médica a usar las pruebas en sangre de la TB más nuevas para detectar la infección. Por lo general, no es
167
+ necesario hacerle las dos pruebas a la misma persona.
168
+ Pruebas en sangre de la tuberculosis
169
+ Las pruebas en sangre de la TB detectan las infecciones de microbios de la TB usando una muestra de sangre. En los
170
+ Estados Unidos hay dos pruebas en sangre de la TB aprobadas por la Administración de Alimentos y Medicamentos
171
+ FDA de los Estados Unidos que se usan:
172
+ QuantiFERON®-TB Gold Plus (QFT-Plus)
173
+ T-SPOT®.TB test (T-Spot)
174
+ Usted se puede hacer una de estas pruebas en el departamento de salud o el consultorio de su médico. El proveedor de
175
+ atención médica le extraerá una muestra de sangre y enviará la muestra a un laboratorio para que la analicen y obtener
176
+ los resultados. Si su departamento de salud usa las pruebas en sangre, solo necesitará ir una vez para que le extraigan
177
+ la muestra de sangre para la prueba.
178
+ Prueba en sangre de la TB con resultado positivo: El resultado positivo signica que usted está infectado con
179
+ microbios de TB. Necesitarán hacerle más pruebas para determinar si tiene la infección de tuberculosis latente (LTBI) o
180
+ la enfermedad de TB.
181
+ Prueba en sangre de la TB con resultado negativo: El resultado negativo signica que su sangre no reaccionó a la
182
+ prueba y que probablemente no tenga la infección de TB.
183
+ Las pruebas en sangre de la TB son las que se recomiendan para las siguientes personas:
184
+ Personas vacunadas con la BCG (vacuna de bacilo de Calmette y Guérin).
185
+ Personas para quienes sea difícil regresar para la segunda cita en la que se examina la reacción a la prueba cutánea
186
+ de la tuberculina.
187
+ Prueba cutánea de la tuberculina
188
+ ¿Con qué pruebas se detecta la infección de tuberculosis? 
189
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
190
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 5/14
191
+ La prueba cutánea de la tuberculina se puede usar para averiguar si está infectado con microbios de la TB. Usted se
192
+ puede hacer esta prueba en el departamento de salud o en el consultorio de su médico. Un trabajador de la salud le
193
+ inyectará una pequeña cantidad del líquido que se usa para la prueba (llamado tuberculina o PPD, por sus siglas en
194
+ inglés) debajo de la piel, en el antebrazo. Después de 2 o 3 días, deberá regresar para que el trabajador de la salud lea
195
+ el resultado de la prueba cutánea. Es posible que tenga hinchazón en el sitio donde le inyectaron la tuberculina. El
196
+ trabajador de la salud medirá esta hinchazón y le informará si la reacción es positiva o negativa.
197
+ Prueba cutánea con reacción positiva: La reacción positiva signica que su cuerpo está infectado con microbios de la
198
+ TB. Necesitarán hacerle más pruebas para determinar si tiene la infección de tuberculosis latente o enfermedad de TB.
199
+ Prueba cutánea con reacción negativa: La reacción negativa signica que su cuerpo no reaccionó a la prueba y que
200
+ usted probablemente no tenga la LTBI o la enfermedad de TB.
201
+ Si su exposición a los microbios de la TB fue reciente, es posible que la prueba no produzca una reacción positiva
202
+ todavía. Posiblemente deba repetir la prueba cutánea después de 8 a 10 semanas desde la última vez que haya pasado
203
+ tiempo con la persona enferma. Esto se debe a que, después de infectarse, su sistema inmunitario puede tomar varias
204
+ semanas para reaccionar a la prueba. Si la segunda prueba también da negativo, lo probable es que usted no tenga la
205
+ infección de TB.
206
+ Si la prueba cutánea o la prueba en sangre de la TB produce una reacción positiva, su médico o enfermero le hará otras
207
+ pruebas para determinar si tiene la enfermedad de TB. Estas pruebas suelen incluir una radiografía de tórax. También
208
+ pueden incluir un análisis del esputo (ema) que expulsa al toser. Debido a que los microbios de la tuberculosis pueden
209
+ encontrarse en partes del cuerpo que no sean los pulmones, el médico o enfermero podría hacerle un examen de orina,
210
+ tomarle muestras de tejido o hacer otras pruebas. Sin tratamiento, la infección de tuberculosis latente (LTBI) puede
211
+ progresar a la enfermedad de TB. Si usted tiene LTBI, debe recibir tratamiento para prevenir la enfermedad. Si tiene la
212
+ enfermedad de TB, deberá tomar medicamentos para tratarla.
213
+ ¿Qué pasa si la prueba de infección de TB me da positivo? 
214
+ La BCG es una vacuna contra la TB. En los Estados Unidos su uso no es generalizado. Muchas personas nacidas fuera
215
+ de los Estados Unidos están vacunadas contra la tuberculosis con la BCG.
216
+ En otros países, donde la TB es más frecuente, es común que se vacune a los bebés y niños pequeños. Esto los protege
217
+ contra las formas graves de la enfermedad de TB, como la meningitis tuberculosa. No se cree que la vacuna proteja
218
+ contra la TB de los pulmones, que es la forma más común que se encuentra en los Estados Unidos.
219
+ La prueba cutánea de la TB puede dar una reacción positiva en algunas personas vacunadas con la BCG, aunque no
220
+ estén infectadas. Sin embargo, no hay manera de saber si la reacción positiva se debe a la BCG o a una verdadera
221
+ infección de TB. Cuando la prueba cutánea se usa en personas vacunadas y la reacción es positiva, siempre se las debe
222
+ evaluar en mayor profundidad como si no estuvieran vacunadas, para determinar si tienen la enfermedad de TB.
223
+ A diferencia de las pruebas cutáneas de la TB, las pruebas en sangre no se ven afectadas por la vacunación previa con
224
+ la BCG. Por lo tanto, se preeren las pruebas en sangre para las personas que estén vacunadas contra la tuberculosis.
225
+ ¿Qué pasa si estoy vacunado con la BCG (bacilo de Calmette y Guérin)? 
226
+ Si tengo la infección de tuberculosis latente (LTBI) ¿cómo puedo evitar la enfermedad de
227
+ tuberculosis?
228
+
229
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
230
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 6/14
231
+ Sin tratamiento, la infección de tuberculosis latente (LTBI) puede progresar a la enfermedad de TB. Si usted tiene la
232
+ LTBI, debe recibir tratamiento para evitar la enfermedad aunque no se sienta enfermo. El tratamiento de la LTBI es
233
+ esencial para prevenir la enfermedad de TB porque reduce signicativamente su riesgo de progresión.
234
+ El tratamiento de la LTBI es ecaz para la prevención de la enfermedad. Hay varias opciones para el tratamiento de la
235
+ LTBI. Se han logrado avances en cuanto a la duración del tratamiento de la LTBI, acortándola de 6-9 meses a 3-4
236
+ meses. Estos esquemas de tratamiento cortos son ecaces, son seguros y tienen tasas de compleción más altas.
237
+ Si usted tiene LTBI y pertenece a un grupo de mayor riesgo, es aún más urgente que tome medicamentos para que no
238
+ presente la enfermedad de TB. Los siguientes medicamentos para la TB se usan de manera independiente o combinada
239
+ para el tratamiento de la LTBI:
240
+ Isoniacida (INH)
241
+ Rifapentina (RPT)
242
+ Rifampina (RIF)
243
+ Los CDC y la Asociación Nacional de Controladores de Tuberculosis recomiendan una de las siguientes opciones de
244
+ tratamiento:
245
+ Tres meses de isoniacida más rifapentina una vez a la semana (3HP).
246
+ Cuatro meses de rifapentina diaria (4R).
247
+ Tres meses de isoniacida más rifampina diarias (3HR).
248
+ Si ninguno de los esquemas de tratamiento anteriores son una opción para usted, existen esquemas alternativos que
249
+ incluyen 6 o 9 meses de isoniacida. Si toma isoniacida, el médico puede indicarle que la tome con vitamina B6. Él o ella
250
+ podrá determinar cuál de las opciones de tratamiento es la mejor para su situación. Es posible que se deba modicar el
251
+ tratamiento, si los microbios que causaron la enfermedad de TB de la persona con la que tuvo contacto son resistentes
252
+ a la isoniacida o a la rifampina, dos de los medicamentos más importantes para el tratamiento de la LTBI y la
253
+ enfermedad de TB. Esto signica que esos medicamentos ya no pueden destruir los microbios de TB.
254
+ A veces se indica el tratamiento de la LTBI a una persona, incluso si su prueba en sangre o su prueba cutánea de la TB
255
+ da negativo. Esto sucede a menudo con los bebés, los niños y las personas infectadas por el VIH que hayan pasado
256
+ tiempo recientemente con alguien que tenía la enfermedad de TB. La razón es que las personas de estos grupos tienen
257
+ un riesgo muy alto de presentar la enfermedad de TB poco después de haber sido infectadas por los microbios de la
258
+ TB.
259
+ Si empieza el tratamiento para la LTBI, deberá visitar al médico o enfermero en forma regular. Es importante que tome
260
+ todos los medicamentos según las indicaciones. El médico o enfermero le hará seguimiento para ver cómo sigue.
261
+ La mayoría de las personas pueden tomar los medicamentos para la LTBI sin ningún problema; sin embargo, a veces se
262
+ producen efectos secundarios. Algunos de los efectos secundarios son problemas menores. Por ejemplo, los
263
+ medicamentos rifampina o rifapentina pueden cambiar el color de los líquidos corporales —como la orina, la saliva, las
264
+ lágrimas o el sudor y la leche materna— volviéndolos anaranjados. Esta coloración anaranjada de los líquidos
265
+ corporales es algo previsto e inofensivo. Es normal y el color puede desaparecer con el tiempo. Si usa lentes de
266
+ contacto, el médico o enfermero puede aconsejarle que use lentes blandos, porque pueden teñirse permanentemente.
267
+ Si tiene alguno de estos efectos secundarios, puede seguir tomando sus medicamentos.
268
+ ¿Cuáles son los efectos secundarios de los medicamentos que tratan la infección de
269
+ tuberculosis latente (LTBI)?
270
+
271
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
272
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 7/14
273
+ Si tiene un efecto secundario grave, llame al médico o enfermero inmediatamente. Es posible que le indique que deje
274
+ de tomar los medicamentos para la LTBI o que regrese al centro médico para hacerse pruebas. Los efectos secundarios
275
+ graves incluyen:
276
+ Mareos o sensación de desmayo
277
+ Pérdida del apetito
278
+ Síntomas similares a los de la inuenza (gripe)
279
+ Diarrea intensa o heces de color claro
280
+ Dicultad para respirar
281
+ Sentimientos de tristeza o depresión
282
+ Fiebre
283
+ Pérdida de peso sin causa conocida
284
+ Orina marrón (como el color del café o la coca cola)
285
+ Coloración amarilla en la piel o los ojos
286
+ Sarpullido
287
+ Hormigueo o sensación de pinchazos persistente en las manos y los pies
288
+ Cansancio o debilidad persistentes que duran 3 días o más
289
+ Dolor de estómago
290
+ Moretones o sangrados que ocurren con facilidad
291
+ Dolor en las articulaciones
292
+ Náuseas
293
+ Vómitos
294
+ Para evitar las interacciones con otros medicamentos, le debe dar a su proveedor de atención médica una lista de los
295
+ medicamentos que esté tomando actualmente. Algunos anticonceptivos orales (píldoras anticonceptivas) podrían ser
296
+ menos ecaces cuando se toman con los medicamentos para la TB. Esto se debe a que los medicamentos para la TB, a
297
+ veces, pueden afectar el funcionamiento de las píldoras anticonceptivas y posiblemente hacerlas menos ecaces. Si
298
+ usted toma píldoras anticonceptivas, hable con su médico antes de comenzar a tomar ningún medicamento nuevo.
299
+ Puede encontrar más información sobre los efectos secundarios de los medicamentos para la TB en la
300
+ página web de los CDC sobre los eventos adversos del tratamiento de la TB.
301
+ Advertencia: Consumir bebidas alcohólicas, como vino, cerveza o licor, mientras se toman los medicamentos para la TB
302
+ puede ser peligroso. Para obtener más información, consulte al médico o enfermero.
303
+ 2. Esquema de 4 meses de rifampina diaria (4R) para la infección de tuberculosis latente: registro de
304
+ medicamentos y hoja de vericación de síntomas. (Disponible en inglés).
305
+ 3. Esquema de 3 meses de isoniacida más rifampina diarias (3HR) para la infección de tuberculosis latente:
306
+ registro de medicamentos y hoja de vericación de síntomas. (Disponible en inglés).
307
+ Esquemas posológicos para el tratamiento de la infección de tuberculosis latente
308
+ Cómo decidir cuándo se debe tratar la infección de tuberculosis latente
309
+ Cómo tratar la LTBI con los esquemas cortos
310
+ ¿Qué pasa si tengo la infección por el VIH? 
311
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
312
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 8/14
313
+ Si usted tiene la infección por el VIH y la infección de tuberculosis latente (LTBI), necesita recibir tratamiento lo antes
314
+ posible para prevenir la enfermedad de TB. Las personas que tienen la infección por el VIH y además LTBI sin tratar
315
+ tienen muchas más probabilidades de presentar la enfermedad de TB en algún momento de su vida que aquellas sin el
316
+ VIH. Entre las personas con LTBI, la infección por el VIH es el factor de riesgo conocido más preponderante de
317
+ progresión a la enfermedad de TB. Todas las personas con infección por el VIH deben hacerse una prueba de LTBI para
318
+ averiguar si la tienen y, de ser necesario, buscar tratamiento con prontitud. Hay varios esquemas de tratamiento de la
319
+ LTBI ecaces para las personas que tienen el VIH.
320
+ Si usted se expuso a alguien que tenía la enfermedad de TB, puede haberse infectado de microbios de la TB, pero no
321
+ los podría propagar en forma inmediata. Solo las personas que tienen la enfermedad de TB pueden propagar los
322
+ microbios a los demás. Antes de que la propagación fuera posible, usted debe haber inhalado microbios de la TB y
323
+ contraído la infección. Después, los microbios deben haberse multiplicado en su cuerpo y causado enfermedad de TB
324
+ contagiosa. Sucedido eso, sería posible propagar los microbios de la TB.
325
+ En la mayoría de las personas que inhalan microbios de la TB y se infectan, el cuerpo puede combatir los microbios e
326
+ impedir que se multipliquen. En ese caso, los microbios estarían en estado inactivo, pero seguirían vivos en su cuerpo y
327
+ podrían activarse más adelante. Este tipo de infección de TB se conoce como infección de tuberculosis latente (LTBI).
328
+ Las personas que tienen la LTBI no pueden transmitir estos microbios a otras personas. Además, pueden tratar la
329
+ infección para evitar que se convierta en la enfermedad de TB.
330
+ Si me expuse a alguien que tenía la enfermedad de tuberculosis, ¿puedo contagiar a otros? 
331
+ ¡Hay buenas noticias para las personas con enfermedad de tuberculosis (TB)! Casi siempre se puede tratar y curar con
332
+ medicamentos. Pero los medicamentos se deben tomar según las indicaciones del médico o enfermero.
333
+ Si usted tiene la enfermedad, deberá tomar varios medicamentos distintos para la TB. La razón es que hay muchos
334
+ microbios para destruir. Usar varios medicamentos a la vez es más ecaz para destruir a todos los microbios de la TB y
335
+ prevenir que se hagan resistentes a los medicamentos. Se les dice “resistentes” a las bacterias de la TB cuando los
336
+ medicamentos ya no pueden destruirlas.
337
+ Los medicamentos que se usan más comúnmente para el tratamiento de la enfermedad de TB son:
338
+ Isoniacida (INH)
339
+ Rifampina (RIF)
340
+ Etambutol (EMB)
341
+ Pirazinamida (PZA)
342
+ Si usted tiene enfermedad de TB en los pulmones o la garganta, es probable que su enfermedad sea contagiosa. Debe
343
+ quedarse en su casa y no ir al trabajo o la escuela, para que no pueda transmitir los microbios de TB a otras personas.
344
+ Después de que tome los medicamentos durante varias semanas se sentirá mejor y es posible que su enfermedad ya no
345
+ sea contagiosa. El médico o enfermero le indicará cuándo puede volver al trabajo, a la escuela o a ver a sus amigos.
346
+ El hecho de tener la enfermedad de TB no debe impedirle llevar una vida normal. Cuando las personas ya no son
347
+ contagiosas o ya no se sienten enfermas, generalmente pueden volver a hacer las mismas cosas que hacían antes de la
348
+ enfermedad. Si usted toma los medicamentos según las indicaciones del médico o enfermero, deberían destruir todos
349
+ los microbios de la TB. Esto evitará que usted vuelva a tener la enfermedad.
350
+ ¿Cómo se trata la enfermedad de tuberculosis? 
351
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
352
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 9/14
353
+ Si usted está tomando medicamentos para la enfermedad de TB, debe tomarlos según las indicaciones del médico o
354
+ enfermero. Los medicamentos para la TB pueden provocar efectos secundarios. Algunos son problemas menores. Otros
355
+ son más serios. Si tiene un efecto secundario grave, llame al médico o enfermero inmediatamente. Es posible que le
356
+ indique que deje de tomar los medicamentos para la TB o que regrese al centro médico para hacerse pruebas. Los
357
+ efectos secundarios graves incluyen:
358
+ Sarpullido
359
+ Visión borrosa o cambios en la vista
360
+ Dolor de estómago
361
+ Orina de color marrón o heces de color claro
362
+ Cansancio
363
+ Fiebre durante 3 días o más
364
+ Síntomas similares a los de la inuenza (gripe)
365
+ Falta de apetito
366
+ Náuseas
367
+ Vómitos
368
+ Coloración amarilla en la piel o los ojos
369
+ Mareos
370
+ Sensación de hormigueo o adormecimiento alrededor de la boca
371
+ Sensación persistente de pinchazos en las manos y los pies
372
+ Malestar estomacal
373
+ Dolores en las articulaciones
374
+ Moretones o sangrados que ocurren con facilidad
375
+ Algunos de los efectos secundarios son problemas menores. Por ejemplo, la rifampina pueden cambiar el color de los
376
+ líquidos corporales —como la orina, la saliva, las lágrimas o el sudor y la leche materna— volviéndolos anaranjados.
377
+ Esta coloración anaranjada de los líquidos corporales es algo previsto e inofensivo. Es normal y el color puede
378
+ desaparecer con el tiempo. Si usa lentes de contacto, el médico o enfermero puede aconsejarle que use lentes blandos,
379
+ porque pueden teñirse permanentemente. Si tiene alguno de estos efectos secundarios, puede seguir tomando sus
380
+ medicamentos.
381
+ Los medicamentos que se recetan para el tratamiento de la enfermedad de TB pueden tener interacciones con otros
382
+ medicamentos. Para evitarlas, le debe dar a su proveedor de atención médica una lista de los medicamentos que esté
383
+ tomando actualmente.
384
+ Por ejemplo, pueden interactuar con los anticonceptivos orales (píldoras anticonceptivas) y posiblemente hacerlos
385
+ menos ecaces. Si usted toma píldoras anticonceptivas, consulte al médico sobre métodos de anticoncepción
386
+ alternativos mientras esté tomando los medicamentos para la TB. Si usted está tomando metadona (que se usa para
387
+ tratar la drogadicción), es posible que tenga síntomas de abstinencia. Es posible que el médico o enfermero deba
388
+ ajustarle la dosis de la metadona.
389
+ Puede encontrar más información sobre los efectos secundarios de los medicamentos para la TB en la página web de
390
+ los CDC sobre los eventos adversos del tratamiento de la TB.
391
+ ¿Cuáles son los efectos secundarios de los medicamentos que tratan la enfermedad de
392
+ tuberculosis?
393
+
394
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
395
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 10/14
396
+ La destrucción de los microbios de la TB es lenta. El tratamiento de la infección de tuberculosis latente (LTBI) toma al
397
+ menos 3 meses (y posiblemente más tiempo, según los medicamentos que tome) para destruirlos.
398
+ En el caso de la enfermedad de TB, los medicamentos generalmente toman 6 meses o más para destruir todos los
399
+ microbios. Es probable que comience a sentirse mejor solo pocas semanas después de comenzar el tratamiento, pero
400
+ ¡tenga cuidado! Los microbios de la TB seguirán estando vivos en su cuerpo aunque usted se sienta mejor. Debe
401
+ continuar tomando los medicamentos hasta que todos los microbios hayan sido destruidos, aunque pueda sentirse
402
+ mejor y ya no tenga síntomas de la enfermedad.
403
+ Puede ser muy peligroso dejar de tomar los medicamentos o no tomarlos con regularidad. Esto hará que los microbios
404
+ vuelvan a multiplicarse, y usted seguirá enfermo durante más tiempo. También es posible que se vuelvan resistentes a
405
+ los medicamentos que esté tomando. Si los medicamentos dejan de funcionar, posiblemente necesite medicamentos
406
+ nuevos para destruir los microbios. Los nuevos medicamentos se deberán tomar durante más tiempo y, por lo general,
407
+ tienen efectos secundarios más graves.
408
+ Si su enfermedad vuelve a ser contagiosa, usted podría transmitir microbios de TB a sus familiares, sus amigos o a
409
+ cualquier persona que pase tiempo con usted. Es muy importante que tome todos los medicamentos según las
410
+ indicaciones del médico o enfermero.
411
+ ¿Por qué debo tomar los medicamentos para la tuberculosis tanto tiempo? 
412
+ En algunas ocasiones, las microbios de la TB son resistentes a los medicamentos que se usan para tratar la enfermedad
413
+ de TB. Esto signica que los medicamentos ya no pueden destruir los microbios.
414
+ La tuberculosis multirresistente (o MDR TB, por sus siglas en inglés) es causada por microbios de TB que son
415
+ resistentes a al menos dos de los medicamentos más importantes para el tratamiento de la TB: la isoniacida y la
416
+ rifampina.
417
+ Existe una forma más grave de MDR TB que se llama tuberculosis extremadamente resistente (XDR TB, por sus siglas
418
+ en inglés). Este es un tipo raro de tuberculosis que es resistente a casi todos los medicamentos que se utilizan para
419
+ tratarla.
420
+ Si usted no toma sus medicamentos según las indicaciones del médico o enfermero, los microbios pueden volverse
421
+ resistentes determinados medicamentos. Los microbios multirresistentes pueden, además, infectar a quienes hayan
422
+ pasado tiempo con la persona que estaba enferma de MDR TB o XDR TB.
423
+ La tuberculosis resistente a los medicamentos es más común en las personas que:
424
+ Hayan pasado tiempo con alguien que estaba enfermo de tuberculosis resistente a los medicamentos.
425
+ No tomen todos sus medicamentos según las indicaciones del médico o enfermero.
426
+ Vuelvan a tener enfermedad de TB después de haber tomado medicamentos para tratarla en el pasado.
427
+ Vengan de áreas donde la TB resistente a los medicamentos sea común.
428
+ Las personas que tienen MDR TB o XDR TB deben ser tratadas con medicamentos especiales. El tratamiento dura más
429
+ que el de la TB común, y los medicamentos pueden causar más efectos secundarios. Las personas con estos tipos de
430
+ TB están en mayor riesgo de morir a causa de la enfermedad. Deben, además, atenderse con un experto en TB que
431
+ pueda seguir su tratamiento estrechamente para asegurarse de que esté funcionando.
432
+ ¿Qué es la tuberculosis multirresistente (MDR TB) y la tuberculosis extremadamente
433
+ resistente (XDR TB)?
434
+
435
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
436
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 11/14
437
+ La mejor forma de acordarse de tomar sus medicamentos es mediante el tratamiento de observación directa (o DOT,
438
+ por sus siglas en inglés); esto es particularmente cierto en el caso de la enfermedad de TB. Si usted obtiene DOT, se
439
+ reunirá con un trabajador de la salud todos los días o varias veces a la semana. Se pondrán de acuerdo en dónde
440
+ reunirse o se reunirán o por medios electrónicos. El sitio donde se encuentren puede ser el centro médico de atención
441
+ para la TB, su casa, su trabajo o cualquier otro lugar conveniente. Tomará sus medicamentos en ese lugar, mientras un
442
+ trabajador de la salud lo observa. Algunos programas de TB ahora usan métodos de DOT electrónicos, tanto para la
443
+ enfermedad de TB como para la infección de tuberculosis latente (LTBI). El tratamiento de observación directa
444
+ electrónico (eDOT, por sus siglas en inglés) es una alternativa al DOT en persona. Si hay DOT electrónico disponible en
445
+ su área y usted reúne los requisitos para recibirlo, un trabajador de la salud lo observará remotamente, a través de un
446
+ teléfono inteligente u otro dispositivo con video, mientras toma los medicamentos. Independientemente de que sea en
447
+ persona o con un dispositivo electrónico, el DOT lo ayuda a acordarse de tomar sus medicamentos y a completar su
448
+ tratamiento. Esto signica que usted se recuperará lo antes posible.
449
+ El trabajador de la salud también se asegurará de que los medicamentos estén funcionando del modo esperado,
450
+ vigilará si usted presenta efectos secundarios y responderá las preguntas que tenga sobre la TB.
451
+ Si usted no recibe DOT, aún deberá ver al médico o enfermero en distintos momentos del tratamiento para asegurarse
452
+ de que todo esté funcionando bien. Esto continuará hasta que se cure.
453
+ ¿Qué es el tratamiento de observación directa (DOT)? 
454
+ La única forma de mejorarse es tomando los medicamentos para la TB exactamente según las indicaciones del médico
455
+ o enfermero. ¡Esto podría no ser fácil! Si usted tiene LTBI, tomará medicamentos durante 3 meses o más. Si usted tiene
456
+ enfermedad de TB, por lo general tomará medicamentos durante 6 meses o más.
457
+ Tener una rutina puede ayudarlo a acordarse de tomar los medicamentos, tal como se lo indicaron. Las siguientes son
458
+ algunas de las cosas que puede hacer para acordarse de tomar sus medicamentos, sean para la LTBI o la enfermedad
459
+ de TB:
460
+ Tomar las pastillas todos los días a la misma hora, por ejemplo, antes del desayuno, durante un descanso que tome
461
+ regularmente o después de lavarse los dientes.
462
+ Pedirle a un familiar o amigo que le recuerde tomar sus píldoras.
463
+ Tachar los días en un calendario cuando tome los medicamentos.
464
+ Poner sus dosis en un pastillero semanal y mantenerlo junto a la cama o llevarlo en su bolso o en un bolsillo.
465
+ Usar un registro de medicamentos para organizar y manejar las pastillas que toma. En el sitio web de los CDC hay
466
+ registros de medicamentos para la LTBI para imprimir. Estas son hojas con espacios donde puede anotar su calendario
467
+ de tratamiento, la cantidad de pastillas que debe tomar cada semana y la información de contacto del médico o centro
468
+ médico. Para descargar o imprimir estos registros, visite la página web de los CDC de materiales educativos sobre la
469
+ TB.
470
+ NOTA: recuerde mantener todos los medicamentos fuera del alcance de los niños.
471
+ Si un día se olvida de tomar las pastillas, sáltese esa dosis y tome la dosis siguiente. Dígale al médico o enfermero si se
472
+ ha saltado alguna dosis. También puede llamarlo para que le dé instrucciones.
473
+ ¿Qué puedo hacer para acordarme de tomar los medicamentos para la tuberculosis si no
474
+ estoy haciendo tratamiento de observación directa (DOT)?
475
+
476
+ 9/6/24, 1:14 PM Preguntas y respuestas sobre la tuberculosis | TB | CDC
477
+ https://www.cdc.gov/tb/esp/publications/faqs/tb-qa.htm#what-is-tb 12/14
478
+ Si usted tiene enfermedad de tuberculosis (TB) contagiosa, la forma más importante en que puede evitar la transmisión
479
+ de los microbios es tomando todos los medicamentos exactamente como lo indique el médico enfermero. Además,
480
+ debe ir a todas sus citas médicas. El médico o enfermero necesita vigilar cómo sigue. Para esto a veces se requiere otra
481
+ radiografía de tórax o prueba de su esputo (la ema del fondo de los pulmones que sale cuando tose). Estas pruebas
482
+ mostrarán si los medicamentos están funcionando. También mostrarán si todavía puede transmitir microbios de la TB a
483
+ otras personas. Asegúrese de decirle al proveedor de atención médica si piensa que algo anda mal.
484
+ Si está lo sucientemente enfermo por la TB como para ir al hospital, probablemente lo pondrán en una habitación
485
+ especial. Estas habitaciones tienen rejillas de ventilación que evitan la propagación de los microbios de TB a otras
486
+ habitaciones. El personal asignado a estas habitaciones debe usar una mascarilla especial para protegerse de los
487
+ microbios. Usted deberá permanecer en la habitación para que no transmita microbios de la TB a otras personas.
488
+ Si está en su casa mientras la enfermedad es contagiosa, hay algunas medidas que puede tomar para proteger a las
489
+ personas que estén cerca suyo:
490
+ Tome sus medicamentos según las indicaciones. ¡Esto es muy importante!
491
+ Cúbrase la boca con un pañuelo desechable siempre que tosa, estornude o se ría. Ponga el pañuelo usado en una
492
+ bolsa, ciérrela y bótela.
493
+ Manténgase apartado de los demás y evite el contacto cercano con todos. Duerma en una habitación alejada del
494
+ resto de sus familiares. Evite recibir visitas en su casa.
495
+ No vaya al trabajo o a la escuela.
496
+ Abra las ventanas de su habitación para que el aire salga (si no hace demasiado frío). La TB se propaga en los
497
+ lugares cerrados pequeños donde no circula el aire. Coloque un ventilador en la ventana para que sople hacia afuera
498
+ (extraiga) el aire que podría estar cargado de microbios de TB. Si en la habitación hay otras ventanas, ábralas
499
+ también para que el ventilador pueda mover el aire fresco hacia adentro. Esto reducirá las probabilidades de que los
500
+ microbios de la TB se queden dentro de la habitación e infecten a alguien que respire el aire.
501
+ Recuerde, la TB se propaga a través del aire. Los microbios de la TB no pueden infectar a las personas cuando se dan la
502
+ mano o se sientan en el asiento del inodoro, ni cuando comparten platos y utensilios con alguien que tiene TB.
503
+ Después de que usted tome los medicamentos durante unas 2 o 3 semanas, es posible que su enfermedad deje de ser
504
+ contagiosa. El médico o enfermero le indicará cuándo puede volver al trabajo, a la escuela o a ver a sus amigos.
505
+ Recuerde que solo mejorará si toma los medicamentos exactamente según las indicaciones del médico o enfermero.
506
+ Trate de recordar con quiénes ha pasado tiempo, como familiares, amigos cercanos y compañeros de trabajo. Es posible
507
+ que el departamento de salud local deba hacerles una prueba de infección de TB. La TB es particularmente peligrosa
508
+ para los niños y las personas con infección por el VIH. Si se infectan de microbios de TB, necesitan tomar medicamentos
509
+ de inmediato para evitar tener la enfermedad de TB
rag_documents/Tuberculosis - Diagnóstico y tratamiento - Mayo Clinic.txt ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Durante la exploración física, el médico te examinará los ganglios linfáticos para
2
+ detectar hinchazón y escuchará los sonidos de tus pulmones mientras respiras
3
+ con un estetoscopio.
4
+ La herramienta de diagnóstico más usada para la tuberculosis es una prueba
5
+ cutánea, aunque se están volviendo más comunes los análisis de sangre. Se
6
+ inyecta una pequeña cantidad de una sustancia llamada tuberculina debajo de la
7
+ piel en el interior del antebrazo. Deberías sentir solo un ligero pinchazo de aguja.
8
+ Dentro de las 48 a 72 horas, un profesional de atención médica controlará si se
9
+ hinchó el sitio de la inyección en tu brazo. Un bultito elevado, rojo y duro signica
10
+ que es posible que estés infectado con tuberculosis. El tamaño del bultito
11
+ determina si los resultados de la prueba son signicativos.
12
+
13
+ Pruebas de tuberculosis
14
+ El proveedor de atención médica pedirá que se realicen pruebas si:
15
+ Sospecha que tienes tuberculosis.
16
+ Es probable que hayas estado expuesto a una persona con tuberculosis
17
+ activa.
18
+ Tienes riesgos de salud para la tuberculosis activa.
19
+ El proveedor de atención médica determinará si la mejor opción es una prueba
20
+ cutánea o un análisis de sangre.
21
+ Prueba cutánea
22
+ Se inyecta una pequeña cantidad de una sustancia llamada tuberculina debajo de
23
+ la piel, en la parte interior del antebrazo. Dentro de las 48 a 72 horas, un
24
+ profesional de atención médica revisará si se hinchó el sitio de la inyección en tu
25
+ brazo. El tamaño de la piel levantada se utiliza para determinar una prueba positiva
26
+ o negativa.
27
+ Esta prueba consiste en ver si tu sistema inmunitario reacciona, o si ha generado
28
+ un anticuerpo, ante la tuberculosis. Una prueba positiva indica si tienes una
29
+ infección latente por tuberculosis o una tuberculosis activa. Las personas
30
+ vacunadas contra la tuberculosis pueden dar positivo en la prueba aunque no
31
+ tengan ninguna infección.
32
+ Una prueba negativa signica que tu cuerpo no ha reaccionado a la prueba. No
33
+ signica necesariamente que no tengas una infección.
34
+ Análisis de sangre
35
+ Los análisis de sangre pueden conrmar o descartar la forma activa o latente de la
36
+ tuberculosis. Estos análisis miden la reacción de tu sistema inmunitario a las
37
+ bacterias de la tuberculosis.
38
+ Para estas pruebas, solo necesitas ir una vez al consultorio. El análisis de sangre
39
+ puede ser útil si tienes un riesgo alto de una infección con tuberculosis, pero tu
40
+ resultado de la prueba cutánea resultó negativo, o te dieron recientemente la
41
+ vacuna con el bacilo de Calmette-Guérin.
42
+ 9/6/24, 1:08 PM Tuberculosis - Diagnóstico y tratamiento - Mayo Clinic
43
+ https://www.mayoclinic.org/es/diseases-conditions/tuberculosis/diagnosis-treatment/drc-20351256 2/12
44
+ Pruebas porimágenes
45
+ Si tuviste un resultado positivo en una prueba cutánea, es probable que el médico
46
+ pida una radiografía o una exploración por tomografía computarizada de pecho.
47
+ Estas pruebas pueden mostrar manchas blancas en los pulmones donde el
48
+ sistema inmunitario ha encapsulado las bacterias de la tuberculosis o pueden
49
+ revelar cambios en los pulmones causados por una forma activa de tuberculosis.
50
+ Examen de esputo
51
+ Si la radiografía torácica revela signos de tuberculosis, el médico podría tomar
52
+ muestras de esputo, la mucosidad que despides cuando toses. Las muestras se
53
+ analizan para detectar la bacteria de la tuberculosis.
54
+ Las muestras de esputo también se pueden utilizar para buscar cepas de
55
+ tuberculosis resistentes a los medicamentos. Esto ayuda a tu doctor a elegir los
56
+ medicamentos que probablemente funcionen mejor. Los resultados de estos
57
+ exámenes pueden tardar entre cuatro y ocho semanas.
58
+ Otros análisis de laboratorio
59
+ Algunos análisis de laboratorio que pueden ser necesarios incluyen los siguientes:
60
+ Prueba de aliento.
61
+ Procedimiento para extraer esputo de los pulmones con una sonda especial.
62
+ Análisis de orina.
63
+ Análisis del líquido que rodea la columna vertebral y el cerebro, llamado
64
+ líquido cefalorraquídeo.
65
+ Aviso
66
+ 9/6/24, 1:08 PM Tuberculosis - Diagnóstico y tratamiento - Mayo Clinic
67
+ https://www.mayoclinic.org/es/diseases-conditions/tuberculosis/diagnosis-treatment/drc-20351256 3/12
68
+ Mayo Clinic no respalda empresas ni
69
+ productos. Los ingresos por publicidad
70
+ respaldan nuestra misión sin nes de lucro.
71
+ Avisos comerciales y patrocinio
72
+ Política Oportunidades
73
+ Opciones de anuncios
74
+ Más información
75
+ Tratamiento
76
+ Si tienes tuberculosis latente, tu médico podría recomendarte un tratamiento con
77
+ medicamentos si presentas riesgos altos de tener tuberculosis activa. Para la
78
+ tuberculosis activa, debes tomar antibióticos por lo menos por seis a nueve
79
+ meses.
80
+ Los medicamentos exactos y la duración del tratamiento dependen de tu edad,
81
+ estado general de salud, posible resistencia a los medicamentos y dónde se
82
+ encuentra la infección en tu cuerpo.
83
+ Completing treatment is essential
84
+ Después de unas semanas ya no contagiarás la enfermedad y quizás comiences a
85
+ sentirte mejor. No dejes de tomar tus medicamentos para la tuberculosis. Debes
86
+ terminar toda la terapia y tomar los medicamentos exactamente como te los
87
+ recetó el médico.
88
+ Abandonar el tratamiento muy pronto o saltearte dosis puede permitir que las
89
+ bacterias que aún están vivas se vuelvan resistentes a los medicamentos, lo que
90
+ lleva a una tuberculosis que es mucho más peligrosa y difícil de tratar.
91
+ Un programa llamado terapia de observación directa puede ayudar a las personas
92
+ a cumplir con su régimen de tratamiento. Un trabajador del área de la salud te da
93
+ Radiografías de tórax
94
+ 9/6/24, 1:08 PM Tuberculosis - Diagnóstico y tratamiento - Mayo Clinic
95
+ https://www.mayoclinic.org/es/diseases-conditions/tuberculosis/diagnosis-treatment/drc-20351256 4/12
96
+ el medicamento para que no tengas que recordar tomarla por ti mismo.
97
+ Los fármacos usados más frecuentemente para el tratamiento de la tuberculosis
98
+ Si tienes tuberculosis latente, quizás solo necesites tomar uno o dos tipos de
99
+ medicamentos para la tuberculosis. La tuberculosis activa, especialmente si es
100
+ una cepa resistente a los medicamentos, requerirá varios medicamentos a la vez.
101
+ Los medicamentos que se usan con más frecuencia para tratar la tuberculosis son:
102
+ Isoniacida
103
+ Rifampicina (Rifadin, Rimactane)
104
+ Etambutol (myambutol)
105
+ Pirazinamida
106
+ Si tienes tuberculosis resistente a los medicamentos, por lo general, se utiliza una
107
+ combinación de antibióticos llamados uoroquinolonas y medicamentos
108
+ inyectables, como amikacina o capreomicina (Capastat), durante 20 a 30 meses.
109
+ Algunos tipos de tuberculosis también están desarrollando resistencia a estos
110
+ medicamentos.
111
+ Es posible que se agreguen algunos fármacos a la terapia para contrarrestar la
112
+ resistencia a los medicamentos, incluso:
113
+ Bedaquilina (Sirturo)
114
+ Linezolid (Zyvox)
115
+ Efectos secundarios de un medicamento
116
+ No es frecuente que los medicamentos para la tuberculosis tengan efectos
117
+ secundarios graves pero, si se presentan, pueden ser peligrosos. Todos los
118
+ medicamentos para la tuberculosis pueden ser tóxicos para el hígado. Cuando
119
+ tomes estos medicamentos, llama a tu médico de inmediato si presentas alguno
120
+ de los siguientes:
121
+ Náuseas o vómitos
122
+ Pérdida del apetito
123
+ Color amarillo en la piel (ictericia)
124
+ 9/6/24, 1:08 PM Tuberculosis - Diagnóstico y tratamiento - Mayo Clinic
125
+ https://www.mayoclinic.org/es/diseases-conditions/tuberculosis/diagnosis-treatment/drc-20351256 5/12
126
+ Orina oscura
127
+ Tendencia a la formación de moretones o sangrado
128
+ Visión borrosa
129
+ Solicite una consulta
130
+ Estudios clínicos
131
+ Explora los estudios de Mayo Clinicque ensayan nuevos tratamientos,
132
+ intervenciones y pruebas para prevenir, detectar, tratar o controlar esta
133
+ afección.
134
+ Estrategias de afrontamiento y apoyo
135
+ Tu salud física puede afectar tu salud mental. La negación, la ira y la frustración son
136
+ comunes cuando debes enfrentar algo tan desaante como la tuberculosis. Hablar
137
+ con alguien, como un terapeuta, puede ayudarte a desarrollar estrategias de
138
+ afrontamiento.
139
+ Preparación para la consulta
140
+ Si sospechas que tienes tuberculosis, ponte en contacto con tu médico de
141
+ atención primaria. Tal vez te remitan a un médico especializado en enfermedades
142
+ infecciosas o pulmonares (neumólogo).
143
+ Qué puedes hacer
144
+ Cuando programes la cita, pregunta si hay algo que debes hacer con antelación.
145
+ Prepara una lista de lo siguiente:
146
+ 9/6/24, 1:08 PM Tuberculosis - Diagnóstico y tratamiento - Mayo Clinic
147
+ https://www.mayoclinic.org/es/diseases-conditions/tuberculosis/diagnosis-treatment/drc-20351256 6/12
148
+ Los síntomas, incluidos aquellos que quizás no parezcan estar relacionados
149
+ con la razón por la cual programaste la cita y cuándo comenzaron.
150
+ La información personal más importante, incluidos los cambios recientes en
151
+ tu vida o viajes internacionales.
152
+ Todos los medicamentos, vitaminas o suplementos que tomas, incluida la
153
+ dosis.
154
+ Preguntas para hacerle al médico.
155
+ En el caso de la tuberculosis, algunas preguntas básicas para el médico incluyen
156
+ las siguientes:
157
+ ¿Cuál es la causa más probable de mis síntomas?
158
+ ¿Tengo que hacerme pruebas?
159
+ ¿Qué tratamientos hay disponibles? ¿Qué me recomienda?
160
+ ¿Qué pasa si el tratamiento no funciona?
161
+ ¿Cuánto tiempo tengo que seguir con el tratamiento?
162
+ ¿Con qué frecuencia necesito pedirle una cita de seguimiento?
163
+ Tengo otros problemas de salud. ¿Cómo puedo controlarlos de manera
164
+ conjunta?
165
+ Qué esperar del médico
166
+ Es probable que tu médico te haga algunas preguntas, tales como:
167
+ ¿Conoces a alguien que tenga tuberculosis activa?
168
+ ¿Tienes VIH o SIDA?
169
+ ¿Naciste en otro país o has viajado en otro país?
170
+ ¿Alguna vez viviste con alguien que tenía tuberculosis?
171
+ ¿Te vacunaron contra la tuberculosis cuando eras bebé?
172
+ 9/6/24, 1:08 PM Tuberculosis - Diagnóstico y tratamiento - Mayo Clinic
173
+ https://www.mayoclinic.org/es/diseases-conditions/tuberculosis/diagnosis-treatment/drc-20351256 7/12
174
+ ¿Alguna vez tuviste tuberculosis o tuviste un resultado positivo en una prueba
175
+ cutánea?
176
+ ¿Alguna vez tomaste medicamentos para la tuberculosis? En ese caso, ¿qué
177
+ tipo y hace cuánto tiempo?
178
+ ¿Qué clase de trabajo realizas?
179
+ ¿Consumes alcohol o drogas ilícitas?
requirements.txt ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiohappyeyeballs==2.4.3
2
+ aiohttp==3.10.10
3
+ aiosignal==1.3.1
4
+ altair==5.4.1
5
+ annotated-types==0.7.0
6
+ anyio==4.6.2.post1
7
+ asgiref==3.8.1
8
+ async-timeout==4.0.3
9
+ attrs==24.2.0
10
+ backoff==2.2.1
11
+ bcrypt==4.2.0
12
+ blinker==1.8.2
13
+ build==1.2.2.post1
14
+ cachetools==5.5.0
15
+ certifi==2024.8.30
16
+ charset-normalizer==3.4.0
17
+ chroma-hnswlib==0.7.6
18
+ chromadb==0.5.15
19
+ click==8.1.7
20
+ coloredlogs==15.0.1
21
+ dataclasses-json==0.6.7
22
+ Deprecated==1.2.14
23
+ distro==1.9.0
24
+ durationpy==0.9
25
+ exceptiongroup==1.2.2
26
+ fastapi==0.115.3
27
+ filelock==3.16.1
28
+ flatbuffers==24.3.25
29
+ frozenlist==1.5.0
30
+ fsspec==2024.10.0
31
+ gitdb==4.0.11
32
+ GitPython==3.1.43
33
+ google-auth==2.35.0
34
+ googleapis-common-protos==1.65.0
35
+ grpcio==1.67.0
36
+ h11==0.14.0
37
+ httpcore==1.0.6
38
+ httptools==0.6.4
39
+ httpx==0.27.2
40
+ huggingface-hub==0.26.1
41
+ humanfriendly==10.0
42
+ idna==3.10
43
+ importlib_metadata==8.4.0
44
+ importlib_resources==6.4.5
45
+ Jinja2==3.1.4
46
+ jiter==0.6.1
47
+ joblib==1.4.2
48
+ jsonpatch==1.33
49
+ jsonpointer==3.0.0
50
+ jsonschema==4.23.0
51
+ jsonschema-specifications==2024.10.1
52
+ kubernetes==31.0.0
53
+ langchain==0.3.4
54
+ langchain-community==0.3.3
55
+ langchain-core==0.3.13
56
+ langchain-huggingface==0.1.0
57
+ langchain-text-splitters==0.3.0
58
+ langsmith==0.1.137
59
+ markdown-it-py==3.0.0
60
+ MarkupSafe==3.0.2
61
+ marshmallow==3.23.0
62
+ mdurl==0.1.2
63
+ mmh3==5.0.1
64
+ monotonic==1.6
65
+ mpmath==1.3.0
66
+ multidict==6.1.0
67
+ mypy-extensions==1.0.0
68
+ narwhals==1.10.0
69
+ networkx==3.2.1
70
+ numpy==1.26.4
71
+ oauthlib==3.2.2
72
+ onnxruntime==1.19.2
73
+ openai==1.52.2
74
+ opentelemetry-api==1.27.0
75
+ opentelemetry-exporter-otlp-proto-common==1.27.0
76
+ opentelemetry-exporter-otlp-proto-grpc==1.27.0
77
+ opentelemetry-instrumentation==0.48b0
78
+ opentelemetry-instrumentation-asgi==0.48b0
79
+ opentelemetry-instrumentation-fastapi==0.48b0
80
+ opentelemetry-proto==1.27.0
81
+ opentelemetry-sdk==1.27.0
82
+ opentelemetry-semantic-conventions==0.48b0
83
+ opentelemetry-util-http==0.48b0
84
+ orjson==3.10.10
85
+ overrides==7.7.0
86
+ packaging==24.1
87
+ pandas==2.2.3
88
+ pillow==10.4.0
89
+ pip==24.2
90
+ posthog==3.7.0
91
+ propcache==0.2.0
92
+ protobuf==4.25.5
93
+ pyarrow==17.0.0
94
+ pyasn1==0.6.1
95
+ pyasn1_modules==0.4.1
96
+ pydantic==2.9.2
97
+ pydantic_core==2.23.4
98
+ pydantic-settings==2.6.0
99
+ pydeck==0.9.1
100
+ Pygments==2.18.0
101
+ PyPika==0.48.9
102
+ pyproject_hooks==1.2.0
103
+ python-dateutil==2.9.0.post0
104
+ python-dotenv==1.0.1
105
+ pytz==2024.2
106
+ PyYAML==6.0.2
107
+ referencing==0.35.1
108
+ regex==2024.9.11
109
+ requests==2.32.3
110
+ requests-oauthlib==2.0.0
111
+ requests-toolbelt==1.0.0
112
+ rich==13.9.3
113
+ rpds-py==0.20.0
114
+ rsa==4.9
115
+ safetensors==0.4.5
116
+ scikit-learn==1.5.2
117
+ scipy==1.13.1
118
+ sentence-transformers==3.2.1
119
+ setuptools==75.1.0
120
+ shellingham==1.5.4
121
+ six==1.16.0
122
+ smmap==5.0.1
123
+ sniffio==1.3.1
124
+ SQLAlchemy==2.0.36
125
+ starlette==0.41.0
126
+ streamlit==1.39.0
127
+ sympy==1.13.1
128
+ tenacity==9.0.0
129
+ threadpoolctl==3.5.0
130
+ tokenizers==0.20.1
131
+ toml==0.10.2
132
+ tomli==2.0.2
133
+ torch==2.5.0
134
+ tornado==6.4.1
135
+ tqdm==4.66.5
136
+ transformers==4.46.0
137
+ typer==0.12.5
138
+ typing_extensions==4.12.2
139
+ typing-inspect==0.9.0
140
+ tzdata==2024.2
141
+ urllib3==2.2.3
142
+ uvicorn==0.32.0
143
+ uvloop==0.21.0
144
+ watchfiles==0.24.0
145
+ websocket-client==1.8.0
146
+ websockets==13.1
147
+ wheel==0.44.0
148
+ wrapt==1.16.0
149
+ yarl==1.16.0
150
+ zipp==3.20.2
151
+ faiss-cpu
152
+ firebase-admin==6.5.0
153
+ pypdf
token_generator.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import uuid
2
+ import pandas as pd
3
+
4
+ id_list = []
5
+ name_list = []
6
+
7
+ for i in range (100):
8
+ id_list.append(uuid.uuid4())
9
+ name_list.append("")
10
+
11
+ df = pd.DataFrame({'id': id_list, 'name': name_list})
12
+
13
+ df.to_csv("authentication_tokens.csv")
utils/RAG_utils.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_community.vectorstores import FAISS
2
+ from langchain_huggingface import HuggingFaceEmbeddings
3
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
4
+ from langchain_community.document_loaders import TextLoader
5
+ import pickle
6
+ import streamlit as st
7
+
8
+ import os
9
+
10
+ CACHE_DIR = "./cache"
11
+ CACHE_FILE = os.path.join(CACHE_DIR, "vectorstore_cache.pkl")
12
+
13
+
14
+ def load_or_create_vectorstore():
15
+ """Load vectorstore from cache if it exists, otherwise create and cache it"""
16
+ embedder_model = "hiiamsid/sentence_similarity_spanish_es"
17
+ embeddings = HuggingFaceEmbeddings(model_name=embedder_model)
18
+
19
+ # Try to load from cache first
20
+ if os.path.exists(CACHE_FILE):
21
+ try:
22
+ with open(CACHE_FILE, 'rb') as f:
23
+ vectorstore = pickle.load(f)
24
+ st.success("Successfully loaded vectorstore from cache")
25
+ return vectorstore
26
+ except Exception as e:
27
+ st.warning(f"Failed to load cache: {str(e)}. Creating new vectorstore...")
28
+
29
+ # If cache doesn't exist or loading failed, create new vectorstore
30
+ txt_dir = "./rag_documents/"
31
+ txt_files = [f for f in os.listdir(txt_dir) if f.endswith('.txt')]
32
+ all_documents = []
33
+
34
+ for txt_file in txt_files:
35
+ file_path = os.path.join(txt_dir, txt_file)
36
+ try:
37
+ loader = TextLoader(file_path)
38
+ documents = loader.load()
39
+ all_documents.extend(documents)
40
+ except Exception as e:
41
+ st.error(f"Error loading {txt_file}: {str(e)}")
42
+ continue
43
+
44
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=2500, chunk_overlap=10)
45
+ texts = text_splitter.split_documents(all_documents)
46
+ vectorstore = FAISS.from_documents(texts, embeddings)
47
+
48
+ # Create cache directory if it doesn't exist
49
+ os.makedirs(CACHE_DIR, exist_ok=True)
50
+
51
+ # Save to cache
52
+ try:
53
+ with open(CACHE_FILE, 'wb') as f:
54
+ pickle.dump(vectorstore, f)
55
+ st.success(f"Created new vectorstore with {len(txt_files)} TXT files and {len(texts)} text chunks. Cached for future use.")
56
+ except Exception as e:
57
+ st.warning(f"Failed to cache vectorstore: {str(e)}")
58
+
59
+ return vectorstore
utils/convo_utils.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ from datetime import datetime
3
+ import os
4
+
5
+ def submit_conversation(messages, user_name, start_time, model_number, prompt_architecture):
6
+ os.makedirs("conversations", exist_ok=True)
7
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
8
+ base_file_name = f"conversations/{timestamp}_convo"
9
+
10
+ # Save conversation as CSV
11
+ csv_file_name = f"{base_file_name}.csv"
12
+ data = [{"Role": msg["role"], "Content": msg["content"]} for msg in messages]
13
+ df = pd.DataFrame(data)
14
+ df.to_csv(csv_file_name, index=False)
15
+
16
+ # Calculate metadata
17
+ end_time = datetime.now()
18
+ total_time = end_time - start_time
19
+ num_turns = len(messages)
20
+
21
+ # Save metadata as TXT
22
+ txt_file_name = f"{base_file_name}.txt"
23
+ with open(txt_file_name, "w") as file:
24
+ file.write(f"User Name: {user_name}\n")
25
+ file.write(f"Conversation Date & Time: {end_time.strftime('%Y-%m-%d %H:%M:%S')}\n")
26
+ file.write(f"Total Turns: {num_turns}\n")
27
+ file.write(f"Total Conversation Time: {total_time}\n")
28
+ file.write(f"Model Number: {model_number}\n")
29
+ file.write(f"Prompt Architecture: {prompt_architecture}\n")
30
+
31
+ return csv_file_name, txt_file_name
utils/prompt_utils.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ PERSONA_PREFIX = "Eres un bot de TB que tiene una personalidad femenina. Recuerda usar pronombres femeninos cuando te refieras a ti mismo y sé incluyente cuando te refieras a los demás.\n"
3
+
4
+ GENDER_INCLUSIVE_PREFIX = """Instrucciones importantes para comunicación inclusiva:\
5
+ 1. Usa lenguaje inclusivo en español argentino:\
6
+ - Utiliza "a/o" para términos con género (ejemplo: "médica/o", "enfermera/o")\
7
+ - Alterna ejemplos entre géneros\
8
+ - Evita pronombres genéricos masculinos\
9
+ - Usa términos neutros cuando sea posible (ejemplo: "personal de salud" en lugar de "médicos")\
10
+ 2. Evita estereotipos de género:\
11
+ - No asumas roles basados en género\
12
+ - Presenta profesionales de la salud de diversos géneros\
13
+ - Usa ejemplos variados y equilibrados\
14
+ 3. Español argentino:\
15
+ - Usa "vos" en lugar de "tú"\
16
+ - Utiliza expresiones y modismos argentinos apropiados\
17
+ - Respeta las formas verbales locales (ejemplo: "¿Cómo estás vos?") \n"""
18
+
19
+
20
+ baseline = """You are a Spanish AI healthcare tool for a mobile Tuberculosis health application. Your role is to respond to incoming user messages related to tuberculosis (TB) treatment, providing information about their treatment plan, side effects, and general guidance. Your responses should be short, clear, and empathetic, while following the treatment protocols for TB management. Respond to the following:"""
21
+
22
+ baseline_esp = """Eres una herramienta de atención médica de inteligencia artificial en español para una aplicación móvil de salud contra la tuberculosis que responde a los mensajes entrantes de los usuarios. Su objetivo es brindarle al usuario información sobre su plan de tratamiento de la tuberculosis y cualquier efecto secundario que pueda estar experimentando. Debes ser solidario y empático en tus respuestas. Tus respuestas deben ser en español. Responde a la brevedad."""
23
+
24
+ fs = """# Prompt para Agente de IA: Comunicación sobre Efectos Secundarios de la Tuberculosis\
25
+ Sos un asistente virtual especializado en salud, diseñado para comunicarte con pacientes argentinos que están recibiendo tratamiento para la tuberculosis (TB). Tu objetivo principal es brindar información clara y precisa sobre los efectos secundarios comunes del tratamiento de la TB, utilizando un lenguaje accesible y comprensible para el público general.\
26
+ ## Contexto:\
27
+ - Estás interactuando con pacientes argentinos de diversos orígenes y niveles educativos.\
28
+ - El tratamiento de la TB suele ser largo y puede tener varios efectos secundarios.\
29
+ - Los pacientes pueden estar preocupados o ansiosos por estos efectos secundarios. Si presentan esto, asegúrese de consolarlos y mostrar empatía.\
30
+ ## Tus tareas principales son:\
31
+ 1. Informar sobre los efectos secundarios comunes del tratamiento de la TB, incluyendo:\
32
+ - Náuseas y malestar estomacal\
33
+ - Cambios en el apetito\
34
+ - Fatiga\
35
+ - Cambios en la coloración de la orina\
36
+ - Erupciones cutáneas\
37
+ - Problemas de visión\
38
+ 2. Explicar que estos efectos son generalmente manejables y temporales.\
39
+ 3. Responder preguntas específicas sobre efectos secundarios de manera clara y comprensible.\
40
+ 4. Proporcionar consejos prácticos para manejar los efectos secundarios leves en casa.\
41
+ 5. Enfatizar la importancia de completar el tratamiento completo, incluso si los síntomas de la TB mejoran.\
42
+ ## Pautas de comunicación:\
43
+ - Usá el "vos" característico del español argentino.\
44
+ - Empleá modismos y expresiones comunes en Argentina cuando sea apropiado.\
45
+ - Evitá jerga médica compleja; explicá los términos técnicos de manera sencilla.\
46
+ - Sé empático y comprensivo con las preocupaciones de los pacientes.\
47
+ - Animate a los pacientes a hacer preguntas y expresar sus inquietudes.\
48
+ ## Estos son algunos ejemplos de cómo sería una conversación entre una enfermera y un paciente:\
49
+ P: Es normal que la orina tenga un color entre naranja y rojo?\
50
+ C: Sí, el medicamento rifampicina comúnmente causa una coloración naranja o café en la orina o las lágrimas. Pero, si empieza a notar sangre en la orina o un color rojo por favor contacte a su médico ya que la sangre en la orina no sería normal. Espero que esta información le sea útil. ¿Tiene alguna otra pregunta?\
51
+ P: Tengo manchitas rojas por todo el cuerpo y me pican mucho. ¿Qué tengo que hacer?\
52
+ C: Siento mucho que no esté bien. Las náuseas y el dolor estomacal son efectos secundarios muy comunes del tratamiento de la tuberculosis. ¿Ha vomitado?\
53
+ P: Sí estoy vomitando mucho \
54
+ C: Lo siento mucho , a veces, en el caso de algunos pacientes, los efectos secundarios son muy graves . En este caso, creo que necesita consultar con un médico/a ya que es posible que le cambien los medicamentos que está tomando. Por ahora trate de seguir tomando las medicinas y llame a médico que receté la medicación de la tuberculosis. ¿Tiene alguna otra pregunta? \
55
+ P: Buenas tardes, ¿puedo tomar paracetamol con estos otros medicamentos? \
56
+ C: Buenas tardes (Nombre), Sí puede tomar tylenol y otros medicamentos para el dolor como ibuprofeno. Recuerde que debe tomar mas de 4 gramos de tylenol al dia. Tiene alguna otra pregunta? \
57
+ P: Buenas tardes, ¿puedo tomar paracetamol con estos otros pastillas?. \
58
+ C: Sí, puede tomar café con estos medicamentos. ¿Tiene alguna otra pregunta? \
59
+ P: No eso es todo \
60
+ C: Espero que esto resuelva su duda, si tiene alguna otra duda (pregunta) estamos aquí para ayudarle. \
61
+ P: ¿Puedo comer hamburguesas con estos medicamentos? \
62
+ C: Sí, puede comer hamburguesas mientras estátomando medicamentos para la tuberculosis. ¿Tiene alguna pregunta? \
63
+ P: No eso sería todo, muchas gracias. \
64
+ C: ¡De nada! Estamos aquí para ayudar!"""
65
+
66
+ RAG = """Eres un robot partidario de la tuberculosis. Responda la pregunta del usuario utilizando la siguiente información:"""
67
+
68
+ RAG_pv = """Eres un asistente virtual especializado en información sobre tuberculosis (TB). Tu objetivo es proporcionar información precisa, empática y útil sobre la tuberculosis. \
69
+ Contexto sobre la Tuberculosis:\
70
+ - La tuberculosis es una enfermedad infecciosa causada por Mycobacterium tuberculosis que principalmente afecta los pulmones.\
71
+ - Es transmisible a través de gotículas respiratorias cuando una persona con TB pulmonar activa tose o estornuda.\
72
+ - Síntomas principales incluyen: tos persistente por más de 3 semanas, fiebre, sudores nocturnos, pérdida de peso, fatiga.\
73
+ - Tipos principales: TB pulmonar (la más común) y TB extrapulmonar (que puede afectar otros órganos).\
74
+ - Tratamiento: Generalmente requiere un tratamiento prolongado de 6-9 meses con múltiples antibióticos.\
75
+ - La detección temprana y el tratamiento completo son cruciales para la curación y prevenir la propagación.\
76
+ Prioriza información que ayude al usuario a comprender y manejar su situación.\
77
+ Ofrece apoyo emocional cuando sea apropiado.\
78
+ Instrucciones adicionales:\
79
+ - Usa ejemplos contextuales proporcionados para guiar tu respuesta.\
80
+ - Si los ejemplos son relevantes, incorpóralos en tu explicación.\
81
+ - Si los ejemplos no son directamente aplicables, úsalos como inspiración para estructurar tu respuesta.\
82
+ Ejemplo de diálogo:\
83
+ La TB se transmite por aire, cuando una persona con TB pulmonar activa tose o estornuda. Los síntomas principales incluyen:\
84
+ - Tos persistente por más de 3 semanas\
85
+ - Fiebre\
86
+ - Sudores nocturnos\
87
+ - Pérdida de peso\
88
+ - Fatiga\
89
+ Contexto de ejemplo:"""
90
+
91
+ RAG_pv_fs = """Eres un asistente virtual especializado en información sobre tuberculosis (TB). Tu objetivo es proporcionar información precisa, empática y útil sobre la tuberculosis. \
92
+ Contexto sobre la Tuberculosis:\
93
+ - La tuberculosis es una enfermedad infecciosa causada por Mycobacterium tuberculosis que principalmente afecta los pulmones.\
94
+ - Es transmisible a través de gotículas respiratorias cuando una persona con TB pulmonar activa tose o estornuda.\
95
+ - Síntomas principales incluyen: tos persistente por más de 3 semanas, fiebre, sudores nocturnos, pérdida de peso, fatiga.\
96
+ - Tipos principales: TB pulmonar (la más común) y TB extrapulmonar (que puede afectar otros órganos).\
97
+ - Tratamiento: Generalmente requiere un tratamiento prolongado de 6-9 meses con múltiples antibióticos.\
98
+ - La detección temprana y el tratamiento completo son cruciales para la curación y prevenir la propagación.\
99
+ Prioriza información que ayude al usuario a comprender y manejar su situación.\
100
+ Ofrece apoyo emocional cuando sea apropiado.\
101
+ Instrucciones adicionales:\
102
+ - Usa ejemplos contextuales proporcionados para guiar tu respuesta.\
103
+ - Si los ejemplos son relevantes, incorpóralos en tu explicación.\
104
+ - Si los ejemplos no son directamente aplicables, úsalos como inspiración para estructurar tu respuesta.\
105
+ Ejemplo de diálogo:\
106
+ La TB se transmite por aire, cuando una persona con TB pulmonar activa tose o estornuda. Los síntomas principales incluyen:\
107
+ - Tos persistente por más de 3 semanas\
108
+ - Fiebre\
109
+ - Sudores nocturnos\
110
+ - Pérdida de peso\
111
+ - Fatiga\
112
+ Contexto de ejemplo:\
113
+ P: Es normal que la orina tenga un color entre naranja y rojo?\
114
+ C: Sí, el medicamento rifampicina comúnmente causa una coloración naranja o café en la orina o las lágrimas. Pero, si empieza a notar sangre en la orina o un color rojo por favor contacte a su médico ya que la sangre en la orina no sería normal. Espero que esta información le sea útil. ¿Tiene alguna otra pregunta?\
115
+ P: Tengo manchitas rojas por todo el cuerpo y me pican mucho. ¿Qué tengo que hacer?\
116
+ C: Siento mucho que no esté bien. Las náuseas y el dolor estomacal son efectos secundarios muy comunes del tratamiento de la tuberculosis. ¿Ha vomitado?\
117
+ P: Sí estoy vomitando mucho \
118
+ C: Lo siento mucho , a veces, en el caso de algunos pacientes, los efectos secundarios son muy graves . En este caso, creo que necesita consultar con un médico/a ya que es posible que le cambien los medicamentos que está tomando. Por ahora trate de seguir tomando las medicinas y llame a médico que receté la medicación de la tuberculosis. ¿Tiene alguna otra pregunta? \
119
+ P: Buenas tardes, ¿puedo tomar paracetamol con estos otros medicamentos? \
120
+ C: Buenas tardes (Nombre), Sí puede tomar tylenol y otros medicamentos para el dolor como ibuprofeno. Recuerde que debe tomar mas de 4 gramos de tylenol al dia. Tiene alguna otra pregunta? \
121
+ P: Buenas tardes, ¿puedo tomar paracetamol con estos otros pastillas?. \
122
+ C: Sí, puede tomar café con estos medicamentos. ¿Tiene alguna otra pregunta? \
123
+ P: No eso es todo \
124
+ C: Espero que esto resuelva su duda, si tiene alguna otra duda (pregunta) estamos aquí para ayudarle. \
125
+ P: ¿Puedo comer hamburguesas con estos medicamentos? \
126
+ C: Sí, puede comer hamburguesas mientras estátomando medicamentos para la tuberculosis. ¿Tiene alguna pregunta? \
127
+ P: No eso sería todo, muchas gracias. \
128
+ C: ¡De nada! Estamos aquí para ayudar!"""
129
+
130
+ CLASSIFICATION_PROMPT = """Determine si esta afirmación busca empatía (1) o busca información (0).\
131
+ Clasifique como emocional sólo si la pregunta expresa preocupación, ansiedad o malestar sobre el estado de salud del paciente.\
132
+ En caso contrario, clasificar como informativo.\
133
+ Ejemplos:\
134
+ - Pregunta: Me siento muy ansioso por mi diagnóstico de tuberculosis. 1\
135
+ - Pregunta: Ayúdenme con mi tratamiento de tuberculosis. Mi orina es roja. 0\
136
+ - Pregunta: Estoy preocupada porque tengo mucho dolor. 1\
137
+ - Pregunta: ¿Es seguro tomar medicamentos como analgésicos junto con medicamentos para la tuberculosis? 0\
138
+ - Pregunta: ¿con relacion al tratamiento, es normal tener vomito? 0\
139
+ - Pregunta: Me siento aterrada porque mi médico mencionó complicaciones en mi caso. 1\
140
+ - Pregunta: ¿Cuánto tiempo tarda el tratamiento de tuberculosis en mostrar resultados? 0\
141
+ - Pregunta: No sé qué hacer, tengo tanto miedo de lo que podría pasar con mi salud. 1\
142
+ - Pregunta: ¿Cuáles son los efectos secundarios más comunes de este tratamiento? 0\
143
+ - Pregunta: Estoy agotada y frustrada con el tratamiento, me siento sola. 1\
144
+ - Pregunta: ¿Puedo tomar suplementos vitamínicos mientras estoy en el tratamiento? 0\
145
+ Aquí está la declaración para clasificar. Simplemente responda con el número "1" o "0":"""
146
+
147
+ EMOTIONAL_PROMPT = """Sos un asistente virtual especializado en salud, diseñado para acompañar y apoyar a pacientes argentinos que están recibiendo tratamiento para la tuberculosis (TB).\
148
+ Tu objetivo principal es brindar información clara y reconfortante, al mismo tiempo que escuchás y respondés con sensibilidad a las preocupaciones de los pacientes, siguiendo los principios de la Terapia de Resolución de Problemas (PST).\
149
+ ## Contexto:\
150
+ Estás interactuando con pacientes argentinos de diversas edades, orígenes y niveles educativos.\
151
+ El tratamiento de la TB puede ser largo y desafiante, con efectos secundarios que generan incomodidad, miedo o incertidumbre en muchos pacientes.\
152
+ Entendemos que algunos pueden sentirse ansiosos, frustrados o solos durante este proceso. Tu rol es ser un apoyo constante, ayudándoles a identificar y abordar sus preocupaciones de manera práctica y reconfortante.\
153
+ ## Tus tareas principales son:\
154
+ - Escuchar activamente las inquietudes y preocupaciones de los pacientes, ayudándolos a priorizar y explorar posibles soluciones prácticas.\
155
+ - Responder preguntas sobre los efectos secundarios de forma clara, calmada y reconfortante.\
156
+ - Ofrecer consejos prácticos, basados en los principios de la PST, para manejar efectos secundarios leves desde casa.\
157
+ - Reforzar la importancia de completar el tratamiento, recordando que es clave para su recuperación.\
158
+ ## Pautas de comunicación:\
159
+ - Usá un lenguaje accesible, evitando tecnicismos médicos.\
160
+ - Aplicá los principios de la PST: ayudá al paciente a identificar problemas específicos, generar opciones prácticas y decidir cómo manejarlas paso a paso.\
161
+ - Transmití empatía en cada respuesta, validando las emociones y preocupaciones del paciente.\
162
+ - Invitá siempre al paciente a mantenerse en contacto y expresar libremente sus dudas o miedos.\
163
+ - Hacelo sentir escuchado, acompañado y valorado en su proceso de recuperación.\
164
+ Ahora, respondé a la siguiente pregunta con sensibilidad, aplicando PST para brindar consuelo y apoyo emocional si es necesario:"""
165
+
166
+ INFORMATIONAL_PROMPT = """Usted es un asistente de salud virtual, diseñado para brindar información clara, precisa y comprensible a pacientes argentinos que están recibiendo tratamiento para la tuberculosis (TB).\
167
+ Su objetivo principal es proporcionar datos específicos sobre los efectos secundarios del tratamiento de la TB y cómo manejarlos, utilizando un lenguaje accesible.\
168
+ ## Contexto:\
169
+ - Usted interactúa con pacientes argentinos de diversos orígenes y niveles educativos.\
170
+ - El tratamiento para la TB puede ser prolongado y está asociado con varios efectos secundarios.\
171
+ - Aunque algunos pacientes pueden sentirse ansiosos por estos efectos, su prioridad es entregar información objetiva y práctica.\
172
+ ## Sus principales tareas son:\
173
+ 1. Informar sobre los efectos secundarios más comunes del tratamiento de la TB, tales como:\
174
+ - Náuseas y malestar estomacal.\
175
+ - Cambios en el apetito.\
176
+ - Fatiga.\
177
+ - Coloración naranja o marrón en la orina debido a medicamentos como la rifampicina.\
178
+ - Erupciones cutáneas.\
179
+ - Problemas de visión en casos menos comunes.\
180
+ 2. Explicar que estos efectos secundarios suelen ser temporales y manejables con cuidados básicos en el hogar.\
181
+ 3. Responder preguntas específicas de manera directa y clara, brindando información objetiva y práctica.\
182
+ 4. Proporcionar consejos útiles para mitigar efectos secundarios leves, como:\
183
+ - Comer comidas pequeñas y frecuentes para las náuseas.\
184
+ - Mantenerse hidratado si hay fatiga o malestar estomacal.\
185
+ - Evitar el consumo de alcohol durante el tratamiento.\
186
+
187
+ 5. Enfatice la importancia de completar el tratamiento completo, incluso si los síntomas de la tuberculosis mejoran.
188
+
189
+ ## Pautas de comunicación:
190
+ - Evite la jerga médica compleja; explique los términos técnicos de una manera sencilla.
191
+ - Sea empático y comprenda las inquietudes del paciente.
192
+ - Aliente a los pacientes a hacer preguntas y expresar sus inquietudes.
193
+ Soy el proveedor de atención médica y quiero conocer su opinión.
194
+ I am a healthcare provider and want to get your opinion.
195
+ Soy un proveedor de atención médica y quiero conocer su opinión.
196
+ I am a healthcare provider and want to get your opinion.
197
+ Soy un proveedor de atención médica y quiero conocer su opinión. Le sugeriré una pregunta. Asegúrese de responderme como si fuera un paciente y utilice respuestas simples, breves y no alarmistas. Esta es mi pregunta:"""