JohnSmith9982 commited on
Commit
f71a765
1 Parent(s): 230c8d1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +192 -130
app.py CHANGED
@@ -1,13 +1,17 @@
1
  import json
2
  import gradio as gr
3
- import openai
4
  import os
5
  import sys
 
 
6
  # import markdown
7
 
8
  my_api_key = "" # 在这里输入你的 API 密钥
9
  initial_prompt = "You are a helpful assistant."
10
 
 
 
11
  if my_api_key == "":
12
  my_api_key = os.environ.get('my_api_key')
13
 
@@ -15,172 +19,230 @@ if my_api_key == "empty":
15
  print("Please give a api key!")
16
  sys.exit(1)
17
 
 
18
  def parse_text(text):
19
  lines = text.split("\n")
20
- for i,line in enumerate(lines):
 
21
  if "```" in line:
 
22
  items = line.split('`')
23
- if items[-1]:
24
  lines[i] = f'<pre><code class="{items[-1]}">'
25
  else:
26
  lines[i] = f'</code></pre>'
27
  else:
28
- if i>0:
29
- line = line.replace("<", "&lt;")
30
- line = line.replace(">", "&gt;")
31
- lines[i] = '<br/>'+line.replace(" ", "&nbsp;")
 
 
 
 
 
32
  return "".join(lines)
33
 
34
- def get_response(system, context, myKey, raw = False):
35
- openai.api_key = myKey
36
- response = openai.ChatCompletion.create(
37
- model="gpt-3.5-turbo",
38
- messages=[system, *context],
39
- )
40
- openai.api_key = ""
41
- if raw:
42
- return response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  else:
44
- statistics = f'本次对话Tokens用量【{response["usage"]["total_tokens"]} / 4096】 ( 提问+上文 {response["usage"]["prompt_tokens"]},回答 {response["usage"]["completion_tokens"]} )'
45
- message = response["choices"][0]["message"]["content"]
46
-
47
- message_with_stats = f'{message}\n\n================\n\n{statistics}'
48
- # message_with_stats = markdown.markdown(message_with_stats)
49
-
50
- return message, parse_text(message_with_stats)
51
-
52
- def predict(chatbot, input_sentence, system, context, myKey):
53
- if len(input_sentence) == 0:
54
- return []
55
- context.append({"role": "user", "content": f"{input_sentence}"})
56
-
57
- try:
58
- message, message_with_stats = get_response(system, context, myKey)
59
- except:
60
- chatbot.append((input_sentence, "请求失败,请检查API-key是否正确。"))
61
- return chatbot, context
62
-
63
- context.append({"role": "assistant", "content": message})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
- chatbot.append((input_sentence, message_with_stats))
66
 
67
- return chatbot, context
68
 
69
- def retry(chatbot, system, context, myKey):
70
- if len(context) == 0:
71
- return [], []
72
- try:
73
- message, message_with_stats = get_response(system, context[:-1], myKey)
74
- except:
75
- chatbot.append(("重试请求", "请求失败,请检查API-key是否正确。"))
76
- return chatbot, context
77
- context[-1] = {"role": "assistant", "content": message}
78
 
79
- chatbot[-1] = (context[-2]["content"], message_with_stats)
80
- return chatbot, context
 
 
 
 
 
 
81
 
82
- def delete_last_conversation(chatbot, context):
83
- if len(context) == 0:
84
- return [], []
85
- chatbot = chatbot[:-1]
86
- context = context[:-2]
87
- return chatbot, context
88
 
89
- def reduce_token(chatbot, system, context, myKey):
90
- context.append({"role": "user", "content": "请帮我总结一下上述对话的内容,实现减少tokens的同时,保证对话的质量。在总结中不要加入这一句话。"})
 
 
91
 
92
- response = get_response(system, context, myKey, raw=True)
93
 
94
- statistics = f'本次对话Tokens用量【{response["usage"]["completion_tokens"]+12+12+8} / 4096】'
95
- optmz_str = parse_text( f'好的,我们之前聊了:{response["choices"][0]["message"]["content"]}\n\n================\n\n{statistics}' )
96
- chatbot.append(("请帮我总结一下上述对话的内容,实现减少tokens的同时,保证对话的质量。", optmz_str))
 
 
 
 
97
 
