Spaces:
Build error
Build error
| import streamlit as st | |
| import requests | |
| import json | |
| import urllib.parse | |
| import time | |
| # Streamlit page configuration | |
| st.set_page_config(page_title="Workout & Diet Chatbot", layout="wide") | |
| # Initialize session state for messages per model | |
| if "messages" not in st.session_state: | |
| st.session_state.messages = { | |
| "google/gemini-1.5-flash": [], | |
| "mistralai/Mixtral-8x7B-Instruct-v0.1": [], | |
| "meta-llama/Llama-3.1-70B-Instruct": [] | |
| } | |
| # Streamlit UI | |
| st.title("Workout & Diet Chatbot") | |
| st.markdown("Interact with each model separately for workout, diet, or gym recommendations!") | |
| # Create three columns | |
| col1, col2, col3 = st.columns(3) | |
| # Model names with display names for UI | |
| models = [ | |
| {"id": "google/gemini-1.5-flash", "display": "Gemini"}, | |
| {"id": "mistralai/Mixtral-8x7B-Instruct-v0.1", "display": "Mistral"}, | |
| {"id": "meta-llama/Llama-3.1-70B-Instruct", "display": "Llama"} | |
| ] | |
| def stream_response(query, target_model): | |
| """ | |
| Streams responses from the FastAPI backend for the target model. | |
| """ | |
| encoded_query = urllib.parse.quote(query) | |
| encoded_model = urllib.parse.quote(target_model) | |
| url = f"http://localhost:8000/chat?query={encoded_query}&model={encoded_model}" | |
| try: | |
| with requests.get(url, stream=True, headers={"Accept": "text/event-stream"}) as response: | |
| response.raise_for_status() | |
| full_response = "" | |
| for line in response.iter_lines(decode_unicode=True): | |
| if line: | |
| line = line.strip() | |
| if line.startswith("data:"): | |
| data = line[5:].strip() | |
| try: | |
| event_data = json.loads(data) | |
| event = event_data.get("event") | |
| if event == "response_chunk": | |
| model = event_data["model"] | |
| chunk = event_data["chunk"] | |
| if model == target_model or model == "system": | |
| full_response = chunk # Use the full response sent by server | |
| yield model, full_response | |
| elif event == "done": | |
| break | |
| except json.JSONDecodeError as e: | |
| yield "error", f"Failed to parse SSE data: {data}" | |
| except requests.RequestException as e: | |
| yield "error", f"Error connecting to server: {str(e)}" | |
| # Render each model's conversation form | |
| for col, model in zip([col1, col2, col3], models): | |
| with col: | |
| st.subheader(model["display"]) | |
| chat_container = st.container() | |
| # Display chat history for this model | |
| with chat_container: | |
| for message in st.session_state.messages[model["id"]]: | |
| with st.chat_message(message["role"], avatar="π€" if message["role"] == "assistant" else "π€"): | |
| if message["role"] == "assistant": | |
| st.markdown(f"**{message['display_name']}**: {message['content']}") | |
| else: | |
| st.markdown(message['content']) | |
| # Input box for this model | |
| user_input = st.chat_input(f"Ask {model['display']}...", key=f"input_{model['id']}") | |
| if user_input: | |
| # Add user message to this model's history | |
| st.session_state.messages[model["id"]].append({"role": "user", "content": user_input}) | |
| with chat_container: | |
| with st.chat_message("user", avatar="π€"): | |
| st.markdown(user_input) | |
| # Stream responses for this model | |
| placeholder = st.empty() | |
| current_response = {"model": None, "content": "", "display_name": model["display"]} | |
| with placeholder: | |
| with st.chat_message("assistant", avatar="π€"): | |
| response_container = st.markdown("") | |
| for model_name, content in stream_response(user_input, model["id"]): | |
| if model_name == "error": | |
| st.session_state.messages[model["id"]].append({ | |
| "role": "assistant", | |
| "model": "Error", | |
| "display_name": "Error", | |
| "content": content | |
| }) | |
| with placeholder: | |
| with st.chat_message("assistant", avatar="π€"): | |
| st.markdown(f"**Error**: {content}") | |
| else: | |
| current_response["model"] = model_name | |
| current_response["content"] = content | |
| with placeholder: | |
| with st.chat_message("assistant", avatar="π€"): | |
| response_container.markdown(f"**{model['display']}**: {content}") | |
| time.sleep(0.05) # Smooth streaming effect | |
| # Save the final response as a single message | |
| if current_response["model"]: | |
| st.session_state.messages[model["id"]].append({ | |
| "role": "assistant", | |
| "model": current_response["model"], | |
| "display_name": model["display"], | |
| "content": current_response["content"] | |
| }) |