Spaces:
Running on CPU Upgrade

Yara Kyrychenko commited on
Commit
b0c5cee
·
1 Parent(s): 2e15bba
Files changed (11) hide show
  1. .gitignore +2 -0
  2. .streamlit/config.toml +8 -0
  3. README.md +12 -6
  4. app.py +242 -0
  5. base.txt +6 -0
  6. both.txt +36 -0
  7. bridging.txt +23 -0
  8. index.html +0 -19
  9. personalization.txt +21 -0
  10. requirements.txt +4 -0
  11. style.css +0 -28
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ *.DS_Store
2
+ .streamlit/secrets.toml
.streamlit/config.toml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ [server]
2
+ port = 8501
3
+
4
+ [browser]
5
+ gatherUsageStats = false
6
+
7
+ [theme]
8
+ base="light"
README.md CHANGED
@@ -1,10 +1,16 @@
1
  ---
2
- title: Bot
3
- emoji: 🐢
4
- colorFrom: purple
5
- colorTo: green
6
- sdk: static
 
 
7
  pinned: false
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
1
  ---
2
+ title: Bridging Bot
3
+ emoji: 🤖
4
+ colorFrom: pink
5
+ colorTo: purple
6
+ sdk: streamlit
7
+ sdk_version: 1.44.1
8
+ app_file: app.py
9
  pinned: false
10
+ license: mit
11
  ---
12
 
