File size: 6,322 Bytes
ef731f5
 
 
40f4378
b004f02
 
ef731f5
 
44446f1
 
 
ef731f5
747c66b
ef731f5
 
 
 
 
 
642987a
ef731f5
 
4e214c0
44446f1
642987a
4e214c0
b004f02
03a236a
16a9553
b004f02
06276c4
03a236a
b004f02
03a236a
b004f02
 
06276c4
b004f02
2ba3e7a
039f2bb
 
03a236a
 
2ba3e7a
 
1e43141
2ba3e7a
 
039f2bb
2ba3e7a
58ad244
b004f02
039f2bb
 
 
 
df6f427
220d05a
 
 
642987a
4e214c0
e31b43a
4e214c0
 
 
0c30021
4e214c0
0c30021
4e214c0
ef731f5
4e214c0
 
ef731f5
4e214c0
 
ef731f5
 
 
 
4e214c0
782b216
ef731f5
 
 
 
 
0c30021
 
 
 
4e214c0
 
df6f427
4e214c0
 
df6f427
4e214c0
 
 
ef731f5
0c30021
 
df6f427
14d4557
f8ee72d
43ecc91
f8ee72d
 
14d4557
 
9d37210
 
 
 
f8ee72d
 
59581ee
9d37210
 
 
 
 
 
 
 
 
200dad8
14d4557
039f2bb
 
 
59581ee
 
 
 
 
039f2bb
 
f8ee72d
df6f427
039f2bb
220d05a
6d37736
039f2bb
df6f427
0fb5a09
df6f427
4295a64
200dad8
59581ee
 
4295a64
 
 
fe3216c
039f2bb
 
df6f427
81e1809
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import gradio as gr
import os
from openai import OpenAI
from datetime import datetime, timezone, timedelta
import hashlib
import hmac

################# Start PERSONA-SPECIFIC VALUES ######################
coach_code = os.getenv("COACH_CODE")
coach_name_short = os.getenv("COACH_NAME_SHORT")
coach_name_upper = os.getenv("COACH_NAME_UPPER")
sys_prompt_new = os.getenv("PROMPT_NEW")
theme=os.getenv("THEME")
################# End PERSONA-SPECIFIC VALUES ######################

################# Start OpenAI-SPECIFIC VALUES ######################
# Initialize OpenAI API client with API key
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# OpenAI model
openai_model = os.getenv("OPENAI_MODEL")
################# End OpenAI-SPECIFIC VALUES ######################

tx = os.getenv("TX")
prefix = os.getenv("PREFIX")  #  "/data/" if in HF or "data/" if local
file_name = os.getenv("FILE_NAME")

