| | 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/bootstrap@4.0.0/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) |