Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -21,6 +21,11 @@ import time
|
|
| 21 |
import matplotlib.pyplot as plt
|
| 22 |
from pathlib import Path
|
| 23 |
import plotly.express as px
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
# Set page config
|
| 26 |
st.set_page_config(
|
|
@@ -137,6 +142,13 @@ def analyze_image(image, analysis_types):
|
|
| 137 |
|
| 138 |
def display_results(annotated_img, labels, objects, text):
|
| 139 |
"""Display analysis results in a clean format"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
col1, col2 = st.columns([3, 2])
|
| 141 |
|
| 142 |
with col1:
|
|
@@ -785,7 +797,7 @@ def process_video_file(video_file, analysis_types):
|
|
| 785 |
os.unlink(output_path)
|
| 786 |
|
| 787 |
# Return both the video and the detection statistics
|
| 788 |
-
return processed_video_bytes, detection_stats
|
| 789 |
|
| 790 |
except Exception as e:
|
| 791 |
# Clean up on error
|
|
@@ -826,6 +838,198 @@ def load_bigquery_table(dataset_id, table_id, limit=1000):
|
|
| 826 |
"schema": [field.name for field in table.schema]
|
| 827 |
}
|
| 828 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 829 |
def main():
|
| 830 |
# Header - Updated title
|
| 831 |
st.markdown('<div class="main-header">Cosmick Cloud AI Analyzer</div>', unsafe_allow_html=True)
|
|
@@ -840,6 +1044,9 @@ def main():
|
|
| 840 |
orientation="horizontal",
|
| 841 |
)
|
| 842 |
|
|
|
|
|
|
|
|
|
|
| 843 |
if selected == "Image Analysis":
|
| 844 |
# Sidebar controls
|
| 845 |
with st.sidebar:
|
|
@@ -1552,16 +1759,8 @@ def main():
|
|
| 1552 |
|
| 1553 |
st.info("Note: Make sure your Google Cloud credentials are properly set up to use this application.")
|
| 1554 |
|
| 1555 |
-
#
|
| 1556 |
-
|
| 1557 |
-
st.markdown("""
|
| 1558 |
-
<div style='position: fixed; bottom: 0; width: 100%; background-color: #f8f9fa;
|
| 1559 |
-
text-align: center; padding: 10px; border-top: 1px solid #e9ecef;'>
|
| 1560 |
-
<p style='color: #6c757d; font-size: 14px;'>
|
| 1561 |
-
Powered by Google Cloud with additional tools
|
| 1562 |
-
</p>
|
| 1563 |
-
</div>
|
| 1564 |
-
""", unsafe_allow_html=True)
|
| 1565 |
|
| 1566 |
if __name__ == "__main__":
|
| 1567 |
# Use GOOGLE_CREDENTIALS directly - no need for file or GOOGLE_APPLICATION_CREDENTIALS
|
|
|
|
| 21 |
import matplotlib.pyplot as plt
|
| 22 |
from pathlib import Path
|
| 23 |
import plotly.express as px
|
| 24 |
+
from groq import Groq
|
| 25 |
+
import streamlit.components.v1 as components
|
| 26 |
+
import html
|
| 27 |
+
from streamlit_chat import message
|
| 28 |
+
import uuid
|
| 29 |
|
| 30 |
# Set page config
|
| 31 |
st.set_page_config(
|
|
|
|
| 142 |
|
| 143 |
def display_results(annotated_img, labels, objects, text):
|
| 144 |
"""Display analysis results in a clean format"""
|
| 145 |
+
# Store results in session state for chatbot context
|
| 146 |
+
st.session_state.analysis_results = {
|
| 147 |
+
"labels": labels,
|
| 148 |
+
"objects": objects,
|
| 149 |
+
"text": text
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
col1, col2 = st.columns([3, 2])
|
| 153 |
|
| 154 |
with col1:
|
|
|
|
| 797 |
os.unlink(output_path)
|
| 798 |
|
| 799 |
# Return both the video and the detection statistics
|
| 800 |
+
return processed_video_bytes, {"detection_stats": detection_stats}
|
| 801 |
|
| 802 |
except Exception as e:
|
| 803 |
# Clean up on error
|
|
|
|
| 838 |
"schema": [field.name for field in table.schema]
|
| 839 |
}
|
| 840 |
|
| 841 |
+
def setup_groq_client():
|
| 842 |
+
"""Setup GROQ client with API key from Streamlit secrets"""
|
| 843 |
+
if 'GROQ_API_KEY' in st.secrets:
|
| 844 |
+
return Groq(api_key=st.secrets["GROQ_API_KEY"])
|
| 845 |
+
else:
|
| 846 |
+
st.sidebar.warning("GROQ API key not found in secrets. Chatbot functionality will be limited.")
|
| 847 |
+
return None
|
| 848 |
+
|
| 849 |
+
def get_assistant_response(client, prompt, context=None, model="llama3-70b-8192"):
|
| 850 |
+
"""Get response from GROQ assistant with context awareness"""
|
| 851 |
+
if client is None:
|
| 852 |
+
return "I'm unable to connect to my knowledge base right now. Please check the API configuration."
|
| 853 |
+
|
| 854 |
+
# Build a context-aware prompt
|
| 855 |
+
if context:
|
| 856 |
+
full_prompt = f"""You are an AI assistant for the Cosmick Cloud AI Analyzer application.
|
| 857 |
+
|
| 858 |
+
Current application context: {context}
|
| 859 |
+
|
| 860 |
+
User question: {prompt}
|
| 861 |
+
|
| 862 |
+
Please provide a helpful, accurate response based on the current application context.
|
| 863 |
+
If you need more specific information to answer correctly, please ask for it."""
|
| 864 |
+
else:
|
| 865 |
+
full_prompt = f"""You are an AI assistant for the Cosmick Cloud AI Analyzer application.
|
| 866 |
+
|
| 867 |
+
The application has the following tools:
|
| 868 |
+
1. Image Analysis: Analyzes images for labels, objects, text, and faces
|
| 869 |
+
2. Video Analysis: Processes videos to detect objects, faces, and text
|
| 870 |
+
3. Document Analysis: Extracts text and structure from documents
|
| 871 |
+
4. Data Analysis: Uploads, queries, and visualizes data in BigQuery
|
| 872 |
+
|
| 873 |
+
User question: {prompt}
|
| 874 |
+
|
| 875 |
+
Please provide a helpful response to guide the user on using these tools."""
|
| 876 |
+
|
| 877 |
+
# Call GROQ API
|
| 878 |
+
try:
|
| 879 |
+
chat_completion = client.chat.completions.create(
|
| 880 |
+
messages=[
|
| 881 |
+
{
|
| 882 |
+
"role": "system",
|
| 883 |
+
"content": "You are a helpful, knowledgeable assistant for the Cosmick Cloud AI Analyzer application."
|
| 884 |
+
},
|
| 885 |
+
{
|
| 886 |
+
"role": "user",
|
| 887 |
+
"content": full_prompt
|
| 888 |
+
}
|
| 889 |
+
],
|
| 890 |
+
model=model,
|
| 891 |
+
temperature=0.5,
|
| 892 |
+
max_tokens=1024,
|
| 893 |
+
top_p=1,
|
| 894 |
+
stream=False,
|
| 895 |
+
)
|
| 896 |
+
return chat_completion.choices[0].message.content
|
| 897 |
+
except Exception as e:
|
| 898 |
+
return f"I encountered an error: {str(e)}. Please try again or check the API configuration."
|
| 899 |
+
|
| 900 |
+
def chatbot_interface():
|
| 901 |
+
"""Create a chatbot interface at the bottom of the app"""
|
| 902 |
+
# Initialize chat history
|
| 903 |
+
if "messages" not in st.session_state:
|
| 904 |
+
st.session_state.messages = []
|
| 905 |
+
|
| 906 |
+
# Initialize GROQ client
|
| 907 |
+
if "groq_client" not in st.session_state:
|
| 908 |
+
st.session_state.groq_client = setup_groq_client()
|
| 909 |
+
|
| 910 |
+
# Get current context
|
| 911 |
+
current_context = ""
|
| 912 |
+
if "current_tool" in st.session_state:
|
| 913 |
+
current_context += f"Current tool: {st.session_state.current_tool}\n"
|
| 914 |
+
if "analysis_results" in st.session_state:
|
| 915 |
+
current_context += f"Analysis results: {st.session_state.analysis_results}\n"
|
| 916 |
+
|
| 917 |
+
# Create chatbot container
|
| 918 |
+
chat_container = st.container()
|
| 919 |
+
|
| 920 |
+
with chat_container:
|
| 921 |
+
# Create a custom expandable chat interface
|
| 922 |
+
st.markdown("""
|
| 923 |
+
<style>
|
| 924 |
+
.chat-container {
|
| 925 |
+
position: fixed;
|
| 926 |
+
bottom: 0;
|
| 927 |
+
right: 20px;
|
| 928 |
+
width: 400px;
|
| 929 |
+
background-color: white;
|
| 930 |
+
border-radius: 10px 10px 0 0;
|
| 931 |
+
box-shadow: 0 0 10px rgba(0,0,0,0.2);
|
| 932 |
+
z-index: 1000;
|
| 933 |
+
}
|
| 934 |
+
.chat-header {
|
| 935 |
+
padding: 10px 15px;
|
| 936 |
+
background-color: #4285F4;
|
| 937 |
+
color: white;
|
| 938 |
+
border-radius: 10px 10px 0 0;
|
| 939 |
+
font-weight: bold;
|
| 940 |
+
cursor: pointer;
|
| 941 |
+
}
|
| 942 |
+
.chat-messages {
|
| 943 |
+
max-height: 300px;
|
| 944 |
+
overflow-y: auto;
|
| 945 |
+
padding: 10px;
|
| 946 |
+
}
|
| 947 |
+
.chat-input {
|
| 948 |
+
padding: 10px;
|
| 949 |
+
border-top: 1px solid #eee;
|
| 950 |
+
}
|
| 951 |
+
</style>
|
| 952 |
+
|
| 953 |
+
<div class="chat-container" id="chat-container">
|
| 954 |
+
<div class="chat-header" onclick="toggleChat()">
|
| 955 |
+
💬 Cosmick AI Assistant - Click to toggle
|
| 956 |
+
</div>
|
| 957 |
+
<div id="chat-content">
|
| 958 |
+
<div class="chat-messages" id="chat-messages">
|
| 959 |
+
<div id="messages-container"></div>
|
| 960 |
+
</div>
|
| 961 |
+
<div class="chat-input">
|
| 962 |
+
<input type="text" id="user-input" placeholder="Ask me anything...">
|
| 963 |
+
<button onclick="sendMessage()">Send</button>
|
| 964 |
+
</div>
|
| 965 |
+
</div>
|
| 966 |
+
</div>
|
| 967 |
+
|
| 968 |
+
<script>
|
| 969 |
+
function toggleChat() {
|
| 970 |
+
const content = document.getElementById('chat-content');
|
| 971 |
+
if (content.style.display === 'none') {
|
| 972 |
+
content.style.display = 'block';
|
| 973 |
+
} else {
|
| 974 |
+
content.style.display = 'none';
|
| 975 |
+
}
|
| 976 |
+
}
|
| 977 |
+
|
| 978 |
+
function sendMessage() {
|
| 979 |
+
const input = document.getElementById('user-input');
|
| 980 |
+
const message = input.value;
|
| 981 |
+
if (message.trim() === '') return;
|
| 982 |
+
|
| 983 |
+
// Clear input
|
| 984 |
+
input.value = '';
|
| 985 |
+
|
| 986 |
+
// Add message to UI
|
| 987 |
+
const messagesContainer = document.getElementById('messages-container');
|
| 988 |
+
messagesContainer.innerHTML += `<div style="margin-bottom: 10px;"><strong>You:</strong> ${message}</div>`;
|
| 989 |
+
|
| 990 |
+
// Send message to Streamlit
|
| 991 |
+
window.parent.postMessage({
|
| 992 |
+
type: 'streamlit:message',
|
| 993 |
+
data: {
|
| 994 |
+
type: 'chatbot_message',
|
| 995 |
+
message: message
|
| 996 |
+
}
|
| 997 |
+
}, '*');
|
| 998 |
+
}
|
| 999 |
+
</script>
|
| 1000 |
+
""", unsafe_allow_html=True)
|
| 1001 |
+
|
| 1002 |
+
# Create a container for the actual chat interface using Streamlit components
|
| 1003 |
+
chat_placeholder = st.empty()
|
| 1004 |
+
|
| 1005 |
+
with chat_placeholder:
|
| 1006 |
+
# Display chat messages
|
| 1007 |
+
for message in st.session_state.messages:
|
| 1008 |
+
if message["role"] == "user":
|
| 1009 |
+
st.markdown(f"**You:** {message['content']}")
|
| 1010 |
+
else:
|
| 1011 |
+
st.markdown(f"**Assistant:** {message['content']}")
|
| 1012 |
+
|
| 1013 |
+
# Chat input
|
| 1014 |
+
user_input = st.chat_input("Ask me anything about image, video, document or data analysis...")
|
| 1015 |
+
|
| 1016 |
+
if user_input:
|
| 1017 |
+
# Add user message to history
|
| 1018 |
+
st.session_state.messages.append({"role": "user", "content": user_input})
|
| 1019 |
+
|
| 1020 |
+
# Get assistant response
|
| 1021 |
+
response = get_assistant_response(
|
| 1022 |
+
st.session_state.groq_client,
|
| 1023 |
+
user_input,
|
| 1024 |
+
context=current_context
|
| 1025 |
+
)
|
| 1026 |
+
|
| 1027 |
+
# Add assistant response to history
|
| 1028 |
+
st.session_state.messages.append({"role": "assistant", "content": response})
|
| 1029 |
+
|
| 1030 |
+
# Rerun to update chat display
|
| 1031 |
+
st.rerun()
|
| 1032 |
+
|
| 1033 |
def main():
|
| 1034 |
# Header - Updated title
|
| 1035 |
st.markdown('<div class="main-header">Cosmick Cloud AI Analyzer</div>', unsafe_allow_html=True)
|
|
|
|
| 1044 |
orientation="horizontal",
|
| 1045 |
)
|
| 1046 |
|
| 1047 |
+
# Store current tool in session state for context
|
| 1048 |
+
st.session_state.current_tool = selected
|
| 1049 |
+
|
| 1050 |
if selected == "Image Analysis":
|
| 1051 |
# Sidebar controls
|
| 1052 |
with st.sidebar:
|
|
|
|
| 1759 |
|
| 1760 |
st.info("Note: Make sure your Google Cloud credentials are properly set up to use this application.")
|
| 1761 |
|
| 1762 |
+
# Add the chatbot interface at the bottom of the page
|
| 1763 |
+
chatbot_interface()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1764 |
|
| 1765 |
if __name__ == "__main__":
|
| 1766 |
# Use GOOGLE_CREDENTIALS directly - no need for file or GOOGLE_APPLICATION_CREDENTIALS
|