File size: 6,072 Bytes
919dd4f 285da6d 175f982 919dd4f 175f982 919dd4f 175f982 919dd4f 175f982 919dd4f 175f982 919dd4f 175f982 919dd4f 175f982 919dd4f 175f982 919dd4f 175f982 919dd4f 175f982 919dd4f 175f982 919dd4f 175f982 |
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 |
import streamlit as st
import openai
import os
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from openai import OpenAI
import base64
import requests
# Initialize clients
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
elevenlabs_key = os.getenv("ELEVENLABS_API_KEY")
tavily_key = os.getenv("TAVILY_API_KEY")
# Initialize session state
if "messages" not in st.session_state:
st.session_state.messages = []
if "document_vectors" not in st.session_state:
st.session_state.document_vectors = None
# App title
st.title("π€ SuperBot Pro")
st.caption("An AI Assistant with Superpowers")
# ===== Sidebar Settings =====
with st.sidebar:
st.header("βοΈ Settings")
# Personality and Mode
tone = st.selectbox("Personality:", ["Assistant", "Sarcastic", "Academic", "Shakespeare"])
mode = st.radio("Mode:", ["Chat", "Document Q&A", "Web Researcher"])
# Advanced Features
web_access = st.checkbox("Enable Web Search", value=False)
voice_enabled = st.checkbox("Enable Voice Response", value=False)
# File Uploaders
uploaded_file = st.file_uploader("Upload Document (PDF)", type=["pdf"])
uploaded_image = st.file_uploader("Upload Image", type=["jpg", "png"])
# ===== Document Processing =====
if uploaded_file and mode == "Document Q&A":
with st.spinner("Processing document..."):
# Save and load PDF
with open(uploaded_file.name, "wb") as f:
f.write(uploaded_file.getbuffer())
loader = PyPDFLoader(uploaded_file.name)
pages = loader.load()
# Split and embed
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
texts = text_splitter.split_documents(pages)
embeddings = OpenAIEmbeddings()
st.session_state.document_vectors = FAISS.from_documents(texts, embeddings)
# ===== Chat Interface =====
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if "audio" in message:
st.audio(message["audio"], format="audio/mp3")
# Input area
if prompt := st.chat_input("Ask me anything..."):
# Add user message to history
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# ===== Generate Response =====
with st.chat_message("assistant"):
response_placeholder = st.empty()
full_response = ""
try:
# ===== Content Moderation =====
moderation = client.moderations.create(input=prompt)
if moderation.results[0].flagged:
st.error("Content violates policies")
st.stop()
# ===== System Prompt Engineering =====
system_prompt = f"You are a {tone} assistant. Respond concisely."
if mode == "Document Q&A" and st.session_state.document_vectors:
docs = st.session_state.document_vectors.similarity_search(prompt, k=3)
system_prompt += f"\nDocument context: {[doc.page_content for doc in docs]}"
if web_access and tavily_key:
search_response = requests.post(
"https://api.tavily.com/search",
json={"query": prompt, "api_key": tavily_key}
)
web_results = search_response.json()["results"]
system_prompt += f"\nWeb results: {web_results[:2]}"
# ===== Generate with OpenAI =====
response = client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": system_prompt},
*st.session_state.messages
],
stream=True
)
# Stream response
for chunk in response:
if chunk.choices[0].delta.content:
full_response += chunk.choices[0].delta.content
response_placeholder.markdown(full_response + "β")
response_placeholder.markdown(full_response)
# ===== Voice Output =====
if voice_enabled and elevenlabs_key:
audio_response = requests.post(
"https://api.elevenlabs.io/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM",
headers={"xi-api-key": elevenlabs_key},
json={"text": full_response}
)
st.audio(audio_response.content, format="audio/mp3")
# Add to history
st.session_state.messages.append({
"role": "assistant",
"content": full_response,
"audio": audio_response.content if voice_enabled else None
})
except Exception as e:
st.error(f"Error: {str(e)}")
# ===== Feedback Buttons =====
col1, col2 = st.columns(2)
with col1:
if st.button("π Good Response"):
st.toast("Thanks for your feedback!")
with col2:
if st.button("π Needs Improvement"):
st.toast("We'll do better next time!")
# ===== Image Processing =====
if uploaded_image:
st.image(uploaded_image, caption="Uploaded Image")
with st.spinner("Analyzing image..."):
response = client.chat.completions.create(
model="gpt-4-vision-preview",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image"},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64.b64encode(uploaded_image.getvalue()).decode('utf-8')}"}}
]
}]
)
st.write(response.choices[0].message.content) |