{"system": "You are a helpful assistant.", "history": ["import json\nimport gradio as gr\n# import openai\nimport os\nimport sys\nimport traceback\nimport requests\n# import markdown\nimport csv\n\nmy_api_key = \"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\" # \u5728\u8fd9\u91cc\u8f93\u5165\u4f60\u7684 API \u5bc6\u94a5\nHIDE_MY_KEY = False # \u5982\u679c\u4f60\u60f3\u5728UI\u4e2d\u9690\u85cf\u4f60\u7684 API \u5bc6\u94a5\uff0c\u5c06\u6b64\u503c\u8bbe\u7f6e\u4e3a True\n\ninitial_prompt = \"You are a helpful assistant.\"\nAPI_URL = \"https://api.openai.com/v1/chat/completions\"\nHISTORY_DIR = \"history\"\nTEMPLATES_DIR = \"templates\"\n\n\n\n#if we are running in Docker\nif os.environ.get('dockerrun') == 'yes':\n dockerflag = True\nelse:\n dockerflag = False\n\nif dockerflag:\n my_api_key = os.environ.get('my_api_key')\n if my_api_key == \"empty\":\n print(\"Please give a api key!\")\n sys.exit(1)\n #auth\n username = os.environ.get('USERNAME')\n password = os.environ.get('PASSWORD')\n if isinstance(username, type(None)) or isinstance(password, type(None)):\n authflag = False\n else:\n authflag = True\n\n\ndef parse_text(text):\n lines = text.split(\"\\n\")\n lines = [line for line in lines if line != \"\"]\n count = 0\n firstline = False\n for i, line in enumerate(lines):\n if \"```\" in line:\n count += 1\n items = line.split('`')\n if count % 2 == 1:\n lines[i] = f'
'\n firstline = True\n else:\n lines[i] = f'
'\n else:\n if i > 0:\n if count % 2 == 1:\n line = line.replace(\"&\", \"&\")\n line = line.replace(\"\\\"\", \"`\\\"`\")\n line = line.replace(\"\\'\", \"`\\'`\")\n line = line.replace(\"<\", \"<\")\n line = line.replace(\">\", \">\")\n line = line.replace(\" \", \" \")\n line = line.replace(\"*\", \"*\")\n line = line.replace(\"_\", \"_\")\n line = line.replace(\"#\", \"#\")\n line = line.replace(\"-\", \"-\")\n line = line.replace(\".\", \".\")\n line = line.replace(\"!\", \"!\")\n line = line.replace(\"(\", \"(\")\n line = line.replace(\")\", \")\")\n lines[i] = \"
import os
import datetime
import markdown
def export_markdown(history):
timestamp = datetime.datetime.now().strftime(`'`%Y%m%d %H%M%S`'`)
filename = f`\"`history/{timestamp}.md`\"`
os.makedirs(os.path.dirname(filename), exist_ok=True)
with open(filename, `'`w`'`) as f:
for i in range(0, len(history), 2):
user_input = history[i][`\"`content`\"`]
bot_response = history[i+1][`\"`content`\"`]
f.write(f`\"`\\n## User: {user_input}\\n\\n`\"`)
f.write(f`\"`{markdown.markdown(bot_response)}\\n`\"`)
print(f`\"`\u5bfc\u51fa\u6210\u529f\uff0c\u6587\u4ef6\u540d\u4e3a{filename}`\"`)
return None
exportBtn = gr.Button(label=`\"`\u5bfc\u51faMarkdown`\"`,)
reduceTokenBtn.append(exportBtn)
exportBtn.click(export_markdown, [history], [])"], "chatbot": [["import json
\nimport gradio as gr
\n# import openai
\nimport os
\nimport sys
\nimport traceback
\nimport requests
\n# import markdown
\nimport csv
\n
\nmy_api_key = \u201c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\u201d # \u5728\u8fd9\u91cc\u8f93\u5165\u4f60\u7684 API \u5bc6\u94a5
\nHIDE_MY_KEY = False # \u5982\u679c\u4f60\u60f3\u5728UI\u4e2d\u9690\u85cf\u4f60\u7684 API \u5bc6\u94a5\uff0c\u5c06\u6b64\u503c\u8bbe\u7f6e\u4e3a True
\n
\ninitial_prompt = \u201cYou are a helpful assistant.\u201d
\nAPI_URL = \u201chttps://api.openai.com/v1/chat/completions\u201d
\nHISTORY_DIR = \u201chistory\u201d
\nTEMPLATES_DIR = \u201ctemplates\u201d
\n
\n
\n
\n#if we are running in Docker
\nif os.environ.get(\u2018dockerrun\u2019) == \u2018yes\u2019:
\ndockerflag = True
\nelse:
\ndockerflag = False
\n
\nif dockerflag:
\nmy_api_key = os.environ.get(\u2018my_api_key\u2019)
\nif my_api_key == \u201cempty\u201d:
\nprint(\u201cPlease give a api key!\u201d)
\nsys.exit(1)
\n#auth
\nusername = os.environ.get(\u2018USERNAME\u2019)
\npassword = os.environ.get(\u2018PASSWORD\u2019)
\nif isinstance(username, type(None)) or isinstance(password, type(None)):
\nauthflag = False
\nelse:
\nauthflag = True
\n
\n
\ndef parse_text(text):
\nlines = text.split(\u201c\\n\u201d)
\nlines = [line for line in lines if line != \u201c\u201d]
\ncount = 0
\nfirstline = False
\nfor i, line in enumerate(lines):
\nif \u201c```\u201d in line:
\ncount += 1
\nitems = line.split(\u2018') if count % 2 == 1: lines[i] = f'<pre><code class="{items[-1]}" style="display: block; white-space: pre; background-color: hsl(0, 0%, 32%); border-radius: 8px; padding: 0px 1em 1em; margin-top: 1em; font-size: initial;color: #FFF;">' firstline = True else: lines[i] = f'</code></pre>' else: if i > 0: if count % 2 == 1: line = line.replace("&", "&") line = line.replace("\\"", "
"") line = line.replace("\\'", "
\u2019") line = line.replace("<", "<") line = line.replace(">", ">") line = line.replace(" ", " ") line = line.replace("*", "*") line = line.replace("_", "_") line = line.replace("#", "#") line = line.replace("-", "-") line = line.replace(".", ".") line = line.replace("!", "!") line = line.replace("(", "(") line = line.replace(")", ")") lines[i] = "<br>"+line text = "".join(lines) return text def predict(inputs, top_p, temperature, openai_api_key, chatbot=[], history=[], system_prompt=initial_prompt, retry=False, summary=False): # repetition_penalty, top_k print(f"chatbot 1: {chatbot}") headers = { "Content-Type": "application/json", "Authorization": f"Bearer {openai_api_key}" } chat_counter = len(history) // 2 print(f"chat_counter - {chat_counter}") messages = [compose_system(system_prompt)] if chat_counter: for data in chatbot: temp1 = {} temp1["role"] = "user" temp1["content"] = data[0] temp2 = {} temp2["role"] = "assistant" temp2["content"] = data[1] if temp1["content"] != "": messages.append(temp1) messages.append(temp2) else: messages[-1]['content'] = temp2['content'] if retry and chat_counter: messages.pop() elif summary: messages.append(compose_user( "\u8bf7\u5e2e\u6211\u603b\u7ed3\u4e00\u4e0b\u4e0a\u8ff0\u5bf9\u8bdd\u7684\u5185\u5bb9\uff0c\u5b9e\u73b0\u51cf\u5c11\u5b57\u6570\u7684\u540c\u65f6\uff0c\u4fdd\u8bc1\u5bf9\u8bdd\u7684\u8d28\u91cf\u3002\u5728\u603b\u7ed3\u4e2d\u4e0d\u8981\u52a0\u5165\u8fd9\u4e00\u53e5\u8bdd\u3002")) history = ["\u6211\u4eec\u521a\u521a\u804a\u4e86\u4ec0\u4e48\uff1f"] else: temp3 = {} temp3["role"] = "user" temp3["content"] = inputs messages.append(temp3) chat_counter += 1 # messages payload = { "model": "gpt-3.5-turbo", "messages": messages, # [{"role": "user", "content": f"{inputs}"}], "temperature": temperature, # 1.0, "top_p": top_p, # 1.0, "n": 1, "stream": True, "presence_penalty": 0, "frequency_penalty": 0, } if not summary: history.append(inputs) print(f"payload is - {payload}") # make a POST request to the API endpoint using the requests.post method, passing in stream=True response = requests.post(API_URL, headers=headers, json=payload, stream=True) #response = requests.post(API_URL, headers=headers, json=payload, stream=True) token_counter = 0 partial_words = "" counter = 0 chatbot.append((history[-1], "")) for chunk in response.iter_lines(): if counter == 0: counter += 1 continue counter += 1 # check whether each line is non-empty if chunk: # decode each line as response data is in bytes try: if len(json.loads(chunk.decode()[6:])['choices'][0]["delta"]) == 0: break except Exception as e: chatbot.pop() chatbot.append((history[-1], f"\u2639\ufe0f\u53d1\u751f\u4e86\u9519\u8bef<br>\u8fd4\u56de\u503c\uff1a{response.text}<br>\u5f02\u5e38\uff1a{e}")) history.pop() yield chatbot, history break #print(json.loads(chunk.decode()[6:])['choices'][0]["delta"] ["content"]) partial_words = partial_words + \\ json.loads(chunk.decode()[6:])[ 'choices'][0]["delta"]["content"] if token_counter == 0: history.append(" " + partial_words) else: history[-1] = parse_text(partial_words) chatbot[-1] = (history[-2], history[-1]) # chat = [(history[i], history[i + 1]) for i in range(0, len(history) - 1, 2) ] # convert to tuples of list token_counter += 1 # resembles {chatbot: chat, state: history} yield chatbot, history def delete_last_conversation(chatbot, history): chatbot.pop() history.pop() history.pop() return chatbot, history def save_chat_history(filename, system, history, chatbot): if filename == "": return if not filename.endswith(".json"): filename += ".json" os.makedirs(HISTORY_DIR, exist_ok=True) json_s = {"system": system, "history": history, "chatbot": chatbot} with open(os.path.join(HISTORY_DIR, filename), "w") as f: json.dump(json_s, f) def load_chat_history(filename): with open(os.path.join(HISTORY_DIR, filename), "r") as f: json_s = json.load(f) return filename, json_s["system"], json_s["history"], json_s["chatbot"] def get_file_names(dir, plain=False, filetype=".json"): # find all json files in the current directory and return their names try: files = [f for f in os.listdir(dir) if f.endswith(filetype)] except FileNotFoundError: files = [] if plain: return files else: return gr.Dropdown.update(choices=files) def get_history_names(plain=False): return get_file_names(HISTORY_DIR, plain) def load_template(filename): lines = [] with open(os.path.join(TEMPLATES_DIR, filename), "r", encoding="utf8") as csvfile: reader = csv.reader(csvfile) lines = list(reader) lines = lines[1:] return {row[0]:row[1] for row in lines}, gr.Dropdown.update(choices=[row[0] for row in lines]) def get_template_names(plain=False): return get_file_names(TEMPLATES_DIR, plain, filetype=".csv") def reset_state(): return [], [] def compose_system(system_prompt): return {"role": "system", "content": system_prompt} def compose_user(user_input): return {"role": "user", "content": user_input} def reset_textbox(): return gr.update(value='') title = """<h1 align="center">\u5ddd\u864eChatGPT \ud83d\ude80</h1>""" description = """<div align=center> \u7531Bilibili [\u571f\u5ddd\u864e\u864e\u864e](https://space.bilibili.com/29125536) \u5f00\u53d1 \u8bbf\u95ee\u5ddd\u864eChatGPT\u7684 [GitHub\u9879\u76ee](https://github.com/GaiZhenbiao/ChuanhuChatGPT) \u4e0b\u8f7d\u6700\u65b0\u7248\u811a\u672c \u6b64App\u4f7f\u7528
gpt-3.5-turbo` \u5927\u8bed\u8a00\u6a21\u578b
\n
\n\u201c\u201d"
\nwith gr.Blocks() as demo:
\ngr.HTML(title)
\nkeyTxt = gr.Textbox(show_label=True, placeholder=f"\u5728\u8fd9\u91cc\u8f93\u5165\u4f60\u7684OpenAI API-key\u2026\u201c,
\nvalue=my_api_key, label=\u201cAPI Key\u201d, type=\u201cpassword\u201d, visible=not HIDE_MY_KEY).style(container=True)
\nchatbot = gr.Chatbot() # .style(color_map=(\u201d#1D51EE", \u201c#585A5B\u201d))
\nhistory = gr.State([])
\npromptTemplates = gr.State({})
\nTRUECOMSTANT = gr.State(True)
\nFALSECONSTANT = gr.State(False)
\ntopic = gr.State(\u201c\u672a\u547d\u540d\u5bf9\u8bdd\u5386\u53f2\u8bb0\u5f55\u201d)
\n
\nwith gr.Row():
\nwith gr.Column(scale=12):
\ntxt = gr.Textbox(show_label=False, placeholder=\u201c\u5728\u8fd9\u91cc\u8f93\u5165\u201d).style(
\ncontainer=False)
\nwith gr.Column(min_width=50, scale=1):
\nsubmitBtn = gr.Button(\u201c\ud83d\ude80\u201d, variant=\u201cprimary\u201d)
\nwith gr.Row():
\nemptyBtn = gr.Button(\u201c\ud83e\uddf9 \u65b0\u7684\u5bf9\u8bdd\u201d)
\nretryBtn = gr.Button(\u201c\ud83d\udd04 \u91cd\u65b0\u751f\u6210\u201d)
\ndelLastBtn = gr.Button(\u201c\ud83d\uddd1\ufe0f \u5220\u9664\u4e0a\u6761\u5bf9\u8bdd\u201d)
\nreduceTokenBtn = gr.Button(\u201c\u267b\ufe0f \u603b\u7ed3\u5bf9\u8bdd\u201d)
\nsystemPromptTxt = gr.Textbox(show_label=True, placeholder=f"\u5728\u8fd9\u91cc\u8f93\u5165System Prompt\u2026\u201c,
\nlabel=\u201cSystem prompt\u201d, value=initial_prompt).style(container=True)
\nwith gr.Accordion(label=\u201c\u52a0\u8f7dPrompt\u6a21\u677f\u201d, open=False):
\nwith gr.Column():
\nwith gr.Row():
\nwith gr.Column(scale=6):
\ntemplateFileSelectDropdown = gr.Dropdown(label=\u201c\u9009\u62e9Prompt\u6a21\u677f\u96c6\u5408\u6587\u4ef6\uff08.csv\uff09\u201d, choices=get_template_names(plain=True), multiselect=False)
\nwith gr.Column(scale=1):
\ntemplateRefreshBtn = gr.Button(\u201c\ud83d\udd04 \u5237\u65b0\u201d)
\ntemplaeFileReadBtn = gr.Button(\u201c\ud83d\udcc2 \u8bfb\u5165\u6a21\u677f\u201d)
\nwith gr.Row():
\nwith gr.Column(scale=6):
\ntemplateSelectDropdown = gr.Dropdown(label=\u201c\u4ecePrompt\u6a21\u677f\u4e2d\u52a0\u8f7d\u201d, choices=[], multiselect=False)
\nwith gr.Column(scale=1):
\ntemplateApplyBtn = gr.Button(\u201c\u2b07\ufe0f \u5e94\u7528\u201d)
\nwith gr.Accordion(label=\u201c\u4fdd\u5b58/\u52a0\u8f7d\u5bf9\u8bdd\u5386\u53f2\u8bb0\u5f55(\u5728\u6587\u672c\u6846\u4e2d\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u70b9\u51fb\u201c\u4fdd\u5b58\u5bf9\u8bdd\u201d\u6309\u94ae\uff0c\u5386\u53f2\u8bb0\u5f55\u6587\u4ef6\u4f1a\u88ab\u5b58\u50a8\u5230Python\u6587\u4ef6\u65c1\u8fb9)\u201d, open=False):
\nwith gr.Column():
\nwith gr.Row():
\nwith gr.Column(scale=6):
\nsaveFileName = gr.Textbox(
\nshow_label=True, placeholder=f"\u5728\u8fd9\u91cc\u8f93\u5165\u4fdd\u5b58\u7684\u6587\u4ef6\u540d\u2026\u201d, label=\u201c\u8bbe\u7f6e\u4fdd\u5b58\u6587\u4ef6\u540d\u201d, value=\u201c\u5bf9\u8bdd\u5386\u53f2\u8bb0\u5f55\u201d).style(container=True)
\nwith gr.Column(scale=1):
\nsaveBtn = gr.Button(\u201c\ud83d\udcbe \u4fdd\u5b58\u5bf9\u8bdd\u201d)
\nwith gr.Row():
\nwith gr.Column(scale=6):
\nhistoryFileSelectDropdown = gr.Dropdown(label=\u201c\u4ece\u5217\u8868\u4e2d\u52a0\u8f7d\u5bf9\u8bdd\u201d, choices=get_history_names(plain=True), multiselect=False)
\nwith gr.Column(scale=1):
\nhistoryRefreshBtn = gr.Button(\u201c\ud83d\udd04 \u5237\u65b0\u201d)
\nhistoryReadBtn = gr.Button(\u201c\ud83d\udcc2 \u8bfb\u5165\u5bf9\u8bdd\u201d)
\n#inputs, top_p, temperature, top_k, repetition_penalty
\nwith gr.Accordion(\u201c\u53c2\u6570\u201d, open=False):
\ntop_p = gr.Slider(minimum=-0, maximum=1.0, value=1.0, step=0.05,
\ninteractive=True, label=\u201cTop-p (nucleus sampling)\u201d,)
\ntemperature = gr.Slider(minimum=-0, maximum=5.0, value=1.0,
\nstep=0.1, interactive=True, label=\u201cTemperature\u201d,)
\n#top_k = gr.Slider( minimum=1, maximum=50, value=4, step=1, interactive=True, label=\u201cTop-k\u201d,)
\n#repetition_penalty = gr.Slider( minimum=0.1, maximum=3.0, value=1.03, step=0.01, interactive=True, label=\u201cRepetition Penalty\u201d, )
\ngr.Markdown(description)
\n
\n
\ntxt.submit(predict, [txt, top_p, temperature, keyTxt,
\nchatbot, history, systemPromptTxt], [chatbot, history])
\ntxt.submit(reset_textbox, [], [txt])
\nsubmitBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot,
\nhistory, systemPromptTxt], [chatbot, history], show_progress=True)
\nsubmitBtn.click(reset_textbox, [], [txt])
\nemptyBtn.click(reset_state, outputs=[chatbot, history])
\nretryBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot, history,
\nsystemPromptTxt, TRUECOMSTANT], [chatbot, history], show_progress=True)
\ndelLastBtn.click(delete_last_conversation, [chatbot, history], [
\nchatbot, history], show_progress=True)
\nreduceTokenBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot, history,
\nsystemPromptTxt, FALSECONSTANT, TRUECOMSTANT], [chatbot, history], show_progress=True)
\nsaveBtn.click(save_chat_history, [
\nsaveFileName, systemPromptTxt, history, chatbot], None, show_progress=True)
\nsaveBtn.click(get_history_names, None, [historyFileSelectDropdown])
\nhistoryRefreshBtn.click(get_history_names, None, [historyFileSelectDropdown])
\nhistoryReadBtn.click(load_chat_history, [historyFileSelectDropdown], [saveFileName, systemPromptTxt, history, chatbot], show_progress=True)
\ntemplateRefreshBtn.click(get_template_names, None, [templateFileSelectDropdown])
\ntemplaeFileReadBtn.click(load_template, [templateFileSelectDropdown], [promptTemplates, templateSelectDropdown], show_progress=True)
\ntemplateApplyBtn.click(lambda x, y: x[y], [promptTemplates, templateSelectDropdown], [systemPromptTxt], show_progress=True)
\n
\nprint(\u201c\u5ddd\u864e\u7684\u6e29\u99a8\u63d0\u793a\uff1a\u8bbf\u95ee http://localhost:7860 \u67e5\u770b\u754c\u9762\u201d)
\n# \u9ed8\u8ba4\u5f00\u542f\u672c\u5730\u670d\u52a1\u5668\uff0c\u9ed8\u8ba4\u53ef\u4ee5\u76f4\u63a5\u4eceIP\u8bbf\u95ee\uff0c\u9ed8\u8ba4\u4e0d\u521b\u5efa\u516c\u5f00\u5206\u4eab\u94fe\u63a5
\ndemo.title = \u201c\u5ddd\u864eChatGPT \ud83d\ude80\u201d
\n
\n#if running in Docker
\nif dockerflag:
\nif authflag:
\ndemo.queue().launch(server_name=\u201c0.0.0.0\u201d, server_port=7860,auth=(username, password))
\nelse:
\ndemo.queue().launch(server_name=\u201c0.0.0.0\u201d, server_port=7860, share=False)
\n#if not running in Docker
\nelse:
\n# demo.queue().launch(share=False) # \u6539\u4e3a share=True \u53ef\u4ee5\u521b\u5efa\u516c\u5f00\u5206\u4eab\u94fe\u63a5
\ndemo.queue().launch(server_name=\u201c0.0.0.0\u201d, server_port=7160, share=False) # \u53ef\u81ea\u5b9a\u4e49\u7aef\u53e3
\n#demo.queue().launch(server_name=\u201c0.0.0.0\u201d, server_port=7860,auth=(\u201c\u5728\u8fd9\u91cc\u586b\u5199\u7528\u6237\u540d\u201d, \u201c\u5728\u8fd9\u91cc\u586b\u5199\u5bc6\u7801\u201d)) # \u53ef\u8bbe\u7f6e\u7528\u6237\u540d\u4e0e\u5bc6\u7801
\n##################
\n\u6211\u60f3\u5728\u4e0a\u9762\u4ee3\u7801\u91cc\u9762\u589e\u52a0\u4e00\u4e2a\u6309\u94ae\u201c\u5bfc\u51faMarkDown", \u653e\u5728\u201c\u603b\u7ed3\u5bf9\u8bdd\u201d\u7684\u53f3\u8fb9\uff0c\u8fd9\u4e2a\u6309\u94ae\u7684\u529f\u80fd\u4e3a\u628a\u804a\u5929\u5386\u53f2\u8bb0\u5f55\u5230\u5904\u4e3amarkdown\u6587\u4ef6\uff0c\u6587\u4ef6\u53ef\u4ee5\u4fdd\u5b58\u5728\u8be5\u6587\u4ef6\u76ee\u5f55\u4e0b\u7684/history\u76ee\u5f55\uff0c\u5bfc\u51fa\u6210\u529f\u540e\u63d0\u793a\u5012\u51fa\u6210\u529f\uff0c\u6587\u4ef6\u683c\u5f0f\u4e3a\u5f53\u524dyyyymmdd hhmmss.md\u683c\u5f0f\u3002
\n\u4e0d\u7528\u8fd4\u56de\u6574\u4e2a\u4ee3\u7801\uff0c\u53ea\u8981\u628a\u65b0\u589e\u7684\u4ee3\u7801\u7ed9\u6211\u5c31\u53ef\u4ee5", "\u597d\u7684\uff0c\u53ef\u4ee5\u5728\u4ee3\u7801\u4e2d\u52a0\u5165\u4ee5\u4e0b\u5185\u5bb9\u5b9e\u73b0\u5bfc\u51faMarkdown\u7684\u529f\u80fd\uff1a
import\u00a0os
import\u00a0datetime
import\u00a0markdown
def\u00a0export_markdown(history):
\u00a0\u00a0\u00a0\u00a0timestamp\u00a0=\u00a0datetime.datetime.now().strftime('
%Y%m%d\u00a0%H%M%S'
)
\u00a0\u00a0\u00a0\u00a0filename\u00a0=\u00a0f"
history/{timestamp}.md"
\u00a0\u00a0\u00a0\u00a0os.makedirs(os.path.dirname(filename),\u00a0exist_ok=True)
\u00a0\u00a0\u00a0\u00a0with\u00a0open(filename,\u00a0'
w'
)\u00a0as\u00a0f:
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for\u00a0i\u00a0in\u00a0range(0,\u00a0len(history),\u00a02):
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0user_input\u00a0=\u00a0history[i]["
content"
]
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0bot_response\u00a0=\u00a0history[i+1]["
content"
]
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0f.write(f"
\\n##\u00a0User:\u00a0{user_input}\\n\\n"
)
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0f.write(f"
{markdown.markdown(bot_response)}\\n"
)
\u00a0\u00a0\u00a0\u00a0print(f"
\u5bfc\u51fa\u6210\u529f\uff0c\u6587\u4ef6\u540d\u4e3a{filename}"
)
\u00a0\u00a0\u00a0\u00a0return\u00a0None
exportBtn\u00a0=\u00a0gr.Button(label="
\u5bfc\u51faMarkdown"
,)
reduceTokenBtn.append(exportBtn)
exportBtn.click(export_markdown,\u00a0[history],\u00a0[])"]]}