Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -111,7 +111,6 @@ def _build_messages(
|
|
| 111 |
companion_name: str = "Lumi",
|
| 112 |
companion_desc: str = "a warm and patient AI companion",
|
| 113 |
) -> list[dict]:
|
| 114 |
-
history = history or []
|
| 115 |
prompt = build_system_prompt(
|
| 116 |
PATIENT_ID, PATIENT_NAME,
|
| 117 |
companion_name=companion_name,
|
|
@@ -230,12 +229,10 @@ def _save_wav_np(audio_tuple) -> str | None:
|
|
| 230 |
|
| 231 |
|
| 232 |
def lumi_api(message: str, history: list[dict], profile_id: str, session_id: str | None = None):
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
print(f" session_id: {session_id}")
|
| 238 |
-
|
| 239 |
profile = get_profile(profile_id)
|
| 240 |
cname = profile["display_name"]
|
| 241 |
cdesc = profile["description"]
|
|
@@ -243,21 +240,16 @@ def lumi_api(message: str, history: list[dict], profile_id: str, session_id: str
|
|
| 243 |
is_scam, deflection = check_and_deflect(message)
|
| 244 |
if is_scam:
|
| 245 |
audio_path, _ = _tts_and_video(deflection, profile_id)
|
| 246 |
-
return deflection, _audio_b64(audio_path), "gentle", session_id
|
| 247 |
|
| 248 |
messages = _build_messages(history, cname, cdesc) + [{"role": "user", "content": message}]
|
| 249 |
try:
|
| 250 |
-
print(f"[API] Calling LLM...")
|
| 251 |
raw = _call_llm(messages)
|
| 252 |
-
print(f"[API] LLM Response received. Parsing...")
|
| 253 |
parsed = parse_structured_output(raw)
|
| 254 |
response_text = parsed["full_response"]
|
| 255 |
avatar_tag = parsed["avatar_tag"]
|
| 256 |
-
|
| 257 |
-
print(f"[API] Generating audio...")
|
| 258 |
audio_path, _ = _tts_and_video(response_text, profile_id)
|
| 259 |
|
| 260 |
-
print(f"[API] Saving session...")
|
| 261 |
# Real-time saving
|
| 262 |
new_history = history + [
|
| 263 |
{"role": "user", "content": message},
|
|
@@ -268,13 +260,12 @@ def lumi_api(message: str, history: list[dict], profile_id: str, session_id: str
|
|
| 268 |
f"Chat - {len(new_history)//2} turns",
|
| 269 |
new_history, session_id)
|
| 270 |
|
| 271 |
-
|
| 272 |
-
return response_text, _audio_b64(audio_path), avatar_tag, final_id, parsed.get("actions", [])
|
| 273 |
except Exception as e:
|
| 274 |
print(f"[API Error] {e}")
|
| 275 |
err_msg = "I'm sorry, I'm having a little trouble. Could you try again?"
|
| 276 |
audio_path, _ = _tts_and_video(err_msg, profile_id)
|
| 277 |
-
return err_msg, _audio_b64(audio_path), "concerned", session_id
|
| 278 |
|
| 279 |
|
| 280 |
def voice_submit(audio_tuple, history: list[dict], profile_id: str):
|
|
@@ -833,14 +824,11 @@ Built for the AMD Developer Hackathon 2026 · Fine-Tuning Track
|
|
| 833 |
_resp = gr.Textbox(visible=False)
|
| 834 |
_audio = gr.Textbox(visible=False)
|
| 835 |
_tag = gr.Textbox(visible=False)
|
| 836 |
-
|
| 837 |
-
_final_id = gr.Textbox(visible=False)
|
| 838 |
-
_actions = gr.JSON(visible=False)
|
| 839 |
-
_btn = gr.Button(visible=False)
|
| 840 |
_btn.click(
|
| 841 |
fn=lumi_api,
|
| 842 |
-
inputs=[_msg, _hist, _prof
|
| 843 |
-
outputs=[_resp, _audio, _tag
|
| 844 |
api_name="lumi_api",
|
| 845 |
)
|
| 846 |
|
|
@@ -860,31 +848,6 @@ async def fetch_summaries():
|
|
| 860 |
# For the hackathon, we use the global PATIENT_ID.
|
| 861 |
return get_all_summaries(PATIENT_ID)
|
| 862 |
|
| 863 |
-
@_fastapi.get("/api/diag")
|
| 864 |
-
async def diagnostic():
|
| 865 |
-
results = {}
|
| 866 |
-
# 1. Test LLM
|
| 867 |
-
try:
|
| 868 |
-
start = time.time()
|
| 869 |
-
test_resp = llm.chat.completions.create(
|
| 870 |
-
model=MODEL_NAME,
|
| 871 |
-
messages=[{"role": "user", "content": "ping"}],
|
| 872 |
-
max_tokens=5
|
| 873 |
-
)
|
| 874 |
-
results["llm"] = {"status": "ok", "latency": time.time() - start, "response": test_resp.choices[0].message.content}
|
| 875 |
-
except Exception as e:
|
| 876 |
-
results["llm"] = {"status": "error", "message": str(e)}
|
| 877 |
-
|
| 878 |
-
# 2. Test ChromaDB
|
| 879 |
-
try:
|
| 880 |
-
from pipeline.memory import _get_collection
|
| 881 |
-
col = _get_collection()
|
| 882 |
-
results["chroma"] = {"status": "ok", "count": col.count()}
|
| 883 |
-
except Exception as e:
|
| 884 |
-
results["chroma"] = {"status": "error", "message": str(e)}
|
| 885 |
-
|
| 886 |
-
return results
|
| 887 |
-
|
| 888 |
@_fastapi.get("/api/whoami")
|
| 889 |
async def whoami(request: Request):
|
| 890 |
# Check multiple possible HF headers (request-specific)
|
|
|
|
| 111 |
companion_name: str = "Lumi",
|
| 112 |
companion_desc: str = "a warm and patient AI companion",
|
| 113 |
) -> list[dict]:
|
|
|
|
| 114 |
prompt = build_system_prompt(
|
| 115 |
PATIENT_ID, PATIENT_NAME,
|
| 116 |
companion_name=companion_name,
|
|
|
|
| 229 |
|
| 230 |
|
| 231 |
def lumi_api(message: str, history: list[dict], profile_id: str, session_id: str | None = None):
|
| 232 |
+
"""
|
| 233 |
+
Unified API for the React frontend.
|
| 234 |
+
Returns: (response_text, audio_b64_data_uri, avatar_tag, final_session_id)
|
| 235 |
+
"""
|
|
|
|
|
|
|
| 236 |
profile = get_profile(profile_id)
|
| 237 |
cname = profile["display_name"]
|
| 238 |
cdesc = profile["description"]
|
|
|
|
| 240 |
is_scam, deflection = check_and_deflect(message)
|
| 241 |
if is_scam:
|
| 242 |
audio_path, _ = _tts_and_video(deflection, profile_id)
|
| 243 |
+
return deflection, _audio_b64(audio_path), "gentle", session_id
|
| 244 |
|
| 245 |
messages = _build_messages(history, cname, cdesc) + [{"role": "user", "content": message}]
|
| 246 |
try:
|
|
|
|
| 247 |
raw = _call_llm(messages)
|
|
|
|
| 248 |
parsed = parse_structured_output(raw)
|
| 249 |
response_text = parsed["full_response"]
|
| 250 |
avatar_tag = parsed["avatar_tag"]
|
|
|
|
|
|
|
| 251 |
audio_path, _ = _tts_and_video(response_text, profile_id)
|
| 252 |
|
|
|
|
| 253 |
# Real-time saving
|
| 254 |
new_history = history + [
|
| 255 |
{"role": "user", "content": message},
|
|
|
|
| 260 |
f"Chat - {len(new_history)//2} turns",
|
| 261 |
new_history, session_id)
|
| 262 |
|
| 263 |
+
return response_text, _audio_b64(audio_path), avatar_tag, final_id
|
|
|
|
| 264 |
except Exception as e:
|
| 265 |
print(f"[API Error] {e}")
|
| 266 |
err_msg = "I'm sorry, I'm having a little trouble. Could you try again?"
|
| 267 |
audio_path, _ = _tts_and_video(err_msg, profile_id)
|
| 268 |
+
return err_msg, _audio_b64(audio_path), "concerned", session_id
|
| 269 |
|
| 270 |
|
| 271 |
def voice_submit(audio_tuple, history: list[dict], profile_id: str):
|
|
|
|
| 824 |
_resp = gr.Textbox(visible=False)
|
| 825 |
_audio = gr.Textbox(visible=False)
|
| 826 |
_tag = gr.Textbox(visible=False)
|
| 827 |
+
_btn = gr.Button(visible=False)
|
|
|
|
|
|
|
|
|
|
| 828 |
_btn.click(
|
| 829 |
fn=lumi_api,
|
| 830 |
+
inputs=[_msg, _hist, _prof],
|
| 831 |
+
outputs=[_resp, _audio, _tag],
|
| 832 |
api_name="lumi_api",
|
| 833 |
)
|
| 834 |
|
|
|
|
| 848 |
# For the hackathon, we use the global PATIENT_ID.
|
| 849 |
return get_all_summaries(PATIENT_ID)
|
| 850 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 851 |
@_fastapi.get("/api/whoami")
|
| 852 |
async def whoami(request: Request):
|
| 853 |
# Check multiple possible HF headers (request-specific)
|