Umang Chaudhry commited on
Commit
8e04782
1 Parent(s): 3ac6f08

Merge pull request #98 from vanderbilt-data-science/hf-struggle

Browse files
app.py CHANGED
@@ -1,20 +1,29 @@
1
  import streamlit as st
2
  import streamlit_authenticator as stauth
3
- import sqlite3
4
  import yaml
5
  from yaml.loader import SafeLoader
6
  import os
 
7
 
8
  from free_speech_app.DataLoadDb import *
9
  from free_speech_app.FreeSpeechPromptsResponses import *
10
  from langchain.chat_models import ChatOpenAI
11
 
12
- # Connect to SQLite database
13
- conn = sqlite3.connect('user_data.db')
 
14
 
15
- # Load the configuration file
16
- with open('config.yaml') as file:
17
- config = yaml.load(file, Loader=SafeLoader)
 
 
 
 
 
 
 
18
 
19
  # Create an authenticator
20
  authenticator = stauth.Authenticate(
@@ -25,25 +34,23 @@ authenticator = stauth.Authenticate(
25
  config['preauthorized']
26
  )
27
 
28
- # Render the login module
29
- name, authentication_status, username = authenticator.login('Login', 'main')
 
 
 
 
30
 
31
- # Create table for user data if it doesn't exist
32
- conn.execute('''CREATE TABLE IF NOT EXISTS user_data
33
- (username TEXT PRIMARY KEY,
34
- principles TEXT,
35
- writing_style TEXT,
36
- sources TEXT)''')
37
 
38
- def get_user_data(user):
39
- cursor = conn.cursor()
40
- cursor.execute("SELECT * FROM user_data WHERE username = ?", (user,))
41
- data = cursor.fetchone()
42
- return data
43
 
44
- def update_user_data(user, principles, writing_style, sources):
45
- conn.execute("INSERT OR REPLACE INTO user_data VALUES (?, ?, ?, ?)", (user, principles, writing_style, sources))
46
- conn.commit()
47
 
48
  # If the user is authenticated
49
  if authentication_status:
@@ -51,51 +58,157 @@ if authentication_status:
51
  st.write(f'Welcome *{name}*')
52
 
53
  # Sidebar for navigation
54
- page = st.sidebar.selectbox("Choose a page", ["Main screen", "Principles and sources"])
55
 
56
  # Fetch user data from the database
57
  user_data = get_user_data(username)
58
 
59
- if page == "Main screen":
60
- st.title("Main Screen")
 
 
61
 
62
- # Input boxes
63
- api_input = st.text_input("OpenAI API Token")
64
- original_post = st.text_input("Paste Original Post Here")
65
- background_info = st.text_input("Background information on original post (references, relevant information, best practices for responding)")
 
 
 
 
66
 
67
- chat_mdl = None
68
- draft_response = ''
69
-
70
- # Check if the "Submit" button is clicked
71
- if st.button("Submit"):
72
- if api_input:
73
- os.environ["OPENAI_API_KEY"] = api_input
74
- chat_mdl = ChatOpenAI(model_name = 'gpt-3.5-turbo-16k', temperature=0.1)
75
 
76
- if chat_mdl is not None:
77
- if user_data is None:
78
- draft_response = generate_custom_response(original_post, chat_mdl, background_info, "", "", "").content
79
- else:
80
- draft_response = generate_custom_response(original_post, chat_mdl, background_info, user_data[1], user_data[2], user_data[3]).content
81
-
82
- # Output from function
83
- st.text_area(label="Draft Response. Please edit here or prompt suggestions in the box below.", value=draft_response, height=350)
84
 
85
- regenerate_prompt = st.text_input("Additional prompting for regenerating draft response")
 
86
 
87
- elif page == "Principles and sources":
88
- st.title("Principles and Sources")
89
 
90
- # Input boxes with existing data
91
- principles = st.text_input("My Principles", value=user_data[1] if user_data else "")
92
- writing_style = st.text_input("My Writing Style (Paste Examples)", value=user_data[2] if user_data else "")
93
- sources = st.text_input("Sources (Provide all sources you would like to use)", value=user_data[3] if user_data else "")
 
 
 
94
 
95
- # Update button
96
- if st.button("Update"):
97
- update_user_data(username, principles, writing_style, sources)
 
 
 
 
 
 
 
 
 
 
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  elif authentication_status is False:
100
  st.error('Username/password is incorrect')
101
 
@@ -103,10 +216,12 @@ elif authentication_status is None:
103
  st.warning('Please enter your username and password')
104
 
105
  try:
106
- if authenticator.register_user('Register user', preauthorization=False):
107
- st.success('User registered successfully')
108
  except Exception as e:
109
  st.error(e)
110
 
111
  with open('config.yaml', 'w') as file:
112
  yaml.dump(config, file, default_flow_style=False)
 
 
 
1
  import streamlit as st
2
  import streamlit_authenticator as stauth
3
+ from deta import Deta
4
  import yaml
5
  from yaml.loader import SafeLoader
6
  import os
7
+ from cryptography.fernet import Fernet
8
 
9
  from free_speech_app.DataLoadDb import *
10
  from free_speech_app.FreeSpeechPromptsResponses import *
11
  from langchain.chat_models import ChatOpenAI
12
 
13
+ #connect to/create Deta user database
14
+ deta = Deta(st.secrets["deta_key"])
15
+ db = deta.Base("user_data")
16
 
17
+ #fernet key (generated locally, stored in streamlit secrets)
18
+ fernet = Fernet(bytes(st.secrets["fernet_key"],'utf-8'))
19
+
20
+ #activeloop_token
21
+ os.environ["ACTIVELOOP_TOKEN"] = st.secrets["deeplake_key"]
22
+
23
+ config_drive = deta.Drive("passwords")
24
+ config = config_drive.get("config.yaml").read()
25
+
26
+ config = yaml.load(config, Loader=SafeLoader)
27
 
28
  # Create an authenticator
29
  authenticator = stauth.Authenticate(
 
34
  config['preauthorized']
35
  )
36
 
37
+ def get_user_data(user):
38
+ data = db.fetch().items
39
+ for person in data:
40
+ if person['key'] == user:
41
+ return person
42
+ return None
43
 
44
+ def encrypt(api_key: str, fernet) -> bytes:
45
+ """Encrypt the API key."""
46
+ return fernet.encrypt(api_key.encode())
 
 
 
47
 
48
+ def decrypt(encrypted_api_key: bytes, fernet) -> str:
49
+ """Decrypt the encrypted API key."""
50
+ return fernet.decrypt(encrypted_api_key).decode()
 
 
51
 
52
+ # Render the login module
53
+ name, authentication_status, username = authenticator.login('Login', 'main')
 
54
 
55
  # If the user is authenticated
56
  if authentication_status:
 
58
  st.write(f'Welcome *{name}*')
59
 
60
  # Sidebar for navigation
61
+ page = st.sidebar.radio("Choose a page", ["OpenAI API Key Setup", "Account Setup", "Respond to Post"])
62
 
63
  # Fetch user data from the database
64
  user_data = get_user_data(username)
65
 
66
+ if page == "Account Setup":
67
+
68
+ st.title("Account Setup")
69
+ st.markdown("Please use this page to provide your OpenAI API Key, Principles and Writing Style. **Please make sure to press the Save Changes button after providing the information.**")
70
 
71
+
72
+ # Input boxes with existing data
73
+
74
+ if 'api_key' not in st.session_state:
75
+ st.session_state.api_key = ""
76
+ api_input = st.text_input("OpenAI API Key", value=decrypt(user_data["api_key"].encode()[2:-1], fernet) if user_data and "api_key" in user_data else "", type="password")
77
+ encrypted_api_key = str(encrypt(api_input, fernet))
78
+ st.session_state.api_key = api_input
79
 
80
+ principles = st.text_input("My Principles", placeholder = "Enter the main principles of your life you wish this response to uphold", value=user_data["principles"] if user_data and "principles" in user_data else "")
81
+ writing_style = st.text_input("My Writing Style (Paste Examples)", placeholder = "Provide examples of your writing style here", value=user_data["writing_style"] if user_data and "writing_style" in user_data else "")
82
+ sources = st.text_input("Sources (Provide all sources you would like to use)", value=st.session_state.sources if 'sources' in st.session_state else '', key = 'sources_key')
 
 
 
 
 
83
 
84
+ # Update button
85
+ if st.button("Save Changes"):
86
+ db.put({"key": username, "principles": principles, "writing_style": writing_style, "sources": sources, "api_key": encrypted_api_key})
87
+
88
+ if page == "OpenAI API Key Setup":
89
+ st.title("OpenAI API Key Setup")
 
 
90
 
91
+ st.header('What is an API key?')
92
+ st.write('An API (Application Programming Interface) key is like a password that allows you to access certain functions or data from a website or service. Many sites use API keys to identify you and control access to their APIs.')
93
 
94
+ st.header('Why do you need an API key?')
95
+ st.write('API keys allow sites to track usage and prevent abuse of their services. They help keep things secure. When you request an API key, the site knows the calls are coming from you.')
96
 
97
+ image = 'free_speech_app/apikeyex.png'
98
+ st.header('How to get an OpenAI API key:')
99
+ st.write('1. Go to https://platform.openai.com/account/api-keys')
100
+ st.write('2. Log in or create an OpenAI account if you do not have one')
101
+ st.write('3. Click "Create new secret key" and give your key a name')
102
+ st.image(image, caption=None, width=None, use_column_width=None, clamp=False, channels="RGB", output_format="auto")
103
+ st.write('4. Copy the generated API key and keep it private like a password')
104
 
105
+ st.header('Using your API key')
106
+ st.write('When making calls to the OpenAI API, include your API key in the request headers or parameters to authenticate.')
107
+ st.code('headers = {"Authorization": f"Bearer {YOUR_API_KEY}"}')
108
+
109
+ st.warning('Treat your API key like a secret! Do not share it publicly.')
110
+
111
+
112
+ elif page == "Respond to Post":
113
+ st.title("Respond to Post")
114
+
115
+ left_col, right_col = st.columns(2)
116
+
117
+ # Input boxes
118
 
119
+ with right_col:
120
+ background_info = st.text_area("Background information on original post (references, relevant information, best practices for responding)", height = 700, value=st.session_state.background_info if 'background_info' in st.session_state else '', key = 'background_info_key')
121
+
122
+ with left_col:
123
+ original_post = st.text_area("Paste Original Post Here \n", height=100)
124
+
125
+ chat_mdl = None
126
+ draft_response = ''
127
+
128
+ # Check if the "Submit" button is clicked
129
+ if st.button("Submit"):
130
+ if st.session_state.api_key:
131
+ os.environ["OPENAI_API_KEY"] = st.session_state.api_key
132
+ # add condition to check for passphrase to allow use of DSI api key stored in secrets
133
+ if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
134
+ os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key"]
135
+ chat_mdl = ChatOpenAI(model_name='gpt-4', temperature=0.1)
136
+
137
+ if chat_mdl is not None:
138
+ if user_data is None:
139
+ draft_response, background_text, sources_text = generate_custom_response(original_post, chat_mdl, "", "")
140
+ st.session_state.draft_response = draft_response.content
141
+ st.session_state.background_text = background_text
142
+ st.session_state.sources_text = sources_text
143
+ st.session_state.background_info = background_text
144
+ st.session_state.sources = sources_text
145
+ st.rerun()
146
+ else:
147
+ draft_response, background_text, sources_text = generate_custom_response(original_post, chat_mdl, user_data['principles'], user_data['writing_style'])
148
+ st.session_state.draft_response = draft_response.content
149
+ st.session_state.background_text = background_text
150
+ st.session_state.sources_text = sources_text
151
+ st.session_state.background_info = background_text
152
+ st.session_state.sources = sources_text
153
+ st.rerun()
154
+
155
+
156
+ # Ensure session state variables are initialized
157
+ if 'draft_response' not in st.session_state:
158
+ st.session_state.draft_response = ''
159
+ if 'regenerate_prompt' not in st.session_state:
160
+ st.session_state.regenerate_prompt = ''
161
+
162
+ # Output from function
163
+ response_textarea = st.text_area(
164
+ label="Draft Response. Please edit here or prompt suggestions in the box below.",
165
+ value=st.session_state.draft_response if 'draft_response' in st.session_state else '',
166
+ height=350,
167
+ key='draft_response_key'
168
+ )
169
+
170
+ # Initialization of the regeneration flag
171
+ if 'is_regenerating' not in st.session_state:
172
+ st.session_state.is_regenerating = False
173
+
174
+ # Check if the app is in the "regeneration" phase
175
+ if st.session_state.is_regenerating:
176
+ # Display the regenerated response explicitly
177
+ regenerate_prompt = st.text_area(
178
+ "Request a new draft",
179
+ value=st.session_state.regenerate_prompt,
180
+ placeholder="You may edit the regenerated draft directly above, or request further changes here.",
181
+ height=100,
182
+ key='regenerate_prompt_key'
183
+ )
184
+ # Reset the regeneration flag
185
+ st.session_state.is_regenerating = False
186
+ else:
187
+ # Normal behavior: display the text area for manual input
188
+ regenerate_prompt = st.text_area(
189
+ "Request a new draft",
190
+ placeholder="You may edit the draft directly above, or request a new draft with additional guidance here.",
191
+ height=100,
192
+ key='regenerate_prompt_key'
193
+ )
194
+
195
+ if (draft_response is not None) and (regenerate_prompt is not None):
196
+ if st.button("Regenerate"):
197
+ if st.session_state.api_key:
198
+ os.environ['OPENAI_API_KEY'] = st.session_state.api_key
199
+ # add condition to check for passphrase to allow use of DSI api key stored in secrets
200
+ if (os.environ["OPENAI_API_KEY"] == st.secrets["secret_passphrase"]):
201
+ os.environ["OPENAI_API_KEY"] = st.secrets["dsi_openai_key"]
202
+ chat_mdl = ChatOpenAI(model_name='gpt-4', temperature=0.1)
203
+
204
+ if chat_mdl is not None:
205
+ updated_response = regenerate_custom_response(chat_mdl, regenerate_prompt, st.session_state.draft_response).content
206
+ st.session_state.regenerate_prompt = updated_response
207
+ st.session_state.is_regenerating = True
208
+
209
+ st.rerun()
210
+
211
+
212
  elif authentication_status is False:
213
  st.error('Username/password is incorrect')
214
 
 
216
  st.warning('Please enter your username and password')
217
 
218
  try:
219
+ if authenticator.register_user('New User Registration', preauthorization=False):
220
+ st.success('User Registered Successfully! Please log in above.')
221
  except Exception as e:
222
  st.error(e)
223
 
224
  with open('config.yaml', 'w') as file:
225
  yaml.dump(config, file, default_flow_style=False)
226
+
227
+ config_drive.put("config.yaml", path = "config.yaml")
free_speech_app/DataLoadDb.py CHANGED
@@ -1,9 +1,9 @@
1
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/free-speech-stores.ipynb.
2
 
3
  # %% auto 0
4
- __all__ = ['setup_openai_api_key', 'is_google_colab', 'upload_docs', 'setup_db']
5
 
6
- # %% ../nbs/free-speech-stores.ipynb 5
7
  # libraries required for functionality
8
  import os
9
  from getpass import getpass
@@ -17,49 +17,23 @@ from langchain.text_splitter import CharacterTextSplitter
17
  from langchain.embeddings import OpenAIEmbeddings
18
  from langchain.vectorstores import Chroma
19
 
20
- # %% ../nbs/free-speech-stores.ipynb 9
21
  def setup_openai_api_key():
22
  openai_api_key = getpass()
23
  os.environ["OPENAI_API_KEY"] = openai_api_key
24
 
25
- # %% ../nbs/free-speech-stores.ipynb 12
26
  import nltk
27
  nltk.download('averaged_perceptron_tagger')
28
 
29
- # %% ../nbs/free-speech-stores.ipynb 13
30
- def is_google_colab():
31
- try:
32
- from google.colab import files
33
- return True
34
- except:
35
- return False
36
-
37
- def upload_docs():
38
-
39
- if not is_google_colab():
40
- raise ModuleNotFoundError('This function only works in Google Colab; local functionality not currently supported.')
41
-
42
- # upload files if google colab
43
- from google.colab import files
44
- uploaded = files.upload()
45
- file_list = []
46
-
47
- for name, data in uploaded.items():
48
- with open(name, 'wb') as f:
49
- f.write(data)
50
- print('saved file', name)
51
- file_list.append(name)
52
- return file_list
53
-
54
-
55
- # %% ../nbs/free-speech-stores.ipynb 22
56
- def setup_db(list_of_files, chunk_size=1000, chunk_overlap=5):
57
- # set path to files
58
- #paths = ["https://github.com/vanderbilt-data-science/free-speech-app/raw/9818f87679a82769ab6f90dba00801447b6e952c/response-resources/2307.04761_Understanding_counterspeech.pdf", "https://github.com/vanderbilt-data-science/free-speech-app/raw/main/response-resources/campaigns.docx", "https://github.com/vanderbilt-data-science/free-speech-app/raw/9818f87679a82769ab6f90dba00801447b6e952c/response-resources/samples.pdf"]
59
 
60
  # set up loaders
61
  loaders_list = []
62
- for file_path in list_of_files:
 
63
  loaders_list.append(UnstructuredFileLoader(file_path))
64
 
65
  loader_all = MergedDataLoader(loaders=[loader for loader in loaders_list])
@@ -70,7 +44,7 @@ def setup_db(list_of_files, chunk_size=1000, chunk_overlap=5):
70
  texts = text_splitter.split_documents(documents)
71
  embeddings = OpenAIEmbeddings()
72
 
73
- # store docs in db
74
- db = Chroma.from_documents(texts, embeddings)
75
 
76
- return db
 
1
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/free-speech-stores.ipynb.
2
 
3
  # %% auto 0
4
+ __all__ = ['setup_openai_api_key', 'setup_db']
5
 
6
+ # %% ../nbs/free-speech-stores.ipynb 4
7
  # libraries required for functionality
8
  import os
9
  from getpass import getpass
 
17
  from langchain.embeddings import OpenAIEmbeddings
18
  from langchain.vectorstores import Chroma
19
 
20
+ # %% ../nbs/free-speech-stores.ipynb 12
21
  def setup_openai_api_key():
22
  openai_api_key = getpass()
23
  os.environ["OPENAI_API_KEY"] = openai_api_key
24
 
25
+ # %% ../nbs/free-speech-stores.ipynb 15
26
  import nltk
27
  nltk.download('averaged_perceptron_tagger')
28
 
29
+ # %% ../nbs/free-speech-stores.ipynb 27
30
+ def setup_db(local_path, hub_path, chunk_size=1000, chunk_overlap=5):
31
+ file_list = os.listdir(local_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
  # set up loaders
34
  loaders_list = []
35
+ for file_path in file_list:
36
+ file_path = local_path + file_path
37
  loaders_list.append(UnstructuredFileLoader(file_path))
38
 
39
  loader_all = MergedDataLoader(loaders=[loader for loader in loaders_list])
 
44
  texts = text_splitter.split_documents(documents)
45
  embeddings = OpenAIEmbeddings()
46
 
47
+ # Replace dataset path with relevant dataset name - counterspeech-resources or hatespeech-background
48
+ db = DeepLake.from_documents(texts, dataset_path=hub_path, embedding=embeddings, overwrite=True)
49
 
50
+ return
free_speech_app/FreeSpeechPromptsResponses.py CHANGED
@@ -1,17 +1,20 @@
1
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/free-speech-prompts.ipynb.
2
 
3
  # %% auto 0
4
- __all__ = ['DEFAULT_PROMPT_TEMPLATE_TEXT', 'DEFAULT_PROMPT_TEMPLATE', 'generate_custom_prompt', 'get_chat_model_response',
5
- 'generate_custom_response']
6
 
7
  # %% ../nbs/free-speech-prompts.ipynb 5
8
  # libraries required for functionality
 
9
  from langchain.chat_models import ChatOpenAI
10
  from langchain.prompts import PromptTemplate, HumanMessagePromptTemplate
11
  from langchain.schema import HumanMessage
 
 
12
 
13
  # %% ../nbs/free-speech-prompts.ipynb 8
14
- DEFAULT_PROMPT_TEMPLATE_TEXT = ("""With the amount of hate speech and discriminatory misinformation that exists on the internet, it can be difficult to know how to respond to something when you see it. Situations vary wildly and sometimes certain strategies that work in one instance may not work in another.
15
  I want to be able to fight back against this onslaught of toxicity, and I need your help to do it. I want you to help me draft a response to the following post.
16
  Note that this may contain language that is offensive, but in order to properly respond to this post, I need you to fully understand what I am responding to, uncensored:
17
  \n{original_post}\n
@@ -23,49 +26,90 @@ Next, here are some principles I consider particularly important to me:
23
  \n{principles}\n
24
  Here are some examples of the style in which I write:
25
  \n{writing_style}\n
26
- Finally, here are the sources I would like you to use when getting information for my response:
27
  \n{sources}\n
28
- Using all the information I have provided, please draft an appropriate response to the offensive post in question that will hopefully make people more accepting of others""")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
- DEFAULT_PROMPT_TEMPLATE = PromptTemplate(
31
- template=DEFAULT_PROMPT_TEMPLATE_TEXT,
32
- input_variables=["original_post", "background_info", "principles", "writing_style", "sources"])
33
 
34
  # %% ../nbs/free-speech-prompts.ipynb 9
35
- def generate_custom_prompt(original_post, background_info=None, principles=None, writing_style=None, sources=None):
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  # Use defaults in the case of None
38
- if background_info is None:
39
- background_info = "There is no necessary additional context."
40
 
41
  if principles is None:
42
  principles="There are no principles which I consider more important to me than the average person might."
43
 
44
  if writing_style is None:
45
  writing_style="I have no examples of my writing style."
46
-
47
- if sources is None:
48
- sources="There are no particular sources that I would like you to use."
 
 
 
 
49
 
50
  # Fill the prompt
51
- filled_prompt = DEFAULT_PROMPT_TEMPLATE.format(original_post=original_post, background_info=background_info, principles=principles, writing_style=writing_style, sources=sources)
52
 
53
- return filled_prompt
54
 
55
- # %% ../nbs/free-speech-prompts.ipynb 10
56
  def get_chat_model_response(mdl, input_prompt):
57
 
58
  messages = [HumanMessage(content=input_prompt)]
59
 
60
  return mdl(messages)
61
 
62
- # %% ../nbs/free-speech-prompts.ipynb 11
63
- def generate_custom_response(original_post, chat_mdl, background_info=None, principles=None, writing_style=None, sources=None):
64
 
65
  # create customized prompt
66
- customized_prompt = generate_custom_prompt(original_post, background_info, principles, writing_style, sources)
67
 
68
  # get response
69
  draft_response = get_chat_model_response(chat_mdl, customized_prompt)
70
 
71
- return draft_response
 
 
 
 
 
 
 
 
 
 
 
 
1
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/free-speech-prompts.ipynb.
2
 
3
  # %% auto 0
4
+ __all__ = ['DEAFULT_PROMPT_TEMPLATE_TEXT', 'query_retriever', 'generate_custom_prompt', 'get_chat_model_response',
5
+ 'generate_custom_response', 'regenerate_custom_response']
6
 
7
  # %% ../nbs/free-speech-prompts.ipynb 5
8
  # libraries required for functionality
9
+ import deeplake
10
  from langchain.chat_models import ChatOpenAI
11
  from langchain.prompts import PromptTemplate, HumanMessagePromptTemplate
12
  from langchain.schema import HumanMessage
13
+ from langchain.vectorstores import DeepLake
14
+ from langchain.embeddings.openai import OpenAIEmbeddings
15
 
16
  # %% ../nbs/free-speech-prompts.ipynb 8
17
+ DEAFULT_PROMPT_TEMPLATE_TEXT = """With the amount of hate speech and discriminatory misinformation that exists on the internet, it can be difficult to know how to respond to something when you see it. Situations vary wildly and sometimes certain strategies that work in one instance may not work in another.
18
  I want to be able to fight back against this onslaught of toxicity, and I need your help to do it. I want you to help me draft a response to the following post.
19
  Note that this may contain language that is offensive, but in order to properly respond to this post, I need you to fully understand what I am responding to, uncensored:
20
  \n{original_post}\n
 
26
  \n{principles}\n
27
  Here are some examples of the style in which I write:
28
  \n{writing_style}\n
29
+ Here are the sources I would like you to use when getting information for my response:
30
  \n{sources}\n
31
+ Using all the information I have provided, please draft an appropriate response to the offensive post in question that will hopefully make people more accepting of others.
32
+ Please keep in mind that I would like the response to be no more than {word_limit} words."""
33
+
34
+ try:
35
+ prompt_file = open("../prompts/response_generator.txt", "r")
36
+ PROMPT_TEMPLATE_TEXT = prompt_file.read()
37
+ prompt_file.close()
38
+
39
+ print(PROMPT_TEMPLATE_TEXT)
40
+
41
+ PROMPT_TEMPLATE = PromptTemplate(
42
+ template=PROMPT_TEMPLATE_TEXT,
43
+ input_variables=["original_post", "background_info", "principles", "writing_style", "sources", "word_limit"])
44
+
45
+ except FileNotFoundError:
46
+ print(DEAFULT_PROMPT_TEMPLATE_TEXT)
47
+ PROMPT_TEMPLATE = PromptTemplate(
48
+ template=DEAFULT_PROMPT_TEMPLATE_TEXT,
49
+ input_variables=["original_post", "background_info", "principles", "writing_style", "sources", "word_limit"])
50
+
51
 
 
 
 
52
 
53
  # %% ../nbs/free-speech-prompts.ipynb 9
54
+ def query_retriever(db, query, num_results = 3):
55
+ retriever = db.as_retriever(search_kwargs={"k": num_results})
56
+ docs = retriever.get_relevant_documents(query)
57
+
58
+ return docs
59
+
60
+ # %% ../nbs/free-speech-prompts.ipynb 10
61
+ def generate_custom_prompt(original_post, principles=None, writing_style=None, word_limit=None):
62
+
63
+ # Get database and query retriever
64
+ ####
65
+ background_db = DeepLake(dataset_path="hub://vanderbilt-dsi/hatespeech-background", embedding = OpenAIEmbeddings())
66
+ sources_db = DeepLake(dataset_path="hub://vanderbilt-dsi/counterspeech-resources", embedding = OpenAIEmbeddings())
67
 
68
  # Use defaults in the case of None
 
 
69
 
70
  if principles is None:
71
  principles="There are no principles which I consider more important to me than the average person might."
72
 
73
  if writing_style is None:
74
  writing_style="I have no examples of my writing style."
75
+
76
+ if word_limit is None:
77
+ word_limit="an infinite amount of"
78
+
79
+ retriever_query = original_post
80
+ background_info = query_retriever(background_db, retriever_query)
81
+ sources = query_retriever(sources_db, retriever_query)
82
 
83
  # Fill the prompt
84
+ filled_prompt = PROMPT_TEMPLATE.format(original_post=original_post, background_info=background_info, principles=principles, writing_style=writing_style, sources=sources, word_limit=word_limit)
85
 
86
+ return filled_prompt, background_info, sources
87
 
88
+ # %% ../nbs/free-speech-prompts.ipynb 11
89
  def get_chat_model_response(mdl, input_prompt):
90
 
91
  messages = [HumanMessage(content=input_prompt)]
92
 
93
  return mdl(messages)
94
 
95
+ # %% ../nbs/free-speech-prompts.ipynb 12
96
+ def generate_custom_response(original_post, chat_mdl, principles=None, writing_style=None, word_limit=None):
97
 
98
  # create customized prompt
99
+ customized_prompt, background_info, sources = generate_custom_prompt(original_post, principles, writing_style, word_limit)
100
 
101
  # get response
102
  draft_response = get_chat_model_response(chat_mdl, customized_prompt)
103
 
104
+ return draft_response, background_info, sources
105
+
106
+ # %% ../nbs/free-speech-prompts.ipynb 13
107
+ def regenerate_custom_response(chat_mdl, regenerate_prompt, draft_response):
108
+
109
+ # create customized prompt
110
+ customized_prompt = f"Please update the original response according to the following request. {regenerate_prompt}. Here is the original response: {draft_response}"
111
+
112
+ # get response
113
+ updated_response = get_chat_model_response(chat_mdl, customized_prompt)
114
+
115
+ return updated_response
requirements.txt CHANGED
@@ -1,11 +1,12 @@
1
  streamlit
2
- sqlite3
3
- yaml
 
 
 
4
  langchain
5
  openai
6
  chromadb
7
  tiktoken
8
  unstructured
9
- getpass
10
  nltk
11
- free_speech_app @ git+https://github.com/vanderbilt-data-science/free-speech-app.git
 
1
  streamlit
2
+ streamlit-authenticator
3
+ deeplake
4
+ deta
5
+ cryptography
6
+ pyyaml
7
  langchain
8
  openai
9
  chromadb
10
  tiktoken
11
  unstructured
 
12
  nltk