Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Removing "_ has entered the chat" test
#1
by riderle - opened
- README.md +1 -1
- chat_application/main.py +17 -147
- chat_application/static/styles/styles.css +8 -41
- chat_application/templates/base.html +1 -1
- chat_application/templates/room.html +14 -111
- data/inference_instructions/coolbot_instructions_main.txt +0 -12
- data/inference_instructions/frobot_instructions_main.txt +0 -15
- data/inference_instructions/hotbot_instructions_main.txt +0 -12
README.md
CHANGED
|
@@ -6,6 +6,6 @@ colorTo: blue
|
|
| 6 |
sdk: docker
|
| 7 |
pinned: false
|
| 8 |
license: mit
|
| 9 |
-
short_description: A space for hosting our experiment website
|
| 10 |
---
|
| 11 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 6 |
sdk: docker
|
| 7 |
pinned: false
|
| 8 |
license: mit
|
| 9 |
+
short_description: A space for hosting our experiment website
|
| 10 |
---
|
| 11 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
chat_application/main.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
| 1 |
-
from google.api_core import exceptions
|
| 2 |
from flask import Flask, request, render_template, redirect, url_for, session, make_response, render_template_string
|
| 3 |
from flask_socketio import SocketIO, join_room, leave_room, send
|
| 4 |
from pymongo import MongoClient
|
|
@@ -29,17 +28,14 @@ from duplicate_detection import duplicate_check
|
|
| 29 |
from huggingface_hub import upload_folder
|
| 30 |
from huggingface_hub import HfApi
|
| 31 |
from huggingface_hub import login
|
| 32 |
-
|
| 33 |
-
|
| 34 |
|
| 35 |
class datasetHandler():
|
| 36 |
|
| 37 |
-
def __init__(self,hf_token,mongoDB_name
|
| 38 |
login(hf_token)
|
| 39 |
self.api = HfApi(token = hf_token)
|
| 40 |
self.DB_name = mongoDB_name
|
| 41 |
-
self.timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
| 42 |
-
self.max_dumps = max_dumps
|
| 43 |
|
| 44 |
def make_dump(self):
|
| 45 |
try:
|
|
@@ -51,47 +47,21 @@ class datasetHandler():
|
|
| 51 |
|
| 52 |
def upload_dump(self):
|
| 53 |
try:
|
| 54 |
-
upload_folder(folder_path="/tmp/mongoDBContents",path_in_repo=
|
| 55 |
return 0
|
| 56 |
except Exception as e:
|
| 57 |
print(e)
|
| 58 |
return 1
|
| 59 |
|
| 60 |
-
def list_dumps(self):
|
| 61 |
-
all_files = self.api.list_repo_files(repo_id="ProjectFrozone/MongoDBDumps", repo_type="dataset")
|
| 62 |
-
all_dirs = [f[:f.index("/")] for f in all_files if "mongoDump_" in f]
|
| 63 |
-
dates = [date[date.index("_") + 1:] for date in all_dirs]
|
| 64 |
-
return (all_dirs, dates)
|
| 65 |
-
|
| 66 |
-
def delete_dump(self,dump_name):
|
| 67 |
-
self.api.delete_folder(
|
| 68 |
-
repo_id="ProjectFrozone/MongoDBDumps",
|
| 69 |
-
path_in_repo=f"{dump_name}",
|
| 70 |
-
repo_type="dataset",
|
| 71 |
-
commit_message=f"Deleted {dump_name}"
|
| 72 |
-
)
|
| 73 |
-
|
| 74 |
-
def cleanup_dataset(self,dirs,dates):
|
| 75 |
-
if len(dates) > self.max_dumps:
|
| 76 |
-
to_remove = dirs[0]
|
| 77 |
-
self.delete_dump(to_remove)
|
| 78 |
-
return f"Deleted {to_remove}"
|
| 79 |
-
return "Nothing to delete"
|
| 80 |
-
|
| 81 |
def dump_db(self):
|
| 82 |
self.make_dump()
|
| 83 |
self.upload_dump()
|
| 84 |
-
|
| 85 |
-
def clean(self):
|
| 86 |
-
dirs,dates = self.list_dumps()
|
| 87 |
-
print(self.cleanup_dataset(dirs,dates))
|
| 88 |
-
# End database backup code
|
| 89 |
|
| 90 |
#controls
|
| 91 |
CHAT_CONTEXT = 20 #how many messages from chat history to append to inference prompt
|
| 92 |
#minimum number of chars where we start checking for duplicate messages
|
| 93 |
DUP_LEN = 25 #since short messages may reasonably be the same
|
| 94 |
-
REMOVE_PUNC_RATE = .8 #how often to remove final punctuation
|
| 95 |
|
| 96 |
# Directory alignment
|
| 97 |
BASE_DIR = Path(__file__).resolve().parent
|
|
@@ -143,7 +113,6 @@ frobot = "projects/700531062565/locations/us-central1/endpoints/2951406418055397
|
|
| 143 |
client = MongoClient("mongodb://127.0.0.1:27017/")
|
| 144 |
db = client["huggingFaceData"]
|
| 145 |
rooms_collection = db.rooms
|
| 146 |
-
feedback_collection = db.feedback
|
| 147 |
|
| 148 |
# List of fruits to choose display names from
|
| 149 |
FRUIT_NAMES = ["blueberry", "strawberry", "orange", "cherry"]
|
|
@@ -302,12 +271,6 @@ def replace_semicolons(text, probability=0.80):
|
|
| 302 |
modified_text.append(char)
|
| 303 |
return ''.join(modified_text)
|
| 304 |
|
| 305 |
-
def get_last_paragraph(text):
|
| 306 |
-
text = text.strip()
|
| 307 |
-
if "\n" not in text:
|
| 308 |
-
return text
|
| 309 |
-
return text.rsplit("\n", 1)[-1].strip()
|
| 310 |
-
|
| 311 |
def get_response_delay(response):
|
| 312 |
baseDelay = 5 # standard delay for thinking
|
| 313 |
randFactor = np.random.uniform(0,30, len(response) // 4)
|
|
@@ -321,7 +284,7 @@ def get_response_delay(response):
|
|
| 321 |
|
| 322 |
# Ask a bot for its response, store in DB, and send to client
|
| 323 |
# Returns true if the bot passed
|
| 324 |
-
def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt
|
| 325 |
# Prevents crashing if bot model did not load
|
| 326 |
if bot is None:
|
| 327 |
return False
|
|
@@ -354,35 +317,6 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt , wa
|
|
| 354 |
),
|
| 355 |
)
|
| 356 |
parsed_response = response.candidates[0].content.parts[0].text.strip()
|
| 357 |
-
|
| 358 |
-
# Deal with rate limit issues
|
| 359 |
-
except exceptions.TooManyRequests:
|
| 360 |
-
print(f"429 Rate Limit Exceeded")
|
| 361 |
-
socketio.sleep(wait_time)
|
| 362 |
-
wait_time *= 2
|
| 363 |
-
|
| 364 |
-
# Prevent Stack Overflow
|
| 365 |
-
if wait_time > 32:
|
| 366 |
-
print("Rate Limit Exceeded and Exponential Backoff Too Long")
|
| 367 |
-
print("Treating this bot's response as a pass.")
|
| 368 |
-
room_doc = rooms_collection.find_one({"_id": room_id})
|
| 369 |
-
if not room_doc or room_doc.get("ended", False):
|
| 370 |
-
return False
|
| 371 |
-
# Store the error response in the database
|
| 372 |
-
bot_message = {
|
| 373 |
-
"sender": bot_display_name,
|
| 374 |
-
"message": "ERROR in bot response - treated as a (pass)",
|
| 375 |
-
"timestamp": datetime.utcnow()
|
| 376 |
-
}
|
| 377 |
-
rooms_collection.update_one(
|
| 378 |
-
{"_id": room_id},
|
| 379 |
-
{"$push": {"messages": bot_message}}
|
| 380 |
-
)
|
| 381 |
-
return True
|
| 382 |
-
|
| 383 |
-
return ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt , wait_time = wait_time)
|
| 384 |
-
|
| 385 |
-
|
| 386 |
except Exception as e:
|
| 387 |
print("Error in bot response: ", e)
|
| 388 |
print("Treating this bot's response as a pass.")
|
|
@@ -413,14 +347,6 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt , wa
|
|
| 413 |
parsed_response = re.sub(r"\b"
|
| 414 |
+ aliases[bot_display_name]
|
| 415 |
+ r"\b:\s?", '', parsed_response)
|
| 416 |
-
|
| 417 |
-
# Only keep the last paragraph of frobot responses
|
| 418 |
-
if bot == frobot:
|
| 419 |
-
print("=========== OG FROBOT RESPONSE")
|
| 420 |
-
print(parsed_response)
|
| 421 |
-
parsed_response = get_last_paragraph(parsed_response)
|
| 422 |
-
print("=========== LAST PARAGRAPH")
|
| 423 |
-
print(parsed_response)
|
| 424 |
|
| 425 |
# Check for if the bot passed (i.e. response = "(pass)")
|
| 426 |
if ("(pass)" in parsed_response) or (parsed_response == ""):
|
|
@@ -442,26 +368,21 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt , wa
|
|
| 442 |
print("PASSED")
|
| 443 |
return True # a pass is still recorded in the database, but not sent to the client
|
| 444 |
|
| 445 |
-
#sub letters for names, so if the bot addressed A -> Apple
|
| 446 |
-
named_response = let_to_name(room_id, parsed_response)
|
| 447 |
#remove encapsulating quotes
|
| 448 |
-
no_quotes = remove_quotes(
|
| 449 |
#humanize the response (remove obvious AI formatting styles)
|
| 450 |
humanized_response = humanize(no_quotes)
|
| 451 |
#replace most semicolons
|
| 452 |
less_semicolons_response = replace_semicolons(humanized_response)
|
| 453 |
#corrupt the response (add some typos and misspellings)
|
| 454 |
-
corrupted_response = corrupt(less_semicolons_response
|
| 455 |
#remove weird chars
|
| 456 |
no_weird_chars = remove_weird_characters(corrupted_response)
|
| 457 |
-
#
|
| 458 |
-
|
| 459 |
-
no_weird_chars = re.sub(r'[^\w\s]+$', '', no_weird_chars)
|
| 460 |
-
|
| 461 |
-
final_response = no_weird_chars
|
| 462 |
|
| 463 |
#check that there are no reccent duplicate messages
|
| 464 |
-
if len(
|
| 465 |
print("****DUPLICATE MESSAGE DETECTED")
|
| 466 |
print("Treating this bot's response as a pass.")
|
| 467 |
# Do not store/send messages if the chat has ended
|
|
@@ -471,7 +392,7 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt , wa
|
|
| 471 |
# Store the error response in the database
|
| 472 |
bot_message = {
|
| 473 |
"sender": bot_display_name,
|
| 474 |
-
"message": f"DUPLICATE message detected - treated as a (pass) : {
|
| 475 |
"timestamp": datetime.utcnow()
|
| 476 |
}
|
| 477 |
rooms_collection.update_one(
|
|
@@ -486,7 +407,7 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt , wa
|
|
| 486 |
print(corrupted_response)
|
| 487 |
|
| 488 |
# Add latency/wait time for bot responses
|
| 489 |
-
delay = get_response_delay(
|
| 490 |
print(delay)
|
| 491 |
time.sleep(delay)
|
| 492 |
|
|
@@ -498,7 +419,7 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt , wa
|
|
| 498 |
# Store the response in the database
|
| 499 |
bot_message = {
|
| 500 |
"sender": bot_display_name,
|
| 501 |
-
"message":
|
| 502 |
"timestamp": datetime.utcnow()
|
| 503 |
}
|
| 504 |
rooms_collection.update_one(
|
|
@@ -507,7 +428,7 @@ def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt , wa
|
|
| 507 |
)
|
| 508 |
|
| 509 |
# Send the bot's response to the client
|
| 510 |
-
socketio.emit("message", {"sender": bot_display_name, "message":
|
| 511 |
return False
|
| 512 |
|
| 513 |
def ask_bot_round(room_id):
|
|
@@ -539,7 +460,6 @@ def backup_mongo(time):
|
|
| 539 |
token = os.getenv("HF_TOKEN")
|
| 540 |
handler = datasetHandler(token , 'huggingFaceData')
|
| 541 |
handler.dump_db()
|
| 542 |
-
handler.clean()
|
| 543 |
socketio.sleep(time)
|
| 544 |
|
| 545 |
# Build the routes
|
|
@@ -567,8 +487,7 @@ def home():
|
|
| 567 |
session['user_id'] = user_id
|
| 568 |
return redirect(url_for('topics'))
|
| 569 |
else:
|
| 570 |
-
|
| 571 |
-
return render_template('home.html',prolific_pid=prolific_pid, feedback_form_url=link)
|
| 572 |
|
| 573 |
@app.route('/topics', methods=["GET", "POST"])
|
| 574 |
def topics():
|
|
@@ -640,14 +559,6 @@ def choose():
|
|
| 640 |
"ended": False,
|
| 641 |
"ended_at": None
|
| 642 |
})
|
| 643 |
-
# Create the new feedback in the database
|
| 644 |
-
feedback_collection.insert_one({
|
| 645 |
-
"_id": room_id,
|
| 646 |
-
# creation date/time
|
| 647 |
-
"created_at": datetime.utcnow(),
|
| 648 |
-
# user identity
|
| 649 |
-
"user_id": user_id,
|
| 650 |
-
})
|
| 651 |
|
| 652 |
session['room'] = room_id
|
| 653 |
session['display_name'] = user_name
|
|
@@ -670,18 +581,8 @@ def room():
|
|
| 670 |
m for m in room_doc["messages"]
|
| 671 |
if len(re.findall(r"pass",m.get("message", "").strip())) == 0
|
| 672 |
]
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
return render_template("room.html", room=room_id, topic_info=topic_info, user=display_name,
|
| 676 |
-
messages=nonpass_messages, FroBot_name=room_doc["FroBot_name"],
|
| 677 |
-
HotBot_name=room_doc["HotBot_name"], CoolBot_name=room_doc["CoolBot_name"],
|
| 678 |
-
ended=room_doc["ended"], feedback_form_url=link)
|
| 679 |
-
else:
|
| 680 |
-
return render_template("room.html", room=room_id, topic_info=topic_info, user=display_name,
|
| 681 |
-
messages=nonpass_messages, FroBot_name=room_doc["FroBot_name"],
|
| 682 |
-
HotBot_name=room_doc["HotBot_name"], CoolBot_name=room_doc["CoolBot_name"],
|
| 683 |
-
ended=room_doc["ended"])
|
| 684 |
-
|
| 685 |
@app.route("/abort", methods=["POST"])
|
| 686 |
def abort_room():
|
| 687 |
room_id = session.get("room")
|
|
@@ -816,37 +717,6 @@ def handle_message(payload):
|
|
| 816 |
# Ask each bot for a response
|
| 817 |
socketio.start_background_task(ask_bot_round, room)
|
| 818 |
|
| 819 |
-
|
| 820 |
-
@socketio.on('feedback_given')
|
| 821 |
-
def handle_message(payload):
|
| 822 |
-
room = session.get('room')
|
| 823 |
-
name = session.get('display_name')
|
| 824 |
-
if not room or not name:
|
| 825 |
-
return
|
| 826 |
-
|
| 827 |
-
text = payload.get("feedback", "").strip()
|
| 828 |
-
if not text:
|
| 829 |
-
return # ignore empty text
|
| 830 |
-
|
| 831 |
-
# Database-only message (with datetime)
|
| 832 |
-
db_feedback = {
|
| 833 |
-
"message": text,
|
| 834 |
-
"timestamp": datetime.utcnow()
|
| 835 |
-
}
|
| 836 |
-
|
| 837 |
-
print(db_feedback)
|
| 838 |
-
# Store the full version in the database
|
| 839 |
-
result = feedback_collection.update_one(
|
| 840 |
-
{"_id": room},
|
| 841 |
-
{"$push": {"feedback_responses": db_feedback}}
|
| 842 |
-
)
|
| 843 |
-
|
| 844 |
-
if result:
|
| 845 |
-
print(result)
|
| 846 |
-
if result.modified_count > 0:
|
| 847 |
-
return {'status':'True'}
|
| 848 |
-
return {'ststus':'False'}
|
| 849 |
-
|
| 850 |
@socketio.on('disconnect')
|
| 851 |
def handle_disconnect():
|
| 852 |
room = session.get("room")
|
|
|
|
|
|
|
| 1 |
from flask import Flask, request, render_template, redirect, url_for, session, make_response, render_template_string
|
| 2 |
from flask_socketio import SocketIO, join_room, leave_room, send
|
| 3 |
from pymongo import MongoClient
|
|
|
|
| 28 |
from huggingface_hub import upload_folder
|
| 29 |
from huggingface_hub import HfApi
|
| 30 |
from huggingface_hub import login
|
| 31 |
+
import os
|
|
|
|
| 32 |
|
| 33 |
class datasetHandler():
|
| 34 |
|
| 35 |
+
def __init__(self,hf_token,mongoDB_name):
|
| 36 |
login(hf_token)
|
| 37 |
self.api = HfApi(token = hf_token)
|
| 38 |
self.DB_name = mongoDB_name
|
|
|
|
|
|
|
| 39 |
|
| 40 |
def make_dump(self):
|
| 41 |
try:
|
|
|
|
| 47 |
|
| 48 |
def upload_dump(self):
|
| 49 |
try:
|
| 50 |
+
upload_folder(folder_path="/tmp/mongoDBContents",path_in_repo="mongoDump", repo_id="ProjectFrozone/MongoDBDumps", repo_type="dataset")
|
| 51 |
return 0
|
| 52 |
except Exception as e:
|
| 53 |
print(e)
|
| 54 |
return 1
|
| 55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
def dump_db(self):
|
| 57 |
self.make_dump()
|
| 58 |
self.upload_dump()
|
| 59 |
+
# End backup code
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
|
| 61 |
#controls
|
| 62 |
CHAT_CONTEXT = 20 #how many messages from chat history to append to inference prompt
|
| 63 |
#minimum number of chars where we start checking for duplicate messages
|
| 64 |
DUP_LEN = 25 #since short messages may reasonably be the same
|
|
|
|
| 65 |
|
| 66 |
# Directory alignment
|
| 67 |
BASE_DIR = Path(__file__).resolve().parent
|
|
|
|
| 113 |
client = MongoClient("mongodb://127.0.0.1:27017/")
|
| 114 |
db = client["huggingFaceData"]
|
| 115 |
rooms_collection = db.rooms
|
|
|
|
| 116 |
|
| 117 |
# List of fruits to choose display names from
|
| 118 |
FRUIT_NAMES = ["blueberry", "strawberry", "orange", "cherry"]
|
|
|
|
| 271 |
modified_text.append(char)
|
| 272 |
return ''.join(modified_text)
|
| 273 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 274 |
def get_response_delay(response):
|
| 275 |
baseDelay = 5 # standard delay for thinking
|
| 276 |
randFactor = np.random.uniform(0,30, len(response) // 4)
|
|
|
|
| 284 |
|
| 285 |
# Ask a bot for its response, store in DB, and send to client
|
| 286 |
# Returns true if the bot passed
|
| 287 |
+
def ask_bot(room_id, bot, bot_display_name, initial_prompt, instruct_prompt):
|
| 288 |
# Prevents crashing if bot model did not load
|
| 289 |
if bot is None:
|
| 290 |
return False
|
|
|
|
| 317 |
),
|
| 318 |
)
|
| 319 |
parsed_response = response.candidates[0].content.parts[0].text.strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 320 |
except Exception as e:
|
| 321 |
print("Error in bot response: ", e)
|
| 322 |
print("Treating this bot's response as a pass.")
|
|
|
|
| 347 |
parsed_response = re.sub(r"\b"
|
| 348 |
+ aliases[bot_display_name]
|
| 349 |
+ r"\b:\s?", '', parsed_response)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 350 |
|
| 351 |
# Check for if the bot passed (i.e. response = "(pass)")
|
| 352 |
if ("(pass)" in parsed_response) or (parsed_response == ""):
|
|
|
|
| 368 |
print("PASSED")
|
| 369 |
return True # a pass is still recorded in the database, but not sent to the client
|
| 370 |
|
|
|
|
|
|
|
| 371 |
#remove encapsulating quotes
|
| 372 |
+
no_quotes = remove_quotes(parsed_response)
|
| 373 |
#humanize the response (remove obvious AI formatting styles)
|
| 374 |
humanized_response = humanize(no_quotes)
|
| 375 |
#replace most semicolons
|
| 376 |
less_semicolons_response = replace_semicolons(humanized_response)
|
| 377 |
#corrupt the response (add some typos and misspellings)
|
| 378 |
+
corrupted_response = corrupt(less_semicolons_response)
|
| 379 |
#remove weird chars
|
| 380 |
no_weird_chars = remove_weird_characters(corrupted_response)
|
| 381 |
+
#sub letters for names, so if the bot addressed A -> Apple
|
| 382 |
+
named_response = let_to_name(room_id, no_weird_chars)
|
|
|
|
|
|
|
|
|
|
| 383 |
|
| 384 |
#check that there are no reccent duplicate messages
|
| 385 |
+
if len(named_response) > DUP_LEN and duplicate_check(named_response, context):
|
| 386 |
print("****DUPLICATE MESSAGE DETECTED")
|
| 387 |
print("Treating this bot's response as a pass.")
|
| 388 |
# Do not store/send messages if the chat has ended
|
|
|
|
| 392 |
# Store the error response in the database
|
| 393 |
bot_message = {
|
| 394 |
"sender": bot_display_name,
|
| 395 |
+
"message": f"DUPLICATE message detected - treated as a (pass) : {named_response}",
|
| 396 |
"timestamp": datetime.utcnow()
|
| 397 |
}
|
| 398 |
rooms_collection.update_one(
|
|
|
|
| 407 |
print(corrupted_response)
|
| 408 |
|
| 409 |
# Add latency/wait time for bot responses
|
| 410 |
+
delay = get_response_delay(named_response);
|
| 411 |
print(delay)
|
| 412 |
time.sleep(delay)
|
| 413 |
|
|
|
|
| 419 |
# Store the response in the database
|
| 420 |
bot_message = {
|
| 421 |
"sender": bot_display_name,
|
| 422 |
+
"message": named_response, #save fruits in db so page reload shows proper names
|
| 423 |
"timestamp": datetime.utcnow()
|
| 424 |
}
|
| 425 |
rooms_collection.update_one(
|
|
|
|
| 428 |
)
|
| 429 |
|
| 430 |
# Send the bot's response to the client
|
| 431 |
+
socketio.emit("message", {"sender": bot_display_name, "message": named_response}, to=room_id)
|
| 432 |
return False
|
| 433 |
|
| 434 |
def ask_bot_round(room_id):
|
|
|
|
| 460 |
token = os.getenv("HF_TOKEN")
|
| 461 |
handler = datasetHandler(token , 'huggingFaceData')
|
| 462 |
handler.dump_db()
|
|
|
|
| 463 |
socketio.sleep(time)
|
| 464 |
|
| 465 |
# Build the routes
|
|
|
|
| 487 |
session['user_id'] = user_id
|
| 488 |
return redirect(url_for('topics'))
|
| 489 |
else:
|
| 490 |
+
return render_template('home.html',prolific_pid=prolific_pid)
|
|
|
|
| 491 |
|
| 492 |
@app.route('/topics', methods=["GET", "POST"])
|
| 493 |
def topics():
|
|
|
|
| 559 |
"ended": False,
|
| 560 |
"ended_at": None
|
| 561 |
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 562 |
|
| 563 |
session['room'] = room_id
|
| 564 |
session['display_name'] = user_name
|
|
|
|
| 581 |
m for m in room_doc["messages"]
|
| 582 |
if len(re.findall(r"pass",m.get("message", "").strip())) == 0
|
| 583 |
]
|
| 584 |
+
return render_template("room.html", room=room_id, topic_info=topic_info, user=display_name, messages=nonpass_messages, FroBot_name=room_doc["FroBot_name"], HotBot_name=room_doc["HotBot_name"], CoolBot_name=room_doc["CoolBot_name"], ended=room_doc["ended"])
|
| 585 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 586 |
@app.route("/abort", methods=["POST"])
|
| 587 |
def abort_room():
|
| 588 |
room_id = session.get("room")
|
|
|
|
| 717 |
# Ask each bot for a response
|
| 718 |
socketio.start_background_task(ask_bot_round, room)
|
| 719 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 720 |
@socketio.on('disconnect')
|
| 721 |
def handle_disconnect():
|
| 722 |
room = session.get("room")
|
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,48 +498,15 @@ hr {
|
|
| 498 |
background: #ccc;
|
| 499 |
}
|
| 500 |
|
| 501 |
-
#welcomeOkBtn
|
| 502 |
background: green;
|
| 503 |
color: white;
|
| 504 |
}
|
| 505 |
|
| 506 |
-
#welcomeOkBtn:hover
|
| 507 |
background: #016601;
|
| 508 |
}
|
| 509 |
|
| 510 |
-
#feedback-btn {
|
| 511 |
-
color: white;
|
| 512 |
-
font-weight: 800;
|
| 513 |
-
background-color: green;
|
| 514 |
-
text-decoration: none;
|
| 515 |
-
padding: 6px;
|
| 516 |
-
border: 2px solid green;
|
| 517 |
-
display: inline-block;
|
| 518 |
-
margin-top: 5px;
|
| 519 |
-
border-radius: 10px;
|
| 520 |
-
transition: all 0.1s ease-in;
|
| 521 |
-
}
|
| 522 |
-
|
| 523 |
-
#feedback-btn:hover {
|
| 524 |
-
color: green;
|
| 525 |
-
background-color: white;
|
| 526 |
-
}
|
| 527 |
-
|
| 528 |
-
.feedback-col {
|
| 529 |
-
display: flex;
|
| 530 |
-
flex-direction: column;
|
| 531 |
-
gap: 6px;
|
| 532 |
-
|
| 533 |
-
textarea {
|
| 534 |
-
width: 100%;
|
| 535 |
-
min-height: 120px;
|
| 536 |
-
padding: 10px;
|
| 537 |
-
border: 1px solid #ccc;
|
| 538 |
-
border-radius: 6px;
|
| 539 |
-
resize: vertical;
|
| 540 |
-
}
|
| 541 |
-
}
|
| 542 |
-
|
| 543 |
#idYesBtn {
|
| 544 |
background: green;
|
| 545 |
color: white;
|
|
@@ -567,12 +534,12 @@ hr {
|
|
| 567 |
background: #016991;
|
| 568 |
}
|
| 569 |
|
| 570 |
-
#endNoBtn
|
| 571 |
background: #e5e5e5;
|
| 572 |
color: #333;
|
| 573 |
}
|
| 574 |
|
| 575 |
-
#endNoBtn:hover
|
| 576 |
background: #ccc;
|
| 577 |
}
|
| 578 |
|
|
|
|
| 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 |
background: #ccc;
|
| 499 |
}
|
| 500 |
|
| 501 |
+
#welcomeOkBtn {
|
| 502 |
background: green;
|
| 503 |
color: white;
|
| 504 |
}
|
| 505 |
|
| 506 |
+
#welcomeOkBtn:hover {
|
| 507 |
background: #016601;
|
| 508 |
}
|
| 509 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 510 |
#idYesBtn {
|
| 511 |
background: green;
|
| 512 |
color: white;
|
|
|
|
| 534 |
background: #016991;
|
| 535 |
}
|
| 536 |
|
| 537 |
+
#endNoBtn {
|
| 538 |
background: #e5e5e5;
|
| 539 |
color: #333;
|
| 540 |
}
|
| 541 |
|
| 542 |
+
#endNoBtn:hover {
|
| 543 |
background: #ccc;
|
| 544 |
}
|
| 545 |
|
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>Flask Chat</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/room.html
CHANGED
|
@@ -12,34 +12,26 @@
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
</div>
|
| 32 |
<div class="topic-header-buttons">
|
| 33 |
-
<button id="
|
| 34 |
-
<button id="end-exp-btn">End Chat Session</button>
|
| 35 |
<button id="abort-exp-btn">Abort Experiment</button>
|
| 36 |
</div>
|
| 37 |
</div>
|
| 38 |
<div id="end-modal" class="modal">
|
| 39 |
<div class="modal-content">
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
<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>
|
| 43 |
<div class="modal-buttons">
|
| 44 |
<button class="modal-btn" id="endYesBtn">Continue</button>
|
| 45 |
<button class="modal-btn" id="endNoBtn">Cancel</button>
|
|
@@ -49,48 +41,13 @@
|
|
| 49 |
<div id="abort-modal" class="modal">
|
| 50 |
<div class="modal-content">
|
| 51 |
<h3>Are you sure you want to leave this experiment?</h3>
|
| 52 |
-
<p>
|
| 53 |
-
<p>By clicking yes, you will exit the experiment <strong>without</strong> completing the final survey.</p>
|
| 54 |
<div class="modal-buttons">
|
| 55 |
-
<button class="modal-btn" id="abortYesBtn">
|
| 56 |
<button class="modal-btn" id="abortNoBtn">Cancel</button>
|
| 57 |
</div>
|
| 58 |
</div>
|
| 59 |
</div>
|
| 60 |
-
|
| 61 |
-
<div id="feedback-modal" class="modal">
|
| 62 |
-
<div class="modal-content">
|
| 63 |
-
<h3>Feedback</h3>
|
| 64 |
-
<form id="feedback-form">
|
| 65 |
-
<div class="feedback-col">
|
| 66 |
-
<label for="enter-feedback">Tell us if you noticed something confusing, unexpected, or not working.</label>
|
| 67 |
-
<textarea id="enter-feedback" name="feedback"></textarea>
|
| 68 |
-
</div>
|
| 69 |
-
<br>
|
| 70 |
-
<div class="modal-buttons">
|
| 71 |
-
<button class="modal-btn" id="submitFeedbackBtn" type="submit">Submit</button>
|
| 72 |
-
<button type="button" class="modal-btn" id="cancelFeedbackBtn">Cancel</button>
|
| 73 |
-
</div>
|
| 74 |
-
</form>
|
| 75 |
-
</div>
|
| 76 |
-
</div>
|
| 77 |
-
|
| 78 |
-
<div id="feedback-status-confirm" class="modal">
|
| 79 |
-
<div class="modal-content">
|
| 80 |
-
<p>Feedback submitted.</p>
|
| 81 |
-
<div class="modal-buttons">
|
| 82 |
-
<button class="modal-btn" id="cancelFeedbackStatusBtn">Ok</button>
|
| 83 |
-
</div>
|
| 84 |
-
</div>
|
| 85 |
-
</div>
|
| 86 |
-
<div id="feedback-status-fail" class="modal">
|
| 87 |
-
<div class="modal-content">
|
| 88 |
-
<p>Feedback failed to submit.</p>
|
| 89 |
-
<div class="modal-buttons">
|
| 90 |
-
<button class="modal-btn" id="cancelFeedbackStatusBtn2">Ok</button>
|
| 91 |
-
</div>
|
| 92 |
-
</div>
|
| 93 |
-
</div>
|
| 94 |
</div>
|
| 95 |
<div id="chat-room-widget">
|
| 96 |
<div id="msgs-container">
|
|
@@ -117,23 +74,16 @@
|
|
| 117 |
document.getElementById("send-btn").disabled = true;
|
| 118 |
document.getElementById("end-exp-btn").disabled = true;
|
| 119 |
document.getElementById("abort-exp-btn").disabled = true;
|
| 120 |
-
document.getElementById("feedback-btn").disabled = true; //since without socket io, it won't submit
|
| 121 |
if (socketio) {
|
| 122 |
socketio.close();
|
| 123 |
}
|
| 124 |
}
|
| 125 |
// Handler for the welcome modal
|
| 126 |
let welcomeModal = document.getElementById("welcome-modal");
|
| 127 |
-
let timerModal = document.getElementById("timer-modal");
|
| 128 |
const displayNameText = document.getElementById("displayNameText");
|
| 129 |
displayNameText.textContent = "{{ user }}";
|
| 130 |
// Show the modal instantly when the page loads
|
| 131 |
window.onload = function() {
|
| 132 |
-
timerModal.style.display = "block";
|
| 133 |
-
};
|
| 134 |
-
//timer pop-up
|
| 135 |
-
document.getElementById("timerOkBtn").onclick = function () {
|
| 136 |
-
timerModal.style.display = "none";
|
| 137 |
welcomeModal.style.display = "block";
|
| 138 |
};
|
| 139 |
// Close the modal on OK
|
|
@@ -142,7 +92,6 @@
|
|
| 142 |
};
|
| 143 |
// Creates the post-survey link (based on the bot names)
|
| 144 |
const endpoint = "{{ url_for('post_survey') }}";
|
| 145 |
-
const endpointQuitEarly = "https://app.prolific.com/submissions/complete?cc=C9V2XFDU";
|
| 146 |
socketio.on("message", function (message) { createChatItem(message.message, message.sender) });
|
| 147 |
function createChatItem(message, sender) {
|
| 148 |
//autoscroll capabilities
|
|
@@ -212,7 +161,6 @@
|
|
| 212 |
document.getElementById("send-btn").disabled = true;
|
| 213 |
document.getElementById("end-exp-btn").disabled = true;
|
| 214 |
document.getElementById("abort-exp-btn").disabled = true;
|
| 215 |
-
document.getElementById("feedback-btn").disabled = true; //since without socket io, it won't submit
|
| 216 |
if (socketio) {
|
| 217 |
socketio.close();
|
| 218 |
}
|
|
@@ -225,69 +173,24 @@
|
|
| 225 |
document.getElementById("abortNoBtn").onclick = function () {
|
| 226 |
modal.style.display = "none";
|
| 227 |
};
|
| 228 |
-
|
| 229 |
document.getElementById("abortYesBtn").onclick = function (e) {
|
| 230 |
//block browser confirmation popup
|
| 231 |
e.stopPropagation();
|
| 232 |
// Mark that user aborted and redirect to ending survey
|
| 233 |
fetch("/abort", { method: "POST" })
|
| 234 |
.then(() => {
|
| 235 |
-
window.open(
|
| 236 |
-
|
| 237 |
modal.style.display = "none";
|
| 238 |
textarea.disabled = true;
|
| 239 |
textarea.placeholder = "The chat has ended.";
|
| 240 |
document.getElementById("send-btn").disabled = true;
|
| 241 |
document.getElementById("end-exp-btn").disabled = true;
|
| 242 |
document.getElementById("abort-exp-btn").disabled = true;
|
| 243 |
-
document.getElementById("feedback-btn").disabled = true; //since without socket io, it won't submit
|
| 244 |
if (socketio) {
|
| 245 |
-
|
| 246 |
}
|
| 247 |
};
|
| 248 |
-
|
| 249 |
-
//handler for feedback modal popup
|
| 250 |
-
let feedbackModal = document.getElementById("feedback-modal");
|
| 251 |
-
let form = document.getElementById("feedback-form");
|
| 252 |
-
let feedbackConfirm = document.getElementById("feedback-status-confirm");
|
| 253 |
-
let feedbackFail = document.getElementById("feedback-status-fail");
|
| 254 |
-
document.getElementById("feedback-btn").onclick = function () {
|
| 255 |
-
feedbackModal.style.display = "block";
|
| 256 |
-
};
|
| 257 |
-
document.getElementById("cancelFeedbackBtn").onclick = function () {
|
| 258 |
-
feedbackModal.style.display = "none";
|
| 259 |
-
};
|
| 260 |
-
|
| 261 |
-
document.getElementById("cancelFeedbackStatusBtn").onclick = function () {
|
| 262 |
-
feedbackConfirm.style.display = "none";
|
| 263 |
-
feedbackFail.style.display = "none";
|
| 264 |
-
};
|
| 265 |
-
|
| 266 |
-
document.getElementById("cancelFeedbackStatusBtn2").onclick = function () {
|
| 267 |
-
feedbackConfirm.style.display = "none";
|
| 268 |
-
feedbackFail.style.display = "none";
|
| 269 |
-
};
|
| 270 |
-
|
| 271 |
-
//override form function to instead emit save feedback event
|
| 272 |
-
form.addEventListener("submit", function (e) {
|
| 273 |
-
e.preventDefault();
|
| 274 |
-
|
| 275 |
-
const data = new FormData(form);
|
| 276 |
-
const feedback = data.get("feedback")?.trim();
|
| 277 |
-
|
| 278 |
-
if (!feedback) return;
|
| 279 |
-
|
| 280 |
-
socketio.emit("feedback_given", { feedback }, (response) => {
|
| 281 |
-
if (response?.status === "True" || response?.status === true) {
|
| 282 |
-
feedbackConfirm.style.display = "block";
|
| 283 |
-
form.reset();
|
| 284 |
-
document.getElementById("feedback-modal").style.display = "none";
|
| 285 |
-
} else {
|
| 286 |
-
feedbackFail.style.display = "block";
|
| 287 |
-
}
|
| 288 |
-
});
|
| 289 |
-
});
|
| 290 |
-
|
| 291 |
// add auto scroll
|
| 292 |
function isNearBottom(container, threshold = 120) {
|
| 293 |
const distanceFromBottom = container.scrollHeight - (container.scrollTop + container.clientHeight);
|
|
|
|
| 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 |
+
<h2 id="room-code-display">Topic: <span class="topic-title">{{ topic_info.title }}</span>
|
| 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 Ends</button>
|
|
|
|
| 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 |
+
<h3>Only Exit This Way When Instructed.</h3>
|
| 34 |
+
<p>This signals the end of the chat session of the experiment. You will be redirected to the post-survey. This button is only to be used when the experiment ends, as indicated by the proctor. If you wish to exit the chat before instructed, use the "Abort Experiment" button instead.</p>
|
|
|
|
| 35 |
<div class="modal-buttons">
|
| 36 |
<button class="modal-btn" id="endYesBtn">Continue</button>
|
| 37 |
<button class="modal-btn" id="endNoBtn">Cancel</button>
|
|
|
|
| 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. However, if you do choose to leave, you will still receive the offered extra credit from your professor. If the chat session has ended, as signaled by the proctor, do NOT exit via this button. Use the "Chat Session Ends" button instead.</p>
|
|
|
|
| 45 |
<div class="modal-buttons">
|
| 46 |
+
<button class="modal-btn" id="abortYesBtn">Yes</button>
|
| 47 |
<button class="modal-btn" id="abortNoBtn">Cancel</button>
|
| 48 |
</div>
|
| 49 |
</div>
|
| 50 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
</div>
|
| 52 |
<div id="chat-room-widget">
|
| 53 |
<div id="msgs-container">
|
|
|
|
| 74 |
document.getElementById("send-btn").disabled = true;
|
| 75 |
document.getElementById("end-exp-btn").disabled = true;
|
| 76 |
document.getElementById("abort-exp-btn").disabled = true;
|
|
|
|
| 77 |
if (socketio) {
|
| 78 |
socketio.close();
|
| 79 |
}
|
| 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
|
|
|
|
| 92 |
};
|
| 93 |
// Creates the post-survey link (based on the bot names)
|
| 94 |
const endpoint = "{{ url_for('post_survey') }}";
|
|
|
|
| 95 |
socketio.on("message", function (message) { createChatItem(message.message, message.sender) });
|
| 96 |
function createChatItem(message, sender) {
|
| 97 |
//autoscroll capabilities
|
|
|
|
| 161 |
document.getElementById("send-btn").disabled = true;
|
| 162 |
document.getElementById("end-exp-btn").disabled = true;
|
| 163 |
document.getElementById("abort-exp-btn").disabled = true;
|
|
|
|
| 164 |
if (socketio) {
|
| 165 |
socketio.close();
|
| 166 |
}
|
|
|
|
| 173 |
document.getElementById("abortNoBtn").onclick = function () {
|
| 174 |
modal.style.display = "none";
|
| 175 |
};
|
|
|
|
| 176 |
document.getElementById("abortYesBtn").onclick = function (e) {
|
| 177 |
//block browser confirmation popup
|
| 178 |
e.stopPropagation();
|
| 179 |
// Mark that user aborted and redirect to ending survey
|
| 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.";
|
| 187 |
document.getElementById("send-btn").disabled = true;
|
| 188 |
document.getElementById("end-exp-btn").disabled = true;
|
| 189 |
document.getElementById("abort-exp-btn").disabled = true;
|
|
|
|
| 190 |
if (socketio) {
|
| 191 |
+
socketio.close();
|
| 192 |
}
|
| 193 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
// add auto scroll
|
| 195 |
function isNearBottom(container, threshold = 120) {
|
| 196 |
const distanceFromBottom = container.scrollHeight - (container.scrollTop + container.clientHeight);
|
data/inference_instructions/coolbot_instructions_main.txt
CHANGED
|
@@ -1,16 +1,6 @@
|
|
| 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,10 +63,8 @@ NATURAL CHAT BEHAVIOR
|
|
| 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.
|
|
|
|
| 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 |
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.
|
data/inference_instructions/frobot_instructions_main.txt
CHANGED
|
@@ -1,16 +1,6 @@
|
|
| 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,9 +58,6 @@ Also follow these presentation rules:
|
|
| 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,10 +83,8 @@ NATURAL CHAT BEHAVIOR
|
|
| 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.
|
|
|
|
| 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 |
|
| 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 |
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.
|
data/inference_instructions/hotbot_instructions_main.txt
CHANGED
|
@@ -1,16 +1,6 @@
|
|
| 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,10 +66,8 @@ NATURAL CHAT BEHAVIOR
|
|
| 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.
|
|
|
|
| 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 |
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.
|