ThreeAI-Demo / interface.py
VolodymyrHula's picture
Fixed endless scroll with parent component
642ca5c
import gradio as gr
from generate_service import OpenAIService
# Initialize OpenAI service
openai_service = OpenAIService()
def respond(message, history):
"""
Process user message and stream the response from OpenAI Assistant.
Args:
message: User's input message
history: Chat history as list of tuples
Yields:
Updated history with streaming response
"""
if not message.strip():
return
# Add user message to history with loading indicator
history.append((message, '<span class="loading-dots">🤔 Thinking<span style="animation: blink 1.4s infinite; animation-delay: 0s;">.</span><span style="animation: blink 1.4s infinite; animation-delay: 0.2s;">.</span><span style="animation: blink 1.4s infinite; animation-delay: 0.4s;">.</span></span>'))
yield history, ""
# Stream the assistant's response
response_text = ""
first_chunk = True
for chunk in openai_service.generate_stream(message):
response_text += chunk
# Replace loading message with actual response
history[-1] = (message, response_text)
yield history, ""
first_chunk = False
def clear_chat():
"""Clear the chat history and create a new thread."""
openai_service.clear_thread()
return []
with gr.Blocks(css="""
#component-0 {
height: calc(100vh - 200px) !important;
}
#chatbot-container {
height: 100% !important;
min-height: 600px;
}
#input-row {
position: sticky;
bottom: 0;
background: white;
padding: 10px 0;
}
.contain {
max-width: 100% !important;
padding: 0 !important;
}
#clear-btn {
position: absolute;
right: 10px;
top: 10px;
z-index: 100;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
.message.bot:has(.loading-dots) {
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
""") as demo:
with gr.Row():
gr.Markdown("# Chat Interface")
clear_button = gr.Button("Clear", elem_id="clear-btn", size="sm")
chatbot = gr.Chatbot(
value=[],
elem_id="chatbot-container",
height="calc(100vh - 200px)",
show_label=False,
sanitize_html=False,
)
with gr.Row(elem_id="input-row"):
with gr.Column(scale=9):
msg_input = gr.Textbox(
placeholder="Type your message here...",
show_label=False,
container=False
)
with gr.Column(scale=1, min_width=100):
send_button = gr.Button("Send", variant="primary")
# Event handlers
msg_input.submit(
respond,
inputs=[msg_input, chatbot],
outputs=[chatbot, msg_input]
)
send_button.click(
respond,
inputs=[msg_input, chatbot],
outputs=[chatbot, msg_input]
)
clear_button.click(
clear_chat,
inputs=None,
outputs=chatbot
)
if __name__ == "__main__":
demo.launch(inbrowser=True)