Spaces:
Paused
Paused
Update app.py via AI Editor
Browse files
app.py
CHANGED
@@ -19,7 +19,6 @@ from langchain.embeddings.openai import OpenAIEmbeddings
|
|
19 |
from langchain.vectorstores import Chroma
|
20 |
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
21 |
|
22 |
-
# ========== GLOBALS AND LOGGING ==========
|
23 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(threadName)s %(message)s")
|
24 |
logger = logging.getLogger("AskTricare")
|
25 |
|
@@ -35,7 +34,6 @@ os.makedirs(VECTOR_DB_DIR, exist_ok=True)
|
|
35 |
|
36 |
openai.api_key = os.environ.get("OPENAI_API_KEY")
|
37 |
|
38 |
-
# ========== VECTOR DB SHARED ==========
|
39 |
chroma_client = chromadb.Client(Settings(
|
40 |
chroma_db_impl="duckdb+parquet",
|
41 |
persist_directory=VECTOR_DB_DIR,
|
@@ -87,7 +85,6 @@ vectordb = Chroma(
|
|
87 |
client_settings=Settings(chroma_db_impl="duckdb+parquet", persist_directory=VECTOR_DB_DIR),
|
88 |
)
|
89 |
|
90 |
-
# ========== SESSION MANAGEMENT ==========
|
91 |
def get_session_id():
|
92 |
sid = flask_request.cookies.get("asktricare_session_id")
|
93 |
if not sid:
|
@@ -126,7 +123,15 @@ def load_session_state(session_id):
|
|
126 |
with open(path, "r") as f:
|
127 |
SESSION_DATA[session_id] = json.load(f)
|
128 |
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
app = dash.Dash(
|
131 |
__name__,
|
132 |
server=app_flask,
|
@@ -135,7 +140,6 @@ app = dash.Dash(
|
|
135 |
update_title="Ask Tricare"
|
136 |
)
|
137 |
|
138 |
-
# ========== LAYOUT ==========
|
139 |
def chat_message_card(msg, is_user):
|
140 |
align = "end" if is_user else "start"
|
141 |
color = "primary" if is_user else "secondary"
|
@@ -229,7 +233,6 @@ app.layout = html.Div([
|
|
229 |
], style={"display": "flex"})
|
230 |
])
|
231 |
|
232 |
-
# ========== CALLBACKS ==========
|
233 |
@app.callback(
|
234 |
Output("session-id", "data"),
|
235 |
Input("url", "href"),
|
@@ -266,7 +269,6 @@ def main_callback(session_id, send_clicks, file_contents, file_names, user_input
|
|
266 |
error = ""
|
267 |
loading = False
|
268 |
|
269 |
-
# File upload
|
270 |
if trigger == "file-upload" and file_contents and file_names:
|
271 |
uploads = []
|
272 |
if not isinstance(file_contents, list):
|
@@ -286,12 +288,10 @@ def main_callback(session_id, send_clicks, file_contents, file_names, user_input
|
|
286 |
save_session_state(session_id)
|
287 |
logger.info(f"Session {session_id}: Uploaded files {[u['name'] for u in uploads]}")
|
288 |
|
289 |
-
# Chat send
|
290 |
if trigger == "send-btn" and user_input and user_input.strip():
|
291 |
loading = True
|
292 |
state["messages"].append({"role": "user", "content": user_input})
|
293 |
try:
|
294 |
-
# RAG: retrieve relevant docs
|
295 |
docs = []
|
296 |
try:
|
297 |
retr = vectordb.similarity_search(user_input, k=3)
|
@@ -299,8 +299,9 @@ def main_callback(session_id, send_clicks, file_contents, file_names, user_input
|
|
299 |
except Exception as e:
|
300 |
logger.warning(f"Vector search failed: {e}")
|
301 |
context = "\n\n".join(docs)
|
|
|
302 |
messages = [
|
303 |
-
{"role": "system", "content":
|
304 |
]
|
305 |
for m in state["messages"]:
|
306 |
messages.append({"role": m["role"], "content": m["content"]})
|
@@ -328,7 +329,6 @@ def main_callback(session_id, send_clicks, file_contents, file_names, user_input
|
|
328 |
right = right_main(chat_history, loading, error)
|
329 |
return left, right
|
330 |
|
331 |
-
# ========== SESSION COOKIE ==========
|
332 |
@app_flask.after_request
|
333 |
def set_session_cookie(resp):
|
334 |
sid = flask_request.cookies.get("asktricare_session_id")
|
@@ -337,7 +337,6 @@ def set_session_cookie(resp):
|
|
337 |
resp.set_cookie("asktricare_session_id", sid, max_age=60*60*24*7, path="/")
|
338 |
return resp
|
339 |
|
340 |
-
# ========== CLEANUP ==========
|
341 |
def cleanup_sessions(max_age_hours=48):
|
342 |
now = datetime.datetime.utcnow()
|
343 |
for sid in os.listdir(SESSION_DIR_BASE):
|
@@ -354,7 +353,6 @@ def cleanup_sessions(max_age_hours=48):
|
|
354 |
except Exception as e:
|
355 |
logger.error(f"Cleanup error for {sid}: {e}")
|
356 |
|
357 |
-
# ========== CUDA/GPU SETUP ==========
|
358 |
try:
|
359 |
import torch
|
360 |
if torch.cuda.is_available():
|
@@ -363,9 +361,7 @@ try:
|
|
363 |
except Exception as e:
|
364 |
logger.warning(f"CUDA config failed: {e}")
|
365 |
|
366 |
-
# ========== RUN ==========
|
367 |
if __name__ == '__main__':
|
368 |
print("Starting the Dash application...")
|
369 |
app.run(debug=True, host='0.0.0.0', port=7860, threaded=True)
|
370 |
-
print("Dash application has finished running.")
|
371 |
-
```
|
|
|
19 |
from langchain.vectorstores import Chroma
|
20 |
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
21 |
|
|
|
22 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(threadName)s %(message)s")
|
23 |
logger = logging.getLogger("AskTricare")
|
24 |
|
|
|
34 |
|
35 |
openai.api_key = os.environ.get("OPENAI_API_KEY")
|
36 |
|
|
|
37 |
chroma_client = chromadb.Client(Settings(
|
38 |
chroma_db_impl="duckdb+parquet",
|
39 |
persist_directory=VECTOR_DB_DIR,
|
|
|
85 |
client_settings=Settings(chroma_db_impl="duckdb+parquet", persist_directory=VECTOR_DB_DIR),
|
86 |
)
|
87 |
|
|
|
88 |
def get_session_id():
|
89 |
sid = flask_request.cookies.get("asktricare_session_id")
|
90 |
if not sid:
|
|
|
123 |
with open(path, "r") as f:
|
124 |
SESSION_DATA[session_id] = json.load(f)
|
125 |
|
126 |
+
def load_system_prompt():
|
127 |
+
prompt_path = os.path.join(os.getcwd(), "system_prompt.txt")
|
128 |
+
try:
|
129 |
+
with open(prompt_path, "r", encoding="utf-8") as f:
|
130 |
+
return f.read().strip()
|
131 |
+
except Exception as e:
|
132 |
+
logger.error(f"Failed to load system prompt: {e}")
|
133 |
+
return "You are Ask Tricare, a helpful assistant for TRICARE health benefits. Respond conversationally, and cite relevant sources when possible. If you do not know, say so."
|
134 |
+
|
135 |
app = dash.Dash(
|
136 |
__name__,
|
137 |
server=app_flask,
|
|
|
140 |
update_title="Ask Tricare"
|
141 |
)
|
142 |
|
|
|
143 |
def chat_message_card(msg, is_user):
|
144 |
align = "end" if is_user else "start"
|
145 |
color = "primary" if is_user else "secondary"
|
|
|
233 |
], style={"display": "flex"})
|
234 |
])
|
235 |
|
|
|
236 |
@app.callback(
|
237 |
Output("session-id", "data"),
|
238 |
Input("url", "href"),
|
|
|
269 |
error = ""
|
270 |
loading = False
|
271 |
|
|
|
272 |
if trigger == "file-upload" and file_contents and file_names:
|
273 |
uploads = []
|
274 |
if not isinstance(file_contents, list):
|
|
|
288 |
save_session_state(session_id)
|
289 |
logger.info(f"Session {session_id}: Uploaded files {[u['name'] for u in uploads]}")
|
290 |
|
|
|
291 |
if trigger == "send-btn" and user_input and user_input.strip():
|
292 |
loading = True
|
293 |
state["messages"].append({"role": "user", "content": user_input})
|
294 |
try:
|
|
|
295 |
docs = []
|
296 |
try:
|
297 |
retr = vectordb.similarity_search(user_input, k=3)
|
|
|
299 |
except Exception as e:
|
300 |
logger.warning(f"Vector search failed: {e}")
|
301 |
context = "\n\n".join(docs)
|
302 |
+
system_prompt = load_system_prompt()
|
303 |
messages = [
|
304 |
+
{"role": "system", "content": system_prompt},
|
305 |
]
|
306 |
for m in state["messages"]:
|
307 |
messages.append({"role": m["role"], "content": m["content"]})
|
|
|
329 |
right = right_main(chat_history, loading, error)
|
330 |
return left, right
|
331 |
|
|
|
332 |
@app_flask.after_request
|
333 |
def set_session_cookie(resp):
|
334 |
sid = flask_request.cookies.get("asktricare_session_id")
|
|
|
337 |
resp.set_cookie("asktricare_session_id", sid, max_age=60*60*24*7, path="/")
|
338 |
return resp
|
339 |
|
|
|
340 |
def cleanup_sessions(max_age_hours=48):
|
341 |
now = datetime.datetime.utcnow()
|
342 |
for sid in os.listdir(SESSION_DIR_BASE):
|
|
|
353 |
except Exception as e:
|
354 |
logger.error(f"Cleanup error for {sid}: {e}")
|
355 |
|
|
|
356 |
try:
|
357 |
import torch
|
358 |
if torch.cuda.is_available():
|
|
|
361 |
except Exception as e:
|
362 |
logger.warning(f"CUDA config failed: {e}")
|
363 |
|
|
|
364 |
if __name__ == '__main__':
|
365 |
print("Starting the Dash application...")
|
366 |
app.run(debug=True, host='0.0.0.0', port=7860, threaded=True)
|
367 |
+
print("Dash application has finished running.")
|
|