Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,14 +1,19 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
import os
|
| 3 |
from openai import OpenAI
|
| 4 |
-
import os.path
|
| 5 |
from datetime import datetime
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
################# Start PERSONA-SPECIFIC VALUES ######################
|
| 8 |
coach_code = os.getenv("COACH_CODE")
|
| 9 |
coach_name_short = os.getenv("COACH_NAME_SHORT")
|
| 10 |
coach_name_upper = os.getenv("COACH_NAME_UPPER")
|
|
|
|
| 11 |
sys_prompt_new = os.getenv("PROMPT_NEW")
|
|
|
|
|
|
|
| 12 |
theme=os.getenv("THEME")
|
| 13 |
################# End PERSONA-SPECIFIC VALUES ######################
|
| 14 |
|
|
@@ -19,70 +24,393 @@ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
|
| 19 |
openai_model = os.getenv("OPENAI_MODEL")
|
| 20 |
################# End OpenAI-SPECIFIC VALUES ######################
|
| 21 |
|
| 22 |
-
|
| 23 |
prefix = os.getenv("PREFIX") # "/data/" if in HF or "data/" if local
|
| 24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
def predict(user_input, history):
|
| 28 |
-
max_length =
|
| 29 |
-
|
| 30 |
-
|
| 31 |
|
| 32 |
-
if user_input == tx
|
| 33 |
try:
|
| 34 |
-
#
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
|
|
|
|
|
|
| 39 |
except FileNotFoundError:
|
| 40 |
-
|
|
|
|
| 41 |
elif len(user_input) > max_length:
|
| 42 |
-
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
for human, assistant in history:
|
| 49 |
-
history_openai_format.append({"role": "user", "content": human})
|
| 50 |
-
history_openai_format.append({"role": "assistant", "content":
|
| 51 |
history_openai_format.append({"role": "user", "content": user_input})
|
| 52 |
|
| 53 |
completion = client.chat.completions.create(
|
| 54 |
model=openai_model,
|
| 55 |
-
messages=history_openai_format,
|
| 56 |
-
temperature=
|
| 57 |
frequency_penalty=0.4,
|
| 58 |
presence_penalty=0.1,
|
| 59 |
stream=True
|
| 60 |
)
|
| 61 |
|
| 62 |
output_stream = ""
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
|
| 71 |
# Append latest user and assistant messages to the transcript
|
| 72 |
-
transcript += "
|
| 73 |
-
transcript += f"
|
| 74 |
-
|
| 75 |
# Write the updated transcript to the file
|
| 76 |
-
with open(transcript_file_path, "
|
| 77 |
file.write(transcript)
|
| 78 |
|
| 79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
#GUI
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
""
|
| 87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
demo.launch(show_api=False)
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import os
|
| 3 |
from openai import OpenAI
|
|
|
|
| 4 |
from datetime import datetime
|
| 5 |
+
import threading
|
| 6 |
+
import time
|
| 7 |
+
import os.path
|
| 8 |
|
| 9 |
################# Start PERSONA-SPECIFIC VALUES ######################
|
| 10 |
coach_code = os.getenv("COACH_CODE")
|
| 11 |
coach_name_short = os.getenv("COACH_NAME_SHORT")
|
| 12 |
coach_name_upper = os.getenv("COACH_NAME_UPPER")
|
| 13 |
+
coach_name_long = os.getenv("COACH_NAME_LONG")
|
| 14 |
sys_prompt_new = os.getenv("PROMPT_NEW")
|
| 15 |
+
sys_prompt_hist = os.getenv("PROMPT_HIST")
|
| 16 |
+
pics_prompt = os.getenv("PROMPT_PICS")
|
| 17 |
theme=os.getenv("THEME")
|
| 18 |
################# End PERSONA-SPECIFIC VALUES ######################
|
| 19 |
|
|
|
|
| 24 |
openai_model = os.getenv("OPENAI_MODEL")
|
| 25 |
################# End OpenAI-SPECIFIC VALUES ######################
|
| 26 |
|
| 27 |
+
# define file name prefix
|
| 28 |
prefix = os.getenv("PREFIX") # "/data/" if in HF or "data/" if local
|
| 29 |
+
tx = os.getenv("TX")
|
| 30 |
+
|
| 31 |
+
# Assistants API prompts
|
| 32 |
+
bullet_instructions = os.getenv("PROMPT_BULLET")
|
| 33 |
+
summary_instructions = os.getenv("PROMPT_SUMM")
|
| 34 |
+
|
| 35 |
+
# Get dateTime string to build a filename reflecting the UserID + Timestamp
|
| 36 |
+
dt = datetime.now()
|
| 37 |
+
dt_string = str(dt)
|
| 38 |
+
|
| 39 |
+
# User inactivity check interval in seconds
|
| 40 |
+
CHECK_INTERVAL = 10
|
| 41 |
+
|
| 42 |
+
# User inactivity timeout in seconds (initially set to 1 minute)
|
| 43 |
+
USER_TIMEOUT = 1 * 60
|
| 44 |
+
|
| 45 |
+
# Keep track of the last interaction time, current user_id, and the last file modification time
|
| 46 |
+
last_interaction_time = time.time()
|
| 47 |
+
user_id = "NOTLOGGEDIN"
|
| 48 |
+
last_file_mod_time = None
|
| 49 |
+
|
| 50 |
+
# Function to determine whether user is new or returning, and generate the appropriate SYSTEM PROMPT
|
| 51 |
+
def get_system_prompt(user_id):
|
| 52 |
+
past_summary_bullet = ""
|
| 53 |
+
past_summary_summ = ""
|
| 54 |
+
pics_file = ""
|
| 55 |
+
user_summ_file_bullet = f"{prefix}{coach_code}-{user_id.upper().replace(' ', '')}-bullet.txt"
|
| 56 |
+
user_summ_file_summ = f"{prefix}{coach_code}-{user_id.upper().replace(' ', '')}-summ.txt"
|
| 57 |
+
pics_file_path = f"{prefix}{coach_code}-{user_id.upper().replace(' ', '')}-pics.txt"
|
| 58 |
+
|
| 59 |
+
# Create pics file if not exist
|
| 60 |
+
if not os.path.exists(pics_file_path):
|
| 61 |
+
pics_file = "The user has not shared any images."
|
| 62 |
+
with open(pics_file_path, "w", encoding="UTF-8") as file:
|
| 63 |
+
file.write(pics_file)
|
| 64 |
+
|
| 65 |
+
if os.path.exists(pics_file_path):
|
| 66 |
+
with open(pics_file_path, "r", encoding="UTF-8") as file:
|
| 67 |
+
user_pics_content = file.read().strip()
|
| 68 |
+
|
| 69 |
+
# Check if the bullet summary file exists and read from it
|
| 70 |
+
if os.path.exists(user_summ_file_bullet):
|
| 71 |
+
with open(user_summ_file_bullet, "r", encoding="UTF-8") as file:
|
| 72 |
+
past_summary_bullet = file.read().strip() # Read the contents of the summary file
|
| 73 |
+
|
| 74 |
+
# Check if the summary file exists and read from it
|
| 75 |
+
if os.path.exists(user_summ_file_summ):
|
| 76 |
+
with open(user_summ_file_summ, "r", encoding="UTF-8") as file:
|
| 77 |
+
past_summary_summ = file.read().strip() # Read the contents of the summary file
|
| 78 |
+
|
| 79 |
+
# past_summary = past_summary_bullet + "\n" + past_summary_summ
|
| 80 |
+
past_summary = past_summary_bullet
|
| 81 |
+
|
| 82 |
+
# System prompt for returning users includes past summary
|
| 83 |
+
return [
|
| 84 |
+
{"role": "system", "content": sys_prompt_hist + past_summary +
|
| 85 |
+
"If the user asks how to share or upload pictures, refer them to the 'DatingFinesse.com' website for instructions. The user may have shared pictures with you. Each picture will be separated by 'IMAGE - Date/Time:'. If the user has shared images, most recently shared will be listed last and they would be summarized here: " +
|
| 86 |
+
user_pics_content + pics_prompt}
|
| 87 |
+
]
|
| 88 |
+
else:
|
| 89 |
+
# System prompt for new users
|
| 90 |
+
return [
|
| 91 |
+
{"role": "system", "content": "IDENTITY: " + sys_prompt_new + " If the user asks about sharing or uploading pictures, refer them to the 'DatingFinesse.com' website for instructions."}
|
| 92 |
+
]
|
| 93 |
+
|
| 94 |
+
# Function that returns the modification time of the user's history file or None if it does not exist
|
| 95 |
+
def get_user_hist_file_mod_time(user_id):
|
| 96 |
+
user_hist_file = f"{prefix}{coach_code}-{user_id.upper().replace(' ', '')}.txt"
|
| 97 |
+
if os.path.exists(user_hist_file):
|
| 98 |
+
return os.path.getmtime(user_hist_file)
|
| 99 |
+
else:
|
| 100 |
+
return None
|
| 101 |
+
|
| 102 |
+
# Function to be run in the case of user timeout
|
| 103 |
+
############################## LAUNCH DUAL SUMMARIZER ASSISTANT
|
| 104 |
+
def on_timeout(user_id):
|
| 105 |
+
global last_file_mod_time
|
| 106 |
+
current_mod_time = get_user_hist_file_mod_time(user_id)
|
| 107 |
+
if current_mod_time is not None and (last_file_mod_time is None or current_mod_time > last_file_mod_time):
|
| 108 |
+
#print(f"User with ID {user_id} has been inactive, but the history file was updated. Running timeout script.")
|
| 109 |
+
last_file_mod_time = current_mod_time
|
| 110 |
+
# Insert your timeout script here
|
| 111 |
+
# Construct the filename for the user's summary file & user's history file
|
| 112 |
+
user_bullet_file = prefix + coach_code + "-" + user_id + "-bullet.txt" # Filename where the user history summary will be stored.
|
| 113 |
+
user_summ_file = prefix + coach_code + "-" + user_id + "-summ.txt" # Filename where the user history summary will be stored.
|
| 114 |
+
user_hist_file = prefix + coach_code + "-" + user_id + ".txt" # Filename where the user history is stored.
|
| 115 |
+
# Construct the filename for the user's bullet file
|
| 116 |
+
user_summ_file_bullet = f"{prefix}{coach_code}-{user_id.upper().replace(' ', '')}-bullet.txt"
|
| 117 |
+
|
| 118 |
+
# Construct the filename for the user's transcript file
|
| 119 |
+
transcript_file_path = f"{prefix}{coach_code}-{user_id}-transcript.txt"
|
| 120 |
+
|
| 121 |
+
if os.path.exists(transcript_file_path):
|
| 122 |
+
with open(transcript_file_path, "r", encoding="UTF-8") as file:
|
| 123 |
+
transcript = file.read().strip()
|
| 124 |
+
else:
|
| 125 |
+
transcript = ""
|
| 126 |
+
|
| 127 |
+
assistant = client.beta.assistants.create(
|
| 128 |
+
name="Summarizer_Bullet",
|
| 129 |
+
instructions=bullet_instructions + transcript,
|
| 130 |
+
model="gpt-4o"
|
| 131 |
+
)
|
| 132 |
+
|
| 133 |
+
assistant_id = assistant.id
|
| 134 |
+
|
| 135 |
+
# Create a conversation thread with the assistant
|
| 136 |
+
thread = client.beta.threads.create(
|
| 137 |
+
messages=[
|
| 138 |
+
{
|
| 139 |
+
"role": "user",
|
| 140 |
+
"content": " ", # Start the thread with a greeting message. CANNOT BE EMPTY ""
|
| 141 |
+
}
|
| 142 |
+
]
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
# Start a run to get the assistant's reply
|
| 146 |
+
run = client.beta.threads.runs.create(
|
| 147 |
+
thread_id=thread.id,
|
| 148 |
+
assistant_id=assistant.id
|
| 149 |
+
# The 'instructions' parameter is commented out, but indicates what kind of responses are expected from the assistant.
|
| 150 |
+
)
|
| 151 |
+
|
| 152 |
+
# Function to wait for the run to complete before fetching the response
|
| 153 |
+
def wait_on_run(run, thread):
|
| 154 |
+
while run.status == "queued" or run.status == "in_progress":
|
| 155 |
+
# Poll for the run's completion status
|
| 156 |
+
run = client.beta.threads.runs.retrieve(
|
| 157 |
+
thread_id=thread.id,
|
| 158 |
+
run_id=run.id,
|
| 159 |
+
)
|
| 160 |
+
time.sleep(0.5) # Sleep for 0.5 second between each poll to avoid hammering the API
|
| 161 |
+
return run
|
| 162 |
|
| 163 |
+
# Call the function to wait for the run to complete
|
| 164 |
+
run = wait_on_run(run, thread)
|
| 165 |
+
|
| 166 |
+
# Get the messages from the thread
|
| 167 |
+
messages = client.beta.threads.messages.list(
|
| 168 |
+
thread_id=thread.id
|
| 169 |
+
)
|
| 170 |
+
|
| 171 |
+
# Print out all messages in reverse order (to show the conversation flow correctly)
|
| 172 |
+
for message in reversed(messages.data):
|
| 173 |
+
try:
|
| 174 |
+
print(message.content[0].text.value)
|
| 175 |
+
except (IndexError, AttributeError) as e:
|
| 176 |
+
print(f"An error occurred while accessing message content: {e}")
|
| 177 |
+
|
| 178 |
+
# Open the file for appending messages
|
| 179 |
+
with open(user_summ_file_bullet, "a", encoding="UTF-8") as file:
|
| 180 |
+
# Add a separator between previous and new bullet points
|
| 181 |
+
file.write("\n--- New Conversation ---")
|
| 182 |
+
|
| 183 |
+
# Loop through each message and append its contents
|
| 184 |
+
for message in reversed(messages.data):
|
| 185 |
+
try:
|
| 186 |
+
# Attempt to write message content
|
| 187 |
+
file.write(message.content[0].text.value + "\n")
|
| 188 |
+
except IndexError:
|
| 189 |
+
# Handle cases where message.content list is not as expected
|
| 190 |
+
file.write("\n")
|
| 191 |
+
except AttributeError:
|
| 192 |
+
# Handle cases where .text or .value attributes are not present
|
| 193 |
+
file.write("An error occurred while accessing message text attributes.\n")
|
| 194 |
+
|
| 195 |
+
client.beta.assistants.delete(assistant_id)
|
| 196 |
+
|
| 197 |
+
# Delete the TRANSCRIPT file
|
| 198 |
+
if os.path.exists(f"{prefix}{coach_code}-{user_id}-transcript.txt"):
|
| 199 |
+
os.remove(f"{prefix}{coach_code}-{user_id}-transcript.txt")
|
| 200 |
+
|
| 201 |
+
user_id = "NOTLOGGEDIN"
|
| 202 |
+
############################## END OF SUMMARIZER ASSISTANT
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
############################## USER INACTIVITY CHECK
|
| 206 |
+
# Function to keep checking for user inactivity
|
| 207 |
+
def check_for_inactivity():
|
| 208 |
+
global last_interaction_time, user_id, USER_TIMEOUT
|
| 209 |
+
while True:
|
| 210 |
+
time.sleep(CHECK_INTERVAL)
|
| 211 |
+
current_time = time.time()
|
| 212 |
+
if current_time - last_interaction_time > USER_TIMEOUT and os.path.exists(f"{prefix}{coach_code}-{user_id}-transcript.txt") and user_id is not None:
|
| 213 |
+
on_timeout(user_id)
|
| 214 |
+
# Reset the last interaction time (WHY???)
|
| 215 |
+
# last_interaction_time = current_time
|
| 216 |
+
|
| 217 |
+
# Initialize and start the inactivity check thread
|
| 218 |
+
inactivity_thread = threading.Thread(target=check_for_inactivity)
|
| 219 |
+
inactivity_thread.daemon = True
|
| 220 |
+
inactivity_thread.start()
|
| 221 |
+
|
| 222 |
+
############### CHAT ###################
|
| 223 |
def predict(user_input, history):
|
| 224 |
+
max_length = 2000
|
| 225 |
+
if len(user_input) > max_length:
|
| 226 |
+
user_input = ""
|
| 227 |
|
| 228 |
+
if user_input == tx:
|
| 229 |
try:
|
| 230 |
+
# Read the contents of the user_hist_file
|
| 231 |
+
with open(user_hist_file, "r", encoding="UTF-8") as file:
|
| 232 |
+
file_contents = file.read()
|
| 233 |
+
|
| 234 |
+
# Yield the file contents as chat output
|
| 235 |
+
yield file_contents
|
| 236 |
+
return
|
| 237 |
except FileNotFoundError:
|
| 238 |
+
yield "File '" + user_hist_file + "' not found."
|
| 239 |
+
return
|
| 240 |
elif len(user_input) > max_length:
|
| 241 |
+
raise gr.Error(f"Input is TOO LONG. Max length is {max_length} characters. Try again.")
|
| 242 |
+
|
| 243 |
+
global last_interaction_time, user_id, last_file_mod_time
|
| 244 |
+
# ... [other global variables that are used]
|
| 245 |
+
|
| 246 |
+
# Update the last interaction time
|
| 247 |
+
last_interaction_time = time.time()
|
| 248 |
+
|
| 249 |
+
user_hist_file = f"{prefix}{coach_code}-{user_id}.txt"
|
| 250 |
+
pics_file_path = f"{prefix}{coach_code}-{user_id}-pics.txt"
|
| 251 |
|
| 252 |
+
if user_id == "NOTLOGGEDIN":
|
| 253 |
+
raise gr.Error(f"You must be LOGGED IN to Chat. Refresh the page and try again.")
|
| 254 |
+
if user_id == "":
|
| 255 |
+
raise gr.Error(f"You must be LOGGED IN to Chat. Refresh the page and try again.")
|
| 256 |
+
if user_id == None:
|
| 257 |
+
raise gr.Error(f"You must be LOGGED IN to Chat. Refresh the page and try again.")
|
| 258 |
+
if user_hist_file == prefix + coach_code + "-None.txt":
|
| 259 |
+
raise gr.Error(f"You must be LOGGED IN to Chat. Refresh the page and try again.")
|
| 260 |
+
if user_hist_file == prefix + coach_code + "-.txt":
|
| 261 |
+
raise gr.Error(f"You must be LOGGED IN to Chat. Refresh the page and try again.")
|
| 262 |
+
|
| 263 |
+
# Determine appropriate system prompt based on new or returning user
|
| 264 |
+
# This is a placeholder line, replace it with your actual function logic that creates the prompt message
|
| 265 |
+
system_prompt = get_system_prompt(user_id)
|
| 266 |
+
|
| 267 |
+
history_openai_format = system_prompt
|
| 268 |
for human, assistant in history:
|
| 269 |
+
history_openai_format.append({"role": "user", "content": human })
|
| 270 |
+
history_openai_format.append({"role": "assistant", "content":assistant})
|
| 271 |
history_openai_format.append({"role": "user", "content": user_input})
|
| 272 |
|
| 273 |
completion = client.chat.completions.create(
|
| 274 |
model=openai_model,
|
| 275 |
+
messages= history_openai_format,
|
| 276 |
+
temperature=1.0,
|
| 277 |
frequency_penalty=0.4,
|
| 278 |
presence_penalty=0.1,
|
| 279 |
stream=True
|
| 280 |
)
|
| 281 |
|
| 282 |
output_stream = ""
|
| 283 |
+
for chunk in completion:
|
| 284 |
+
if chunk.choices[0].delta.content is not None:
|
| 285 |
+
output_stream = output_stream + (chunk.choices[0].delta.content)
|
| 286 |
+
yield output_stream
|
| 287 |
+
message_content = output_stream
|
| 288 |
+
|
| 289 |
+
# Prepare the transcript for the Textbox output
|
| 290 |
+
transcript_file_path = f"{prefix}{coach_code}-{user_id}-transcript.txt"
|
| 291 |
+
if os.path.exists(transcript_file_path):
|
| 292 |
+
with open(transcript_file_path, "r", encoding="UTF-8") as file:
|
| 293 |
+
transcript = file.read()
|
| 294 |
+
else:
|
| 295 |
+
transcript = "START OF CONVERSATION - Date/Time: " + datetime.now().strftime("%Y-%m-%d %H:%M:%S") + "\n\n"
|
| 296 |
|
| 297 |
# Append latest user and assistant messages to the transcript
|
| 298 |
+
transcript += f"YOU: {user_input}\n"
|
| 299 |
+
transcript += f"{coach_name_upper}: {message_content}\n\n"
|
| 300 |
+
|
| 301 |
# Write the updated transcript to the file
|
| 302 |
+
with open(transcript_file_path, "w", encoding="UTF-8") as file:
|
| 303 |
file.write(transcript)
|
| 304 |
|
| 305 |
+
# Get the last exchange (the user input and the assistant's message)
|
| 306 |
+
last_exchange = f"User: {user_input}\nAssistant: {message_content}\n\n"
|
| 307 |
+
|
| 308 |
+
# Write the last exchange to the history file
|
| 309 |
+
with open(user_hist_file, "a+", encoding="UTF-8") as file:
|
| 310 |
+
file.write(last_exchange)
|
| 311 |
+
return message_content, transcript
|
| 312 |
+
|
| 313 |
+
# Function to update transcript
|
| 314 |
+
def update_transcript(transcript_update, user_id):
|
| 315 |
+
transcript_file_path = f"{prefix}{coach_code}-{user_id}-transcript.txt"
|
| 316 |
+
if os.path.exists(transcript_file_path):
|
| 317 |
+
with open(transcript_file_path, "r", encoding="UTF-8") as file:
|
| 318 |
+
transcript = file.read()
|
| 319 |
+
else:
|
| 320 |
+
transcript = "START OF CONVERSATION - Date/Time: " + datetime.now().strftime("%Y-%m-%d %H:%M:%S") + "\n\n"
|
| 321 |
+
transcript += transcript_update
|
| 322 |
+
with open(transcript_file_path, "w", encoding="UTF-8") as file:
|
| 323 |
+
file.write(transcript)
|
| 324 |
+
return transcript
|
| 325 |
+
|
| 326 |
+
def get_user_summary(name):
|
| 327 |
+
global user_id
|
| 328 |
+
name_cap = str(name)
|
| 329 |
+
user_id = name.strip().upper().replace(" ", "")
|
| 330 |
+
name_cap = name_cap.title()
|
| 331 |
+
summary = "Welcome! Please proceed to the '" + coach_name_long + "' tab (at top of chatbot) to chat."
|
| 332 |
+
user_summ_file = f"{prefix}{coach_code}-{user_id}-summ.txt"
|
| 333 |
+
if os.path.exists(user_summ_file):
|
| 334 |
+
with open(user_summ_file, "r", encoding="UTF-8") as file:
|
| 335 |
+
summary = file.read().strip()
|
| 336 |
+
summary = summary.replace("User", "Client")
|
| 337 |
+
summary = summary.replace("user", "Client")
|
| 338 |
+
summary = summary.replace("the assistant", coach_name_short)
|
| 339 |
+
summary = summary.replace("The assistant", coach_name_short)
|
| 340 |
+
summary = summary.replace("- Assistant", "- Coach")
|
| 341 |
+
summary = f"COACH: {coach_name_short}\n\nLAST ENCOUNTER: {summary}"
|
| 342 |
+
return "Welcome! Please proceed to the '" + coach_name_long + "' tab (at top of chatbot) to chat", summary, admin()
|
| 343 |
+
|
| 344 |
+
def admin():
|
| 345 |
+
if user_id == "POIPOIPOI":
|
| 346 |
+
# Set the directory path
|
| 347 |
+
directory_path = "data" # different on huggingface
|
| 348 |
+
|
| 349 |
+
# Get a list of all files in the directory
|
| 350 |
+
file_list = os.listdir(directory_path)
|
| 351 |
+
|
| 352 |
+
# Print the list of files
|
| 353 |
+
for file_name in file_list:
|
| 354 |
+
print(file_name)
|
| 355 |
|
| 356 |
#GUI
|
| 357 |
+
with gr.Blocks(theme) as demo:
|
| 358 |
+
output_choice = gr.State('Text') # Set 'Text' as the default state value
|
| 359 |
+
|
| 360 |
+
with gr.Tabs() as tabs:
|
| 361 |
+
with gr.TabItem("Log In"):
|
| 362 |
+
username_input = gr.Textbox(label="Username (REQUIRED):", placeholder="Enter your USERNAME", type="text")
|
| 363 |
+
password_input = gr.Textbox(label="Emailed Code (REQUIRED):", placeholder="Enter CODE from your email", type="password")
|
| 364 |
+
|
| 365 |
+
# The submit_name function will expect two inputs
|
| 366 |
+
name = ""
|
| 367 |
+
password = ""
|
| 368 |
+
|
| 369 |
+
def submit_name(name, password):
|
| 370 |
+
name = name + "7777"
|
| 371 |
+
pwd = password
|
| 372 |
+
if name != pwd:
|
| 373 |
+
name = "NOTLOGGEDIN"
|
| 374 |
+
raise gr.Error(f"You must be LOGGED IN to Chat. Refresh the page, log in, and try again.")
|
| 375 |
+
if name == "":
|
| 376 |
+
name = "NOTLOGGEDIN"
|
| 377 |
+
raise gr.Error(f"You must be LOGGED IN to Chat. Refresh the page, log in, and try again.")
|
| 378 |
+
else:
|
| 379 |
+
name = name[:-4]
|
| 380 |
+
user_summary = get_user_summary(name)
|
| 381 |
+
return user_summary[0] if isinstance(user_summary, tuple) else user_summary
|
| 382 |
+
|
| 383 |
+
submit_name_button = gr.Button("Log in")
|
| 384 |
+
status_text = gr.Label(label="", container=False)
|
| 385 |
+
|
| 386 |
+
submit_name_button.click(
|
| 387 |
+
fn=submit_name,
|
| 388 |
+
inputs=[username_input, password_input],
|
| 389 |
+
outputs=[status_text]
|
| 390 |
+
)
|
| 391 |
+
|
| 392 |
+
# Attach submit event to both the username and password fields
|
| 393 |
+
username_input.submit(
|
| 394 |
+
fn=submit_name,
|
| 395 |
+
inputs=[username_input, password_input],
|
| 396 |
+
outputs=[status_text]
|
| 397 |
+
)
|
| 398 |
+
|
| 399 |
+
# Make sure this is done for the password field as well
|
| 400 |
+
password_input.submit(
|
| 401 |
+
fn=submit_name,
|
| 402 |
+
inputs=[username_input, password_input],
|
| 403 |
+
outputs=[status_text]
|
| 404 |
+
)
|
| 405 |
+
|
| 406 |
+
with gr.TabItem(coach_name_long):
|
| 407 |
+
gr.ChatInterface(
|
| 408 |
+
predict,
|
| 409 |
+
submit_btn="Chat with " + coach_name_short,
|
| 410 |
+
retry_btn=None,
|
| 411 |
+
undo_btn=None,
|
| 412 |
+
clear_btn=None,
|
| 413 |
+
css=".gradio-container {height: 1600px !important;}" # Add custom CSS
|
| 414 |
+
)
|
| 415 |
+
|
| 416 |
demo.launch(show_api=False)
|