98
- context = []
99
- context.append({"role": "user", "content": "我们之前聊了什么?"})
100
- context.append({"role": "assistant", "content": f'我们之前聊了:{response["choices"][0]["message"]["content"]}'})
101
- return chatbot, context
102
 
103
- def save_chat_history(filepath, system, context):
104
- if filepath == "":
105
- return
106
- history = {"system": system, "context": context}
107
- with open(f"{filepath}.json", "w") as f:
108
- json.dump(history, f)
109
 
110
- def load_chat_history(fileobj):
111
- with open(fileobj.name, "r") as f:
112
- history = json.load(f)
113
- context = history["context"]
114
- chathistory = []
115
- for i in range(0, len(context), 2):
116
- chathistory.append((parse_text(context[i]["content"]), parse_text(context[i+1]["content"])))
117
- return chathistory , history["system"], context, history["system"]["content"]
118
 
119
- def get_history_names():
120
- with open("history.json", "r") as f:
121
- history = json.load(f)
122
- return list(history.keys())
123
 
124
 
125
- def reset_state():
126
- return [], []
127
 
128
- def update_system(new_system_prompt):
129
- return {"role": "system", "content": new_system_prompt}
130
 
131
- def set_apikey(new_api_key, myKey):
132
- old_api_key = myKey
133
- try:
134
- get_response(update_system(initial_prompt), [{"role": "user", "content": "test"}], new_api_key)
135
- except:
136
- return "无效的api-key", myKey
137
- encryption_str = "验证成功,api-key已做遮挡处理:" + new_api_key[:4] + "..." + new_api_key[-4:]
138
- return encryption_str, new_api_key
139
 
140
 
141
  with gr.Blocks() as demo:
142
- keyTxt = gr.Textbox(show_label=True, placeholder=f"在这里输入你的API-key...", value=my_api_key, label="API Key").style(container=True)
143
- chatbot = gr.Chatbot().style(color_map=("#1D51EE", "#585A5B"))
144
- context = gr.State([])
145
- systemPrompt = gr.State(update_system(initial_prompt))
146
- myKey = gr.State(my_api_key)
 
147
  topic = gr.State("未命名对话历史记录")
148
 
149
  with gr.Row():
150
  with gr.Column(scale=12):
151
- txt = gr.Textbox(show_label=False, placeholder="在这里输入").style(container=False)
 
152
  with gr.Column(min_width=50, scale=1):
153
  submitBtn = gr.Button("🚀", variant="primary")
154
  with gr.Row():
155
  emptyBtn = gr.Button("🧹 新的对话")
156
  retryBtn = gr.Button("🔄 重新生成")
157
  delLastBtn = gr.Button("🗑️ 删除上条对话")
158
- reduceTokenBtn = gr.Button("♻️ 优化Tokens")
159
- newSystemPrompt = gr.Textbox(show_label=True, placeholder=f"在这里输入新的System Prompt...", label="更改 System prompt").style(container=True)
160
- systemPromptDisplay = gr.Textbox(show_label=True, value=initial_prompt, interactive=False, label="目前的 System prompt").style(container=True)
161
- # with gr.Accordion(label="保存/加载对话历史记录(在文本框中输入文件名,点击“保存对话”按钮,历史记录文件会被存储到本地)", open=False):
162
- # with gr.Column():
163
- # with gr.Row():
164
- # with gr.Column(scale=6):
165
- # saveFileName = gr.Textbox(show_label=True, placeholder=f"在这里输入保存的文件名...", label="保存对话", value="对话历史记录").style(container=True)
166
- # with gr.Column(scale=1):
167
- # saveBtn = gr.Button("💾 保存对话")
168
- # uploadBtn = gr.UploadButton("📂 读取对话", file_count="single", file_types=["json"])
169
-
170
- txt.submit(predict, [chatbot, txt, systemPrompt, context, myKey], [chatbot, context], show_progress=True)
171
- txt.submit(lambda :"", None, txt)
172
- submitBtn.click(predict, [chatbot, txt, systemPrompt, context, myKey], [chatbot, context], show_progress=True)
173
- submitBtn.click(lambda :"", None, txt)
174
- emptyBtn.click(reset_state, outputs=[chatbot, context])
175
- newSystemPrompt.submit(update_system, newSystemPrompt, systemPrompt)
176
- newSystemPrompt.submit(lambda x: x, newSystemPrompt, systemPromptDisplay)
177
- newSystemPrompt.submit(lambda :"", None, newSystemPrompt)
178
- retryBtn.click(retry, [chatbot, systemPrompt, context, myKey], [chatbot, context], show_progress=True)
179
- delLastBtn.click(delete_last_conversation, [chatbot, context], [chatbot, context], show_progress=True)
180
- reduceTokenBtn.click(reduce_token, [chatbot, systemPrompt, context, myKey], [chatbot, context], show_progress=True)
181
- keyTxt.submit(set_apikey, [keyTxt, myKey], [keyTxt, myKey], show_progress=True)
182
- # uploadBtn.upload(load_chat_history, uploadBtn, [chatbot, systemPrompt, context, systemPromptDisplay], show_progress=True)
183
- # saveBtn.click(save_chat_history, [saveFileName, systemPrompt, context], None, show_progress=True)
184
-
185
-
186
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import json
2
  import gradio as gr
3
+ # import openai
4
  import os
5
  import sys
6
+ import traceback
7
+ import requests
8
  # import markdown
9
 
10
  my_api_key = "" # 在这里输入你的 API 密钥
11
  initial_prompt = "You are a helpful assistant."
12
 
13
+ API_URL = "https://api.openai.com/v1/chat/completions"
14
+
15
  if my_api_key == "":
16
  my_api_key = os.environ.get('my_api_key')
17
 
 
19
  print("Please give a api key!")
20
  sys.exit(1)
21
 
22
+
23
  def parse_text(text):
24
  lines = text.split("\n")
25
+ count = 0
26
+ for i, line in enumerate(lines):
27
  if "```" in line:
28
+ count += 1
29
  items = line.split('`')
30
+ if count % 2 == 1:
31
  lines[i] = f'<pre><code class="{items[-1]}">'
32
  else:
33
  lines[i] = f'</code></pre>'
34
  else:
35
+ if i > 0:
36
+ if count % 2 == 1:
37
+ line = line.replace("&", "&amp;")
38
+ line = line.replace("\"", "&quot;")
39
+ line = line.replace("\'", "&apos;")
40
+ line = line.replace("<", "&lt;")
41
+ line = line.replace(">", "&gt;")
42
+ line = line.replace(" ", "&nbsp;")
43
+ lines[i] = '<br/>'+line
44
  return "".join(lines)
45
 
46
+ def predict(inputs, top_p, temperature, openai_api_key, chatbot=[], history=[], system_prompt=initial_prompt, retry=False, summary=False): # repetition_penalty, top_k
47
+
48
+ headers = {
49
+ "Content-Type": "application/json",
50
+ "Authorization": f"Bearer {openai_api_key}"
51
+ }
52
+
53
+ chat_counter = len(history) // 2
54
+
55
+ print(f"chat_counter - {chat_counter}")
56
+
57
+ messages = [compose_system(system_prompt)]
58
+ if chat_counter:
59
+ for data in chatbot:
60
+ temp1 = {}
61
+ temp1["role"] = "user"
62
+ temp1["content"] = data[0]
63
+ temp2 = {}
64
+ temp2["role"] = "assistant"
65
+ temp2["content"] = data[1]
66
+ if temp1["content"] != "":
67
+ messages.append(temp1)
68
+ messages.append(temp2)
69
+ else:
70
+ messages[-1]['content'] = temp2['content']
71
+ if retry and chat_counter:
72
+ messages.pop()
73
+ elif summary and chat_counter:
74
+ messages.append(compose_user(
75
+ "请帮我总结一下上述对话的内容,实现减少字数的同时,保证对话的质量。在总结中不要加入这一句话。"))
76
+ history = ["我们刚刚聊了什么?"]
77
  else:
78
+ temp3 = {}
79
+ temp3["role"] = "user"
80
+ temp3["content"] = inputs
81
+ messages.append(temp3)
82
+ chat_counter += 1
83
+ # messages
84
+ payload = {
85
+ "model": "gpt-3.5-turbo",
86
+ "messages": messages, # [{"role": "user", "content": f"{inputs}"}],
87
+ "temperature": temperature, # 1.0,
88
+ "top_p": top_p, # 1.0,
89
+ "n": 1,
90
+ "stream": True,
91
+ "presence_penalty": 0,
92
+ "frequency_penalty": 0,
93
+ }
94
+
95
+ if not summary:
96
+ history.append(inputs)
97
+ print(f"payload is - {payload}")
98
+ # make a POST request to the API endpoint using the requests.post method, passing in stream=True
99
+ response = requests.post(API_URL, headers=headers,
100
+ json=payload, stream=True)
101
+ #response = requests.post(API_URL, headers=headers, json=payload, stream=True)
102
+
103
+ token_counter = 0
104
+ partial_words = ""
105
+
106
+ counter = 0
107
+ chatbot.append((history[-1], ""))
108
+ for chunk in response.iter_lines():
109
+ if counter == 0:
110
+ counter += 1
111
+ continue
112
+ counter += 1
113
+ # check whether each line is non-empty
114
+ if chunk:
115
+ # decode each line as response data is in bytes
116
+ if len(json.loads(chunk.decode()[6:])['choices'][0]["delta"]) == 0:
117
+ break
118
+ #print(json.loads(chunk.decode()[6:])['choices'][0]["delta"] ["content"])
119
+ partial_words = partial_words + \
120
+ json.loads(chunk.decode()[6:])[
121
+ 'choices'][0]["delta"]["content"]
122
+ if token_counter == 0:
123
+ history.append(" " + partial_words)
124
+ else:
125
+ history[-1] = parse_text(partial_words)
126
+ chatbot[-1] = (history[-2], history[-1])
127
+ # chat = [(history[i], history[i + 1]) for i in range(0, len(history) - 1, 2) ] # convert to tuples of list
128
+ token_counter += 1
129
+ # resembles {chatbot: chat, state: history}
130
+ yield chatbot, history
131
 
 
132
 
 
133
 
134
+ def delete_last_conversation(chatbot, history):
135
+ if chat_counter > 0:
136
+ chat_counter -= 1
137
+ chatbot.pop()
138
+ history.pop()
139
+ history.pop()
140
+ return chatbot, history
 
 
141
 
142
+ def save_chat_history(filepath, system, history, chatbot):
143
+ if filepath == "":
144
+ return
145
+ if not filepath.endswith(".json"):
146
+ filepath += ".json"
147
+ json_s = {"system": system, "history": history, "chatbot": chatbot}
148
+ with open(filepath, "w") as f:
149
+ json.dump(json_s, f)
150
 
 
 
 
 
 
 
151
 
152
+ def load_chat_history(filename):
153
+ with open(filename, "r") as f:
154
+ json_s = json.load(f)
155
+ return filename, json_s["system"], json_s["history"], json_s["chatbot"]
156
 
 
157
 
158
+ def get_history_names(plain=False):
159
+ # find all json files in the current directory and return their names
160
+ files = [f for f in os.listdir() if f.endswith(".json")]
161
+ if plain:
162
+ return files
163
+ else:
164
+ return gr.Dropdown.update(choices=files)
165
 
 
 
 
 
166
 
167
+ def reset_state():
168
+ return [], []
 
 
 
 
169
 
 
 
 
 
 
 
 
 
170
 
171
+ def compose_system(system_prompt):
172
+ return {"role": "system", "content": system_prompt}
 
 
173
 
174
 
175
+ def compose_user(user_input):
176
+ return {"role": "user", "content": user_input}
177
 
 
 
178
 
179
+ def reset_textbox():
180
+ return gr.update(value='')
 
 
 
 
 
 
181
 
182
 
183
  with gr.Blocks() as demo:
184
+ keyTxt = gr.Textbox(show_label=True, placeholder=f"在这里输入你的OpenAI API-key...",
185
+ value=my_api_key, label="API Key", type="password").style(container=True)
186
+ chatbot = gr.Chatbot() # .style(color_map=("#1D51EE", "#585A5B"))
187
+ history = gr.State([])
188
+ TRUECOMSTANT = gr.State(True)
189
+ FALSECONSTANT = gr.State(False)
190
  topic = gr.State("未命名对话历史记录")
191
 
192
  with gr.Row():
193
  with gr.Column(scale=12):
194
+ txt = gr.Textbox(show_label=False, placeholder="在这里输入").style(
195
+ container=False)
196
  with gr.Column(min_width=50, scale=1):
197
  submitBtn = gr.Button("🚀", variant="primary")
198
  with gr.Row():
199
  emptyBtn = gr.Button("🧹 新的对话")
200
  retryBtn = gr.Button("🔄 重新生成")
201
  delLastBtn = gr.Button("🗑️ 删除上条对话")
202
+ reduceTokenBtn = gr.Button("♻️ 总结对话")
203
+ systemPromptTxt = gr.Textbox(show_label=True, placeholder=f"在这里输入System Prompt...",
204
+ label="System prompt", value=initial_prompt).style(container=True)
205
+ with gr.Accordion(label="保存/加载对话历史记录(在文本框中输入文件名,点击“保存对话”按钮,历史记录文件会被存储到Python文件旁边)", open=False):
206
+ with gr.Column():
207
+ with gr.Row():
208
+ with gr.Column(scale=6):
209
+ saveFileName = gr.Textbox(
210
+ show_label=True, placeholder=f"在这里输入保存的文件名...", label="设置保存文件名", value="对话历史记录").style(container=True)
211
+ with gr.Column(scale=1):
212
+ saveBtn = gr.Button("💾 保存对话")
213
+ with gr.Row():
214
+ with gr.Column(scale=6):
215
+ uploadDropdown = gr.Dropdown(label="从列表中加载对话", choices=get_history_names(plain=True), multiselect=False)
216
+ with gr.Column(scale=1):
217
+ refreshBtn = gr.Button("🔄 刷新")
218
+ uploadBtn = gr.Button("📂 读取对话")
219
+ #inputs, top_p, temperature, top_k, repetition_penalty
220
+ with gr.Accordion("参数", open=False):
221
+ top_p = gr.Slider(minimum=-0, maximum=1.0, value=1.0, step=0.05,
222
+ interactive=True, label="Top-p (nucleus sampling)",)
223
+ temperature = gr.Slider(minimum=-0, maximum=5.0, value=1.0,
224
+ step=0.1, interactive=True, label="Temperature",)
225
+ #top_k = gr.Slider( minimum=1, maximum=50, value=4, step=1, interactive=True, label="Top-k",)
226
+ #repetition_penalty = gr.Slider( minimum=0.1, maximum=3.0, value=1.03, step=0.01, interactive=True, label="Repetition Penalty", )
227
+
228
+ txt.submit(predict, [txt, top_p, temperature, keyTxt,
229
+ chatbot, history, systemPromptTxt], [chatbot, history])
230
+ txt.submit(reset_textbox, [], [txt])
231
+ submitBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot,
232
+ history, systemPromptTxt], [chatbot, history], show_progress=True)
233
+ submitBtn.click(reset_textbox, [], [txt])
234
+ emptyBtn.click(reset_state, outputs=[chatbot, history])
235
+ retryBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot, history,
236
+ systemPromptTxt, TRUECOMSTANT], [chatbot, history], show_progress=True)
237
+ delLastBtn.click(delete_last_conversation, [chatbot, history], [
238
+ chatbot, history], show_progress=True)
239
+ reduceTokenBtn.click(predict, [txt, top_p, temperature, keyTxt, chatbot, history,
240
+ systemPromptTxt, FALSECONSTANT, TRUECOMSTANT], [chatbot, history], show_progress=True)
241
+ saveBtn.click(save_chat_history, [
242
+ saveFileName, systemPromptTxt, history, chatbot], None, show_progress=True)
243
+ saveBtn.click(get_history_names, None, [uploadDropdown])
244
+ refreshBtn.click(get_history_names, None, [uploadDropdown])
245
+ uploadBtn.click(load_chat_history, [uploadDropdown], [saveFileName, systemPromptTxt, history, chatbot], show_progress=True)
246
+
247
+
248
+ demo.queue().launch(debug=True)