diff --git a/crazy_functions/Latex输出PDF结果.py b/crazy_functions/Latex输出PDF结果.py index f3919edc..18a8d1ba 100644 --- a/crazy_functions/Latex输出PDF结果.py +++ b/crazy_functions/Latex输出PDF结果.py @@ -88,6 +88,9 @@ def arxiv_download(chatbot, history, txt, allow_cache=True): target_file = pj(translation_dir, 'translate_zh.pdf') if os.path.exists(target_file): promote_file_to_downloadzone(target_file, rename_file=None, chatbot=chatbot) + target_file_compare = pj(translation_dir, 'comparison.pdf') + if os.path.exists(target_file_compare): + promote_file_to_downloadzone(target_file_compare, rename_file=None, chatbot=chatbot) return target_file return False def is_float(s): diff --git a/crazy_functions/latex_fns/latex_actions.py b/crazy_functions/latex_fns/latex_actions.py index 74e8757e..be3d52e7 100644 --- a/crazy_functions/latex_fns/latex_actions.py +++ b/crazy_functions/latex_fns/latex_actions.py @@ -418,6 +418,7 @@ def 编译Latex(chatbot, history, main_file_original, main_file_modified, work_f merge_pdfs(origin_pdf, result_pdf, concat_pdf) promote_file_to_downloadzone(concat_pdf, rename_file=None, chatbot=chatbot) # promote file to web UI except Exception as e: + print(e) pass return True # 成功啦 else: diff --git a/crazy_functions/latex_fns/latex_toolbox.py b/crazy_functions/latex_fns/latex_toolbox.py index 4555ff18..0a6a873b 100644 --- a/crazy_functions/latex_fns/latex_toolbox.py +++ b/crazy_functions/latex_fns/latex_toolbox.py @@ -493,11 +493,38 @@ def compile_latex_with_timeout(command, cwd, timeout=60): return False return True +def run_in_subprocess_wrapper_func(func, args, kwargs, return_dict, exception_dict): + import sys + try: + result = func(*args, **kwargs) + return_dict['result'] = result + except Exception as e: + exc_info = sys.exc_info() + exception_dict['exception'] = exc_info +def run_in_subprocess(func): + import multiprocessing + def wrapper(*args, **kwargs): + return_dict = multiprocessing.Manager().dict() + exception_dict = multiprocessing.Manager().dict() + process = multiprocessing.Process(target=run_in_subprocess_wrapper_func, + args=(func, args, kwargs, return_dict, exception_dict)) + process.start() + process.join() + process.close() + if 'exception' in exception_dict: + # ooops, the subprocess ran into an exception + exc_info = exception_dict['exception'] + raise exc_info[1].with_traceback(exc_info[2]) + if 'result' in return_dict.keys(): + # If the subprocess ran successfully, return the result + return return_dict['result'] + return wrapper -def merge_pdfs(pdf1_path, pdf2_path, output_path): - import PyPDF2 +def _merge_pdfs(pdf1_path, pdf2_path, output_path): + import PyPDF2 # PyPDF2这个库有严重的内存泄露问题,把它放到子进程中运行,从而方便内存的释放 Percent = 0.95 + # raise RuntimeError('PyPDF2 has a serious memory leak problem, please use other tools to merge PDF files.') # Open the first PDF file with open(pdf1_path, 'rb') as pdf1_file: pdf1_reader = PyPDF2.PdfFileReader(pdf1_file) @@ -531,3 +558,5 @@ def merge_pdfs(pdf1_path, pdf2_path, output_path): # Save the merged PDF file with open(output_path, 'wb') as output_file: output_writer.write(output_file) + +merge_pdfs = run_in_subprocess(_merge_pdfs) # PyPDF2这个库有严重的内存泄露问题,把它放到子进程中运行,从而方便内存的释放 diff --git a/crazy_functions/互动小游戏.py b/crazy_functions/互动小游戏.py new file mode 100644 index 00000000..e00ef32b --- /dev/null +++ b/crazy_functions/互动小游戏.py @@ -0,0 +1,159 @@ +from toolbox import CatchException, update_ui, get_conf, select_api_key, get_log_folder +from crazy_functions.multi_stage.multi_stage_utils import GptAcademicState +from crazy_functions.crazy_utils import request_gpt_model_in_new_thread_with_ui_alive +import random + +class 小游戏(GptAcademicState): + def __init__(self): + self.need_game_reset = True + self.llm_kwargs = None + super().__init__() + + def lock_plugin(self, chatbot): + chatbot._cookies['lock_plugin'] = 'crazy_functions.互动小游戏->谁是卧底' + self.dump_state(chatbot) + + def unlock_plugin(self, chatbot): + self.reset() + chatbot._cookies['lock_plugin'] = None + self.dump_state(chatbot) + + def set_state(self, chatbot, key, value): + return super().set_state(chatbot, key, value) + + def init_game(self, chatbot): + chatbot.get_cookies()['lock_plugin'] = '' + + def clean_up_game(self, chatbot): + chatbot.get_cookies()['lock_plugin'] = None + + def init_player(self): + pass + + def step(self, prompt, chatbot): + pass + + def continue_game(self, prompt, chatbot): + if self.need_game_reset: + self.need_game_reset = False + yield from self.init_game(chatbot) + yield from self.step(prompt, chatbot) + self.dump_state(chatbot) + yield update_ui(chatbot=chatbot, history=[]) + +class 小游戏_谁是卧底_玩家(): + def __init__(self, game_handle, card, llm_model, name) -> None: + self.game_handle = game_handle + self.card = card + self.name = name + self.is_out = False + self.llm_model = llm_model + self.is_human = llm_model == 'human' + self.what_player_has_spoken = [] + + def speek(self, content=None): + if content is None: + assert not self.is_human + speak_what = yield from + else: + self.what_player_has_spoken.append(content) + + def agi_speek(self): + inputs = f'please say something about {self.card}' + res = yield from request_gpt_model_in_new_thread_with_ui_alive( + inputs = inputs, + inputs_show_user=inputs, + llm_kwargs=self.game_handle.llm_kwargs, + chatbot=chatbot, + history=history, + sys_prompt=sys_prompt + ) + pass + + def vote(self, content=None): + if content is None: + assert not self.is_human + self.vote_who = yield from + else: + try: + self.vote_who = int(content) + except: + self.vote_who = None + + def agi_vote(self): + pass + +class 小游戏_谁是卧底(小游戏): + def __init__(self): + self.game_phase = '发言' # 投票 + super().__init__() + + def init_game(self, chatbot): + self.n_players = 3 + self.n_ai_players = self.n_players - 1 + card = "橙子" + undercover_card = "橘子" + llm_model = self.llm_kwargs['llm_model'] + self.players = [ + 小游戏_谁是卧底(self, card, llm_model, str(i)) for i in range(self.n_players) + ] + + undercover = random.randint(0, self.n_players-1) + human = 0 + + self.players[undercover].card = undercover_card + self.players[human].llm_model = 'human' + super().init_game(chatbot) + + def who_is_out(self): + votes = {} + for player in self.players: + if player.is_out: continue + if player.vote is None: continue + if player.vote not in votes: votes[player.vote] = 0 + votes[player.vote] += 1 + max_votes = max(votes.values()) + players_with_max_votes = [player for player, vote_count in votes.items() if vote_count == max_votes] + for player in players_with_max_votes: + print('淘汰了', player.name) + player.is_out = True + return players_with_max_votes + + def step(self, prompt, chatbot): + + if self.game_phase == '发言': + for player in self.players: + if player.is_out: continue + if player.is_human: + player.speek(prompt) + else: + player.speek() + self.game_phase = '投票' + + elif self.game_phase == '投票': + for player in self.players: + if player.is_out: continue + if player.is_human: + player.vote(prompt) + else: + player.vote() + self.who_is_out() + if len([player for player in self.players if not player.is_out]) <= 2: + if sum([player for player in self.players if player.is_undercover]) == 1: + print('卧底获胜') + else: + print('平民获胜') + self.need_game_reset = True + self.game_phase = '发言' + + else: + raise RuntimeError + + +@CatchException +def 谁是卧底(prompt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port): + # 尚未完成 + history = [] # 清空历史 + state = 小游戏_谁是卧底.get_state(chatbot, 小游戏_谁是卧底) + state.llm_kwargs = llm_kwargs + yield from state.continue_game(prompt, chatbot) diff --git a/toolbox.py b/toolbox.py index 920f5737..a427872c 100644 --- a/toolbox.py +++ b/toolbox.py @@ -563,7 +563,8 @@ def promote_file_to_downloadzone(file, rename_file=None, chatbot=None): user_name = get_user(chatbot) else: user_name = default_user_name - + if not os.path.exists(file): + raise FileNotFoundError(f'文件{file}不存在') user_path = get_log_folder(user_name, plugin_name=None) if file_already_in_downloadzone(file, user_path): new_path = file