Spaces:
Sleeping
Sleeping
Init app
Browse files- README.md +0 -13
- api.py +59 -0
- app.py +149 -0
- process.py +115 -0
- requirements.txt +3 -0
- tools.py +129 -0
README.md
DELETED
@@ -1,13 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: EscapeGame
|
3 |
-
emoji: 👁
|
4 |
-
colorFrom: pink
|
5 |
-
colorTo: indigo
|
6 |
-
sdk: gradio
|
7 |
-
sdk_version: 3.40.1
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
-
license: mit
|
11 |
-
---
|
12 |
-
|
13 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
api.py
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os, openai, time
|
2 |
+
from tools import printInColor
|
3 |
+
from concurrent.futures import ThreadPoolExecutor, TimeoutError
|
4 |
+
|
5 |
+
openai.api_key = os.environ["OPENAI_API_KEY"]
|
6 |
+
|
7 |
+
def ask_openai(prompt, assistant=None):
|
8 |
+
printInColor("Asking OpenAI...\n===================\n"+ prompt + "\n====================", 'green')
|
9 |
+
attempt_limit = 3
|
10 |
+
wait_time = 5000
|
11 |
+
timeout_duration = 30 # seconds
|
12 |
+
start_time = time.time() # measure the start time
|
13 |
+
|
14 |
+
prompt = [
|
15 |
+
{"role": "user", "content": prompt}
|
16 |
+
]
|
17 |
+
|
18 |
+
prompt.append({"role": "system", "content": "我们在模拟密室逃脱游戏,你是玩家,我是游戏主持人。你需要通过观察周围的环境来交互。每次玩家行为结束,我需要从头考虑环境变化和影响,构筑新的线索,调整游戏难度,重估剩余步骤。"})
|
19 |
+
|
20 |
+
if assistant:
|
21 |
+
prompt.append({"role": "assistant", "content": assistant})
|
22 |
+
|
23 |
+
models = {
|
24 |
+
"gpt4": "gpt-4",
|
25 |
+
"turbo": "gpt-3.5-turbo",
|
26 |
+
}
|
27 |
+
|
28 |
+
currentModel = models["turbo"]
|
29 |
+
while attempt_limit > 0:
|
30 |
+
try:
|
31 |
+
|
32 |
+
with ThreadPoolExecutor(max_workers=1) as executor:
|
33 |
+
future = executor.submit(
|
34 |
+
openai.ChatCompletion.create,
|
35 |
+
model = currentModel,
|
36 |
+
messages = prompt,
|
37 |
+
stop = ["玩家:", "你可以", "你需要", "你有"],
|
38 |
+
temperature = 0.2,
|
39 |
+
)
|
40 |
+
response = future.result(timeout=timeout_duration)
|
41 |
+
|
42 |
+
print(f"Token: {response.usage}")
|
43 |
+
duration = time.time() - start_time # calculate the duration
|
44 |
+
printInColor(f"Time use: {duration}ms", 'yellow')
|
45 |
+
# print cost
|
46 |
+
# calculate_cost(response, currentModel)
|
47 |
+
break
|
48 |
+
|
49 |
+
except TimeoutError:
|
50 |
+
print(f"Request timed out after {timeout_duration} seconds. Attempts {attempt_limit} left.")
|
51 |
+
except Exception as e:
|
52 |
+
print('Failed to send request. Exception:', e)
|
53 |
+
|
54 |
+
time.sleep(wait_time/1000)
|
55 |
+
wait_time *= 2
|
56 |
+
attempt_limit -= 1
|
57 |
+
|
58 |
+
|
59 |
+
return response
|
app.py
ADDED
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/python
|
2 |
+
# coding:UTF-8
|
3 |
+
|
4 |
+
from flask import Flask, stream_with_context
|
5 |
+
from flask_cors import CORS
|
6 |
+
from process import continue_conversataion
|
7 |
+
import time, uuid
|
8 |
+
|
9 |
+
app = Flask(__name__)
|
10 |
+
CORS(app)
|
11 |
+
|
12 |
+
# final response to awang bot
|
13 |
+
def api_response(text):
|
14 |
+
return {
|
15 |
+
'data': {
|
16 |
+
'type': 'text',
|
17 |
+
'content': text
|
18 |
+
}
|
19 |
+
}
|
20 |
+
|
21 |
+
def botProxy(prompt=None, uid=None, qid=None):
|
22 |
+
|
23 |
+
res = continue_conversataion(prompt, uid, qid)
|
24 |
+
# print(f"res: {res}")
|
25 |
+
|
26 |
+
def generate():
|
27 |
+
for chunk in res:
|
28 |
+
yield chunk.encode('utf-8')
|
29 |
+
|
30 |
+
return res
|
31 |
+
# return app.response_class(stream_with_context(generate()))
|
32 |
+
|
33 |
+
import gradio as gr
|
34 |
+
import time
|
35 |
+
|
36 |
+
css = """
|
37 |
+
#col-container {max-width: 80%; margin-left: auto; margin-right: auto;}
|
38 |
+
#chatbox {min-height: 500px;}
|
39 |
+
#label {font-size: 0.8em; padding: 0.3em; margin: 0;}
|
40 |
+
.message { font-size: 1em; }
|
41 |
+
#sub-chat {
|
42 |
+
background-color: orange;
|
43 |
+
color: white;
|
44 |
+
border: none;
|
45 |
+
padding: 10px 20px;
|
46 |
+
border-radius: 5px;
|
47 |
+
cursor: pointer;
|
48 |
+
}
|
49 |
+
"""
|
50 |
+
|
51 |
+
# Dictionary to maintain separate chat histories for each user ID
|
52 |
+
chatHistories = {}
|
53 |
+
welcome_msg = "你醒来了,发现自己躺在一个陌生的房间里,躺在一张破床上。房间没有窗户,几乎没有光线,什么都看不清。你不知道自己在哪。你感觉自己左小腿疼痛难忍,伸手一模,上面正绑着绷带;正是这种疼痛将你唤醒。你无法正常站立,只能扶着墙慢慢行动;墙面光滑如镜。你感觉自己有些口渴,需要找点水喝。晦暗中你注意到一扇厚重的门,一把坚实的锁把门和墙壁固定在一起。 "
|
54 |
+
|
55 |
+
def submit_message(prompt, uid):
|
56 |
+
|
57 |
+
# Get chat history for the specified user ID, or create a new one if it doesn't exist
|
58 |
+
history = chatHistories.get(uid, [])
|
59 |
+
|
60 |
+
# prevent state for empty input
|
61 |
+
if prompt == "":
|
62 |
+
chat_messages = [(history[i]['content'], history[i+1]['content']) for i in range(0, len(history)-1, 2)]
|
63 |
+
return "", chat_messages, 0
|
64 |
+
|
65 |
+
# continue with non-empty input
|
66 |
+
start_time = time.time() # measure the start time
|
67 |
+
|
68 |
+
# add inital message
|
69 |
+
if history == [] or history is None:
|
70 |
+
history.append({ "role": "user", "content": "游戏开始" })
|
71 |
+
history.append({ "role": "system", "content": welcome_msg })
|
72 |
+
|
73 |
+
# add latest user input
|
74 |
+
prompt_msg = { "role": "user", "content": prompt }
|
75 |
+
history.append(prompt_msg)
|
76 |
+
|
77 |
+
# get result from LLM (OpenAI)
|
78 |
+
# TODO: steaming response
|
79 |
+
res = botProxy(prompt, uid)
|
80 |
+
|
81 |
+
# add the latest response
|
82 |
+
res_msg = { "role": "system", "content": res +"\n\n你的行为:" }
|
83 |
+
history.append(res_msg)
|
84 |
+
|
85 |
+
# print(history)
|
86 |
+
|
87 |
+
# Update chat history for the user
|
88 |
+
chatHistories[uid] = history
|
89 |
+
|
90 |
+
# update chat messages
|
91 |
+
chat_messages = [(history[i]['content'], history[i+1]['content']) for i in range(0, len(history)-1, 2)]
|
92 |
+
|
93 |
+
# print(chat_messages)
|
94 |
+
|
95 |
+
# calculate the duration
|
96 |
+
duration = round(time.time() - start_time, 2)
|
97 |
+
|
98 |
+
return "", chat_messages, duration
|
99 |
+
|
100 |
+
|
101 |
+
def get_empty_state():
|
102 |
+
return { "messages": [] }
|
103 |
+
|
104 |
+
def clear_conversation(uid):
|
105 |
+
|
106 |
+
# Remove the chat history for the specified user
|
107 |
+
if uid in chatHistories:
|
108 |
+
del chatHistories[uid]
|
109 |
+
|
110 |
+
chat_messages = []
|
111 |
+
return gr.update(value=None, visible=True), chat_messages, 0
|
112 |
+
|
113 |
+
|
114 |
+
def init_bot():
|
115 |
+
return [(None, welcome_msg)]
|
116 |
+
|
117 |
+
with gr.Blocks(css=css, theme=gr.themes.Base()) as demo:
|
118 |
+
uid = str(uuid.uuid4())
|
119 |
+
state = gr.State()
|
120 |
+
|
121 |
+
with gr.Row():
|
122 |
+
with gr.Column():
|
123 |
+
chatbot = gr.Chatbot(elem_id="chatbox", value=init_bot, label="密室游戏")
|
124 |
+
input_message = gr.Textbox(show_label=False, placeholder="输入你的行为并回车", visible=True)
|
125 |
+
|
126 |
+
with gr.Column(elem_id="col-container"):
|
127 |
+
btn_clear_conversation = gr.Button("重开")
|
128 |
+
duration_text = gr.Textbox(interactive=False, label="请求时间")
|
129 |
+
user_id = gr.Textbox(interactive=False, label="User id", visible=False, value=uid)
|
130 |
+
gr.Examples(
|
131 |
+
examples=[
|
132 |
+
["看看四周。", uid],
|
133 |
+
["砸门。", uid],
|
134 |
+
["大吼大叫。", uid],
|
135 |
+
["用力推门。", uid],
|
136 |
+
["敲击墙面。", uid],
|
137 |
+
],
|
138 |
+
label="Shortcut",
|
139 |
+
run_on_click=True,
|
140 |
+
fn=submit_message,
|
141 |
+
inputs=[input_message, user_id],
|
142 |
+
outputs=[input_message, chatbot, duration_text]
|
143 |
+
)
|
144 |
+
|
145 |
+
input_message.submit(submit_message, [input_message, user_id], [input_message, chatbot, duration_text])
|
146 |
+
btn_clear_conversation.click(clear_conversation, [user_id], [input_message, chatbot, duration_text])
|
147 |
+
|
148 |
+
if __name__ == "__main__":
|
149 |
+
demo.launch()
|
process.py
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from tools import *
|
2 |
+
from api import *
|
3 |
+
from datetime import datetime
|
4 |
+
|
5 |
+
now = datetime.now()
|
6 |
+
|
7 |
+
history = {}
|
8 |
+
def reset_converstation(uid):
|
9 |
+
global history
|
10 |
+
history[uid] = ""
|
11 |
+
|
12 |
+
def continue_conversataion(prompt, uid, qid):
|
13 |
+
# 找出该 uid 对应的历史对话
|
14 |
+
global history
|
15 |
+
global currentIndex
|
16 |
+
|
17 |
+
if uid in history:
|
18 |
+
msgs = history[uid]
|
19 |
+
else:
|
20 |
+
msgs = ""
|
21 |
+
# print(f"msgs: [{msgs}]")
|
22 |
+
|
23 |
+
# get latest response with chat historys
|
24 |
+
response, append_response, restart = one_shot(prompt, msgs, uid)
|
25 |
+
|
26 |
+
# push latest response to history with uid
|
27 |
+
# print(f"history: {history}")
|
28 |
+
# print(msgs, prompt, response)
|
29 |
+
|
30 |
+
if restart:
|
31 |
+
reset_converstation(uid)
|
32 |
+
else:
|
33 |
+
history[uid] = msgs + append_response
|
34 |
+
|
35 |
+
return response
|
36 |
+
|
37 |
+
basePrompt = f"""
|
38 |
+
从现在开始,我们来玩逃脱绝境故事大冒险游戏。你是故事的主持人和作者,负责游戏故事的所有情节、环境、NPC角色、推进和互动等。你可以完全自由地引用所有专业级作家和游戏制作人的所有知识,熟悉各种小说、电影、书籍、剧本里的职业技巧和细微末节。玩家向你描述他在游戏里的行为,和你一起相互影响游戏环境的变化和演进。
|
39 |
+
|
40 |
+
主持规则:
|
41 |
+
- 安装需要重新生成这个密室描述。
|
42 |
+
- 如果玩家用自己的叙事蓄意破坏规则和环境,忽略玩家叙事,用“幻觉和苏醒”来替换后续故事,返回环境。
|
43 |
+
- 如果玩家要求线索,给一些无关紧要,但看似有用的细节观察。
|
44 |
+
- 不反馈任何故事情节以外的解释、描述。
|
45 |
+
- 不给玩家任何建议,不给玩家任何线索,不要求玩家。
|
46 |
+
- 不代表玩家发言、行动、决定、思考、观察、感觉、想象、猜测、推理。
|
47 |
+
- 不代表主持人发言,只叙述故事、情节,不要暴露自己。
|
48 |
+
- 房间里没有任何纸条文字。
|
49 |
+
- 游戏失败和成功以后提示用户。
|
50 |
+
- 玩家没有超能力、魔法、高科技,体力虚弱。
|
51 |
+
|
52 |
+
参考以下说话风格,每次回复不超过 100 汉字,比如:
|
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 |
+
失败结局1:玩家触发了危险的机关,导致中毒、失血、死亡。
|
83 |
+
失败结局2:玩家封死了门锁的匙孔,无法使用钥匙。
|
84 |
+
失败结局3:玩家对话回合过长,体力不支死亡。
|
85 |
+
失败结局4:玩家用小刀剖开小腿,小概率意外破坏自己的血管,失血死亡。
|
86 |
+
|
87 |
+
初始状态:
|
88 |
+
- 玩家是否找到了透视药水:否;
|
89 |
+
- 玩家是否找到了青龙钥匙:否;
|
90 |
+
- 玩家是否可以打开门锁:否;
|
91 |
+
|
92 |
+
Analyze current status step by step and return lastest game status:
|
93 |
+
"""
|
94 |
+
|
95 |
+
# copy base prompt, reset it after a successful query.
|
96 |
+
startPrompt = basePrompt
|
97 |
+
def one_shot(prompt, userHistory, uid):
|
98 |
+
|
99 |
+
startNewConv = False
|
100 |
+
historyText = "".join(userHistory)
|
101 |
+
|
102 |
+
# TODO: reset converstion in user's request
|
103 |
+
|
104 |
+
answerRes = get_anwser(prompt, historyText)
|
105 |
+
printInColor(f"{answerRes}", "bright_magenta")
|
106 |
+
|
107 |
+
appendResponse = f"\n玩家:{prompt} \n\n{answerRes}\n\n"
|
108 |
+
return answerRes, appendResponse, False
|
109 |
+
|
110 |
+
def get_anwser(prompt, historyText):
|
111 |
+
exePrompt = truncate_prompt(basePrompt, historyText, f"玩家:{prompt}")
|
112 |
+
res = ask_openai(exePrompt)
|
113 |
+
text = res.choices[0].message.content
|
114 |
+
# print(text)
|
115 |
+
return text
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
flask
|
2 |
+
flask_cors
|
3 |
+
openai
|
tools.py
ADDED
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests, re, json
|
2 |
+
|
3 |
+
def printInColor(text, color=None):
|
4 |
+
colorSet = {
|
5 |
+
"green": '\033[1;32m',
|
6 |
+
"blue": '\033[34m',
|
7 |
+
"red": '\033[1;31m',
|
8 |
+
"yellow": '\033[1;33m',
|
9 |
+
"magenta": '\033[1;35m',
|
10 |
+
"cyan": '\033[1;36m',
|
11 |
+
"gray": '\033[1;30m',
|
12 |
+
"bright_green": '\033[1;92m',
|
13 |
+
"bright_blue": '\033[1;94m',
|
14 |
+
"bright_red": '\033[1;91m',
|
15 |
+
"bright_yellow": '\033[1;93m',
|
16 |
+
"bright_magenta": '\033[1;95m',
|
17 |
+
"bright_cyan": '\033[1;96m',
|
18 |
+
"bright_white": '\033[1;97m',
|
19 |
+
"reset": '\033[0m',
|
20 |
+
}
|
21 |
+
if color == None:
|
22 |
+
color = colorSet['blue']
|
23 |
+
else:
|
24 |
+
color = colorSet[color]
|
25 |
+
|
26 |
+
print(color + text + colorSet['reset'])
|
27 |
+
|
28 |
+
def remove_sentence_with_keyword(text, keywords):
|
29 |
+
for keyword in keywords:
|
30 |
+
# Regex pattern to match a sentence containing the keyword
|
31 |
+
pattern = r"[^.!?。?!]*?" + re.escape(keyword) + r"[^.!?。?!]*?[.!?。?!]+(\s|$)"
|
32 |
+
|
33 |
+
# Use re.sub to replace matching sentences with an empty string
|
34 |
+
text = re.sub(pattern, '', text)
|
35 |
+
return text
|
36 |
+
|
37 |
+
def remove_line_with_keyword(text, keyword):
|
38 |
+
# Create the pattern string, which matches the exact line containing the keyword
|
39 |
+
pattern = r'.*{}\.*\n'.format(keyword)
|
40 |
+
|
41 |
+
# Use the re.sub function to replace the matching line with an empty string
|
42 |
+
new_text = re.sub(pattern, '', text, flags=re.IGNORECASE)
|
43 |
+
|
44 |
+
return new_text
|
45 |
+
|
46 |
+
def extract_as(text):
|
47 |
+
pattern = f"<as>(.*?)</as>"
|
48 |
+
return re.findall(pattern, text)
|
49 |
+
|
50 |
+
def extract_last_sentence(text):
|
51 |
+
pattern = r"(\d+\.\s)([\s\S]*?)(?=\d+\.|$)"
|
52 |
+
paragraphs = re.findall(pattern, text)
|
53 |
+
|
54 |
+
if paragraphs: # If there are bullet points
|
55 |
+
|
56 |
+
text = paragraphs[-1][1]
|
57 |
+
printInColor(f"Last paragraph:\n{text}", 'bright_blue')
|
58 |
+
|
59 |
+
return text # Return the last paragraph
|
60 |
+
else:
|
61 |
+
return text # If no bullet points, return the whole text
|
62 |
+
|
63 |
+
def extract_json(text):
|
64 |
+
# Extract JSON string from the text using regular expressions
|
65 |
+
match = re.search(r'\{.*\}', text, re.DOTALL)
|
66 |
+
if match:
|
67 |
+
json_string = match.group(0)
|
68 |
+
# print(f"json_string: {json_string}")
|
69 |
+
# Load JSON data from the extracted JSON string
|
70 |
+
json_data = json.loads(json_string)
|
71 |
+
return json_data
|
72 |
+
else:
|
73 |
+
return {}
|
74 |
+
|
75 |
+
def extract_response(text):
|
76 |
+
pattern = r'#(.*?)#'
|
77 |
+
matches = re.findall(pattern, text)
|
78 |
+
if matches:
|
79 |
+
return matches[-1]
|
80 |
+
else:
|
81 |
+
return None
|
82 |
+
|
83 |
+
def extract_url(text):
|
84 |
+
pattern = r'https?://\S+'
|
85 |
+
match = re.search(pattern, text)
|
86 |
+
if match:
|
87 |
+
return match.group(0)
|
88 |
+
else:
|
89 |
+
return None
|
90 |
+
|
91 |
+
def has_url(text):
|
92 |
+
pattern = r'https?://\S+'
|
93 |
+
return bool(re.search(pattern, text))
|
94 |
+
|
95 |
+
def truncate_text(text, maxLen=2200):
|
96 |
+
res = "".join(text)
|
97 |
+
if len(res) > maxLen:
|
98 |
+
res = res[:maxLen]
|
99 |
+
return res
|
100 |
+
|
101 |
+
def mock_tokencount(prompt):
|
102 |
+
return int(len(prompt)*0.45)
|
103 |
+
|
104 |
+
def truncate_prompt(basePrompt, processPrompt, latestInput, maxTokenCount=3200):
|
105 |
+
|
106 |
+
prompt = basePrompt + processPrompt + latestInput
|
107 |
+
|
108 |
+
currentPromptCount = mock_tokencount(prompt)
|
109 |
+
# print(f"total_tokens: {total_tokens}")
|
110 |
+
|
111 |
+
# If the total tokens exceed the maximum, truncate the process prompt
|
112 |
+
if currentPromptCount > maxTokenCount:
|
113 |
+
# print(f"Token exceeds:{total_tokens - max_tokens}")
|
114 |
+
|
115 |
+
baseTokenCount = mock_tokencount(basePrompt)
|
116 |
+
# print("base_tokens: " + str(base_tokens))
|
117 |
+
|
118 |
+
availableTokenCount = maxTokenCount - baseTokenCount
|
119 |
+
availablePrompt = processPrompt + latestInput
|
120 |
+
|
121 |
+
truncate_text = availablePrompt[maxTokenCount-availableTokenCount:]
|
122 |
+
|
123 |
+
prompt = basePrompt + truncate_text
|
124 |
+
|
125 |
+
# print("prompt2: " + prompt)
|
126 |
+
currentPromptCount = mock_tokencount(prompt)
|
127 |
+
|
128 |
+
printInColor(f"truncated prompt length: {currentPromptCount}", "bright_red")
|
129 |
+
return prompt
|