File size: 9,269 Bytes
aa2e875
df36d20
fcab49d
0944853
aa2e875
bb63de8
 
 
 
 
a0e8812
 
54f7f86
39193db
547e5c5
88d5b1a
 
 
 
 
 
9266a10
88d5b1a
 
 
 
 
 
 
 
 
 
 
9266a10
 
547e5c5
 
 
 
9266a10
 
 
 
 
 
 
 
 
 
547e5c5
a0e8812
39193db
ce17a21
2fa8fbf
c35fe56
7b69fde
 
0d614c5
 
4cfce75
 
 
64a8d23
 
4cfce75
5f09f43
4cfce75
343724c
5f09f43
c35fe56
5f09f43
c35fe56
5f09f43
64a8d23
 
39193db
54f7f86
64a8d23
 
5f09f43
c35fe56
39193db
 
 
 
 
7fe812c
 
 
288fcab
64a8d23
 
288fcab
 
 
64a8d23
 
288fcab
 
 
64a8d23
 
288fcab
 
 
64a8d23
 
288fcab
 
343724c
64a8d23
 
7fe812c
 
 
64a8d23
 
5f09f43
 
b8ac00f
5f09f43
b8ac00f
 
 
 
 
 
 
 
 
 
 
 
 
96e77e9
64a8d23
7c5277c
9266a10
 
2fa8fbf
b8ac00f
64a8d23
7c5277c
b8ac00f
07fe324
64a8d23
39193db
c35fe56
 
 
 
 
 
39193db
 
 
 
 
 
 
 
 
64a8d23
c35fe56
 
 
 
 
 
 
 
 
7fe812c
c35fe56
 
39193db
c35fe56
64a8d23
39193db
 
 
 
 
 
 
a803285
88d5b1a
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import gradio as gr
import openai

openai.api_key = "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"

theme = gr.themes.Monochrome()
css = "@import url(https://fonts.googleapis.com/css2?family=Silkscreen&display=swap);.gradio-container{" \
      "background-color:#f3e8ff;font-family:Silkscreen}.tabitem,button{background-color:#002366}"

