4waiz commited on
Commit
9049520
·
verified ·
1 Parent(s): cfcebe2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -176
app.py CHANGED
@@ -1,179 +1,24 @@
1
- import os, requests, streamlit as st
2
- from audio_recorder_streamlit import audio_recorder
3
 
4
- # ----- Config (set secrets in Space → Settings → Secrets) -----
5
- HF_TOKEN = os.getenv("HF_TOKEN", "").strip()
6
- HF_API_BASE= os.getenv("HF_API_BASE", "https://api-inference.huggingface.co").rstrip("/")
7
- CHAT_MODEL = os.getenv("HF_MODEL", "google/gemma-2-2b-it").strip()
8
- SYSTEM_PROMPT = os.getenv("SYSTEM_PROMPT", "You are EDGE AI, a concise helpful assistant.")
9
 
10
- # Voice defaults (you can also move these to Secrets if you want)
11
- ASR_MODEL = os.getenv("ASR_MODEL", "openai/whisper-small").strip()
12
- TTS_MODEL = os.getenv("TTS_MODEL", "parler-tts/parler-tts-mini-v1").strip()
13
-
14
- HEADERS = {"Authorization": f"Bearer {HF_TOKEN}", "Accept": "application/json"} if HF_TOKEN else {}
15
-
16
- # ----- Page UI -----
17
- st.set_page_config(page_title="EDGE AI", page_icon="🤖", layout="centered")
18
-
19
- # Show your logo if present
20
- if os.path.exists("logo.png"):
21
  st.image("logo.png", width=220)
