Rajan Sharma commited on
Commit
d46abd4
·
verified ·
1 Parent(s): ff10e4f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -20
app.py CHANGED
@@ -1,12 +1,19 @@
1
  # app.py
2
  import os
3
  import time
 
4
  from datetime import datetime, timezone
5
  from functools import lru_cache
6
 
7
  import gradio as gr
8
  import torch
9
 
 
 
 
 
 
 
10
  # Try to import Cohere SDK if present (for hosted path)
11
  try:
12
  import cohere # pip install cohere
@@ -35,12 +42,27 @@ USE_HOSTED_COHERE = bool(COHERE_API_KEY and _HAS_COHERE)
35
  # -------------------
36
  # Helpers
37
  # -------------------
38
- def utc_now():
39
- return datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- def header(processing_time=None):
 
42
  s = (
43
- f"Current Date and Time (UTC - YYYY-MM-DD HH:MM:SS formatted): {utc_now()} "
44
  f"Current User's Login: Raj-VedAI\n"
45
  )
46
  if processing_time is not None:
@@ -54,6 +76,38 @@ def pick_dtype_and_map():
54
  return torch.float16, {"": "mps"}
55
  return torch.float32, "cpu" # CPU path (likely too big for R7B)
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  # -------------------
59
  # Cohere Hosted Path
@@ -73,7 +127,6 @@ def _cohere_parse(resp):
73
  return resp.output_text.strip()
74
  if getattr(resp, "message", None) and getattr(resp.message, "content", None):
75
  parts = resp.message.content
76
- # pick first text part
77
  for p in parts:
78
  if hasattr(p, "text") and p.text:
79
  return p.text.strip()
@@ -83,8 +136,7 @@ def _cohere_parse(resp):
83
  return "Sorry, I couldn't parse the response from Cohere."
84
 
85
  def cohere_chat(message, history):
86
- # Build a clean user prompt from history (simple, safe)
87
- # If you want structured history, you can pass messages when using responses.create
88
  try:
89
  # Try modern API first
90
  try:
@@ -177,40 +229,45 @@ def local_generate(model, tokenizer, input_ids, max_new_tokens=350):
177
  # -------------------
178
  # Chat callback
179
  # -------------------
180
- def chat_fn(message, history):
181
  t0 = time.time()
182
  try:
 
 
 
 
 
183
  if USE_HOSTED_COHERE:
184
  reply = cohere_chat(message, history)
185
- return f"{header(time.time() - t0)}{reply}"
186
 
187
- # Local load (GPU strongly recommended; CPU likely OOM for R7B)
188
  model, tokenizer = load_local_model()
189
  inputs = build_inputs(tokenizer, message, history)
190
  reply = local_generate(model, tokenizer, inputs, max_new_tokens=350)
191
- return f"{header(time.time() - t0)}{reply}"
192
 
193
  except RuntimeError as e:
194
  emsg = str(e)
195
  if "out of memory" in emsg.lower() or "cuda" in emsg.lower():
196
  return (
197
- f"{header(time.time() - t0)}Local load likely OOM. "
198
  "Use a GPU Space or set COHERE_API_KEY to run via Cohere hosted API."
199
  )
200
- return f"{header(time.time() - t0)}Error during chat: {e}"
201
  except Exception as e:
202
- return f"{header(time.time() - t0)}Error during chat: {e}"
203
 
204
 
205
  # -------------------
206
  # Connection check
207
  # -------------------
208
- def check_connection():
209
  try:
210
  mode = "Cohere API (hosted)" if USE_HOSTED_COHERE else "Local HF"
211
  if USE_HOSTED_COHERE:
