Spaces:
Sleeping
Sleeping
Changed to 3 choices
Browse files- app.py +9 -114
- chat_gpt.py +3 -3
- chat_quest.py +4 -3
- utils.py +114 -0
app.py
CHANGED
@@ -1,91 +1,8 @@
|
|
1 |
from functools import partial
|
2 |
-
import time
|
3 |
import gradio as gr
|
4 |
|
5 |
-
from
|
6 |
|
7 |
-
def clear_text_box():
|
8 |
-
return gr.Textbox.update(value='')
|
9 |
-
|
10 |
-
def format_goal_messsage(goal: str) -> str:
|
11 |
-
return f'###### **Objetivo:** {goal}'
|
12 |
-
|
13 |
-
def format_chat_header(name: str) -> str:
|
14 |
-
return f'**{name}**<br>Active now'
|
15 |
-
|
16 |
-
|
17 |
-
def _format_dialogue(dialogue_list, opponent):
|
18 |
-
formatted_dialogue = []
|
19 |
-
for entry in dialogue_list:
|
20 |
-
player_line, opponent_line = entry
|
21 |
-
if opponent_line:
|
22 |
-
formatted_dialogue.append(f"{opponent}: {opponent_line}")
|
23 |
-
if player_line:
|
24 |
-
formatted_dialogue.append(f"Player: {player_line}")
|
25 |
-
return '\n'.join(formatted_dialogue)
|
26 |
-
|
27 |
-
|
28 |
-
def retry_level(current_situation: ConversationSituation):
|
29 |
-
choices_update = [gr.update(value=c, interactive=True, visible=True) for c in current_situation.starting_choices]
|
30 |
-
outcome_update = gr.update(visible=False)
|
31 |
-
chat_history_update = [(None, current_situation.first_message)]
|
32 |
-
|
33 |
-
return choices_update + [current_situation.starting_choices, outcome_update, chat_history_update, chat_history_update]
|
34 |
-
|
35 |
-
|
36 |
-
def load_next_level():
|
37 |
-
new_situation = sample_conversation_christmas
|
38 |
-
choices_update = [gr.update(value=c, interactive=True, visible=True) for c in new_situation.starting_choices]
|
39 |
-
outcome_update = gr.update(visible=False)
|
40 |
-
chat_history_update = [(None, new_situation.first_message)]
|
41 |
-
|
42 |
-
opponent_name = format_chat_header(new_situation.character)
|
43 |
-
goal_message = format_goal_messsage(new_situation.goal_message)
|
44 |
-
|
45 |
-
|
46 |
-
return choices_update + [new_situation, new_situation.starting_choices, outcome_update, chat_history_update, chat_history_update] + [new_situation.character_emoji, opponent_name, goal_message, False]
|
47 |
-
|
48 |
-
|
49 |
-
def update_chat(choice_index, choices, msg_history):
|
50 |
-
history = msg_history or []
|
51 |
-
|
52 |
-
|
53 |
-
print(choice_index, choices)
|
54 |
-
user_msg = choices[choice_index]
|
55 |
-
|
56 |
-
history.append((user_msg, None))
|
57 |
-
|
58 |
-
return [history, history] + [gr.update(interactive=False) for _ in choice_buttons]
|
59 |
-
|
60 |
-
|
61 |
-
def process_last_msg(msg_history, conversation_situation: ConversationSituation):
|
62 |
-
# Wait for history to update with the last user input
|
63 |
-
time.sleep(0.2)
|
64 |
-
history = msg_history or []
|
65 |
-
|
66 |
-
dialogue = _format_dialogue(history, conversation_situation.character)
|
67 |
-
|
68 |
-
dialogue_length = len(history)
|
69 |
-
|
70 |
-
print(dialogue_length)
|
71 |
-
|
72 |
-
if dialogue_length > 6:
|
73 |
-
bot_response = generate_last_response(situation=conversation_situation, dialogue=dialogue)
|
74 |
-
choices_update = [gr.update(visible=False) for _ in conversation_situation.starting_choices]
|
75 |
-
won_update = [gr.update(visible=bot_response.has_won)]
|
76 |
-
lost_update = [gr.update(visible=not bot_response.has_won)]
|
77 |
-
else:
|
78 |
-
bot_response = generate_chat_response(situation=conversation_situation, dialogue=dialogue)
|
79 |
-
choices_update = [gr.update(value=c, interactive=True) for c in bot_response.choices]
|
80 |
-
won_update = [gr.update(visible=bot_response.has_won)]
|
81 |
-
lost_update = [gr.update(visible=False)]
|
82 |
-
|
83 |
-
history.append((None, bot_response.message))
|
84 |
-
chat_update = [bot_response.has_won, bot_response.choices, history, history]
|
85 |
-
|
86 |
-
return chat_update + choices_update + won_update + lost_update
|
87 |
-
|
88 |
-
|
89 |
|
90 |
demo = gr.Blocks(
|
91 |
css="#gradio_center {text-align: center} #char_icon {font-size: 24px; padding-top: 0px; padding-bottom: 0px;}",
|
@@ -103,7 +20,13 @@ with demo:
|
|
103 |
## Title
|
104 |
gr.Markdown('# Chat Quest!', elem_id='gradio_center')
|
105 |
|
106 |
-
input_openai_key = gr.Textbox(
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
|
108 |
with gr.Column(variant='panel'):
|
109 |
## Header
|
@@ -144,8 +67,7 @@ with demo:
|
|
144 |
inputs=[current_choices, chat_history],
|
145 |
outputs=[chat_output, chat_history] + choice_buttons,
|
146 |
queue=False
|
147 |
-
)
|
148 |
-
c.click(
|
149 |
process_last_msg,
|
150 |
inputs=[chat_history, current_situation],
|
151 |
outputs=[user_win_state, current_choices, chat_output, chat_history] + choice_buttons + [outcome_won, outcome_lost]
|
@@ -165,39 +87,12 @@ with demo:
|
|
165 |
queue=False
|
166 |
)
|
167 |
|
168 |
-
def update_openai_key(input_key: str):
|
169 |
-
import openai
|
170 |
-
|
171 |
-
processed_pw = process_key(input_key)
|
172 |
-
is_valid_login = validate_openai_key(processed_pw)
|
173 |
-
|
174 |
-
if is_valid_login:
|
175 |
-
openai.api_key = processed_pw
|
176 |
-
else:
|
177 |
-
gr.Warning("Not a valid password")
|
178 |
-
|
179 |
-
return gr.update(value='', visible=not is_valid_login)
|
180 |
-
|
181 |
input_openai_key.submit(
|
182 |
update_openai_key,
|
183 |
inputs=[input_openai_key],
|
184 |
outputs=[input_openai_key]
|
185 |
)
|
186 |
|
187 |
-
|
188 |
-
def process_key(openai_key: str):
|
189 |
-
import os
|
190 |
-
|
191 |
-
result = openai_key
|
192 |
-
|
193 |
-
if openai_key.lower() == os.environ.get('USER'):
|
194 |
-
result = os.environ.get('PASSWORD')
|
195 |
-
|
196 |
-
return result
|
197 |
-
|
198 |
-
def validate_openai_key(password: str):
|
199 |
-
return password.startswith("sk-")
|
200 |
-
|
201 |
if __name__ == "__main__":
|
202 |
demo.launch(
|
203 |
server_port=None,
|
|
|
1 |
from functools import partial
|
|
|
2 |
import gradio as gr
|
3 |
|
4 |
+
from utils import *
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
demo = gr.Blocks(
|
8 |
css="#gradio_center {text-align: center} #char_icon {font-size: 24px; padding-top: 0px; padding-bottom: 0px;}",
|
|
|
20 |
## Title
|
21 |
gr.Markdown('# Chat Quest!', elem_id='gradio_center')
|
22 |
|
23 |
+
input_openai_key = gr.Textbox(
|
24 |
+
label='Para jugar necesitás una API key de OpenAI.',
|
25 |
+
placeholder='sk-********************',
|
26 |
+
type='password',
|
27 |
+
interactive=True,
|
28 |
+
autofocus=True
|
29 |
+
)
|
30 |
|
31 |
with gr.Column(variant='panel'):
|
32 |
## Header
|
|
|
67 |
inputs=[current_choices, chat_history],
|
68 |
outputs=[chat_output, chat_history] + choice_buttons,
|
69 |
queue=False
|
70 |
+
).then(
|
|
|
71 |
process_last_msg,
|
72 |
inputs=[chat_history, current_situation],
|
73 |
outputs=[user_win_state, current_choices, chat_output, chat_history] + choice_buttons + [outcome_won, outcome_lost]
|
|
|
87 |
queue=False
|
88 |
)
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
input_openai_key.submit(
|
91 |
update_openai_key,
|
92 |
inputs=[input_openai_key],
|
93 |
outputs=[input_openai_key]
|
94 |
)
|
95 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
if __name__ == "__main__":
|
97 |
demo.launch(
|
98 |
server_port=None,
|
chat_gpt.py
CHANGED
@@ -22,14 +22,14 @@ def get_chatgpt_answer(user_msg: str, system_msg: str=default_system_message, te
|
|
22 |
@backoff.on_exception(backoff.expo, (openai.error.RateLimitError, openai.error.APIConnectionError))
|
23 |
def get_chatgpt_serious_answer(user_msg: str) -> str:
|
24 |
completion = openai.ChatCompletion.create(
|
25 |
-
model='gpt-3.5-turbo-0613',
|
26 |
-
|
27 |
messages=[
|
28 |
{"role": "system", "content": "You are a instruction-following bot and you give the user exactly what they want, in the format they want, and nothing else. You have set verbose=0."},
|
29 |
{"role": "user", "content": user_msg},
|
30 |
],
|
31 |
temperature=0.0,
|
32 |
-
frequency_penalty=0.
|
33 |
#n=3,
|
34 |
#top_p=0.7,
|
35 |
)
|
|
|
22 |
@backoff.on_exception(backoff.expo, (openai.error.RateLimitError, openai.error.APIConnectionError))
|
23 |
def get_chatgpt_serious_answer(user_msg: str) -> str:
|
24 |
completion = openai.ChatCompletion.create(
|
25 |
+
# model='gpt-3.5-turbo-0613',
|
26 |
+
model="gpt-3.5-turbo",
|
27 |
messages=[
|
28 |
{"role": "system", "content": "You are a instruction-following bot and you give the user exactly what they want, in the format they want, and nothing else. You have set verbose=0."},
|
29 |
{"role": "user", "content": user_msg},
|
30 |
],
|
31 |
temperature=0.0,
|
32 |
+
frequency_penalty=0.2,
|
33 |
#n=3,
|
34 |
#top_p=0.7,
|
35 |
)
|
chat_quest.py
CHANGED
@@ -4,6 +4,7 @@ from dataclasses import dataclass
|
|
4 |
|
5 |
from chat_gpt import get_chatgpt_answer, get_chatgpt_serious_answer
|
6 |
|
|
|
7 |
|
8 |
@dataclass
|
9 |
class ConversationSituation:
|
@@ -61,7 +62,7 @@ sample_conversation = ConversationSituation(
|
|
61 |
first_message="""Te estás portando mal, serás castigada! No voy a darte ningún regalo este año.""",
|
62 |
starting_choices=[
|
63 |
"No me importan los regalos 😏",
|
64 |
-
"Nooo, Papá Noel, por favor! 🙏",
|
65 |
"Lo entiendo, sí, me porté mal 😞",
|
66 |
"Mentira! Me porté bien 😤"
|
67 |
]
|
@@ -77,7 +78,7 @@ sample_conversation_christmas = ConversationSituation(
|
|
77 |
starting_choices=[
|
78 |
"Perdón, rey de la siesta 👑",
|
79 |
"Hola gatito, ¿puedo dormir con vos? 😴",
|
80 |
-
"Perdón, prometo
|
81 |
"Uh, disculpá, ¿me voy? 🚶♂️",
|
82 |
]
|
83 |
)
|
@@ -116,7 +117,7 @@ def _parse_conversation_response(string: str) -> ConversationResponse:
|
|
116 |
|
117 |
return ConversationResponse(message, has_won, choices)
|
118 |
|
119 |
-
def generate_chat_response(situation: ConversationSituation, dialogue: str, n_choices=
|
120 |
prompt_template = """RULES
|
121 |
Welcome to "TextQuest", an interactive text-based game where you engage in realistic conversations with various characters through your phone. Each conversation reflects different relationships in your life, and your choices will shape the outcome of the story. Get ready to navigate through challenging scenarios, make crucial decisions, and see where your text-based adventures take you!
|
122 |
|
|
|
4 |
|
5 |
from chat_gpt import get_chatgpt_answer, get_chatgpt_serious_answer
|
6 |
|
7 |
+
N_CHOICES = 3
|
8 |
|
9 |
@dataclass
|
10 |
class ConversationSituation:
|
|
|
62 |
first_message="""Te estás portando mal, serás castigada! No voy a darte ningún regalo este año.""",
|
63 |
starting_choices=[
|
64 |
"No me importan los regalos 😏",
|
65 |
+
# "Nooo, Papá Noel, por favor! 🙏",
|
66 |
"Lo entiendo, sí, me porté mal 😞",
|
67 |
"Mentira! Me porté bien 😤"
|
68 |
]
|
|
|
78 |
starting_choices=[
|
79 |
"Perdón, rey de la siesta 👑",
|
80 |
"Hola gatito, ¿puedo dormir con vos? 😴",
|
81 |
+
# "Perdón, prometo no hacer ruido la próxima 🙇",
|
82 |
"Uh, disculpá, ¿me voy? 🚶♂️",
|
83 |
]
|
84 |
)
|
|
|
117 |
|
118 |
return ConversationResponse(message, has_won, choices)
|
119 |
|
120 |
+
def generate_chat_response(situation: ConversationSituation, dialogue: str, n_choices=N_CHOICES):
|
121 |
prompt_template = """RULES
|
122 |
Welcome to "TextQuest", an interactive text-based game where you engage in realistic conversations with various characters through your phone. Each conversation reflects different relationships in your life, and your choices will shape the outcome of the story. Get ready to navigate through challenging scenarios, make crucial decisions, and see where your text-based adventures take you!
|
123 |
|
utils.py
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
|
3 |
+
import time
|
4 |
+
from chat_quest import sample_conversation, sample_conversation_christmas, generate_chat_response, generate_last_response, ConversationSituation, N_CHOICES
|
5 |
+
|
6 |
+
|
7 |
+
def update_chat(choice_index, choices, msg_history):
|
8 |
+
history = msg_history or []
|
9 |
+
|
10 |
+
print(choice_index, choices)
|
11 |
+
user_msg = choices[choice_index]
|
12 |
+
|
13 |
+
history.append((user_msg, None))
|
14 |
+
|
15 |
+
return [history, history] + [gr.update(interactive=False) for _ in range(N_CHOICES)]
|
16 |
+
|
17 |
+
|
18 |
+
def process_last_msg(msg_history, conversation_situation: ConversationSituation):
|
19 |
+
history = msg_history or []
|
20 |
+
|
21 |
+
dialogue = _format_dialogue(history, conversation_situation.character)
|
22 |
+
|
23 |
+
dialogue_length = len(history)
|
24 |
+
|
25 |
+
print(dialogue_length)
|
26 |
+
|
27 |
+
if dialogue_length > 6:
|
28 |
+
bot_response = generate_last_response(situation=conversation_situation, dialogue=dialogue)
|
29 |
+
choices_update = [gr.update(visible=False) for _ in conversation_situation.starting_choices]
|
30 |
+
won_update = [gr.update(visible=bot_response.has_won)]
|
31 |
+
lost_update = [gr.update(visible=not bot_response.has_won)]
|
32 |
+
else:
|
33 |
+
bot_response = generate_chat_response(situation=conversation_situation, dialogue=dialogue)
|
34 |
+
choices_update = [gr.update(value=c, interactive=True) for c in bot_response.choices]
|
35 |
+
won_update = [gr.update(visible=bot_response.has_won)]
|
36 |
+
lost_update = [gr.update(visible=False)]
|
37 |
+
|
38 |
+
history.append((None, bot_response.message))
|
39 |
+
chat_update = [bot_response.has_won, bot_response.choices, history, history]
|
40 |
+
|
41 |
+
return chat_update + choices_update + won_update + lost_update
|
42 |
+
|
43 |
+
|
44 |
+
def clear_text_box():
|
45 |
+
return gr.Textbox.update(value='')
|
46 |
+
|
47 |
+
|
48 |
+
def format_goal_messsage(goal: str) -> str:
|
49 |
+
return f'###### **Objetivo:** {goal}'
|
50 |
+
|
51 |
+
|
52 |
+
def format_chat_header(name: str) -> str:
|
53 |
+
return f'**{name}**<br>Active now'
|
54 |
+
|
55 |
+
|
56 |
+
def retry_level(current_situation: ConversationSituation):
|
57 |
+
choices_update = [gr.update(value=c, interactive=True, visible=True) for c in current_situation.starting_choices]
|
58 |
+
outcome_update = gr.update(visible=False)
|
59 |
+
chat_history_update = [(None, current_situation.first_message)]
|
60 |
+
|
61 |
+
return choices_update + [current_situation.starting_choices, outcome_update, chat_history_update, chat_history_update]
|
62 |
+
|
63 |
+
|
64 |
+
def load_next_level():
|
65 |
+
new_situation = sample_conversation_christmas
|
66 |
+
choices_update = [gr.update(value=c, interactive=True, visible=True) for c in new_situation.starting_choices]
|
67 |
+
outcome_update = gr.update(visible=False)
|
68 |
+
chat_history_update = [(None, new_situation.first_message)]
|
69 |
+
|
70 |
+
opponent_name = format_chat_header(new_situation.character)
|
71 |
+
goal_message = format_goal_messsage(new_situation.goal_message)
|
72 |
+
|
73 |
+
|
74 |
+
return choices_update + [new_situation, new_situation.starting_choices, outcome_update, chat_history_update, chat_history_update] + [new_situation.character_emoji, opponent_name, goal_message, False]
|
75 |
+
|
76 |
+
|
77 |
+
def process_key(openai_key: str):
|
78 |
+
import os
|
79 |
+
|
80 |
+
result = openai_key
|
81 |
+
|
82 |
+
if openai_key.lower() == os.environ.get('USER'):
|
83 |
+
result = os.environ.get('PASSWORD')
|
84 |
+
|
85 |
+
return result
|
86 |
+
|
87 |
+
|
88 |
+
def validate_openai_key(password: str):
|
89 |
+
return password.startswith("sk-")
|
90 |
+
|
91 |
+
|
92 |
+
def update_openai_key(input_key: str):
|
93 |
+
import openai
|
94 |
+
|
95 |
+
processed_pw = process_key(input_key)
|
96 |
+
is_valid_login = validate_openai_key(processed_pw)
|
97 |
+
|
98 |
+
if is_valid_login:
|
99 |
+
openai.api_key = processed_pw
|
100 |
+
else:
|
101 |
+
gr.Warning("Not a valid password")
|
102 |
+
|
103 |
+
return gr.update(value='', visible=not is_valid_login)
|
104 |
+
|
105 |
+
|
106 |
+
def _format_dialogue(dialogue_list, opponent):
|
107 |
+
formatted_dialogue = []
|
108 |
+
for entry in dialogue_list:
|
109 |
+
player_line, opponent_line = entry
|
110 |
+
if opponent_line:
|
111 |
+
formatted_dialogue.append(f"{opponent}: {opponent_line}")
|
112 |
+
if player_line:
|
113 |
+
formatted_dialogue.append(f"Player: {player_line}")
|
114 |
+
return '\n'.join(formatted_dialogue)
|