with gr.Blocks(theme=theme, css=css) as iface:
    chatbot = []
    msg = []
    accusationButtons = []
    culpritId = 1
    roles = ["Security Guard", "Curator", "Researcher", "Conservationist", "Tour Guide"]
    initText = ["You are Steve Binner, 31, a security guard for a museum of medieval "
                "history. You're absolutely sure that this place is haunted. A month ago, "
                "before the spooky stuff started, you were really happy with your job, "
                "but that changed real fast. The ghost is a french nobleman named Baron "
                "Hugo Antoine the Third. You've been trying to tell other people about "
                "this, but  you've only been laughed at so far. But you've got evidence! "
                "Every thursday, around 10pm, the broom closet gets locked from the inside and "
                "the interior gets wrecked. We're talking pushed over tables, "
                "broken containers, the whole shebang. When it comes to the murder of "
                "director Eisenholz last thursday, that has to have been the ghost, "
                "no question. You even have the door card records for the room he was in: "
                "After the museum closed at 5pm, nobody entered that room till the next "
                "morning. Now you're being interrogated by a detective. You don't use "
                "uptight language, and you're not super well educated on most stuff, "
                "but when it comes to the paranormal, you're an ace. ",
                "You are a Curator. ",
                "You are a Researcher. ",
                "You are a Conservationist. ",
                "You are Lyanne Brimes, 27, a tour guide for a medieval history museum. You graduated from university "
                "a few years ago and have a degree in history. You work here part-time. You know director Eisenholz "
                "very well because you had a secret relationship. You'd prefer not to disclose any info about it "
                "unless pressed. You met every Thursday in the broom cupboard for your private meeting. You thought "
                "no one knew, but you are not sure anymore. Lately Eisenholz has been behaving very strangely. "
                "Something was troubling him. You tried to talk to him about it the"
                "night of the murder, but he never showed up. After waiting in the closet for 2 hours, you decided to "
                "go home. On your way out, you noticed the door to the room with all the weapons was open, "
                "but you thought Steve, the security guard, might be lurking around. Some might think Steve could be "
                "the murderer because he's been going crazy lately with the whole ghost thing and because he has "
                "access to every room, but you don't think he could have done it because he's kind-hearted. You are "
                "not the murderer, but if you had to guess who it was, you would say it was the curator. The curator "
                "and Eisenholz have been arguing recently about a medallion that has been in his family for "
                "centuries, but he doesn't want to give it to the museum because it's too valuable. You think you "
                "have a good nose for murder because you read detective novels. Now you're being questioned by a "
                "detective. You use formal language and are very well educated in history, especially medieval "
                "history. You have a bubbly personality. "]

    with gr.Row() as chatRow:
        with gr.Column(scale=2):
            questionCounter = gr.Label(label="Remaining Questions", value="24")
            mapButton = gr.Button("Show Floor Plan")
            finishButton = gr.Button("Try to Solve")
        with gr.Column(scale=10):
            i = 0
            while i < len(roles):
                with gr.Tab(roles[i]):
                    with gr.Row():
                        with gr.Column(scale=9):
                            chatbot.append(gr.Chatbot(label=roles[i]))
                            msg.append(gr.Textbox(label=""))
                        with gr.Column(scale=3):
                            characterImage = gr.Label(label="", elem_classes="character-image-" + str(i))
                i += 1

    with gr.Row(visible=False, elem_classes="abs-window") as mapRow:
        with gr.Column():
            closeMapButton = gr.Button("X", elem_classes="close-button")

    with gr.Row(visible=False, elem_classes="abs-window") as solvingRow:
        i = 0
        while i < len(roles):
            with gr.Column():
                accusationButtons.append(gr.Button(roles[i]))
            i += 1

        closeSolvingButton = gr.Button("X", elem_classes="close-button")

    with gr.Row(visible=False) as resultRow:
        with gr.Column():
            resultLabel = gr.Label(label="Result")


    def user(user_message, history):
        return "", history + [[user_message, None]]

    # this is an ugly workaround, you cannot pass regular integers to gradio functions, so i had to do it this way
    def bot0(history, questionCounterText):
        bot_message = generateAIMessage(history, questionCounterText, 0)
        history[-1][1] = bot_message
        return history

    def bot1(history, questionCounterText):
        bot_message = generateAIMessage(history, questionCounterText, 1)
        history[-1][1] = bot_message
        return history

    def bot2(history, questionCounterText):
        bot_message = generateAIMessage(history, questionCounterText, 2)
        history[-1][1] = bot_message
        return history

    def bot3(history, questionCounterText):
        bot_message = generateAIMessage(history, questionCounterText, 3)
        history[-1][1] = bot_message
        return history

    def bot4(history, questionCounterText):
        bot_message = generateAIMessage(history, questionCounterText, 4)
        history[-1][1] = bot_message
        return history

    def generateAIMessage(history, questionCounterText, characterId):
        if checkIfQuestionsLeft(questionCounterText):
            initSysMessage = initText[characterId] + "Stay in character. Use natural language. Don't reveal all of " \
                                                     "the information in a single message, and leave hints."
            message_history = [
                {"role": "system", "content": initSysMessage}
            ]
            for pair in history:
                message_history.append({"role": "user", "content": pair[0]})
                print()
                if pair[1] is not None:
                    message_history.append({"role": "assistant", "content": pair[1]})
            completion = openai.ChatCompletion.create(
                model="gpt-3.5-turbo",
                messages=message_history
            )
            return completion.choices[0].message.content
        else:
            return "--- YOU'VE RUN OUT OF QUESTIONS, MAKE YOUR CHOICE ---"

    def updateQuestions(questionCounterText):
        remainingQuestions = int(questionCounterText["label"])
        if remainingQuestions > 0:
            remainingQuestions -= 1
        return str(remainingQuestions)
    
    def checkIfQuestionsLeft(questionCounterText):
        remainingQuestions = int(questionCounterText["label"])
        return remainingQuestions > 0

    def tryToSolve():
        return {solvingRow: gr.update(visible=True)}
    def showMap():
        return {mapRow: gr.update(visible=True)}
    def hideSolveBox():
        return {solvingRow: gr.update(visible=False)}
    def hideMap():
        return {mapRow: gr.update(visible=False)}

    def showResult():
        return {chatRow: gr.update(visible=False), solvingRow: gr.update(visible=False), resultRow: gr.update(visible=True)}

    def declareLoss():
        return "You failed! The real culprit got away... "

    def declareVictory():
        return "Congratulations, you found the killer! "

    botfunctions = [bot0, bot1, bot2, bot3, bot4]
    i = 0
    while i < len(roles):
        msg[i].submit(user, [msg[i], chatbot[i]], [msg[i], chatbot[i]], queue=False).then(
            botfunctions[i], [chatbot[i], questionCounter], chatbot[i]
        ).then(
            updateQuestions, questionCounter, questionCounter
        )
        i += 1

    mapButton.click(showMap, None, mapRow)
    closeMapButton.click(hideMap, None, mapRow)
    finishButton.click(tryToSolve, None, solvingRow)
    closeSolvingButton.click(hideSolveBox, None, solvingRow)

    i = 0
    while i < len(roles):
        if i == culpritId:
            accusationButtons[i].click(showResult, None, [chatRow, solvingRow, resultRow]).then(declareVictory, None, resultLabel)
        else:
            accusationButtons[i].click(showResult, None, [chatRow, solvingRow, resultRow]).then(declareLoss, None, resultLabel)
        i += 1

iface.launch()