|
import streamlit as st |
|
import pinecone |
|
import openai |
|
import uuid |
|
|
|
@st.experimental_singleton |
|
def init_pinecone(): |
|
pinecone.init(api_key=st.secrets["PINECONE_KEY"], environment="us-west1-gcp") |
|
return pinecone.Index(st.secrets["PINECONE_INDEX"]) |
|
|
|
openai.organization = st.secrets["OPENAI_ORG"] |
|
openai.api_key = st.secrets["OPENAI_KEY"] |
|
|
|
|
|
def modCheck(query): |
|
response = openai.Moderation.create(input=query) |
|
return response["results"][0]['flagged'] |
|
|
|
def promptMaker(query, matchtext, prompt_type=None): |
|
prompt = "The Pogcast is a weekly podcast co-hosted by Veritas and Jesse Kazam. They are both twitch streamers and on the podcast they discuss all the poggers things in life like the first-person shooter Escape from Tarkov, chess, speed-running, and everyday activities relevant to being a twitch streamer.\n" |
|
if not prompt_type: |
|
prompt+= "You will be given relevant snippets from the Pogcast that should help you answer or provide context to an inquiry. \n" + \ |
|
"If the inquiry is in the form of a question, answer it in a verbose manner, provide a quote from the snippets to support your answer, and provide a deep summarization of the relevant portions of the snippets.\n" + \ |
|
"If the inquiry is not in the form of a question, summarize the parts of the snippets most relevant to the inquiry.\n" + \ |
|
"Snippets:\n" + matchtext +" \nInquiry: " + query + "\nResult:" |
|
else: |
|
prompt+= "Use the following snippets from the podcast to write a " + prompt_type + " about " + query + "\nSnippets: " + matchtext + "\nResult:" |
|
return prompt |
|
|
|
def runInquiry(query): |
|
prompt_type = None |
|
if query.startswith("/"): |
|
prompt_type = query.split(" ")[0][1:] |
|
query = " ".join(query.split(" ")[1:]).strip() |
|
|
|
if len(query)< 6: |
|
st.error("Please ask a question with at least 6 characters") |
|
return |
|
with st.spinner('Checking query...'): |
|
flagged = modCheck(query) |
|
if flagged: |
|
st.error("You know what you did. I ain't answering that.") |
|
return |
|
|
|
with st.spinner('Embedding query...'): |
|
xq = openai.Embedding.create(input=query, engine="text-embedding-ada-002")['data'][0]['embedding'] |
|
index = init_pinecone() |
|
res = index.query(xq, namespace=st.secrets["PINECONE_NAMESPACE"], top_k=5, include_metadata=True) |
|
with st.spinner('Thinking...'): |
|
matchtext = "\n".join(match['metadata']['content'] for match in res['matches'][:3]) |
|
|
|
if 'uid' not in st.session_state: |
|
st.session_state.uid = str(uuid.uuid4()) |
|
|
|
comp = openai.Completion.create( |
|
model="text-davinci-003", |
|
prompt=promptMaker(query, matchtext, prompt_type), |
|
max_tokens=2000, |
|
temperature=0.9, |
|
user = st.session_state.uid |
|
) |
|
st.markdown(f""" |
|
<div> |
|
<p class="lead">{comp['choices'][0]['text']}</p> |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
for context in res['matches']: |
|
card( |
|
context['metadata']['episode_num'], |
|
context['metadata']['episode_id'], |
|
context['metadata']['start_second'], |
|
context['metadata']['end_second'], |
|
context['metadata']['content'] |
|
) |
|
return (comp, res['matches']) |
|
|
|
def card(episode, episode_id, start_second, end_second, context): |
|
return st.markdown(f""" |
|
<div class="container-fluid mb-2"> |
|
<div class="row align-items-start"> |
|
<div class="col-md-4 col-sm-4"> |
|
<div class="position-relative"> |
|
<iframe width="220" height="124" src="https://www.youtube.com/embed/{episode_id}?start={int(start_second)}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
|
</div> |
|
</div> |
|
<div class="col-md-8 col-sm-8"> |
|
<a href=https://www.youtube.com/watch?v={episode_id}&t={int(start_second)}s>Episode {int(episode)}</a> |
|
<br> |
|
<span style="color: #808080;"> |
|
<small>{context[:200].capitalize()+"...."}</small> |
|
</span> |
|
</div> |
|
</div> |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
st.markdown("<h1 style='text-align: center;'>PogcastGPT</h1>", unsafe_allow_html=True) |
|
st.write(""" |
|
This app uses semantic search to find and summarize relevant sections of the Pogcast to answer your question |
|
""") |
|
st.markdown(""" |
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> |
|
""", unsafe_allow_html=True) |
|
|
|
query = st.text_input(label="Ask me a question about the Pogcast!", max_chars=200, value="", key="inquiryBox", type='default') |
|
if query != "": |
|
runInquiry(query) |