############### VERIFY USER ###################
def generate_access_code(time):
    secret = os.getenv("SHARED_SECRET_KEY")
    
    time_block = time.replace(minute=(time.minute // 10) * 10, second=0, microsecond=0)
    time_string = time_block.strftime('%Y%m%d%H%M')
    
    hmac_obj = hmac.new(secret.encode(), time_string.encode(), hashlib.sha256)
    hmac_digest = hmac_obj.hexdigest()
    
    xor_result = bytes(int(hmac_digest[i], 16) ^ int(hmac_digest[-4+i], 16) for i in range(4))
    
    return xor_result.hex()[:4]

def verify_code(code, access_granted):
    now = datetime.now(timezone.utc)
    
    codes = [generate_access_code(now + timedelta(minutes=offset)) 
             for offset in [-20, -10, 0, 10, 20]]
    
    if code in codes:
        return True, gr.update(interactive=True), gr.update(interactive=True), "Access granted. Please proceed to the Chat tab."
    else:
        return False, gr.update(interactive=False), gr.update(interactive=False), "Incorrect code. Please try again."

############### CHAT ###################
def predict(user_input, history, access_granted):
    if not access_granted:
        return history, "Access not granted. Please enter the correct code in the Access tab."
    
    max_length = 1000
    if len(user_input) > max_length:
        user_input = ""

    transcript_file_path = f"{prefix}{coach_code}-{file_name}"

    if user_input == tx + coach_code:
        try:
            if os.path.exists(transcript_file_path):
                with open(transcript_file_path, "r", encoding="UTF-8") as file:
                    return history, file.read()
        except FileNotFoundError:
            return history, "File '" + file_name + "' not found."

    history_openai_format = [
        {"role": "system", "content": "IDENTITY: " + sys_prompt_new}
    ]
    for human, assistant in history:
        history_openai_format.append({"role": "user", "content": human})
        history_openai_format.append({"role": "assistant", "content": assistant})
    history_openai_format.append({"role": "user", "content": user_input})

    completion = client.chat.completions.create(
        model=openai_model,
        messages=history_openai_format,
        temperature=0.8,
        frequency_penalty=0.4,
        presence_penalty=0.1,
        stream=True
    )

    message_content = ""
    for chunk in completion:
        if chunk.choices[0].delta.content is not None:
            message_content += chunk.choices[0].delta.content

    # Append latest user and assistant messages to the transcript
    transcript = f"Date/Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
    transcript += f"YOU: {user_input}\n\n"
    transcript += f"{coach_name_upper}: {message_content}\n\n\n"
    
    # Write the updated transcript to the file
    with open(transcript_file_path, "a", encoding="UTF-8") as file:
        file.write(transcript)

    history.append((user_input, message_content))
    return history, ""

with gr.Blocks(theme, css="""
    #chatbot { flex-grow: 1; height: 340px; overflow-y: auto; }
    .gradio-container { height: 680px; max-width: 100% !important; padding: 0 !important; }
    #component-0 { height: 95%; }
    #component-3 { height: calc(95% - 250px); }
    footer { display: none !important; }
    #submit-btn { margin-top: 10px; }
    #code_submit {
        height: 50px !important;
        font-size: 1.2em !important;
    }
    .message-wrap { max-height: none !important; overflow-y: auto !important; }
    .chat-wrap { max-height: none !important; overflow-y: auto !important; }

    @media (max-width: 600px) {
        #code_submit {
            height: 60px !important;
            font-size: 1.3em !important;
        }
        #code_message {
            font-size: 1.2em !important;
            padding: 10px !important;
        }
    }
""") as demo:
    access_granted = gr.State(False)

    with gr.Tab("Access"):
        with gr.Tab("Access"):
            gr.Markdown("Enter the Access Code displayed in the upper-left corner.")
            code_input = gr.Textbox(label="Access Code", type="text", placeholder="Enter CODE here...")
            code_submit = gr.Button("Submit Code", elem_id="code_submit")
            code_message = gr.Label(label="Status", elem_id="code_message")

    with gr.Tab("Chat"):
        chatbot = gr.Chatbot(label="Conversation", elem_id="chatbot", height=340)
        msg = gr.Textbox(
            label=f"Chat with {coach_name_short}", 
            placeholder="Type your message here... (MAX: 1000 characters)",
            autofocus=True,
            interactive=False
        )
        submit = gr.Button("Submit Message", interactive=False)

    def submit_code(code, access_granted):
        success, _, _, message = verify_code(code, access_granted)
        color = "#388e3c" if success else "#d32f2f"  # Green for success, Red for error
        return success, gr.update(interactive=success), gr.update(interactive=success), gr.update(value=message, color=color)

    code_input.submit(submit_code, inputs=[code_input, access_granted], outputs=[access_granted, msg, submit, code_message])
    code_submit.click(submit_code, inputs=[code_input, access_granted], outputs=[access_granted, msg, submit, code_message])

    msg.submit(predict, [msg, chatbot, access_granted], [chatbot, msg])
    submit.click(predict, [msg, chatbot, access_granted], [chatbot, msg])

demo.launch(show_api=False)