22
- else:
23
- st.markdown("<h1 style='text-align:center;margin:0'>🤖 EDGE AI</h1>", unsafe_allow_html=True)
24
-
25
- st.caption("Streamlit chatbot text + voice")
26
-
27
- with st.sidebar:
28
- st.subheader("Models")
29
- chat_model = st.selectbox(
30
- "Chat model",
31
- ["google/gemma-2-2b-it", "HuggingFaceH4/zephyr-7b-beta", "mistralai/Mistral-7B-Instruct-v0.2"],
32
- index=0 if CHAT_MODEL.startswith("google/gemma-2-2b-it") else (1 if "zephyr" in CHAT_MODEL else 2),
33
- )
34
- asr_model = st.text_input("ASR model (speech→text)", ASR_MODEL) # Whisper family is good
35
- tts_model = st.text_input("TTS model (text→speech)", TTS_MODEL) # parler-tts works well
36
- use_tts = st.checkbox("Speak assistant replies", value=True)
37
- system_prompt = st.text_area("System prompt", SYSTEM_PROMPT, height=100)
38
- clear = st.button("Clear chat")
39
- st.write("HF token:", "✅ set" if HF_TOKEN else "❌ missing")
40
-
41
- if not HF_TOKEN:
42
- st.error("HF_TOKEN is missing. Add it in **Space → Settings → Secrets**.")
43
- st.stop()
44
-
45
- # ----- State -----
46
- if "messages" not in st.session_state or clear:
47
- st.session_state.messages = [{"role": "system", "content": system_prompt}]
48
- else:
49
- st.session_state.messages[0]["content"] = system_prompt # keep in sync if edited
50
-
51
- # Render history
52
- for m in st.session_state.messages:
53
- if m["role"] in ("user", "assistant"):
54
- with st.chat_message(m["role"]):
55
- st.markdown(m["content"])
56
-
57
- # ----- HF helpers -----
58
- def call_v1_chat(messages, model):
59
- url = f"{HF_API_BASE}/v1/chat/completions"
60
- payload = {"model": model, "messages": messages, "max_tokens": 300, "temperature": 0.7}
61
- return requests.post(url, headers=HEADERS, json=payload, timeout=90)
62
-
63
- def call_legacy_chat(messages, model):
64
- parts = []
65
- for m in messages:
66
- if m["role"] == "system":
67
- parts.append(f"<|system|>\n{m['content']}</s>\n")
68
- else:
69
- role = "assistant" if m["role"] == "assistant" else "user"
70
- parts.append(f"<|{role}|>\n{m['content']}</s>\n")
71
- parts.append("<|assistant|>\n")
72
- prompt = "".join(parts)
73
- url = f"{HF_API_BASE}/models/{model}"
74
- payload = {"inputs": prompt, "parameters": {"max_new_tokens": 256, "return_full_text": False},
75
- "options": {"wait_for_model": True}}
76
- return requests.post(url, headers=HEADERS, json=payload, timeout=90)
77
-
78
- def chat_reply(messages, model):
79
- # v1 first
80
- try:
81
- r = call_v1_chat(messages, model)
82
- if r.status_code == 200:
83
- data = r.json()
84
- return data["choices"][0]["message"]["content"].strip(), "v1"
85
- except Exception:
86
- pass
87
- # legacy fallback
88
- r2 = call_legacy_chat(messages, model)
89
- r2.raise_for_status()
90
- data2 = r2.json()
91
- return (data2[0]["generated_text"] or "").strip(), "legacy"
92
-
93
- def transcribe_audio(audio_bytes, model):
94
- """Send audio bytes to HF ASR model; returns text."""
95
- url = f"{HF_API_BASE}/models/{model}"
96
- headers = HEADERS.copy()
97
- headers["Content-Type"] = "audio/wav" # component returns WAV
98
- r = requests.post(url, headers=headers, data=audio_bytes, timeout=90)
99
- r.raise_for_status()
100
- data = r.json()
101
- # Most ASR models return {"text": "..."}
102
- if isinstance(data, dict) and "text" in data:
103
- return data["text"]
104
- # Fallback shapes
105
- if isinstance(data, list) and data and isinstance(data[0], dict) and "text" in data[0]:
106
- return data[0]["text"]
107
- return ""
108
-
109
- def tts_audio(text, model):
110
- """Return WAV bytes from HF TTS model; many TTS models honor Accept: audio/wav."""
111
- url = f"{HF_API_BASE}/models/{model}"
112
- headers = HEADERS.copy()
113
- headers["Accept"] = "audio/wav"
114
- # For most TTS models, JSON with {"inputs": text} works. Parler-TTS also supports this on serverless.
115
- r = requests.post(url, headers=headers, json={"inputs": text}, timeout=120)
116
- r.raise_for_status()
117
- return r.content # raw wav bytes
118
-
119
- # ----- Text chat input -----
120
- user_text = st.chat_input("Type your message…")
121
- if user_text:
122
- st.session_state.messages.append({"role": "user", "content": user_text})
123
- with st.chat_message("user"): st.markdown(user_text)
124
-
125
- with st.chat_message("assistant"):
126
- with st.spinner("Thinking…"):
127
- try:
128
- reply, mode = chat_reply(st.session_state.messages, chat_model)
129
- except Exception as e:
130
- reply, mode = f"_HF error:_ {e}", "error"
131
- st.markdown(reply or "_no reply_")
132
- st.caption(f"• mode: {mode} • model: {chat_model}")
133
- # optional TTS
134
- if use_tts and reply and mode != "error":
135
- try:
136
- wav = tts_audio(reply, tts_model)
137
- st.audio(wav, format="audio/wav")
138
- except Exception as e:
139
- st.info(f"TTS failed: {e}")
140
- if reply:
141
- st.session_state.messages.append({"role": "assistant", "content": reply})
142
-
143
- # ----- Voice recorder -----
144
- st.divider()
145
- st.subheader("🎙️ Voice chat")
146
- st.caption("Click to record, then release to transcribe and chat.")
147
- audio_bytes = audio_recorder(
148
- pause_threshold=1.0, sample_rate=16000, energy_threshold=(-1.0, 1.0), text="Record / Stop", icon_size="2x"
149
- )
150
-
151
- if audio_bytes:
152
- with st.spinner("Transcribing…"):
153
- try:
154
- text_from_audio = transcribe_audio(audio_bytes, asr_model).strip()
155
- except Exception as e:
156
- text_from_audio = ""
157
- st.error(f"ASR failed: {e}")
158
-
159
- if text_from_audio:
160
- # push as a user message and run the normal chat path
161
- st.session_state.messages.append({"role": "user", "content": text_from_audio})
162
- with st.chat_message("user"): st.markdown(text_from_audio)
163
-
164
- with st.chat_message("assistant"):
165
- with st.spinner("Thinking…"):
166
- try:
167
- reply, mode = chat_reply(st.session_state.messages, chat_model)
168
- except Exception as e:
169
- reply, mode = f"_HF error:_ {e}", "error"
170
- st.markdown(reply or "_no reply_")
171
- st.caption(f"• mode: {mode} • model: {chat_model}")
172
- if use_tts and reply and mode != "error":
173
- try:
174
- wav = tts_audio(reply, tts_model)
175
- st.audio(wav, format="audio/wav")
176
- except Exception as e:
177
- st.info(f"TTS failed: {e}")
178
- if reply:
179
- st.session_state.messages.append({"role": "assistant", "content": reply})
 
1
+ import streamlit as st
 
2
 
3
+ st.set_page_config(page_title="EDGE", page_icon="🤖", layout="centered")
 
 
 
 
4
 
5
+ # show your logo if present
6
+ try:
 
 
 
 
 
 
 
 
 
7
  st.image("logo.png", width=220)
8
+ except Exception:
9
+ st.title("EDGE")
10
+
11
+ st.success(" Frontend is alive. Type below to interact.")
12
+
13
+ # tiny chat echo so you can interact
14
+ if "chat" not in st.session_state: st.session_state.chat = []
15
+ for role, text in st.session_state.chat:
16
+ with st.chat_message(role): st.markdown(text)
17
+
18
+ msg = st.chat_input("Say something…")
19
+ if msg:
20
+ st.session_state.chat.append(("user", msg))
21
+ with st.chat_message("user"): st.markdown(msg)
22
+ reply = f"You said: **{msg}**"
23
+ st.session_state.chat.append(("assistant", reply))
24
+ with st.chat_message("assistant"): st.markdown(reply)