13
+
14
+ # Bridging Bot
15
+
16
+ Let's talk!
app.py ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from openai import OpenAI
3
+ from pymongo.mongo_client import MongoClient
4
+ from pymongo.server_api import ServerApi
5
+ from datetime import datetime
6
+ import random
7
+
8
+ st.set_page_config(
9
+ page_title="Chat",
10
+ page_icon="🤖",
11
+ initial_sidebar_state="expanded",
12
+ layout="wide"
13
+ )
14
+ st.markdown(
15
+ """ <style>
16
+ div[role="radiogroup"] > :first-child{
17
+ display: none !important;
18
+ }
19
+ </style>
20
+ """,
21
+ unsafe_allow_html=True
22
+ )
23
+
24
+ ### Setting up the session state
25
+
26
+ def format_personalization(text):
27
+ try:
28
+ for key, value in st.session_state.items():
29
+ text = text.replace(f"[{key.upper()}]", str(value))
30
+
31
+ except Exception as e:
32
+ print(text)
33
+ f"Failed to format personalization: {e}"
34
+ return text
35
+
36
+ if 'inserted' not in st.session_state:
37
+ with open('src/base.txt', 'r') as file:
38
+ st.session_state.base_text = file.read()
39
+ with open('src/bridging.txt', 'r') as file:
40
+ st.session_state.bridging_text = file.read()
41
+ with open('src/personalization.txt', 'r') as file:
42
+ st.session_state.personalization_text = file.read()
43
+ with open('src/both.txt', 'r') as file:
44
+ st.session_state.both_text = file.read()
45
+
46
+ # web app state
47
+ st.session_state.gotit = False
48
+ st.session_state.submitted = False
49
+ st.session_state.inserted = 0
50
+ st.session_state["model"] = "openai/gpt-4.1"
51
+ st.session_state.max_messages = 50
52
+ st.session_state.messages = []
53
+ st.session_state.user_data = {}
54
+
55
+ # user info state
56
+ st.session_state.fields = [
57
+ 'age', 'gender', 'education', 'employment', 'race', 'party',
58
+ 'user_id', 'random_pid'
59
+ ]
60
+
61
+ for field in st.session_state.fields:
62
+ st.session_state[field] = ''
63
+
64
+ st.session_state.user_id = str(random.randint(100000, 999999))
65
+ st.session_state.random_pid = st.query_params['id'] if 'id' in st.query_params else "0"
66
+ st.session_state.party = st.query_params['party'] if 'party' in st.query_params else ""
67
+
68
+ st.session_state.start_time = datetime.now()
69
+ st.session_state.convo_start_time = ''
70
+
71
+ if 'p' not in st.query_params:
72
+ st.query_params['p'] = '4'
73
+ if 'id' not in st.query_params:
74
+ st.query_params['id'] = st.session_state.random_pid
75
+ if 'party' not in st.query_params:
76
+ st.session_state.party = st.radio("Generally speaking, do you usually think of yourself as a Republican, a Democrat, an Independent, or what?",
77
+ ['','Republican', 'Democrat', 'Independent', 'Other'])
78
+ st.query_params['party'] = st.session_state.party
79
+
80
+ def setup_messages():
81
+ # 1 = base,
82
+ # 2 = bridging,
83
+ # 3 = personalization,
84
+ # 4 = bridging + personalization
85
+
86
+ if st.query_params["p"] == "1":
87
+ st.session_state.system_message = st.session_state.base_text
88
+ elif st.query_params["p"] == "2":
89
+ st.session_state.system_message = st.session_state.bridging_text
90
+ elif st.query_params["p"] == "3":
91
+ st.session_state.system_message = format_personalization(st.session_state.personalization_text)
92
+ elif st.query_params["p"] == "4":
93
+ st.session_state.system_message = format_personalization(st.session_state.both_text)
94
+
95
+ st.session_state.messages = [{ "role": "system", "content": st.session_state.system_message}]
96
+ st.session_state.convo_start_time = datetime.now()
97
+
98
+ client = OpenAI( base_url="https://openrouter.ai/api/v1", api_key=st.secrets["OPENROUTER_API_KEY"])
99
+
100
+ ### App interface
101
+ with st.sidebar:
102
+ st.markdown("# Let's talk!")
103
+ st.markdown(f"""
104
+ {"☑" if st.session_state.submitted else "☐"} **Step 1. Complete a form**
105
+
106
+ {"☑" if len(st.session_state.messages) > 0 else "☐"} **Step 2. Type in the chat box to start a conversation**
107
+
108
+ 🎯 Ask, request, or talk to the model about something that you consider politically polarizing or something that people from different US political parties would disagree about it.
109
+
110
+ ❗ Do not share any personal information (e.g., name or address). Do not use AI tools to generate your responses; write them yourself.
111
+
112
+ ⚠️ You must respond **at least 5 times** before you will see a *Finish* button. You can continue before submitting, but **you must finish and enter your chatbot code into the survey to recieve compensation**.
113
+
114
+ ❗ If you encounter any technical issues, please let us know. It might sometimes take 30 seconds or more to generate a response, so please be patient.
115
+
116
+ {"☑" if st.session_state.inserted > 1 else "☐"} **Step 3. Use the *Finish* button to get your chatbot code**
117
+
118
+ ⚠️ Do not forget to copy & paste your chatbot code!
119
+
120
+ ↺ You can always return to this panel by clicking the arrow on the top left.
121
+
122
+ {"🎉 **All done! Please enter your code in the survey and press *Next*.**" if st.session_state.inserted > 1 else ""}
123
+ """)
124
+ if st.session_state.gotit == False or st.session_state.submitted == False:
125
+ st.session_state.gotit = st.button("Let's start!", key=None, help=None, use_container_width=True)
126
+
127
+ @st.dialog('Form', width="large")
128
+ def form():
129
+ st.markdown("**Please answer every question to proceed.**")
130
+ st.session_state.age = st.radio("How old are you?",
131
+ ['', '18-24 years old', '25-34 years old', '35-44 years old', '45-54 years old', '55-64 years old', '65+'])
132
+ st.session_state.gender = st.radio("Do you describe yourself as a man, a woman, or in some other way?",
133
+ ['','Man', 'Woman', 'Other'])
134
+ st.session_state.race = st.radio("Choose a race that you consider yourself to be",
135
+ ['', 'White or Caucasian', 'Black or African American', 'Asian', 'Native Hawaiian or Pacific Islander', 'American Indian/Native American or Alaska Native', 'Mixed', 'Other'])
136
+ st.session_state.education = st.radio("What is the highest level of education you completed?",
137
+ ['',
138
+ 'Did not graduate high school',
139
+ 'High school graduate, GED, or alternative',
140
+ 'Some college, or associates degree',
141
+ "Bachelor's (college) degree or equivalent",
142
+ "Graduate degree (e.g., Master's degree, MBA)",
143
+ 'Doctorate degree (e.g., PhD, MD)'])
144
+ st.session_state.employment = st.radio("What best describes your employment status over the last three months?",
145
+ ['', 'Working full-time', 'Working part-time', 'Unemployed and looking for work',
146
+ 'A homemaker or a stay-at-home parent', 'Student', 'Retired', 'Other'])
147
+
148
+ columns_form = st.columns((1,1,1))
149
+ with columns_form[2]:
150
+ submitted = st.button("Proceed",use_container_width=True,
151
+ help = 'Make sure you answer every question',
152
+ disabled = not (all(st.session_state[field] != '' for field in st.session_state.fields) and st.session_state.recycling != 0))
153
+
154
+ if submitted:
155
+
156
+ st.session_state.user_data = {key: st.session_state[key] for key in st.session_state.fields}
157
+ st.session_state.user_data["model"] = st.session_state["model"]
158
+ st.session_state.user_data["condition"] = st.query_params['p']
159
+ st.session_state.user_data["start_time"] = st.session_state.start_time
160
+ st.session_state.user_data["inserted"] = st.session_state.inserted
161
+ st.session_state.user_data["submission_time"] = datetime.now()
162
+
163
+ st.session_state.inserted += 1
164
+ st.session_state.submitted = True
165
+ setup_messages()
166
+ st.rerun()
167
+
168
+ if st.session_state.gotit and st.session_state.submitted == False:
169
+ form()
170
+
171
+ for message in st.session_state.messages:
172
+ if message['role']!='system':
173
+ with st.chat_message(message["role"]):
174
+ st.markdown(message["content"])
175
+
176
+ if len(st.session_state.messages) >= st.session_state.max_messages:
177
+ st.info(
178
+ "You have reached the limit of messages for this conversation. Please end and submit the conversation."
179
+ )
180
+
181
+ elif st.session_state.submitted == False:
182
+ pass
183
+
184
+ elif st.session_state.inserted > 1:
185
+ st.markdown("## Copy your code!")
186
+ st.markdown('**Your chatbot code is:**')
187
+ st.markdown(f'## {st.session_state.user_id}')
188
+ st.markdown('**Please copy the code and enter it into the survey field below.**')
189
+
190
+ elif prompt := st.chat_input("Ask a polarizing question..."):
191
+
192
+ st.session_state.messages.append({"role": "user", "content": prompt})
193
+ with st.chat_message("user"):
194
+ st.markdown(prompt)
195
+
196
+ with st.chat_message("assistant"):
197
+ try:
198
+ stream = client.chat.completions.create(
199
+ model=st.session_state["model"],
200
+ messages=[
201
+ {"role": m["role"], "content": m["content"]}
202
+ for m in st.session_state.messages
203
+ ],
204
+ stream=True
205
+ )
206
+
207
+ response = st.write_stream(stream)
208
+
209
+ st.session_state.messages.append(
210
+ {"role": "assistant", "content": response}
211
+ )
212
+ except:
213
+ rate_limit_message = """
214
+ An error has occured or you've reached the maximum conversation length. Please submit the conversation.
215
+ """
216
+ st.session_state.messages.append(
217
+ {"role": "assistant", "content": rate_limit_message}
218
+ )
219
+ st.session_state.max_messages = len(st.session_state.messages)
220
+ st.rerun()
221
+
222
+ if len(st.session_state.messages) > 10 or st.session_state.max_messages == len(st.session_state.messages):
223
+ columns = st.columns((1,1,1))
224
+ with columns[2]:
225
+ if st.button("Finish",use_container_width=True):
226
+ keys = ["inserted", "messages", "convo_start_time"]
227
+
228
+ st.session_state.user_data.update({key: st.session_state[key] for key in keys})
229
+
230
+ st.session_state.user_data["convo_end_time"] = datetime.now()
231
+
232
+ with MongoClient(st.secrets["mongo"],server_api=ServerApi('1')) as client:
233
+ db = client.bridge
234
+ collection = db.app
235
+ user_data = st.session_state.user_data
236
+
237
+ collection.insert_one(user_data)
238
+ st.session_state.inserted += 1
239
+ done = True
240
+
241
+ setup_messages()
242
+ st.rerun()
base.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # Formatting
2
+
3
+ - Be concise and informative: respond with AT MOST 100 words.
4
+ - Use bullet points and follow-up questions when necessary. Do not explicity say "Follow up".
5
+ - Avoid repeating yourself or saying general or vague statements.
6
+ - Write your output in Markdown. Remember to escape dollar signes: write \$ instead of $.
both.txt ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ You are a personalized AI assistant fostering engaging conversations to bridging divides between US Republicans and Democrats and depolarize. Keep responses under 100 words, but maintain a dynamic conversation flow.
2
+
3
+ IMPORTANT: Make your conversations as personalized to the user profile as possible.
4
+
5
+ # User Profile
6
+
7
+ The participant has the following attributes:
8
+ - Country: USA
9
+ - Party: [PARTY]
10
+ - Age: [AGE]
11
+ - Gender: [GENDER]
12
+ - Race: [RACE]
13
+ - Education: [EDUCATION]
14
+ - Employment: [EMPLOYMENT]
15
+
16
+ # Bridging Systems
17
+
18
+ Your responses should show these attributes:
19
+ - Affinity: you should reference shared interests, motivations or outlooks between the user and another individual, group or entity.
20
+ - Compassion: you should identifies with or shows concern, empathy, or support for the feelings/emotions of others.
21
+ - Curiosity: you should attempt to clarify or ask follow-up questions to better understand another person or idea.
22
+ - Nuance: you should incorporate multiple points of view in an attempt to provide a full picture or contribute useful detail and/or context.
23
+ - Reasoning: you should make specific or well-reasoned points to provide a fuller understanding of the topic without disrespect or provocation.
24
+ - Respect: you should show deference or appreciation to others, or acknowledges the validity of another person.
25
+
26
+ # Goals
27
+
28
+ - Reduce affective polarization, especially dislike of the out-party
29
+ - Reduce issue polarization on specific topics
30
+
31
+ # Formatting
32
+
33
+ - Be concise and informative: respond with AT MOST 100 words.
34
+ - Use bullet points and follow-up questions when necessary. Do not explicity say "Follow up".
35
+ - Avoid repeating yourself or saying general or vague statements.
36
+ - Write your output in Markdown. Remember to escape dollar signes: write \$ instead of $.
bridging.txt ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ You are an AI assistant fostering engaging conversations to bridging divides between US Republicans and Democrats and depolarize. Keep responses under 100 words, but maintain a dynamic conversation flow.
2
+
3
+ # Bridging Systems
4
+
5
+ Your responses should show these attributes:
6
+ - Affinity: you should reference shared interests, motivations or outlooks between the user and another individual, group or entity.
7
+ - Compassion: you should identifies with or shows concern, empathy, or support for the feelings/emotions of others.
8
+ - Curiosity: you should attempt to clarify or ask follow-up questions to better understand another person or idea.
9
+ - Nuance: you should incorporate multiple points of view in an attempt to provide a full picture or contribute useful detail and/or context.
10
+ - Reasoning: you should make specific or well-reasoned points to provide a fuller understanding of the topic without disrespect or provocation.
11
+ - Respect: you should show deference or appreciation to others, or acknowledges the validity of another person.
12
+
13
+ # Goals
14
+
15
+ - Reduce affective polarization, especially dislike of the out-party
16
+ - Reduce issue polarization on specific topics
17
+
18
+ # Formatting
19
+
20
+ - Be concise and informative: respond with AT MOST 100 words.
21
+ - Use bullet points and follow-up questions when necessary. Do not explicity say "Follow up".
22
+ - Avoid repeating yourself or saying general or vague statements.
23
+ - Write your output in Markdown. Remember to escape dollar signes: write \$ instead of $.
index.html DELETED
@@ -1,19 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
personalization.txt ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ You are a personalized AI assistant fostering engaging conversations. Keep responses under 100 words, but maintain a dynamic conversation flow.
2
+
3
+ IMPORTANT: Make your conversations as personalized to the user profile as possible.
4
+
5
+ # User Profile
6
+
7
+ The participant has the following attributes:
8
+ - Country: USA
9
+ - Party: [PARTY]
10
+ - Age: [AGE]
11
+ - Gender: [GENDER]
12
+ - Race: [RACE]
13
+ - Education: [EDUCATION]
14
+ - Employment: [EMPLOYMENT]
15
+
16
+ # Formatting
17
+
18
+ - Be concise and informative: respond with AT MOST 100 words.
19
+ - Use bullet points and follow-up questions when necessary. Do not explicity say "Follow up".
20
+ - Avoid repeating yourself or saying general or vague statements.
21
+ - Write your output in Markdown. Remember to escape dollar signes: write \$ instead of $.
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ streamlit==1.44.1
2
+ pymongo[srv]==4.11
3
+ datetime==5.5
4
+ openai==1.55.3
style.css DELETED
@@ -1,28 +0,0 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
- }
5
-
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
- }
10
-
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
- }
17
-
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
- }
25
-
26
- .card p:last-child {
27
- margin-bottom: 0;
28
- }