Spaces:
Runtime error
Runtime error
| import sys | |
| sys.path.append("BMTools/") | |
| import gradio as gr | |
| from bmtools.agent.tools_controller import MTQuestionAnswerer, load_valid_tools | |
| from bmtools.agent.singletool import STQuestionAnswerer | |
| from langchain.schema import AgentFinish | |
| import os | |
| import requests | |
| from tool_server import run_tool_server | |
| from threading import Thread | |
| from multiprocessing import Process | |
| import time | |
| tool_server_flag = False | |
| def start_tool_server(): | |
| # server = Thread(target=run_tool_server) | |
| server = Process(target=run_tool_server) | |
| server.start() | |
| global tool_server_flag | |
| tool_server_flag = True | |
| available_models = ["ChatGPT", "GPT-3.5"] | |
| DEFAULTMODEL = "ChatGPT" # "GPT-3.5" | |
| tools_mappings = { | |
| "klarna": "https://www.klarna.com/", | |
| "weather": "http://127.0.0.1:8079/tools/weather/", | |
| # "database": "http://127.0.0.1:8079/tools/database/", | |
| # "db_diag": "http://127.0.0.1:8079/tools/db_diag/", | |
| "chemical-prop": "http://127.0.0.1:8079/tools/chemical-prop/", | |
| "douban-film": "http://127.0.0.1:8079/tools/douban-film/", | |
| "wikipedia": "http://127.0.0.1:8079/tools/wikipedia/", | |
| # "wikidata": "http://127.0.0.1:8079/tools/kg/wikidata/", | |
| "wolframalpha": "http://127.0.0.1:8079/tools/wolframalpha/", | |
| "bing_search": "http://127.0.0.1:8079/tools/bing_search/", | |
| "office-ppt": "http://127.0.0.1:8079/tools/office-ppt/", | |
| "stock": "http://127.0.0.1:8079/tools/stock/", | |
| "bing_map": "http://127.0.0.1:8079/tools/map.bing_map/", | |
| # "baidu_map": "http://127.0.0.1:8079/tools/map/baidu_map/", | |
| "zillow": "http://127.0.0.1:8079/tools/zillow/", | |
| "airbnb": "http://127.0.0.1:8079/tools/airbnb/", | |
| "job_search": "http://127.0.0.1:8079/tools/job_search/", | |
| # "baidu-translation": "http://127.0.0.1:8079/tools/translation/baidu-translation/", | |
| # "nllb-translation": "http://127.0.0.1:8079/tools/translation/nllb-translation/", | |
| "tutorial": "http://127.0.0.1:8079/tools/tutorial/", | |
| "file_operation": "http://127.0.0.1:8079/tools/file_operation/", | |
| "meta_analysis": "http://127.0.0.1:8079/tools/meta_analysis/", | |
| "code_interpreter": "http://127.0.0.1:8079/tools/code_interpreter/", | |
| "arxiv": "http://127.0.0.1:8079/tools/arxiv/", | |
| "google_places": "http://127.0.0.1:8079/tools/google_places/", | |
| "google_serper": "http://127.0.0.1:8079/tools/google_serper/", | |
| "google_scholar": "http://127.0.0.1:8079/tools/google_scholar/", | |
| "python": "http://127.0.0.1:8079/tools/python/", | |
| "sceneXplain": "http://127.0.0.1:8079/tools/sceneXplain/", | |
| "shell": "http://127.0.0.1:8079/tools/shell/", | |
| "image_generation": "http://127.0.0.1:8079/tools/image_generation/", | |
| "hugging_tools": "http://127.0.0.1:8079/tools/hugging_tools/", | |
| "gradio_tools": "http://127.0.0.1:8079/tools/gradio_tools/", | |
| "travel": "http://127.0.0.1:8079/tools/travel", | |
| "walmart": "http://127.0.0.1:8079/tools/walmart", | |
| } | |
| valid_tools_info = [] | |
| all_tools_list = [] | |
| gr.close_all() | |
| MAX_TURNS = 30 | |
| MAX_BOXES = MAX_TURNS * 2 | |
| return_msg = [] | |
| chat_history = "" | |
| MAX_SLEEP_TIME = 40 | |
| def load_tools(): | |
| global valid_tools_info | |
| global all_tools_list | |
| try: | |
| valid_tools_info = load_valid_tools(tools_mappings) | |
| except BaseException as e: | |
| print(repr(e)) | |
| all_tools_list = sorted(list(valid_tools_info.keys())) | |
| return gr.update(choices=all_tools_list) | |
| def set_environ(OPENAI_API_KEY: str, | |
| WOLFRAMALPH_APP_ID: str = "", | |
| WEATHER_API_KEYS: str = "", | |
| BING_SUBSCRIPT_KEY: str = "", | |
| ALPHA_VANTAGE_KEY: str = "", | |
| BING_MAP_KEY: str = "", | |
| BAIDU_TRANSLATE_KEY: str = "", | |
| RAPIDAPI_KEY: str = "", | |
| SERPER_API_KEY: str = "", | |
| GPLACES_API_KEY: str = "", | |
| SCENEX_API_KEY: str = "", | |
| STEAMSHIP_API_KEY: str = "", | |
| HUGGINGFACE_API_KEY: str = "", | |
| AMADEUS_ID: str = "", | |
| AMADEUS_KEY: str = "",): | |
| os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY | |
| os.environ["WOLFRAMALPH_APP_ID"] = WOLFRAMALPH_APP_ID | |
| os.environ["WEATHER_API_KEYS"] = WEATHER_API_KEYS | |
| os.environ["BING_SUBSCRIPT_KEY"] = BING_SUBSCRIPT_KEY | |
| os.environ["ALPHA_VANTAGE_KEY"] = ALPHA_VANTAGE_KEY | |
| os.environ["BING_MAP_KEY"] = BING_MAP_KEY | |
| os.environ["BAIDU_TRANSLATE_KEY"] = BAIDU_TRANSLATE_KEY | |
| os.environ["RAPIDAPI_KEY"] = RAPIDAPI_KEY | |
| os.environ["SERPER_API_KEY"] = SERPER_API_KEY | |
| os.environ["GPLACES_API_KEY"] = GPLACES_API_KEY | |
| os.environ["SCENEX_API_KEY"] = SCENEX_API_KEY | |
| os.environ["STEAMSHIP_API_KEY"] = STEAMSHIP_API_KEY | |
| os.environ["HUGGINGFACE_API_KEY"] = HUGGINGFACE_API_KEY | |
| os.environ["AMADEUS_ID"] = AMADEUS_ID | |
| os.environ["AMADEUS_KEY"] = AMADEUS_KEY | |
| if not tool_server_flag: | |
| start_tool_server() | |
| time.sleep(MAX_SLEEP_TIME) | |
| return gr.update(value="OK!") | |
| def show_avatar_imgs(tools_chosen): | |
| if len(tools_chosen) == 0: | |
| tools_chosen = list(valid_tools_info.keys()) | |
| img_template = '<a href="{}" style="float: left"> <img style="margin:5px" src="{}.png" width="24" height="24" alt="avatar" /> {} </a>' | |
| imgs = [valid_tools_info[tool]['avatar'] for tool in tools_chosen if valid_tools_info[tool]['avatar'] != None] | |
| imgs = ' '.join([img_template.format(img, img, tool) for img, tool in zip(imgs, tools_chosen)]) | |
| return [gr.update(value='<span class="">' + imgs + '</span>', visible=True), gr.update(visible=True)] | |
| def answer_by_tools(question, tools_chosen, model_chosen): | |
| global return_msg | |
| return_msg += [(question, None), (None, '...')] | |
| yield [gr.update(visible=True, value=return_msg), gr.update(), gr.update()] | |
| OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY', '') | |
| if len(tools_chosen) == 0: # if there is no tools chosen, we use all todo (TODO: What if the pool is too large.) | |
| tools_chosen = list(valid_tools_info.keys()) | |
| if len(tools_chosen) == 1: | |
| answerer = STQuestionAnswerer(OPENAI_API_KEY.strip(), stream_output=True, llm=model_chosen) | |
| agent_executor = answerer.load_tools(tools_chosen[0], valid_tools_info[tools_chosen[0]], | |
| prompt_type="react-with-tool-description", return_intermediate_steps=True) | |
| else: | |
| answerer = MTQuestionAnswerer(OPENAI_API_KEY.strip(), | |
| load_valid_tools({k: tools_mappings[k] for k in tools_chosen}), | |
| stream_output=True, llm=model_chosen) | |
| agent_executor = answerer.build_runner() | |
| global chat_history | |
| chat_history += "Question: " + question + "\n" | |
| question = chat_history | |
| for inter in agent_executor(question): | |
| if isinstance(inter, AgentFinish): continue | |
| result_str = [] | |
| return_msg.pop() | |
| if isinstance(inter, dict): | |
| result_str.append("<font color=red>Answer:</font> {}".format(inter['output'])) | |
| chat_history += "Answer:" + inter['output'] + "\n" | |
| result_str.append("...") | |
| else: | |
| try: | |
| not_observation = inter[0].log | |
| except: | |
| print(inter[0]) | |
| not_observation = inter[0] | |
| if not not_observation.startswith('Thought:'): | |
| not_observation = "Thought: " + not_observation | |
| chat_history += not_observation | |
| not_observation = not_observation.replace('Thought:', '<font color=green>Thought: </font>') | |
| not_observation = not_observation.replace('Action:', '<font color=purple>Action: </font>') | |
| not_observation = not_observation.replace('Action Input:', '<font color=purple>Action Input: </font>') | |
| result_str.append("{}".format(not_observation)) | |
| result_str.append("<font color=blue>Action output:</font>\n{}".format(inter[1])) | |
| chat_history += "\nAction output:" + inter[1] + "\n" | |
| result_str.append("...") | |
| return_msg += [(None, result) for result in result_str] | |
| yield [gr.update(visible=True, value=return_msg), gr.update(), gr.update()] | |
| return_msg.pop() | |
| if return_msg[-1][1].startswith("<font color=red>Answer:</font> "): | |
| return_msg[-1] = (return_msg[-1][0], return_msg[-1][1].replace("<font color=red>Answer:</font> ", | |
| "<font color=green>Final Answer:</font> ")) | |
| yield [gr.update(visible=True, value=return_msg), gr.update(visible=True), gr.update(visible=False)] | |
| def retrieve(tools_search): | |
| if tools_search == "": | |
| return gr.update(choices=all_tools_list) | |
| else: | |
| url = "http://127.0.0.1:8079/retrieve" | |
| param = { | |
| "query": tools_search | |
| } | |
| response = requests.post(url, json=param) | |
| result = response.json() | |
| retrieved_tools = result["tools"] | |
| return gr.update(choices=retrieved_tools) | |
| def clear_retrieve(): | |
| return [gr.update(value=""), gr.update(choices=all_tools_list)] | |
| def clear_history(): | |
| global return_msg | |
| global chat_history | |
| return_msg = [] | |
| chat_history = "" | |
| yield gr.update(visible=True, value=return_msg) | |
| with gr.Blocks() as demo: | |
| with gr.Row(): | |
| with gr.Column(scale=14): | |
| gr.Markdown("<h1 align='left'> BMTools </h1>") | |
| with gr.Column(scale=1): | |
| gr.Markdown('<img src="https://openbmb.cn/openbmb/img/head_logo.e9d9f3f.png" width="140">') | |
| with gr.Tab("Key setting"): | |
| OPENAI_API_KEY = gr.Textbox(label="OpenAI API KEY:", placeholder="sk-...", type="text") | |
| WOLFRAMALPH_APP_ID = gr.Textbox(label="Wolframalpha app id:", placeholder="Key to use wlframalpha", type="text") | |
| WEATHER_API_KEYS = gr.Textbox(label="Weather api key:", placeholder="Key to use weather api", type="text") | |
| BING_SUBSCRIPT_KEY = gr.Textbox(label="Bing subscript key:", placeholder="Key to use bing search", type="text") | |
| ALPHA_VANTAGE_KEY = gr.Textbox(label="Stock api key:", placeholder="Key to use stock api", type="text") | |
| BING_MAP_KEY = gr.Textbox(label="Bing map key:", placeholder="Key to use bing map", type="text") | |
| BAIDU_TRANSLATE_KEY = gr.Textbox(label="Baidu translation key:", placeholder="Key to use baidu translation", type="text") | |
| RAPIDAPI_KEY = gr.Textbox(label="Rapidapi key:", placeholder="Key to use zillow, airbnb and job search", type="text") | |
| SERPER_API_KEY = gr.Textbox(label="Serper key:", placeholder="Key to use google serper and google scholar", type="text") | |
| GPLACES_API_KEY = gr.Textbox(label="Google places key:", placeholder="Key to use google places", type="text") | |
| SCENEX_API_KEY = gr.Textbox(label="Scenex api key:", placeholder="Key to use sceneXplain", type="text") | |
| STEAMSHIP_API_KEY = gr.Textbox(label="Steamship api key:", placeholder="Key to use image generation", type="text") | |
| HUGGINGFACE_API_KEY = gr.Textbox(label="Huggingface api key:", placeholder="Key to use models in huggingface hub", type="text") | |
| AMADEUS_ID = gr.Textbox(label="Amadeus id:", placeholder="Id to use Amadeus", type="text") | |
| AMADEUS_KEY = gr.Textbox(label="Amadeus key:", placeholder="Key to use Amadeus", type="text") | |
| key_set_btn = gr.Button(value="Set keys!") | |
| with gr.Tab("Chat with Tool"): | |
| with gr.Row(): | |
| with gr.Column(scale=4): | |
| with gr.Row(): | |
| with gr.Column(scale=0.85): | |
| txt = gr.Textbox(show_label=False, placeholder="Question here. Use Shift+Enter to add new line.", | |
| lines=1).style(container=False) | |
| with gr.Column(scale=0.15, min_width=0): | |
| buttonChat = gr.Button("Chat") | |
| chatbot = gr.Chatbot(show_label=False, visible=True).style(height=600) | |
| buttonClear = gr.Button("Clear History") | |
| buttonStop = gr.Button("Stop", visible=False) | |
| with gr.Column(scale=1): | |
| model_chosen = gr.Dropdown( | |
| list(available_models), value=DEFAULTMODEL, multiselect=False, label="Model provided", | |
| info="Choose the model to solve your question, Default means ChatGPT." | |
| ) | |
| with gr.Row(): | |
| tools_search = gr.Textbox( | |
| lines=1, | |
| label="Tools Search", | |
| placeholder="Please input some text to search tools.", | |
| ) | |
| buttonSearch = gr.Button("Reset search condition") | |
| tools_chosen = gr.CheckboxGroup( | |
| choices=all_tools_list, | |
| value=["chemical-prop"], | |
| label="Tools provided", | |
| info="Choose the tools to solve your question.", | |
| ) | |
| key_set_btn.click(fn=set_environ, inputs=[ | |
| OPENAI_API_KEY, | |
| WOLFRAMALPH_APP_ID, | |
| WEATHER_API_KEYS, | |
| BING_SUBSCRIPT_KEY, | |
| ALPHA_VANTAGE_KEY, | |
| BING_MAP_KEY, | |
| BAIDU_TRANSLATE_KEY, | |
| RAPIDAPI_KEY, | |
| SERPER_API_KEY, | |
| GPLACES_API_KEY, | |
| SCENEX_API_KEY, | |
| STEAMSHIP_API_KEY, | |
| HUGGINGFACE_API_KEY, | |
| AMADEUS_ID, | |
| AMADEUS_KEY, | |
| ], outputs=key_set_btn) | |
| key_set_btn.click(fn=load_tools, outputs=tools_chosen) | |
| tools_search.change(retrieve, tools_search, tools_chosen) | |
| buttonSearch.click(clear_retrieve, [], [tools_search, tools_chosen]) | |
| txt.submit(lambda: [gr.update(value=''), gr.update(visible=False), gr.update(visible=True)], [], | |
| [txt, buttonClear, buttonStop]) | |
| inference_event = txt.submit(answer_by_tools, [txt, tools_chosen, model_chosen], [chatbot, buttonClear, buttonStop]) | |
| buttonChat.click(answer_by_tools, [txt, tools_chosen, model_chosen], [chatbot, buttonClear, buttonStop]) | |
| buttonStop.click(lambda: [gr.update(visible=True), gr.update(visible=False)], [], [buttonClear, buttonStop], | |
| cancels=[inference_event]) | |
| buttonClear.click(clear_history, [], chatbot) | |
| # demo.queue().launch(share=False, inbrowser=True, server_name="127.0.0.1", server_port=7001) | |
| demo.queue().launch() |