Spaces:
Sleeping
Sleeping
Adding voice bot
Browse files- chatbot.py +18 -13
chatbot.py
CHANGED
|
@@ -7,6 +7,7 @@ from html import escape
|
|
| 7 |
import edge_tts
|
| 8 |
import asyncio
|
| 9 |
import os
|
|
|
|
| 10 |
|
| 11 |
GROQ_API_KEY = os.getenv('GROQ_API_KEY')
|
| 12 |
|
|
@@ -45,13 +46,14 @@ class CodeAssistantBot:
|
|
| 45 |
return f"Error: {e}"
|
| 46 |
|
| 47 |
async def text_to_speech(text, filename):
|
| 48 |
-
voice = "
|
| 49 |
-
|
|
|
|
| 50 |
|
| 51 |
def render_chatbot(code, output, error):
|
| 52 |
"""Render the chatbot UI with code-block support and a scrollable chat container."""
|
| 53 |
|
| 54 |
-
#
|
| 55 |
st.markdown("""
|
| 56 |
<style>
|
| 57 |
.chat-container {
|
|
@@ -81,16 +83,15 @@ def render_chatbot(code, output, error):
|
|
| 81 |
</style>
|
| 82 |
""", unsafe_allow_html=True)
|
| 83 |
|
| 84 |
-
# Session state
|
| 85 |
st.session_state.setdefault('conversation', [])
|
| 86 |
-
st.session_state.setdefault('audio_count', 0)
|
| 87 |
st.session_state.setdefault('chat_summary', "")
|
| 88 |
st.session_state.setdefault('chat_display_count', 5)
|
| 89 |
|
| 90 |
-
#
|
| 91 |
c1, c2 = st.columns([4, 1], gap='small')
|
| 92 |
with c1:
|
| 93 |
-
question = st.text_input("Ask your
|
| 94 |
with c2:
|
| 95 |
send = st.button("🚀")
|
| 96 |
|
|
@@ -103,9 +104,8 @@ def render_chatbot(code, output, error):
|
|
| 103 |
response = bot.analyze_code(code, output, error, question, summary, history)
|
| 104 |
|
| 105 |
st.session_state.conversation.append((question, response))
|
| 106 |
-
st.session_state.chat_display_count = 5
|
| 107 |
|
| 108 |
-
# Update summary (based on last 10 entries)
|
| 109 |
if len(st.session_state.conversation) >= 3:
|
| 110 |
try:
|
| 111 |
full_chat = "\n".join([f"User: {q}\nBot: {a}" for q, a in st.session_state.conversation[-10:]])
|
|
@@ -113,15 +113,14 @@ def render_chatbot(code, output, error):
|
|
| 113 |
summarizer = bot.summary_prompt | bot.model | parser
|
| 114 |
st.session_state.chat_summary = summarizer.invoke({'conversation': full_chat})
|
| 115 |
except:
|
| 116 |
-
pass
|
| 117 |
|
| 118 |
-
# Display conversation
|
| 119 |
total_messages = len(st.session_state.conversation)
|
| 120 |
start_idx = max(0, total_messages - st.session_state.chat_display_count)
|
| 121 |
visible_conversation = st.session_state.conversation[start_idx:]
|
| 122 |
|
| 123 |
-
|
| 124 |
-
for q, a in reversed(visible_conversation):
|
| 125 |
st.markdown(f'<div class="chat-message user-message">{escape(q)}</div>', unsafe_allow_html=True)
|
| 126 |
|
| 127 |
def format_response(text):
|
|
@@ -141,6 +140,12 @@ def render_chatbot(code, output, error):
|
|
| 141 |
formatted = format_response(a)
|
| 142 |
st.markdown(f'<div class="chat-message bot-message">{formatted}</div>', unsafe_allow_html=True)
|
| 143 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
if start_idx > 0:
|
| 145 |
if st.button("🔽 Show more"):
|
| 146 |
st.session_state.chat_display_count += 5
|
|
|
|
| 7 |
import edge_tts
|
| 8 |
import asyncio
|
| 9 |
import os
|
| 10 |
+
import uuid
|
| 11 |
|
| 12 |
GROQ_API_KEY = os.getenv('GROQ_API_KEY')
|
| 13 |
|
|
|
|
| 46 |
return f"Error: {e}"
|
| 47 |
|
| 48 |
async def text_to_speech(text, filename):
|
| 49 |
+
voice = "en-US-AriaNeural"
|
| 50 |
+
communicate = edge_tts.Communicate(text, voice)
|
| 51 |
+
await communicate.save(filename)
|
| 52 |
|
| 53 |
def render_chatbot(code, output, error):
|
| 54 |
"""Render the chatbot UI with code-block support and a scrollable chat container."""
|
| 55 |
|
| 56 |
+
# CSS Styling
|
| 57 |
st.markdown("""
|
| 58 |
<style>
|
| 59 |
.chat-container {
|
|
|
|
| 83 |
</style>
|
| 84 |
""", unsafe_allow_html=True)
|
| 85 |
|
| 86 |
+
# Session state
|
| 87 |
st.session_state.setdefault('conversation', [])
|
|
|
|
| 88 |
st.session_state.setdefault('chat_summary', "")
|
| 89 |
st.session_state.setdefault('chat_display_count', 5)
|
| 90 |
|
| 91 |
+
# Chat input
|
| 92 |
c1, c2 = st.columns([4, 1], gap='small')
|
| 93 |
with c1:
|
| 94 |
+
question = st.text_input("Ask something about your code...", key="chat_input")
|
| 95 |
with c2:
|
| 96 |
send = st.button("🚀")
|
| 97 |
|
|
|
|
| 104 |
response = bot.analyze_code(code, output, error, question, summary, history)
|
| 105 |
|
| 106 |
st.session_state.conversation.append((question, response))
|
| 107 |
+
st.session_state.chat_display_count = 5
|
| 108 |
|
|
|
|
| 109 |
if len(st.session_state.conversation) >= 3:
|
| 110 |
try:
|
| 111 |
full_chat = "\n".join([f"User: {q}\nBot: {a}" for q, a in st.session_state.conversation[-10:]])
|
|
|
|
| 113 |
summarizer = bot.summary_prompt | bot.model | parser
|
| 114 |
st.session_state.chat_summary = summarizer.invoke({'conversation': full_chat})
|
| 115 |
except:
|
| 116 |
+
pass
|
| 117 |
|
| 118 |
+
# Display conversation
|
| 119 |
total_messages = len(st.session_state.conversation)
|
| 120 |
start_idx = max(0, total_messages - st.session_state.chat_display_count)
|
| 121 |
visible_conversation = st.session_state.conversation[start_idx:]
|
| 122 |
|
| 123 |
+
for i, (q, a) in enumerate(reversed(visible_conversation)):
|
|
|
|
| 124 |
st.markdown(f'<div class="chat-message user-message">{escape(q)}</div>', unsafe_allow_html=True)
|
| 125 |
|
| 126 |
def format_response(text):
|
|
|
|
| 140 |
formatted = format_response(a)
|
| 141 |
st.markdown(f'<div class="chat-message bot-message">{formatted}</div>', unsafe_allow_html=True)
|
| 142 |
|
| 143 |
+
# 🔊 Speak Answer Button
|
| 144 |
+
audio_filename = f"audio_response_{uuid.uuid4().hex}.mp3"
|
| 145 |
+
if st.button(f"🔊 Speak Answer #{i+1}"):
|
| 146 |
+
asyncio.run(text_to_speech(a, audio_filename))
|
| 147 |
+
st.audio(audio_filename)
|
| 148 |
+
|
| 149 |
if start_idx > 0:
|
| 150 |
if st.button("🔽 Show more"):
|
| 151 |
st.session_state.chat_display_count += 5
|