Spaces:
Sleeping
Sleeping
File size: 9,077 Bytes
a3e0475 ffbccbb 1fd6803 fc5f1c7 d6f5773 fc5f1c7 a3e0475 5c095c6 546ff54 fc42bd4 546ff54 ab8074b 594a593 546ff54 ab8074b 594a593 546ff54 ab8074b 546ff54 b256ef1 5c095c6 3af8ac2 594a593 5c095c6 594a593 5c095c6 1fd6803 5c095c6 1fd6803 391ca85 546ff54 94ac9e7 fc5f1c7 594a593 5c095c6 a3e0475 258dcf5 5c095c6 a3e0475 546ff54 94ac9e7 258dcf5 94ac9e7 5c095c6 546ff54 594a593 073538f 258dcf5 546ff54 ac55e19 546ff54 ac55e19 594a593 c567c97 594a593 c567c97 594a593 c567c97 594a593 792148f 594a593 792148f 594a593 792148f 594a593 c567c97 594a593 b54b055 b744871 594a593 b54b055 792148f b54b055 594a593 b54b055 b744871 594a593 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
import os
import re
import random
import requests
import streamlit as st
from langchain_huggingface import HuggingFaceEndpoint
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from transformers import pipeline
from langdetect import detect # Ensure this package is installed
# β
Environment Variables
HF_TOKEN = os.getenv("HF_TOKEN")
if HF_TOKEN is None:
raise ValueError("HF_TOKEN is not set. Please add it to your environment variables.")
NASA_API_KEY = os.getenv("NASA_API_KEY")
if NASA_API_KEY is None:
raise ValueError("NASA_API_KEY is not set. Please add it to your environment variables.")
# β
Set Up Streamlit
st.set_page_config(page_title="HAL - NASA ChatBot", page_icon="π")
user_input = st.chat_input("Type your message here...") # Make sure this is executed first
# β
Ensure Session State Variables
if "chat_history" not in st.session_state:
st.session_state.chat_history = [{"role": "assistant", "content": "Hello! How can I assist you today?"}]
if "response_ready" not in st.session_state:
st.session_state.response_ready = False
if "follow_up" not in st.session_state:
st.session_state.follow_up = ""
# β
Model Configuration
model_id = "mistralai/Mistral-7B-Instruct-v0.3"
# β
Initialize Hugging Face Model
def get_llm_hf_inference(model_id=model_id, max_new_tokens=1024, temperature=0.7):
return HuggingFaceEndpoint(
repo_id=model_id,
max_new_tokens=max_new_tokens,
temperature=temperature,
token=HF_TOKEN,
task="text-generation"
)
# β
NASA API Function
def get_nasa_apod():
url = f"https://api.nasa.gov/planetary/apod?api_key={NASA_API_KEY}"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return data.get("url", ""), data.get("title", ""), data.get("explanation", "")
return "", "NASA Data Unavailable", "I couldn't fetch data from NASA right now."
# β
Sentiment Analysis
sentiment_analyzer = pipeline(
"sentiment-analysis",
model="distilbert/distilbert-base-uncased-finetuned-sst-2-english"
)
def analyze_sentiment(user_text):
result = sentiment_analyzer(user_text)[0]
return result['label']
# β
Intent Detection
def predict_action(user_text):
if "NASA" in user_text or "space" in user_text:
return "nasa_info"
return "general_query"
# β
Follow-Up Question Generation
def generate_follow_up(user_text):
prompt_text = f"Based on: '{user_text}', generate a concise, friendly follow-up."
hf = get_llm_hf_inference(max_new_tokens=80, temperature=0.9)
output = hf.invoke(input=prompt_text).strip()
return output if output else "Would you like to explore this topic further?"
# β
Ensure English Responses
def ensure_english(text):
try:
detected_lang = detect(text)
if detected_lang != "en":
return "β οΈ Sorry, I only respond in English. Can you rephrase your question?"
except:
return "β οΈ Language detection failed. Please ask your question again."
return text
# β
Ensure Every Response Has a Follow-Up Question
def generate_follow_up(user_text):
"""Generates a clean follow-up question to guide the user toward related topics or next steps."""
prompt_text = (
f"Given the user's question: '{user_text}', generate a SHORT follow-up question "
"suggesting either a related topic or asking if they need further help. "
"Example: 'Would you like to explore quantum superposition or ask about another physics concept?' "
"Keep it concise and engaging."
)
hf = get_llm_hf_inference(max_new_tokens=40, temperature=0.8)
output = hf.invoke(input=prompt_text).strip()
# β
Remove unnecessary characters (like backticks and misplaced formatting)
cleaned_output = re.sub(r"```|''|\"", "", output).strip()
# β
Fallback in case the response is empty or invalid
return cleaned_output if cleaned_output else "Would you like to explore another related topic or ask about something else?"
# β
Main Response Function
def get_response(system_message, chat_history, user_text, max_new_tokens=512):
action = predict_action(user_text)
# β
Handle NASA-Specific Queries
if action == "nasa_info":
nasa_url, nasa_title, nasa_explanation = get_nasa_apod()
response = f"**{nasa_title}**\n\n{nasa_explanation}"
follow_up = generate_follow_up(user_text)
chat_history.append({'role': 'user', 'content': user_text})
chat_history.append({'role': 'assistant', 'content': response})
chat_history.append({'role': 'assistant', 'content': follow_up})
return response, follow_up, chat_history, nasa_url
# β
Set Up LLM Request
hf = get_llm_hf_inference(max_new_tokens=max_new_tokens, temperature=0.9)
# β
Format Chat History
filtered_history = "\n".join(f"{msg['role']}: {msg['content']}" for msg in chat_history)
# β
Prompt Engineering
prompt = PromptTemplate.from_template(
"[INST] {system_message}\n\nCurrent Conversation:\n{chat_history}\n\n"
"User: {user_text}.\n [/INST]\n"
"AI: Provide a detailed explanation with depth. "
"Use a conversational style, starting with 'Certainly!', 'Of course!', or 'Great question!'."
"π¨ Answer **only in English**."
"\nHAL:"
)
# β
Invoke LLM Model
chat = prompt | hf.bind(skip_prompt=True) | StrOutputParser(output_key='content')
response = chat.invoke(input=dict(system_message=system_message, user_text=user_text, chat_history=filtered_history))
response = response.split("HAL:")[-1].strip() if "HAL:" in response else response.strip()
# β
Ensure English
response = ensure_english(response)
# β
Fallback Response
if not response:
response = "I'm sorry, but I couldn't generate a response. Can you rephrase your question?"
follow_up = generate_follow_up(user_text)
chat_history.append({'role': 'user', 'content': user_text})
chat_history.append({'role': 'assistant', 'content': response})
chat_history.append({'role': 'assistant', 'content': follow_up})
return response, follow_up, chat_history, None
# β
Ensure response is displayed
if response:
st.markdown(f"<div class='assistant-msg'><strong>HAL:</strong> {response}</div>", unsafe_allow_html=True)
# β
Save and display follow-up question separately
if follow_up: # π Here is the `if follow_up:` section
st.session_state.chat_history.append({'role': 'assistant', 'content': follow_up})
st.markdown(f"<div class='assistant-msg'><strong>HAL:</strong> {follow_up}</div>", unsafe_allow_html=True)
# β
Streamlit UI
st.title("π HAL - NASA AI Assistant")
# β
Justify all chatbot responses
st.markdown("""
<style>
.user-msg {
background-color: #696969;
color: white;
padding: 10px;
border-radius: 10px;
margin-bottom: 5px;
width: fit-content;
max-width: 80%;
text-align: justify; /* β
Justify text */
}
.assistant-msg {
background-color: #333333;
color: white;
padding: 10px;
border-radius: 10px;
margin-bottom: 5px;
width: fit-content;
max-width: 80%;
text-align: justify; /* β
Justify text */
}
.container {
display: flex;
flex-direction: column;
align-items: flex-start;
}
@media (max-width: 600px) {
.user-msg, .assistant-msg { font-size: 16px; max-width: 100%; }
}
</style>
""", unsafe_allow_html=True)
# β
Reset Chat Button
if st.sidebar.button("Reset Chat"):
st.session_state.chat_history = [{"role": "assistant", "content": "Hello! How can I assist you today?"}]
st.session_state.response_ready = False
st.session_state.follow_up = ""
if user_input:
# β
Ensure get_response() returns a response
response, follow_up, st.session_state.chat_history, image_url = get_response(
system_message="You are a helpful AI assistant.",
user_text=user_input,
chat_history=st.session_state.chat_history
)
# β
Set default value if `response` is missing
if not response:
response = "I'm sorry, but I couldn't generate a response."
# β
Display chatbot response
st.markdown(f"<div class='assistant-msg'><strong>HAL:</strong> {response}</div>", unsafe_allow_html=True)
# β
Handle follow-up question
if follow_up:
st.markdown(f"<div class='assistant-msg'><strong>HAL:</strong> {follow_up}</div>", unsafe_allow_html=True)
# β
Display NASA image if available
if image_url:
st.image(image_url, caption="NASA Image of the Day")
# β
Check before displaying follow-up message
if st.session_state.response_ready and st.session_state.follow_up:
st.markdown(f"<div class='assistant-msg'><strong>HAL:</strong> {st.session_state.follow_up}</div>", unsafe_allow_html=True)
st.session_state.response_ready = False
|