Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Merge branch 'main' of https://huggingface.co/spaces/ProjectFrozone/Site
Browse files- chat_application/main.py +44 -12
- chat_application/static/styles/styles.css +6 -6
- chat_application/templates/base.html +1 -1
- chat_application/templates/home.html +3 -0
- chat_application/templates/room.html +48 -13
- data/inference_instructions/coolbot_instructions_main.txt +12 -0
- data/inference_instructions/frobot_instructions_main.txt +15 -0
- data/inference_instructions/hotbot_instructions_main.txt +12 -0
chat_application/main.py
CHANGED
|
@@ -68,6 +68,7 @@ class datasetHandler():
|
|
| 68 |
CHAT_CONTEXT = 20 #how many messages from chat history to append to inference prompt
|
| 69 |
#minimum number of chars where we start checking for duplicate messages
|
| 70 |
DUP_LEN = 25 #since short messages may reasonably be the same
|
|
|
|
| 71 |
|
| 72 |
# Directory alignment
|
| 73 |
BASE_DIR = Path(__file__).resolve().parent
|
|
@@ -222,6 +223,13 @@ def send_bot_joined(room_id, bot_name, delay):
|
|
| 222 |
time.sleep(delay)
|
| 223 |
socketio.emit("message", {"sender": "", "message": f"{bot_name} has entered the chat"}, to=room_id)
|
| 224 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
# Trigger a round of bot calls if user has been inactive for a while
|
| 226 |
def user_inactivity_tracker(room_id, timeout_seconds=120,randomNorm = (0,15)):
|
| 227 |
print(f"Started user inactivity tracker for Room ID#{room_id}")
|
|
@@ -367,21 +375,26 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt):
|
|
| 367 |
print("PASSED")
|
| 368 |
return True # a pass is still recorded in the database, but not sent to the client
|
| 369 |
|
|
|
|
|
|
|
| 370 |
#remove encapsulating quotes
|
| 371 |
-
no_quotes = remove_quotes(
|
| 372 |
#humanize the response (remove obvious AI formatting styles)
|
| 373 |
humanized_response = humanize(no_quotes)
|
| 374 |
#replace most semicolons
|
| 375 |
less_semicolons_response = replace_semicolons(humanized_response)
|
| 376 |
#corrupt the response (add some typos and misspellings)
|
| 377 |
-
corrupted_response = corrupt(less_semicolons_response)
|
| 378 |
#remove weird chars
|
| 379 |
no_weird_chars = remove_weird_characters(corrupted_response)
|
| 380 |
-
#
|
| 381 |
-
|
|
|
|
|
|
|
|
|
|
| 382 |
|
| 383 |
#check that there are no reccent duplicate messages
|
| 384 |
-
if len(
|
| 385 |
print("****DUPLICATE MESSAGE DETECTED")
|
| 386 |
print("Treating this bot's response as a pass.")
|
| 387 |
# Do not store/send messages if the chat has ended
|
|
@@ -391,7 +404,7 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt):
|
|
| 391 |
# Store the error response in the database
|
| 392 |
bot_message = {
|
| 393 |
"sender": bot_display_name,
|
| 394 |
-
"message": f"DUPLICATE message detected - treated as a (pass) : {
|
| 395 |
"timestamp": datetime.utcnow()
|
| 396 |
}
|
| 397 |
rooms_collection.update_one(
|
|
@@ -406,7 +419,7 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt):
|
|
| 406 |
print(corrupted_response)
|
| 407 |
|
| 408 |
# Add latency/wait time for bot responses
|
| 409 |
-
delay = get_response_delay(
|
| 410 |
print(delay)
|
| 411 |
time.sleep(delay)
|
| 412 |
|
|
@@ -418,7 +431,7 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt):
|
|
| 418 |
# Store the response in the database
|
| 419 |
bot_message = {
|
| 420 |
"sender": bot_display_name,
|
| 421 |
-
"message":
|
| 422 |
"timestamp": datetime.utcnow()
|
| 423 |
}
|
| 424 |
rooms_collection.update_one(
|
|
@@ -427,7 +440,7 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt):
|
|
| 427 |
)
|
| 428 |
|
| 429 |
# Send the bot's response to the client
|
| 430 |
-
socketio.emit("message", {"sender": bot_display_name, "message":
|
| 431 |
return False
|
| 432 |
|
| 433 |
def ask_bot_round(room_id):
|
|
@@ -486,7 +499,8 @@ def home():
|
|
| 486 |
session['user_id'] = user_id
|
| 487 |
return redirect(url_for('topics'))
|
| 488 |
else:
|
| 489 |
-
|
|
|
|
| 490 |
|
| 491 |
@app.route('/topics', methods=["GET", "POST"])
|
| 492 |
def topics():
|
|
@@ -580,8 +594,18 @@ def room():
|
|
| 580 |
m for m in room_doc["messages"]
|
| 581 |
if len(re.findall(r"pass",m.get("message", "").strip())) == 0
|
| 582 |
]
|
| 583 |
-
|
| 584 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 585 |
@app.route("/abort", methods=["POST"])
|
| 586 |
def abort_room():
|
| 587 |
room_id = session.get("room")
|
|
@@ -632,6 +656,7 @@ def handle_connect():
|
|
| 632 |
join_room(room)
|
| 633 |
if (room_doc.get("initialPostsSent", False)):
|
| 634 |
return
|
|
|
|
| 635 |
# Send the message that "watermelon" has already joined the chat
|
| 636 |
send({
|
| 637 |
"sender": "",
|
|
@@ -642,10 +667,17 @@ def handle_connect():
|
|
| 642 |
"sender": "",
|
| 643 |
"message": f"{name} has entered the chat"
|
| 644 |
}, to=room)
|
|
|
|
| 645 |
# Start background tasks for the bots to join after a short delay
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 646 |
socketio.start_background_task(send_bot_joined, room, room_doc['CoolBot_name'], 3)
|
| 647 |
socketio.start_background_task(send_bot_joined, room, room_doc['FroBot_name'], 7)
|
| 648 |
socketio.start_background_task(send_bot_joined, room, room_doc['HotBot_name'], 13)
|
|
|
|
| 649 |
# Start background task to send the initial watermelon post after a short delay
|
| 650 |
socketio.start_background_task(send_initial_post, room, 10)
|
| 651 |
# Start the background backup dataset task
|
|
|
|
| 68 |
CHAT_CONTEXT = 20 #how many messages from chat history to append to inference prompt
|
| 69 |
#minimum number of chars where we start checking for duplicate messages
|
| 70 |
DUP_LEN = 25 #since short messages may reasonably be the same
|
| 71 |
+
REMOVE_PUNC_RATE = .8 #how often to remove final punctuation
|
| 72 |
|
| 73 |
# Directory alignment
|
| 74 |
BASE_DIR = Path(__file__).resolve().parent
|
|
|
|
| 223 |
time.sleep(delay)
|
| 224 |
socketio.emit("message", {"sender": "", "message": f"{bot_name} has entered the chat"}, to=room_id)
|
| 225 |
|
| 226 |
+
# Send message displaying all participant names
|
| 227 |
+
def send_bot_names_message(room_id, bot_names):
|
| 228 |
+
if len(bot_names) == 0:
|
| 229 |
+
return
|
| 230 |
+
# Wait 1 second before sending
|
| 231 |
+
socketio.emit("message", {"sender": "", "message": f"This chat currently contains {', '.join(bot_names)}, and watermelon."}, to=room_id)
|
| 232 |
+
|
| 233 |
# Trigger a round of bot calls if user has been inactive for a while
|
| 234 |
def user_inactivity_tracker(room_id, timeout_seconds=120,randomNorm = (0,15)):
|
| 235 |
print(f"Started user inactivity tracker for Room ID#{room_id}")
|
|
|
|
| 375 |
print("PASSED")
|
| 376 |
return True # a pass is still recorded in the database, but not sent to the client
|
| 377 |
|
| 378 |
+
#sub letters for names, so if the bot addressed A -> Apple
|
| 379 |
+
named_response = let_to_name(room_id, parsed_response)
|
| 380 |
#remove encapsulating quotes
|
| 381 |
+
no_quotes = remove_quotes(named_response)
|
| 382 |
#humanize the response (remove obvious AI formatting styles)
|
| 383 |
humanized_response = humanize(no_quotes)
|
| 384 |
#replace most semicolons
|
| 385 |
less_semicolons_response = replace_semicolons(humanized_response)
|
| 386 |
#corrupt the response (add some typos and misspellings)
|
| 387 |
+
corrupted_response = corrupt(less_semicolons_response, misspell_aug_p=0.01, typo_aug_p=0.005)
|
| 388 |
#remove weird chars
|
| 389 |
no_weird_chars = remove_weird_characters(corrupted_response)
|
| 390 |
+
#remove trailing punctuation % of the time
|
| 391 |
+
if random.random() < REMOVE_PUNC_RATE:
|
| 392 |
+
no_weird_chars = re.sub(r'[^\w\s]+$', '', no_weird_chars)
|
| 393 |
+
|
| 394 |
+
final_response = no_weird_chars
|
| 395 |
|
| 396 |
#check that there are no reccent duplicate messages
|
| 397 |
+
if len(final_response) > DUP_LEN and duplicate_check(final_response, context):
|
| 398 |
print("****DUPLICATE MESSAGE DETECTED")
|
| 399 |
print("Treating this bot's response as a pass.")
|
| 400 |
# Do not store/send messages if the chat has ended
|
|
|
|
| 404 |
# Store the error response in the database
|
| 405 |
bot_message = {
|
| 406 |
"sender": bot_display_name,
|
| 407 |
+
"message": f"DUPLICATE message detected - treated as a (pass) : {final_response}",
|
| 408 |
"timestamp": datetime.utcnow()
|
| 409 |
}
|
| 410 |
rooms_collection.update_one(
|
|
|
|
| 419 |
print(corrupted_response)
|
| 420 |
|
| 421 |
# Add latency/wait time for bot responses
|
| 422 |
+
delay = get_response_delay(final_response);
|
| 423 |
print(delay)
|
| 424 |
time.sleep(delay)
|
| 425 |
|
|
|
|
| 431 |
# Store the response in the database
|
| 432 |
bot_message = {
|
| 433 |
"sender": bot_display_name,
|
| 434 |
+
"message": final_response, #save fruits in db so page reload shows proper names
|
| 435 |
"timestamp": datetime.utcnow()
|
| 436 |
}
|
| 437 |
rooms_collection.update_one(
|
|
|
|
| 440 |
)
|
| 441 |
|
| 442 |
# Send the bot's response to the client
|
| 443 |
+
socketio.emit("message", {"sender": bot_display_name, "message": final_response}, to=room_id)
|
| 444 |
return False
|
| 445 |
|
| 446 |
def ask_bot_round(room_id):
|
|
|
|
| 499 |
session['user_id'] = user_id
|
| 500 |
return redirect(url_for('topics'))
|
| 501 |
else:
|
| 502 |
+
link = f"https://umw.qualtrics.com/jfe/form/SV_08v26NssCOwZTP8?PROLIFIC_PID={prolific_pid}"
|
| 503 |
+
return render_template('home.html',prolific_pid=prolific_pid, feedback_form_url=link)
|
| 504 |
|
| 505 |
@app.route('/topics', methods=["GET", "POST"])
|
| 506 |
def topics():
|
|
|
|
| 594 |
m for m in room_doc["messages"]
|
| 595 |
if len(re.findall(r"pass",m.get("message", "").strip())) == 0
|
| 596 |
]
|
| 597 |
+
if session.get('user_id'):
|
| 598 |
+
link = f"https://umw.qualtrics.com/jfe/form/SV_08v26NssCOwZTP8?PROLIFIC_PID={session.get('user_id')}"
|
| 599 |
+
return render_template("room.html", room=room_id, topic_info=topic_info, user=display_name,
|
| 600 |
+
messages=nonpass_messages, FroBot_name=room_doc["FroBot_name"],
|
| 601 |
+
HotBot_name=room_doc["HotBot_name"], CoolBot_name=room_doc["CoolBot_name"],
|
| 602 |
+
ended=room_doc["ended"], feedback_form_url=link)
|
| 603 |
+
else:
|
| 604 |
+
return render_template("room.html", room=room_id, topic_info=topic_info, user=display_name,
|
| 605 |
+
messages=nonpass_messages, FroBot_name=room_doc["FroBot_name"],
|
| 606 |
+
HotBot_name=room_doc["HotBot_name"], CoolBot_name=room_doc["CoolBot_name"],
|
| 607 |
+
ended=room_doc["ended"])
|
| 608 |
+
|
| 609 |
@app.route("/abort", methods=["POST"])
|
| 610 |
def abort_room():
|
| 611 |
room_id = session.get("room")
|
|
|
|
| 656 |
join_room(room)
|
| 657 |
if (room_doc.get("initialPostsSent", False)):
|
| 658 |
return
|
| 659 |
+
""" Removed and replaced with send_bot_joined() below
|
| 660 |
# Send the message that "watermelon" has already joined the chat
|
| 661 |
send({
|
| 662 |
"sender": "",
|
|
|
|
| 667 |
"sender": "",
|
| 668 |
"message": f"{name} has entered the chat"
|
| 669 |
}, to=room)
|
| 670 |
+
"""
|
| 671 |
# Start background tasks for the bots to join after a short delay
|
| 672 |
+
socketio.start_background_task(send_bot_names_message, room,
|
| 673 |
+
[room_doc['CoolBot_name'], room_doc['FroBot_name'],
|
| 674 |
+
room_doc['HotBot_name']])
|
| 675 |
+
""" Disabling "__Bot_Name_ has entered the chat" message for each bot.
|
| 676 |
+
Instead, displays a single message showing all the participants' names ^^
|
| 677 |
socketio.start_background_task(send_bot_joined, room, room_doc['CoolBot_name'], 3)
|
| 678 |
socketio.start_background_task(send_bot_joined, room, room_doc['FroBot_name'], 7)
|
| 679 |
socketio.start_background_task(send_bot_joined, room, room_doc['HotBot_name'], 13)
|
| 680 |
+
"""
|
| 681 |
# Start background task to send the initial watermelon post after a short delay
|
| 682 |
socketio.start_background_task(send_initial_post, room, 10)
|
| 683 |
# Start the background backup dataset task
|
chat_application/static/styles/styles.css
CHANGED
|
@@ -462,21 +462,21 @@ hr {
|
|
| 462 |
transition: 0.15s ease-in-out;
|
| 463 |
}
|
| 464 |
|
| 465 |
-
#abortYesBtn {
|
| 466 |
background: #d9534f;
|
| 467 |
color: white;
|
| 468 |
}
|
| 469 |
|
| 470 |
-
#abortYesBtn:hover {
|
| 471 |
background: #c9302c;
|
| 472 |
}
|
| 473 |
|
| 474 |
-
#abortNoBtn {
|
| 475 |
background: #e5e5e5;
|
| 476 |
color: #333;
|
| 477 |
}
|
| 478 |
|
| 479 |
-
#abortNoBtn:hover {
|
| 480 |
background: #ccc;
|
| 481 |
}
|
| 482 |
|
|
@@ -498,12 +498,12 @@ hr {
|
|
| 498 |
background: #ccc;
|
| 499 |
}
|
| 500 |
|
| 501 |
-
#welcomeOkBtn {
|
| 502 |
background: green;
|
| 503 |
color: white;
|
| 504 |
}
|
| 505 |
|
| 506 |
-
#welcomeOkBtn:hover {
|
| 507 |
background: #016601;
|
| 508 |
}
|
| 509 |
|
|
|
|
| 462 |
transition: 0.15s ease-in-out;
|
| 463 |
}
|
| 464 |
|
| 465 |
+
#abortYesBtn, #abortYesBtn-pre {
|
| 466 |
background: #d9534f;
|
| 467 |
color: white;
|
| 468 |
}
|
| 469 |
|
| 470 |
+
#abortYesBtn:hover, #abortYesBtn-pre:hover {
|
| 471 |
background: #c9302c;
|
| 472 |
}
|
| 473 |
|
| 474 |
+
#abortNoBtn, #abortNoBtn-pre {
|
| 475 |
background: #e5e5e5;
|
| 476 |
color: #333;
|
| 477 |
}
|
| 478 |
|
| 479 |
+
#abortNoBtn:hover, #abortNoBtn-pre:hover {
|
| 480 |
background: #ccc;
|
| 481 |
}
|
| 482 |
|
|
|
|
| 498 |
background: #ccc;
|
| 499 |
}
|
| 500 |
|
| 501 |
+
#welcomeOkBtn, #timerOkBtn {
|
| 502 |
background: green;
|
| 503 |
color: white;
|
| 504 |
}
|
| 505 |
|
| 506 |
+
#welcomeOkBtn:hover, #timerOkBtn:hover {
|
| 507 |
background: #016601;
|
| 508 |
}
|
| 509 |
|
chat_application/templates/base.html
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html lang="en">
|
| 3 |
<head>
|
| 4 |
-
<title>
|
| 5 |
<link rel="stylesheet" href="../static/styles/styles.css" />
|
| 6 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
|
| 7 |
</head>
|
|
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html lang="en">
|
| 3 |
<head>
|
| 4 |
+
<title>Chat Experiment</title>
|
| 5 |
<link rel="stylesheet" href="../static/styles/styles.css" />
|
| 6 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
|
| 7 |
</head>
|
chat_application/templates/home.html
CHANGED
|
@@ -11,6 +11,9 @@
|
|
| 11 |
<button type="button" id="continue">Continue</button>
|
| 12 |
</div>
|
| 13 |
<hr />
|
|
|
|
|
|
|
|
|
|
| 14 |
</form>
|
| 15 |
</div>
|
| 16 |
<div id="confirmID-modal" class="modal">
|
|
|
|
| 11 |
<button type="button" id="continue">Continue</button>
|
| 12 |
</div>
|
| 13 |
<hr />
|
| 14 |
+
<div class="feedback-notice">
|
| 15 |
+
<p>We encourage you to message us directly through Prolific about any concerns. Additionally, you may provide feedback regarding the experiment <a class="feedback-link" href="{{ feedback_form_url | default('https://umw.qualtrics.com/jfe/form/SV_08v26NssCOwZTP8') }}">in this form</a>.</p>
|
| 16 |
+
</div>
|
| 17 |
</form>
|
| 18 |
</div>
|
| 19 |
<div id="confirmID-modal" class="modal">
|
chat_application/templates/room.html
CHANGED
|
@@ -12,26 +12,33 @@
|
|
| 12 |
</div>
|
| 13 |
</div>
|
| 14 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
<h1 id="home-header">Chat Room</h1>
|
| 16 |
<div id="room-subsection">
|
| 17 |
<div class="topic-header-row">
|
| 18 |
<div class="topic-header-info">
|
| 19 |
-
|
| 20 |
-
</h2>
|
| 21 |
-
<div class="tooltip">
|
| 22 |
-
<button class="prompt-btn">Prompt</button>
|
| 23 |
-
<span class="tooltiptext">{{topic_info.text}}</span>
|
| 24 |
-
</div>
|
| 25 |
</div>
|
| 26 |
<div class="topic-header-buttons">
|
| 27 |
-
<button id="end-exp-btn">Chat Session
|
| 28 |
<button id="abort-exp-btn">Abort Experiment</button>
|
| 29 |
</div>
|
| 30 |
</div>
|
| 31 |
<div id="end-modal" class="modal">
|
| 32 |
<div class="modal-content">
|
| 33 |
-
|
| 34 |
-
|
|
|
|
| 35 |
<div class="modal-buttons">
|
| 36 |
<button class="modal-btn" id="endYesBtn">Continue</button>
|
| 37 |
<button class="modal-btn" id="endNoBtn">Cancel</button>
|
|
@@ -41,7 +48,19 @@
|
|
| 41 |
<div id="abort-modal" class="modal">
|
| 42 |
<div class="modal-content">
|
| 43 |
<h3>Are you sure you want to leave this experiment?</h3>
|
| 44 |
-
<p>This action is permanent. You will be redirected to the post-survey and will not be able to return to the chat room.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
<div class="modal-buttons">
|
| 46 |
<button class="modal-btn" id="abortYesBtn">Yes</button>
|
| 47 |
<button class="modal-btn" id="abortNoBtn">Cancel</button>
|
|
@@ -80,10 +99,16 @@
|
|
| 80 |
}
|
| 81 |
// Handler for the welcome modal
|
| 82 |
let welcomeModal = document.getElementById("welcome-modal");
|
|
|
|
| 83 |
const displayNameText = document.getElementById("displayNameText");
|
| 84 |
displayNameText.textContent = "{{ user }}";
|
| 85 |
// Show the modal instantly when the page loads
|
| 86 |
window.onload = function() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
welcomeModal.style.display = "block";
|
| 88 |
};
|
| 89 |
// Close the modal on OK
|
|
@@ -167,10 +192,15 @@
|
|
| 167 |
};
|
| 168 |
// Handler for the Abort Experiment confirmation pop-up
|
| 169 |
let modal = document.getElementById("abort-modal");
|
|
|
|
| 170 |
document.getElementById("abort-exp-btn").onclick = function () {
|
| 171 |
modal.style.display = "block";
|
| 172 |
};
|
| 173 |
-
document.getElementById("
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
modal.style.display = "none";
|
| 175 |
};
|
| 176 |
document.getElementById("abortYesBtn").onclick = function (e) {
|
|
@@ -180,7 +210,7 @@
|
|
| 180 |
fetch("/abort", { method: "POST" })
|
| 181 |
.then(() => {
|
| 182 |
window.open(endpoint, "_blank");
|
| 183 |
-
|
| 184 |
modal.style.display = "none";
|
| 185 |
textarea.disabled = true;
|
| 186 |
textarea.placeholder = "The chat has ended.";
|
|
@@ -188,9 +218,14 @@
|
|
| 188 |
document.getElementById("end-exp-btn").disabled = true;
|
| 189 |
document.getElementById("abort-exp-btn").disabled = true;
|
| 190 |
if (socketio) {
|
| 191 |
-
|
| 192 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
};
|
|
|
|
| 194 |
// add auto scroll
|
| 195 |
function isNearBottom(container, threshold = 120) {
|
| 196 |
const distanceFromBottom = container.scrollHeight - (container.scrollTop + container.clientHeight);
|
|
|
|
| 12 |
</div>
|
| 13 |
</div>
|
| 14 |
</div>
|
| 15 |
+
|
| 16 |
+
<div id="timer-modal" class="modal">
|
| 17 |
+
<div class="modal-content">
|
| 18 |
+
<h3>Start a Timer</h3>
|
| 19 |
+
<p><strong>Please start a timer for 20 minutes</strong>. At the 20 minute mark, you may click the button "End Chat Session" to continue with the study.</p>
|
| 20 |
+
<div class="modal-buttons">
|
| 21 |
+
<button class="modal-btn" id="timerOkBtn">I have set a timer for 20 minutes.</button>
|
| 22 |
+
</div>
|
| 23 |
+
</div>
|
| 24 |
+
</div>
|
| 25 |
+
|
| 26 |
<h1 id="home-header">Chat Room</h1>
|
| 27 |
<div id="room-subsection">
|
| 28 |
<div class="topic-header-row">
|
| 29 |
<div class="topic-header-info">
|
| 30 |
+
<h2 id="room-code-display">Topic: <span class="topic-title">{{ topic_info.title }}</span></h2>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
</div>
|
| 32 |
<div class="topic-header-buttons">
|
| 33 |
+
<button id="end-exp-btn">End Chat Session</button>
|
| 34 |
<button id="abort-exp-btn">Abort Experiment</button>
|
| 35 |
</div>
|
| 36 |
</div>
|
| 37 |
<div id="end-modal" class="modal">
|
| 38 |
<div class="modal-content">
|
| 39 |
+
<h3>Only Exit This Way After 20 Minutes of Participation in the Chatroom.</h3>
|
| 40 |
+
<p>This signals the end of the chat session of the experiment. You will be redirected to the post-survey.</p>
|
| 41 |
+
<p>This button is only to be used at the end of your 20 minutes of participation in the chatroom. <strong>If you wish to exit the chat before finishing your 20 minutes, use the "Abort Experiment" button instead.</strong></p>
|
| 42 |
<div class="modal-buttons">
|
| 43 |
<button class="modal-btn" id="endYesBtn">Continue</button>
|
| 44 |
<button class="modal-btn" id="endNoBtn">Cancel</button>
|
|
|
|
| 48 |
<div id="abort-modal" class="modal">
|
| 49 |
<div class="modal-content">
|
| 50 |
<h3>Are you sure you want to leave this experiment?</h3>
|
| 51 |
+
<p>This action is permanent. You will be redirected to the post-survey and will not be able to return to the chat room.</p>
|
| 52 |
+
<p><strong>If you finished your 20 minutes in the chatroom, do NOT exit via this button. Use the "End Chat Session" button instead.</strong></p>
|
| 53 |
+
<div class="modal-buttons">
|
| 54 |
+
<button class="modal-btn" id="abortYesBtn-pre">Yes</button>
|
| 55 |
+
<button class="modal-btn" id="abortNoBtn-pre">Cancel</button>
|
| 56 |
+
</div>
|
| 57 |
+
</div>
|
| 58 |
+
</div>
|
| 59 |
+
<div id="abort-modal-confirm" class="modal">
|
| 60 |
+
<div class="modal-content">
|
| 61 |
+
<h3>Confirmation</h3>
|
| 62 |
+
<p>By clicking yes, you will exit the experiment <strong>without</strong> completing the final survey.</p>
|
| 63 |
+
<p>We encourage you to message us about any concerns or to <a href="{{ feedback_form_url | default('https://umw.qualtrics.com/jfe/form/SV_08v26NssCOwZTP8') }}" target="_blank">provide feedback here</a>.</p>
|
| 64 |
<div class="modal-buttons">
|
| 65 |
<button class="modal-btn" id="abortYesBtn">Yes</button>
|
| 66 |
<button class="modal-btn" id="abortNoBtn">Cancel</button>
|
|
|
|
| 99 |
}
|
| 100 |
// Handler for the welcome modal
|
| 101 |
let welcomeModal = document.getElementById("welcome-modal");
|
| 102 |
+
let timerModal = document.getElementById("timer-modal");
|
| 103 |
const displayNameText = document.getElementById("displayNameText");
|
| 104 |
displayNameText.textContent = "{{ user }}";
|
| 105 |
// Show the modal instantly when the page loads
|
| 106 |
window.onload = function() {
|
| 107 |
+
timerModal.style.display = "block";
|
| 108 |
+
};
|
| 109 |
+
//timer pop-up
|
| 110 |
+
document.getElementById("timerOkBtn").onclick = function () {
|
| 111 |
+
timerModal.style.display = "none";
|
| 112 |
welcomeModal.style.display = "block";
|
| 113 |
};
|
| 114 |
// Close the modal on OK
|
|
|
|
| 192 |
};
|
| 193 |
// Handler for the Abort Experiment confirmation pop-up
|
| 194 |
let modal = document.getElementById("abort-modal");
|
| 195 |
+
let abortModalConfirm = document.getElementById("abort-modal-confirm");
|
| 196 |
document.getElementById("abort-exp-btn").onclick = function () {
|
| 197 |
modal.style.display = "block";
|
| 198 |
};
|
| 199 |
+
document.getElementById("abortYesBtn-pre").onclick = function () {
|
| 200 |
+
abortModalConfirm.style.display = "block";
|
| 201 |
+
modal.style.display = "none";
|
| 202 |
+
};
|
| 203 |
+
document.getElementById("abortNoBtn-pre").onclick = function () {
|
| 204 |
modal.style.display = "none";
|
| 205 |
};
|
| 206 |
document.getElementById("abortYesBtn").onclick = function (e) {
|
|
|
|
| 210 |
fetch("/abort", { method: "POST" })
|
| 211 |
.then(() => {
|
| 212 |
window.open(endpoint, "_blank");
|
| 213 |
+
});
|
| 214 |
modal.style.display = "none";
|
| 215 |
textarea.disabled = true;
|
| 216 |
textarea.placeholder = "The chat has ended.";
|
|
|
|
| 218 |
document.getElementById("end-exp-btn").disabled = true;
|
| 219 |
document.getElementById("abort-exp-btn").disabled = true;
|
| 220 |
if (socketio) {
|
| 221 |
+
socketio.close();
|
| 222 |
}
|
| 223 |
+
abortModalConfirm.style.display = "none";
|
| 224 |
+
};
|
| 225 |
+
document.getElementById("abortNoBtn").onclick = function () {
|
| 226 |
+
abortModalConfirm.style.display = "none";
|
| 227 |
};
|
| 228 |
+
|
| 229 |
// add auto scroll
|
| 230 |
function isNearBottom(container, threshold = 120) {
|
| 231 |
const distanceFromBottom = container.scrollHeight - (container.scrollTop + container.clientHeight);
|
data/inference_instructions/coolbot_instructions_main.txt
CHANGED
|
@@ -1,6 +1,16 @@
|
|
| 1 |
ROLE
|
| 2 |
You are a participant in a multi-way chat about current political topics. You speak as an adult from the United States of America.
|
| 3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
INPUT FORMAT
|
| 5 |
You will receive chat transcripts in this structure:
|
| 6 |
|
|
@@ -63,8 +73,10 @@ NATURAL CHAT BEHAVIOR
|
|
| 63 |
pedantically. For example, say "most people approve of X" rather than citing
|
| 64 |
exact percentages or specific studies, and paraphrase public statements
|
| 65 |
instead of quoting them verbatim. These elements are not required.
|
|
|
|
| 66 |
- Do not sound overly neutral, robotic, or overly polite.
|
| 67 |
- Do not restate the entire argument or summarize the conversation.
|
| 68 |
- Focus on one main point per message, as real participants typically do.
|
|
|
|
| 69 |
- Match the writing style of the other participants.
|
| 70 |
- Do not include emojis, hashtags, bullet points, or structured formatting.
|
|
|
|
| 1 |
ROLE
|
| 2 |
You are a participant in a multi-way chat about current political topics. You speak as an adult from the United States of America.
|
| 3 |
|
| 4 |
+
CURRENT CONTEXT
|
| 5 |
+
The current year is 2026, and Donald Trump, a Republican, is the president of the United States.
|
| 6 |
+
Republicans hold the majority of seats in both the House of Representatives and the Senate.
|
| 7 |
+
Some currently prominent issues and themes in U.S. politics include:
|
| 8 |
+
- Stricter immigration enforcement policies and growing debates over the role and actions of ICE.
|
| 9 |
+
- Concerns over inflation and the increasing cost of living, which have resulted in increased discussions around affordability.
|
| 10 |
+
- Debates over foreign policy and U.S. military intervention.
|
| 11 |
+
- Gridlock and perceived inefficiency in the federal government, as evidenced by a government shutdown.
|
| 12 |
+
- An increase in public protests and political activism.
|
| 13 |
+
|
| 14 |
INPUT FORMAT
|
| 15 |
You will receive chat transcripts in this structure:
|
| 16 |
|
|
|
|
| 73 |
pedantically. For example, say "most people approve of X" rather than citing
|
| 74 |
exact percentages or specific studies, and paraphrase public statements
|
| 75 |
instead of quoting them verbatim. These elements are not required.
|
| 76 |
+
- Do not include any URLs in your responses.
|
| 77 |
- Do not sound overly neutral, robotic, or overly polite.
|
| 78 |
- Do not restate the entire argument or summarize the conversation.
|
| 79 |
- Focus on one main point per message, as real participants typically do.
|
| 80 |
+
- Do not send a response that is identical or nearly identical to a response that you have already sent.
|
| 81 |
- Match the writing style of the other participants.
|
| 82 |
- Do not include emojis, hashtags, bullet points, or structured formatting.
|
data/inference_instructions/frobot_instructions_main.txt
CHANGED
|
@@ -1,6 +1,16 @@
|
|
| 1 |
ROLE
|
| 2 |
You are a participant in a multi-way chat about current political topics. You speak as an adult from the United States of America.
|
| 3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
INPUT FORMAT
|
| 5 |
You will receive chat transcripts in this structure:
|
| 6 |
|
|
@@ -58,6 +68,9 @@ Also follow these presentation rules:
|
|
| 58 |
|
| 59 |
- Maintain the persona of an American adult.
|
| 60 |
- Respond in a calm and understanding manner, counteracting the unproductive message you detected.
|
|
|
|
|
|
|
|
|
|
| 61 |
- Optionally address previous participants (e.g., "Hey, watch it, A! The word 'bum' is very insulting.").
|
| 62 |
- Keep your tone natural and conversational; do not sound formal or like a textbook.
|
| 63 |
- Reference recent real-world events if relevant (e.g., "Yeah, President Trump has been trying to deport immigrants for this very reason.").
|
|
@@ -83,8 +96,10 @@ NATURAL CHAT BEHAVIOR
|
|
| 83 |
pedantically. For example, say "most people approve of X" rather than citing
|
| 84 |
exact percentages or specific studies, and paraphrase public statements
|
| 85 |
instead of quoting them verbatim. These elements are not required.
|
|
|
|
| 86 |
- Do not sound overly neutral, robotic, or overly polite.
|
| 87 |
- Do not restate the entire argument or summarize the conversation.
|
| 88 |
- Focus on one main point per message, as real participants typically do.
|
|
|
|
| 89 |
- Match the writing style of the other participants.
|
| 90 |
- Do not include emojis, hashtags, bullet points, or structured formatting.
|
|
|
|
| 1 |
ROLE
|
| 2 |
You are a participant in a multi-way chat about current political topics. You speak as an adult from the United States of America.
|
| 3 |
|
| 4 |
+
CURRENT CONTEXT
|
| 5 |
+
The current year is 2026, and Donald Trump, a Republican, is the president of the United States.
|
| 6 |
+
Republicans hold the majority of seats in both the House of Representatives and the Senate.
|
| 7 |
+
Some currently prominent issues and themes in U.S. politics include:
|
| 8 |
+
- Stricter immigration enforcement policies and growing debates over the role and actions of ICE.
|
| 9 |
+
- Concerns over inflation and the increasing cost of living, which have resulted in increased discussions around affordability.
|
| 10 |
+
- Debates over foreign policy and U.S. military intervention.
|
| 11 |
+
- Gridlock and perceived inefficiency in the federal government, as evidenced by a government shutdown.
|
| 12 |
+
- An increase in public protests and political activism.
|
| 13 |
+
|
| 14 |
INPUT FORMAT
|
| 15 |
You will receive chat transcripts in this structure:
|
| 16 |
|
|
|
|
| 68 |
|
| 69 |
- Maintain the persona of an American adult.
|
| 70 |
- Respond in a calm and understanding manner, counteracting the unproductive message you detected.
|
| 71 |
+
- Address only one unproductive message or behavior per response.
|
| 72 |
+
- Only call out an unproductive message if it was sent after your last response.
|
| 73 |
+
- Do not address the same unproductive message more than one time.
|
| 74 |
- Optionally address previous participants (e.g., "Hey, watch it, A! The word 'bum' is very insulting.").
|
| 75 |
- Keep your tone natural and conversational; do not sound formal or like a textbook.
|
| 76 |
- Reference recent real-world events if relevant (e.g., "Yeah, President Trump has been trying to deport immigrants for this very reason.").
|
|
|
|
| 96 |
pedantically. For example, say "most people approve of X" rather than citing
|
| 97 |
exact percentages or specific studies, and paraphrase public statements
|
| 98 |
instead of quoting them verbatim. These elements are not required.
|
| 99 |
+
- Do not include any URLs in your responses.
|
| 100 |
- Do not sound overly neutral, robotic, or overly polite.
|
| 101 |
- Do not restate the entire argument or summarize the conversation.
|
| 102 |
- Focus on one main point per message, as real participants typically do.
|
| 103 |
+
- Do not send a response that is identical or nearly identical to a response that you have already sent.
|
| 104 |
- Match the writing style of the other participants.
|
| 105 |
- Do not include emojis, hashtags, bullet points, or structured formatting.
|
data/inference_instructions/hotbot_instructions_main.txt
CHANGED
|
@@ -1,6 +1,16 @@
|
|
| 1 |
ROLE
|
| 2 |
You are a participant in a multi-way chat about current political topics. You speak as an adult from the United States of America.
|
| 3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
INPUT FORMAT
|
| 5 |
You will receive chat transcripts in this structure:
|
| 6 |
|
|
@@ -66,8 +76,10 @@ NATURAL CHAT BEHAVIOR
|
|
| 66 |
pedantically. For example, say "most people approve of X" rather than citing
|
| 67 |
exact percentages or specific studies, and paraphrase public statements
|
| 68 |
instead of quoting them verbatim. These elements are not required.
|
|
|
|
| 69 |
- Do not sound overly neutral, robotic, or overly polite.
|
| 70 |
- Do not restate the entire argument or summarize the conversation.
|
| 71 |
- Focus on one main point per message, as real participants typically do.
|
|
|
|
| 72 |
- Do not include emojis, hashtags, bullet points, or structured formatting.
|
| 73 |
- Match the writing style of the other participants.
|
|
|
|
| 1 |
ROLE
|
| 2 |
You are a participant in a multi-way chat about current political topics. You speak as an adult from the United States of America.
|
| 3 |
|
| 4 |
+
CURRENT CONTEXT
|
| 5 |
+
The current year is 2026, and Donald Trump, a Republican, is the president of the United States.
|
| 6 |
+
Republicans hold the majority of seats in both the House of Representatives and the Senate.
|
| 7 |
+
Some currently prominent issues and themes in U.S. politics include:
|
| 8 |
+
- Stricter immigration enforcement policies and growing debates over the role and actions of ICE.
|
| 9 |
+
- Concerns over inflation and the increasing cost of living, which have resulted in increased discussions around affordability.
|
| 10 |
+
- Debates over foreign policy and U.S. military intervention.
|
| 11 |
+
- Gridlock and perceived inefficiency in the federal government, as evidenced by a government shutdown.
|
| 12 |
+
- An increase in public protests and political activism.
|
| 13 |
+
|
| 14 |
INPUT FORMAT
|
| 15 |
You will receive chat transcripts in this structure:
|
| 16 |
|
|
|
|
| 76 |
pedantically. For example, say "most people approve of X" rather than citing
|
| 77 |
exact percentages or specific studies, and paraphrase public statements
|
| 78 |
instead of quoting them verbatim. These elements are not required.
|
| 79 |
+
- Do not include any URLs in your responses.
|
| 80 |
- Do not sound overly neutral, robotic, or overly polite.
|
| 81 |
- Do not restate the entire argument or summarize the conversation.
|
| 82 |
- Focus on one main point per message, as real participants typically do.
|
| 83 |
+
- Do not send a response that is identical or nearly identical to a response that you have already sent.
|
| 84 |
- Do not include emojis, hashtags, bullet points, or structured formatting.
|
| 85 |
- Match the writing style of the other participants.
|