sonoisa commited on
Commit
a606adb
1 Parent(s): 285fd00

Upgrade gradio-lite

Browse files
Files changed (1) hide show
  1. index.html +140 -24
index.html CHANGED
@@ -1,3 +1,4 @@
 
1
  <!--
2
  Copyright (c) 2024 Isao Sonobe
3
  Released under the MIT license
@@ -27,9 +28,62 @@ https://opensource.org/license/mit/
27
  min-height: 500px;
28
  }
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  .chatbot {
31
  white-space: pre-wrap;
32
  }
 
33
 
34
  .gallery-item > .gallery {
35
  max-width: 380px;
@@ -82,7 +136,7 @@ import httpx
82
  await micropip.install("https://raw.githubusercontent.com/sonoisa/pyodide_wheels/main/urllib3/urllib3-2.1.0-py3-none-any.whl", keep_going=True)
83
  import urllib3
84
  urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
85
- await micropip.install("https://raw.githubusercontent.com/sonoisa/pyodide_wheels/main/tiktoken/tiktoken-0.5.1-cp311-cp311-emscripten_3_1_45_wasm32.whl", keep_going=True)
86
 
87
 
88
  import gradio as gr
@@ -111,6 +165,7 @@ from rank_bm25 import BM25Okapi
111
 
112
  from openai import OpenAI, AzureOpenAI
113
  import tiktoken
 
114
 
115
 
116
  class URLLib3Transport(httpx.BaseTransport):
@@ -138,7 +193,28 @@ class Page:
138
  content: str
139
 
140
 
141
- OPENAI_TOKENIZER = tiktoken.get_encoding("cl100k_base")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  JANOME_TOKENIZER = JanomeTokenizer()
143
  JANOME_ANALYZER = JanomeAnalyzer(tokenizer=JANOME_TOKENIZER,
144
  token_filters=[POSStopFilter(["記号,空白"]), LowerCaseFilter()])
@@ -218,6 +294,32 @@ def extract_pages_from_page_tag(document_with_page_tag):
218
  return pages
219
 
220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  def add_s(values):
222
  """
223
  複数形のsを必要に応じて付けるために用いる関数。
@@ -432,7 +534,9 @@ def get_openai_messages(prompt, history, context):
432
  messages = []
433
  for user_message, assistant_message in history:
434
  if user_message is not None and assistant_message is not None:
 
435
  user_message = user_message.replace("{context}", context)
 
436
  messages.append({ "role": "user", "content": user_message })
437
  messages.append({ "role": "assistant", "content": assistant_message })
438
 
@@ -598,7 +702,6 @@ async def process_prompt(prompt, history, context, platform, endpoint, azure_dep
598
  raise gr.Error(str(e))
599
 
600
 
601
-
602
  def load_api_key(file_obj):
603
  """
604
  APIキーファイルからAPIキーを読み込む。
@@ -631,16 +734,16 @@ def get_cost_info(prompt_token_count):
631
 
632
  # デフォルト設定値
633
  DEFAULT_SETTINGS = {
634
- "setting_name": "Default",
635
- "platform": "OpenAI",
636
- "endpoint": "https://api.openai.com/v1",
637
- "azure_deployment": "",
638
- "azure_api_version": "",
639
- "model_name": "gpt-4-turbo-preview",
640
- "max_tokens": 4096,
641
- "temperature": 0.2,
642
- "save_chat_history_to_url": False
643
- };
644
 
645
 
646
  def main():
@@ -1054,8 +1157,16 @@ def main():
1054
  chatbot = gr.Chatbot(
1055
  CHAT_HISTORY,
1056
  elem_id="chatbot", height=500, show_copy_button=True,
1057
- sanitize_html=False, render_markdown=False, likeable=False, layout="bubble",
1058
- avatar_images=[None, Path("robot.png")])
 
 
 
 
 
 
 
 
1059
 
1060
  message_state = gr.State()
1061
  chatbot_state = gr.State(chatbot.value) if chatbot.value else gr.State([])
@@ -1076,6 +1187,7 @@ def main():
1076
  undo_button = gr.Button("↩️ Undo", variant="secondary", size="sm")
1077
  clear_button = gr.Button("🗑️ Clear", variant="secondary", size="sm")
1078
 
 
1079
  def estimate_message_cost(prompt, history, context):
1080
  token_count = 0
1081
  messages = get_openai_messages(prompt, history, context)
@@ -1085,6 +1197,7 @@ def main():
1085
 
1086
  return gr.update(value=get_cost_info(token_count))
1087
 
 
1088
  message_textbox.change(estimate_message_cost, inputs=[message_textbox, chatbot, context], outputs=cost_info, queue=False, show_progress="hidden")
1089
 
1090
  example_title_textbox = gr.Textbox(visible=False, interactive=True)
@@ -1092,17 +1205,21 @@ def main():
1092
  inputs=example_title_textbox, outputs=message_textbox,
1093
  fn=lambda title: examples[title], run_on_click=True)
1094
 
 
1095
  def append_message_to_history(message, history):
 
1096
  history.append([message, None])
1097
  return history, history
1098
 
 
1099
  def undo_chat(history):
1100
  if history:
1101
  message, _ = history.pop()
1102
  message = message or ""
1103
  else:
1104
  message = ""
1105
- return history, history, message
 
1106
 
1107
  async def submit_message(message, history_with_input, *args):
1108
  history = history_with_input[:-1]
@@ -1110,10 +1227,12 @@ def main():
1110
  inputs.extend(args)
1111
 
1112
  generator = process_prompt(*inputs)
 
1113
 
1114
  has_response = False
1115
  async for response in generator:
1116
  has_response = True
 
1117
  update = history + [[message, response]]
1118
  yield update, update
1119
 
@@ -1121,10 +1240,11 @@ def main():
1121
  update = history + [[message, None]]
1122
  yield update, update
1123
 
 
1124
  submit_triggers = [message_textbox.submit, submit_button.click]
1125
 
1126
- submit_event = gr.events.on(submit_triggers, lambda message: ("", message),
1127
- inputs=[message_textbox], outputs=[message_textbox, message_state], queue=False
1128
  ).then(
1129
  append_message_to_history, inputs=[message_state, chatbot_state], outputs=[chatbot, chatbot_state], queue=False
1130
  ).then(
@@ -1181,16 +1301,12 @@ def main():
1181
  estimate_message_cost, inputs=[message_textbox, chatbot, context], outputs=cost_info, show_progress="hidden"
1182
  )
1183
 
1184
- app.load(None, inputs=None, outputs=setting_items,
1185
- js=js_define_utilities_and_load_settings, show_progress="hidden")
1186
 
1187
  app.queue().launch()
1188
 
1189
  main()
1190
  </gradio-file>
1191
-
1192
- <!-- DALL-Eを用いて作ったボットアイコン -->
1193
- <gradio-file name="robot.png" url="https://raw.githubusercontent.com/sonoisa/misc/main/resources/icons/chatbot_icon.png" />
1194
  </gradio-lite>
1195
 
1196
  <script language="javascript" src="https://cdn.jsdelivr.net/npm/lz-string@1.5.0/libs/lz-string.min.js"></script>
@@ -1208,6 +1324,6 @@ main()
1208
  }
1209
  })();
1210
  </script>
1211
- <script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/@gradio/lite@4.14.1/dist/lite.js"></script>
1212
  </body>
1213
  </html>
 
1
+ <!DOCTYPE html>
2
  <!--
3
  Copyright (c) 2024 Isao Sonobe
4
  Released under the MIT license
 
28
  min-height: 500px;
29
  }
30
 
31
+ #chatbot h1 {
32
+ font-size: 2em;
33
+ margin-block-start: 0.67em;
34
+ margin-block-end: 0em;
35
+ margin-inline-start: 0px;
36
+ margin-inline-end: 0px;
37
+ font-weight: bold;
38
+ }
39
+
40
+ #chatbot h2 {
41
+ font-size: 1.5em;
42
+ margin-block-start: 0.83em;
43
+ margin-block-end: 0em;
44
+ margin-inline-start: 0px;
45
+ margin-inline-end: 0px;
46
+ font-weight: bold;
47
+ }
48
+
49
+ #chatbot h3 {
50
+ font-size: 1.17em;
51
+ margin-block-start: 1em;
52
+ margin-block-end: 0em;
53
+ margin-inline-start: 0px;
54
+ margin-inline-end: 0px;
55
+ font-weight: bold;
56
+ }
57
+
58
+ #chatbot h4 {
59
+ margin-block-start: 1.33em;
60
+ margin-block-end: 0em;
61
+ margin-inline-start: 0px;
62
+ margin-inline-end: 0px;
63
+ font-weight: bold;
64
+ }
65
+
66
+ #chatbot h5 {
67
+ margin-block-start: 1.67em;
68
+ margin-block-end: 0em;
69
+ margin-inline-start: 0px;
70
+ margin-inline-end: 0px;
71
+ font-weight: bold;
72
+ }
73
+
74
+ #chatbot h6 {
75
+ margin-block-start: 1.83em;
76
+ margin-block-end: 0em;
77
+ margin-inline-start: 0px;
78
+ margin-inline-end: 0px;
79
+ font-weight: bold;
80
+ }
81
+
82
+ /*
83
  .chatbot {
84
  white-space: pre-wrap;
85
  }
86
+ */
87
 
88
  .gallery-item > .gallery {
89
  max-width: 380px;
 
136
  await micropip.install("https://raw.githubusercontent.com/sonoisa/pyodide_wheels/main/urllib3/urllib3-2.1.0-py3-none-any.whl", keep_going=True)
137
  import urllib3
138
  urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
139
+ await micropip.install("https://raw.githubusercontent.com/sonoisa/pyodide_wheels/main/tiktoken/tiktoken-0.5.2-cp311-cp311-emscripten_3_1_46_wasm32.whl", keep_going=True)
140
 
141
 
142
  import gradio as gr
 
165
 
166
  from openai import OpenAI, AzureOpenAI
167
  import tiktoken
168
+ import requests
169
 
170
 
171
  class URLLib3Transport(httpx.BaseTransport):
 
193
  content: str
194
 
195
 
196
+ def load_tiktoken_model(model_url):
197
+ resp = requests.get(model_url)
198
+ resp.raise_for_status()
199
+ return resp.content
200
+
201
+ # OPENAI_TOKENIZER = tiktoken.get_encoding("cl100k_base")
202
+ OPENAI_TOKENIZER = tiktoken.Encoding(
203
+ name="cl100k_base",
204
+ pat_str=r"""'(?i:[sdmt]|ll|ve|re)|[^\r\n\p{L}\p{N}]?+\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]++[\r\n]*|\s*[\r\n]|\s+(?!\S)|\s+""",
205
+ mergeable_ranks={
206
+ base64.b64decode(token): int(rank)
207
+ for token, rank in (line.split() for line in load_tiktoken_model("https://raw.githubusercontent.com/sonoisa/pyodide_wheels/main/tiktoken/cl100k_base.tiktoken").splitlines() if line)
208
+ },
209
+ special_tokens={
210
+ "&lt;|endoftext|&gt;": 100257,
211
+ "&lt;|fim_prefix|&gt;": 100258,
212
+ "&lt;|fim_middle|&gt;": 100259,
213
+ "&lt;|fim_suffix|&gt;": 100260,
214
+ "&lt;|endofprompt|&gt;": 100276,
215
+ }
216
+ )
217
+
218
  JANOME_TOKENIZER = JanomeTokenizer()
219
  JANOME_ANALYZER = JanomeAnalyzer(tokenizer=JANOME_TOKENIZER,
220
  token_filters=[POSStopFilter(["記号,空白"]), LowerCaseFilter()])
 
294
  return pages
295
 
296
 
297
+ def escape_latex(unescaped_text):
298
+ """
299
+ Chatbotのmarkdownで数式が表示されるように \\(, \\), \\[, \\] をバックスラッシュでエスケープする。
300
+
301
+ Args:
302
+ unescaped_text (str): エスケープ対象文字列
303
+
304
+ Returns:
305
+ str: エスケープされた文字列
306
+ """
307
+ return re.sub(r"(\\[\(\)\[\]])", r"\\\1", unescaped_text)
308
+
309
+
310
+ def unescape_latex(escaped_text):
311
+ """
312
+ Chatbotのmarkdownで数式が表示されるようにエスケープされていた \\(, \\), \\[, \\] をエスケープされていない元の括弧に変換する。
313
+
314
+ Args:
315
+ escaped_text (str): エスケープされた文字列
316
+
317
+ Returns:
318
+ str: エスケープされていない文字列
319
+ """
320
+ return re.sub(r"\\(\\[\(\)\[\]])", r"\1", escaped_text)
321
+
322
+
323
  def add_s(values):
324
  """
325
  複数形のsを必要に応じて付けるために用いる関数。
 
534
  messages = []
535
  for user_message, assistant_message in history:
536
  if user_message is not None and assistant_message is not None:
537
+ user_message = unescape_latex(user_message)
538
  user_message = user_message.replace("{context}", context)
539
+ assistant_message = unescape_latex(assistant_message)
540
  messages.append({ "role": "user", "content": user_message })
541
  messages.append({ "role": "assistant", "content": assistant_message })
542
 
 
702
  raise gr.Error(str(e))
703
 
704
 
 
705
  def load_api_key(file_obj):
706
  """
707
  APIキーファイルからAPIキーを読み込む。
 
734
 
735
  # デフォルト設定値
736
  DEFAULT_SETTINGS = {
737
+ "setting_name": "Default",
738
+ "platform": "OpenAI",
739
+ "endpoint": "https://api.openai.com/v1",
740
+ "azure_deployment": "",
741
+ "azure_api_version": "",
742
+ "model_name": "gpt-4-turbo-preview",
743
+ "max_tokens": 4096,
744
+ "temperature": 0.2,
745
+ "save_chat_history_to_url": False
746
+ };
747
 
748
 
749
  def main():
 
1157
  chatbot = gr.Chatbot(
1158
  CHAT_HISTORY,
1159
  elem_id="chatbot", height=500, show_copy_button=True,
1160
+ sanitize_html=True, render_markdown=True,
1161
+ latex_delimiters=[
1162
+ # { "left": "$$", "right": "$$", "display": True },
1163
+ # { "left": "$", "right": "$", "display": False },
1164
+ { "left": "\\(", "right": "\\)", "display": False },
1165
+ { "left": "\\[", "right": "\\]", "display": True },
1166
+ ],
1167
+ likeable=False, layout="bubble",
1168
+ avatar_images=[None, "https://raw.githubusercontent.com/sonoisa/misc/main/resources/icons/chatbot_icon.png"]
1169
+ )
1170
 
1171
  message_state = gr.State()
1172
  chatbot_state = gr.State(chatbot.value) if chatbot.value else gr.State([])
 
1187
  undo_button = gr.Button("↩️ Undo", variant="secondary", size="sm")
1188
  clear_button = gr.Button("🗑️ Clear", variant="secondary", size="sm")
1189
 
1190
+
1191
  def estimate_message_cost(prompt, history, context):
1192
  token_count = 0
1193
  messages = get_openai_messages(prompt, history, context)
 
1197
 
1198
  return gr.update(value=get_cost_info(token_count))
1199
 
1200
+
1201
  message_textbox.change(estimate_message_cost, inputs=[message_textbox, chatbot, context], outputs=cost_info, queue=False, show_progress="hidden")
1202
 
1203
  example_title_textbox = gr.Textbox(visible=False, interactive=True)
 
1205
  inputs=example_title_textbox, outputs=message_textbox,
1206
  fn=lambda title: examples[title], run_on_click=True)
1207
 
1208
+
1209
  def append_message_to_history(message, history):
1210
+ message = escape_latex(message)
1211
  history.append([message, None])
1212
  return history, history
1213
 
1214
+
1215
  def undo_chat(history):
1216
  if history:
1217
  message, _ = history.pop()
1218
  message = message or ""
1219
  else:
1220
  message = ""
1221
+ return history, history, unescape_latex(message)
1222
+
1223
 
1224
  async def submit_message(message, history_with_input, *args):
1225
  history = history_with_input[:-1]
 
1227
  inputs.extend(args)
1228
 
1229
  generator = process_prompt(*inputs)
1230
+ message = escape_latex(message)
1231
 
1232
  has_response = False
1233
  async for response in generator:
1234
  has_response = True
1235
+ response = escape_latex(response)
1236
  update = history + [[message, response]]
1237
  yield update, update
1238
 
 
1240
  update = history + [[message, None]]
1241
  yield update, update
1242
 
1243
+
1244
  submit_triggers = [message_textbox.submit, submit_button.click]
1245
 
1246
+ submit_event = gr.events.on(
1247
+ submit_triggers, lambda message: ("", message), inputs=[message_textbox], outputs=[message_textbox, message_state], queue=False
1248
  ).then(
1249
  append_message_to_history, inputs=[message_state, chatbot_state], outputs=[chatbot, chatbot_state], queue=False
1250
  ).then(
 
1301
  estimate_message_cost, inputs=[message_textbox, chatbot, context], outputs=cost_info, show_progress="hidden"
1302
  )
1303
 
1304
+ app.load(None, inputs=None, outputs=setting_items, js=js_define_utilities_and_load_settings, show_progress="hidden")
 
1305
 
1306
  app.queue().launch()
1307
 
1308
  main()
1309
  </gradio-file>
 
 
 
1310
  </gradio-lite>
1311
 
1312
  <script language="javascript" src="https://cdn.jsdelivr.net/npm/lz-string@1.5.0/libs/lz-string.min.js"></script>
 
1324
  }
1325
  })();
1326
  </script>
1327
+ <script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/@gradio/lite@4.26.0/dist/lite.js"></script>
1328
  </body>
1329
  </html>