212
  return (
213
- f"{header()}"
214
  f"Connection Status: ✅ Using Cohere hosted API\n"
215
  f"Mode: {mode}\n"
216
  f"Model: command-r7b-12-2024\n"
@@ -219,21 +276,32 @@ def check_connection():
219
  api = HfApi(token=HF_TOKEN)
220
  mi = api.model_info(MODEL_ID)
221
  return (
222
- f"{header()}"
223
  f"Connection Status: ✅ Connected\n"
224
  f"Mode: {mode}\n"
225
  f"Model: {mi.modelId}\n"
226
  f"Last Modified: {mi.lastModified}\n"
227
  )
228
  except Exception as e:
229
- return f"{header()}Connection Status: ❌ Error\nDetails: {e}"
230
 
231
 
232
  # -------------------
233
  # UI
234
  # -------------------
235
  with gr.Blocks(theme=gr.themes.Default()) as demo:
236
- gr.Markdown(f"# Medical Decision Support AI\n{header()}")
 
 
 
 
 
 
 
 
 
 
 
237
 
238
  with gr.Row():
239
  btn = gr.Button("Check Connection Status")
@@ -248,6 +316,7 @@ with gr.Blocks(theme=gr.themes.Default()) as demo:
248
  chat = gr.ChatInterface(
249
  fn=chat_fn,
250
  type="messages",
 
251
  description="A medical decision support system that provides healthcare-related information and guidance.",
252
  examples=[
253
  "What are the symptoms of hypertension?",
@@ -256,7 +325,8 @@ with gr.Blocks(theme=gr.themes.Default()) as demo:
256
  ],
257
  )
258
 
259
- btn.click(fn=check_connection, outputs=status)
 
260
 
261
  if __name__ == "__main__":
262
  # You can disable SSR if it conflicts in your Space:
 
1
  # app.py
2
  import os
3
  import time
4
+ import re
5
  from datetime import datetime, timezone
6
  from functools import lru_cache
7
 
8
  import gradio as gr
9
  import torch
10
 
11
+ # Timezone conversion (Python 3.9+ stdlib)
12
+ try:
13
+ from zoneinfo import ZoneInfo
14
+ except Exception:
15
+ ZoneInfo = None # graceful fallback to UTC
16
+
17
  # Try to import Cohere SDK if present (for hosted path)
18
  try:
19
  import cohere # pip install cohere
 
42
  # -------------------
43
  # Helpers
44
  # -------------------
45
+ def local_now_str(user_tz: str | None) -> tuple[str, str]:
46
+ """
47
+ Returns (label, formatted_time). If user_tz is invalid or zoneinfo missing, falls back to UTC.
48
+ """
49
+ label = "UTC"
50
+ dt = datetime.now(timezone.utc)
51
+ if user_tz and ZoneInfo is not None:
52
+ try:
53
+ tz = ZoneInfo(user_tz)
54
+ dt = datetime.now(tz)
55
+ label = user_tz
56
+ except Exception:
57
+ # Keep UTC if timezone string is unrecognized
58
+ dt = datetime.now(timezone.utc)
59
+ label = "UTC"
60
+ return label, dt.strftime("%Y-%m-%d %H:%M:%S")
61
 
62
+ def header(processing_time=None, user_tz: str | None = None):
63
+ tz_label, now_str = local_now_str(user_tz)
64
  s = (
65
+ f"Current Date and Time ({tz_label} - YYYY-MM-DD HH:MM:SS formatted): {now_str}\n"
66
  f"Current User's Login: Raj-VedAI\n"
67
  )
68
  if processing_time is not None:
 
76
  return torch.float16, {"": "mps"}
77
  return torch.float32, "cpu" # CPU path (likely too big for R7B)
78
 
79
+ def is_identity_query(message: str, history) -> bool:
80
+ """
81
+ Detects identity questions in the current message or the most recent user turn in history.
82
+ """
83
+ patterns = [
84
+ r"\bwho\s+are\s+you\b",
85
+ r"\bwhat\s+are\s+you\b",
86
+ r"\bwhat\s+is\s+your\s+name\b",
87
+ r"\bwho\s+is\s+this\b",
88
+ r"\bidentify\s+yourself\b",
89
+ r"\btell\s+me\s+about\s+yourself\b",
90
+ r"\bdescribe\s+yourself\b",
91
+ r"\band\s+you\s*\?\b",
92
+ r"\byour\s+name\b",
93
+ r"\bwho\s+am\s+i\s+chatting\s+with\b",
94
+ ]
95
+
96
+ def hit(text: str | None) -> bool:
97
+ t = (text or "").strip().lower()
98
+ return any(re.search(p, t) for p in patterns)
99
+
100
+ if hit(message):
101
+ return True
102
+
103
+ if history:
104
+ # Gradio history is List[Tuple[user, assistant]]
105
+ last_user = history[-1][0] if isinstance(history[-1], (list, tuple)) and history[-1] else None
106
+ if hit(last_user):
107
+ return True
108
+
109
+ return False
110
+
111
 
112
  # -------------------
113
  # Cohere Hosted Path
 
127
  return resp.output_text.strip()
128
  if getattr(resp, "message", None) and getattr(resp.message, "content", None):
129
  parts = resp.message.content
 
130
  for p in parts:
131
  if hasattr(p, "text") and p.text:
132
  return p.text.strip()
 
136
  return "Sorry, I couldn't parse the response from Cohere."
137
 
138
  def cohere_chat(message, history):
139
+ # Build a clean user prompt with structured messages
 
140
  try:
141
  # Try modern API first
142
  try:
 
229
  # -------------------
230
  # Chat callback
231
  # -------------------
232
+ def chat_fn(message, history, user_tz):
233
  t0 = time.time()
234
  try:
235
+ # ---- Identity override (history-aware) ----
236
+ if is_identity_query(message, history):
237
+ return f"{header(time.time() - t0, user_tz)}I am ClarityOps, your strategic decision making AI partner."
238
+
239
+ # ---- Hosted Cohere path ----
240
  if USE_HOSTED_COHERE:
241
  reply = cohere_chat(message, history)
242
+ return f"{header(time.time() - t0, user_tz)}{reply}"
243
 
244
+ # ---- Local HF fallback (GPU recommended) ----
245
  model, tokenizer = load_local_model()
246
  inputs = build_inputs(tokenizer, message, history)
247
  reply = local_generate(model, tokenizer, inputs, max_new_tokens=350)
248
+ return f"{header(time.time() - t0, user_tz)}{reply}"
249
 
250
  except RuntimeError as e:
251
  emsg = str(e)
252
  if "out of memory" in emsg.lower() or "cuda" in emsg.lower():
253
  return (
254
+ f"{header(time.time() - t0, user_tz)}Local load likely OOM. "
255
  "Use a GPU Space or set COHERE_API_KEY to run via Cohere hosted API."
256
  )
257
+ return f"{header(time.time() - t0, user_tz)}Error during chat: {e}"
258
  except Exception as e:
259
+ return f"{header(time.time() - t0, user_tz)}Error during chat: {e}"
260
 
261
 
262
  # -------------------
263
  # Connection check
264
  # -------------------
265
+ def check_connection(user_tz=None):
266
  try:
267
  mode = "Cohere API (hosted)" if USE_HOSTED_COHERE else "Local HF"
268
  if USE_HOSTED_COHERE:
269
  return (
270
+ f"{header(user_tz=user_tz)}"
271
  f"Connection Status: ✅ Using Cohere hosted API\n"
272
  f"Mode: {mode}\n"
273
  f"Model: command-r7b-12-2024\n"
 
276
  api = HfApi(token=HF_TOKEN)
277
  mi = api.model_info(MODEL_ID)
278
  return (
279
+ f"{header(user_tz=user_tz)}"
280
  f"Connection Status: ✅ Connected\n"
281
  f"Mode: {mode}\n"
282
  f"Model: {mi.modelId}\n"
283
  f"Last Modified: {mi.lastModified}\n"
284
  )
285
  except Exception as e:
286
+ return f"{header(user_tz=user_tz)}Connection Status: ❌ Error\nDetails: {e}"
287
 
288
 
289
  # -------------------
290
  # UI
291
  # -------------------
292
  with gr.Blocks(theme=gr.themes.Default()) as demo:
293
+ # State to hold browser timezone (e.g., "America/Edmonton")
294
+ user_tz_state = gr.State("")
295
+
296
+ # On load, capture browser timezone via JS and store in user_tz_state
297
+ demo.load(
298
+ fn=lambda: None,
299
+ inputs=None,
300
+ outputs=user_tz_state,
301
+ js="() => Intl.DateTimeFormat().resolvedOptions().timeZone"
302
+ )
303
+
304
+ gr.Markdown(f"# Medical Decision Support AI\n{header(user_tz=None)}")
305
 
306
  with gr.Row():
307
  btn = gr.Button("Check Connection Status")
 
316
  chat = gr.ChatInterface(
317
  fn=chat_fn,
318
  type="messages",
319
+ additional_inputs=[user_tz_state], # pass timezone into chat_fn
320
  description="A medical decision support system that provides healthcare-related information and guidance.",
321
  examples=[
322
  "What are the symptoms of hypertension?",
 
325
  ],
326
  )
327
 
328
+ # Wire timezone into the connection check as well
329
+ btn.click(fn=check_connection, inputs=user_tz_state, outputs=status)
330
 
331
  if __name__ == "__main__":
332
  # You can disable SSR if it conflicts in your Space: