File size: 6,164 Bytes
dac5204
3b538c3
 
 
86cfbfc
3b538c3
26dfd6d
b90e510
fa1ff63
b90e510
3b538c3
ae32d37
7864b80
37f3329
b721670
eb4fba4
265877f
eb4fba4
265877f
 
8d2a3b9
fa132d6
265877f
 
 
 
 
 
b721670
 
f934fb5
 
b90e510
fa132d6
b721670
92a0a4b
37f3329
92a0a4b
 
 
 
 
 
 
 
 
 
 
 
b90e510
fa1ff63
 
b90e510
d8ad4e5
b90e510
fa1ff63
 
b90e510
37f3329
cddb36c
 
 
 
 
 
 
 
 
f934fb5
cddb36c
fa132d6
f934fb5
 
 
b721670
0f8cdfc
8ddef28
 
 
 
0f8cdfc
b721670
eb4fba4
1e727da
26dfd6d
 
4d8d96a
 
1e727da
7fb89c6
b721670
 
37f3329
67283e0
4f9dc3a
fa1ff63
daf6d51
523df60
423d2e0
523df60
37f3329
d62f529
423d2e0
b721670
523df60
26dfd6d
523df60
 
 
 
37f3329
9718b0e
37f3329
265877f
37f3329
daf6d51
26dfd6d
37f3329
 
26dfd6d
 
 
 
 
 
 
0f8cdfc
26dfd6d
cddb36c
f934fb5
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
import os
import gradio as gr
import pandas as pd
from functools import partial
from ai_classroom_suite.UIBaseComponents import *

### User Interface Chatbot Functions ###
def get_tutor_reply(chat_tutor):
  chat_tutor.get_tutor_reply()
  return gr.update(value="", interactive=True), chat_tutor.conversation_memory, chat_tutor

def get_conversation_history(chat_tutor):
    return chat_tutor.conversation_memory, chat_tutor
    
### Instructor Interface Helper Functions ###
def get_instructor_prompt(fileobj):
    # get file path
    file_path = fileobj.name
    with open(file_path, "r") as f: 
        instructor_prompt = f.read()
    return instructor_prompt

def embed_prompt(prompt, chat_tutor):
    # update secret
    os.environ["SECRET_PROMPT"] = prompt
    # update tutor
    chat_tutor.learning_objectives = prompt
    return os.environ.get("SECRET_PROMPT"), chat_tutor
    
### User Interfaces ###
with gr.Blocks() as demo:
    #initialize tutor (with state)
    study_tutor = gr.State(SlightlyDelusionalTutor())

    # Student interface
    with gr.Tab("For Students"): 
        
        # Chatbot interface
        gr.Markdown("""
        ## Chat with the Model
        Description here
        """)
    
        with gr.Row(equal_height=True):
            with gr.Column(scale=2):
              chatbot = gr.Chatbot()
              with gr.Row():
                user_chat_input = gr.Textbox(label="User input", scale=9)
                user_chat_submit = gr.Button("Ask/answer model", scale=1)

        # First add user's message to the conversation history
        # Then get reply from the tutor and add that to the conversation history
        user_chat_submit.click(
            fn = add_user_message, inputs = [user_chat_input, study_tutor], outputs = [user_chat_input, chatbot, study_tutor], queue=False
        ).then(
            fn = get_tutor_reply, inputs = [study_tutor], outputs = [user_chat_input, chatbot, study_tutor], queue=True
        )

        # Download conversation history file
        with gr.Blocks():
            gr.Markdown("""
            ## Export Your Chat History
            Export your chat history as a .json, .txt, or .csv file
            """)
            with gr.Row():
                export_dialogue_button_json = gr.Button("JSON")
                export_dialogue_button_txt = gr.Button("TXT")
                export_dialogue_button_csv = gr.Button("CSV")
        
            file_download = gr.Files(label="Download here", file_types=['.json', '.txt', '.csv'], type="file", visible=False)
        
        export_dialogue_button_json.click(save_json, study_tutor, file_download, show_progress=True)
        export_dialogue_button_txt.click(save_txt, study_tutor, file_download, show_progress=True)
        export_dialogue_button_csv.click(save_csv, study_tutor, file_download, show_progress=True)

        # Testing the chat history storage, can be deleted at deployment
        with gr.Blocks():
            test_btn = gr.Button("View your chat history")
            chat_history = gr.JSON(label = "conversation history")
            test_btn.click(get_conversation_history, inputs=[study_tutor], outputs=[chat_history, study_tutor])

    # Instructor interface
    with gr.Tab("Instructor Only"):
        """
        API Authentication functionality
        Instead of ask students to provide key, the key is now provided by the instructor. 
        To permanently set the key, go to Settings -> Variables and secrets -> Secrets, 
        then replace OPENAI_API_KEY value with whatever openai key of the instructor.
        """
        api_input = gr.Textbox(show_label=False, type="password", visible=False, value=os.environ.get("OPENAI_API_KEY"))

        # Upload secret prompt functionality
        # The instructor will provide a secret prompt/persona to the tutor
        with gr.Blocks():
            # testing purpose, change visible to False at deployment
            view_secret = gr.Textbox(label="Current secret prompt", value=os.environ.get("SECRET_PROMPT"), visible=False)

            # Prompt instructor to upload the secret file
            file_input = gr.File(label="Load a .txt or .py file", file_types=['.py', '.txt'], type="file", elem_classes="short-height")
            
            # Verify prompt content
            instructor_prompt = gr.Textbox(label="Verify your prompt content", visible=True)
            file_input.upload(fn=get_instructor_prompt, inputs=file_input, outputs=instructor_prompt)

            # Placeholders components
            text_input_none = gr.Textbox(visible=False)
            file_input_none = gr.File(visible=False)
            instructor_input_none = gr.TextArea(visible=False)
            learning_objectives_none = gr.Textbox(visible=False)

            # Set the secret prompt in this session and embed it to the study tutor
            prompt_submit_btn = gr.Button("Submit")
            prompt_submit_btn.click(
                fn=embed_prompt, inputs=[instructor_prompt, study_tutor], outputs=[view_secret, study_tutor]
            ).then(
                fn=create_reference_store, 
                inputs=[study_tutor, prompt_submit_btn, instructor_prompt, file_input_none, instructor_input_none, api_input, instructor_prompt],
                outputs=[study_tutor, prompt_submit_btn]
            )
            
            # TODO: The instructor prompt is now only set in session if not go to Settings/secret, 
            # to "permanently" set the secret prompt not seen by the students who use this space, 
            # one possible way is to recreate the instructor interface in another space, 
            # and load it here to chain with the student interface
            
            # TODO: Currently, the instructor prompt is handled as text input and stored in the vector store (and in the learning objective),
            # which means the tutor now is still a question-answering tutor who viewed the prompt as context (but not really acting based on it). 
            # We need to find a way to provide the prompt directly to the model and set its status. 
    
demo.queue().launch(server_name='0.0.0.0', server_port=7860)