JohnSmith9982 commited on
Commit
4dfaeff
·
1 Parent(s): 632a25e

Upload 114 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. CITATION.cff +5 -5
  2. ChuanhuChatbot.py +152 -66
  3. Dockerfile +11 -8
  4. config_example.json +55 -14
  5. locale/en_US.json +23 -9
  6. locale/ja_JP.json +23 -9
  7. locale/ko_KR.json +89 -0
  8. locale/sv-SE.json +87 -0
  9. modules/.DS_Store +0 -0
  10. modules/__pycache__/config.cpython-311.pyc +0 -0
  11. modules/__pycache__/config.cpython-39.pyc +0 -0
  12. modules/__pycache__/index_func.cpython-311.pyc +0 -0
  13. modules/__pycache__/index_func.cpython-39.pyc +0 -0
  14. modules/__pycache__/overwrites.cpython-311.pyc +0 -0
  15. modules/__pycache__/overwrites.cpython-39.pyc +0 -0
  16. modules/__pycache__/pdf_func.cpython-311.pyc +0 -0
  17. modules/__pycache__/presets.cpython-311.pyc +0 -0
  18. modules/__pycache__/presets.cpython-39.pyc +0 -0
  19. modules/__pycache__/repo.cpython-311.pyc +0 -0
  20. modules/__pycache__/shared.cpython-311.pyc +0 -0
  21. modules/__pycache__/shared.cpython-39.pyc +0 -0
  22. modules/__pycache__/train_func.cpython-311.pyc +0 -0
  23. modules/__pycache__/utils.cpython-311.pyc +0 -0
  24. modules/__pycache__/utils.cpython-39.pyc +0 -0
  25. modules/__pycache__/webui.cpython-311.pyc +0 -0
  26. modules/config.py +123 -33
  27. modules/index_func.py +15 -20
  28. modules/models/Google_PaLM.py +26 -0
  29. modules/models/__pycache__/ChuanhuAgent.cpython-311.pyc +0 -0
  30. modules/models/__pycache__/Google_PaLM.cpython-311.pyc +0 -0
  31. modules/models/__pycache__/azure.cpython-311.pyc +0 -0
  32. modules/models/__pycache__/base_model.cpython-311.pyc +0 -0
  33. modules/models/__pycache__/base_model.cpython-39.pyc +0 -0
  34. modules/models/__pycache__/models.cpython-311.pyc +0 -0
  35. modules/models/__pycache__/models.cpython-39.pyc +0 -0
  36. modules/models/azure.py +17 -0
  37. modules/models/base_model.py +130 -28
  38. modules/models/midjourney.py +385 -0
  39. modules/models/models.py +34 -17
  40. modules/overwrites.py +33 -20
  41. modules/presets.py +10 -2
  42. modules/repo.py +239 -0
  43. modules/shared.py +1 -0
  44. modules/train_func.py +161 -0
  45. modules/utils.py +85 -58
  46. modules/webui.py +70 -0
  47. readme/README_en.md +21 -8
  48. readme/README_ja.md +21 -8
  49. requirements.txt +8 -5
  50. requirements_advanced.txt +11 -0
CITATION.cff CHANGED
@@ -1,5 +1,5 @@
1
  cff-version: 1.2.0
2
- title: ChuanhuChatGPT
3
  message: >-
4
  If you use this software, please cite it using these
5
  metadata.
@@ -13,8 +13,8 @@ authors:
13
  orcid: https://orcid.org/0009-0005-0357-272X
14
  repository-code: 'https://github.com/GaiZhenbiao/ChuanhuChatGPT'
15
  url: 'https://github.com/GaiZhenbiao/ChuanhuChatGPT'
16
- abstract: Provided a light and easy to use interface for ChatGPT API
17
  license: GPL-3.0
18
- commit: bd0034c37e5af6a90bd9c2f7dd073f6cd27c61af
19
- version: '20230405'
20
- date-released: '2023-04-05'
 
1
  cff-version: 1.2.0
2
+ title: Chuanhu Chat
3
  message: >-
4
  If you use this software, please cite it using these
5
  metadata.
 
13
  orcid: https://orcid.org/0009-0005-0357-272X
14
  repository-code: 'https://github.com/GaiZhenbiao/ChuanhuChatGPT'
15
  url: 'https://github.com/GaiZhenbiao/ChuanhuChatGPT'
16
+ abstract: This software provides a light and easy-to-use interface for ChatGPT API and many LLMs.
17
  license: GPL-3.0
18
+ commit: c6c08bc62ef80e37c8be52f65f9b6051a7eea1fa
19
+ version: '20230709'
20
+ date-released: '2023-07-09'
ChuanhuChatbot.py CHANGED
@@ -1,8 +1,11 @@
1
  # -*- coding:utf-8 -*-
2
- import os
3
  import logging
4
- import sys
 
 
 
5
 
 
6
  import gradio as gr
7
 
8
  from modules import config
@@ -10,6 +13,9 @@ from modules.config import *
10
  from modules.utils import *
11
  from modules.presets import *
12
  from modules.overwrites import *
 
 
 
13
  from modules.models.models import get_model
14
 
15
  logging.getLogger("httpx").setLevel(logging.WARNING)
@@ -17,13 +23,13 @@ logging.getLogger("httpx").setLevel(logging.WARNING)
17
  gr.Chatbot._postprocess_chat_messages = postprocess_chat_messages
18
  gr.Chatbot.postprocess = postprocess
19
 
20
- with open("assets/custom.css", "r", encoding="utf-8") as f:
21
- customCSS = f.read()
22
 
23
  def create_new_model():
24
  return get_model(model_name = MODELS[DEFAULT_MODEL], access_key = my_api_key)[0]
25
 
26
- with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
27
  user_name = gr.State("")
28
  promptTemplates = gr.State(load_template(get_template_names(plain=True)[0], mode=2))
29
  user_question = gr.State("")
@@ -34,31 +40,45 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
34
  topic = gr.State(i18n("未命名对话历史记录"))
35
 
36
  with gr.Row():
37
- gr.HTML(CHUANHU_TITLE, elem_id="app_title")
38
- status_display = gr.Markdown(get_geoip(), elem_id="status_display")
39
- with gr.Row(elem_id="float_display"):
40
- user_info = gr.Markdown(value="getting user info...", elem_id="user_info")
41
-
42
- with gr.Row().style(equal_height=True):
 
 
 
 
 
 
 
 
 
43
  with gr.Column(scale=5):
44
  with gr.Row():
45
- chatbot = gr.Chatbot(label="Chuanhu Chat", elem_id="chuanhu_chatbot").style(height="100%")
46
  with gr.Row():
47
  with gr.Column(min_width=225, scale=12):
48
  user_input = gr.Textbox(
49
- elem_id="user_input_tb",
50
- show_label=False, placeholder=i18n("在这里输入")
51
- ).style(container=False)
 
52
  with gr.Column(min_width=42, scale=1):
53
- submitBtn = gr.Button(value="", variant="primary", elem_id="submit_btn")
54
- cancelBtn = gr.Button(value="", variant="secondary", visible=False, elem_id="cancel_btn")
55
- with gr.Row():
56
- emptyBtn = gr.Button(
57
- i18n("🧹 新的对话"), elem_id="empty_btn"
58
- )
59
- retryBtn = gr.Button(i18n("🔄 重新生成"))
60
- delFirstBtn = gr.Button(i18n("🗑️ 删除最旧对话"))
61
- delLastBtn = gr.Button(i18n("🗑️ 删除最新对话"))
 
 
 
 
62
  with gr.Row(visible=False) as like_dislike_area:
63
  with gr.Column(min_width=20, scale=1):
64
  likeBtn = gr.Button(i18n("👍"))
@@ -77,9 +97,9 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
77
  label="API-Key",
78
  )
79
  if multi_api_key:
80
- usageTxt = gr.Markdown(i18n("多账号模式已开启,无需输入key,可直接开始对话"), elem_id="usage_display", elem_classes="insert_block")
81
  else:
82
- usageTxt = gr.Markdown(i18n("**发送消息** 或 **提交key** 以显示额度"), elem_id="usage_display", elem_classes="insert_block")
83
  model_select_dropdown = gr.Dropdown(
84
  label=i18n("选择模型"), choices=MODELS, multiselect=False, value=MODELS[DEFAULT_MODEL], interactive=True
85
  )
@@ -87,15 +107,15 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
87
  label=i18n("选择LoRA模型"), choices=[], multiselect=False, interactive=True, visible=False
88
  )
89
  with gr.Row():
90
- single_turn_checkbox = gr.Checkbox(label=i18n("单轮对话"), value=False)
91
- use_websearch_checkbox = gr.Checkbox(label=i18n("使用在线搜索"), value=False)
92
  language_select_dropdown = gr.Dropdown(
93
  label=i18n("选择回复语言(针对搜索&索引功能)"),
94
  choices=REPLY_LANGUAGES,
95
  multiselect=False,
96
  value=REPLY_LANGUAGES[0],
97
  )
98
- index_files = gr.Files(label=i18n("上传"), type="file")
99
  two_column = gr.Checkbox(label=i18n("双栏pdf"), value=advance_docs["pdf"].get("two_column", False))
100
  summarize_btn = gr.Button(i18n("总结"))
101
  # TODO: 公式ocr
@@ -107,8 +127,8 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
107
  placeholder=i18n("在这里输入System Prompt..."),
108
  label="System prompt",
109
  value=INITIAL_SYSTEM_PROMPT,
110
- lines=10,
111
- ).style(container=False)
112
  with gr.Accordion(label=i18n("加载Prompt模板"), open=True):
113
  with gr.Column():
114
  with gr.Row():
@@ -118,7 +138,8 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
118
  choices=get_template_names(plain=True),
119
  multiselect=False,
120
  value=get_template_names(plain=True)[0],
121
- ).style(container=False)
 
122
  with gr.Column(scale=1):
123
  templateRefreshBtn = gr.Button(i18n("🔄 刷新"))
124
  with gr.Row():
@@ -129,7 +150,8 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
129
  get_template_names(plain=True)[0], mode=1
130
  ),
131
  multiselect=False,
132
- ).style(container=False)
 
133
 
134
  with gr.Tab(label=i18n("保存/加载")):
135
  with gr.Accordion(label=i18n("保存/加载对话历史记录"), open=True):
@@ -139,10 +161,14 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
139
  historyFileSelectDropdown = gr.Dropdown(
140
  label=i18n("从列表中加载对话"),
141
  choices=get_history_names(plain=True),
142
- multiselect=False
 
143
  )
144
- with gr.Column(scale=1):
145
- historyRefreshBtn = gr.Button(i18n("🔄 刷新"))
 
 
 
146
  with gr.Row():
147
  with gr.Column(scale=6):
148
  saveFileName = gr.Textbox(
@@ -150,7 +176,9 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
150
  placeholder=i18n("设置文件名: 默认为.json,可选为.md"),
151
  label=i18n("设置保存文件名"),
152
  value=i18n("对话历史记录"),
153
- ).style(container=True)
 
 
154
  with gr.Column(scale=1):
155
  saveHistoryBtn = gr.Button(i18n("💾 保存对话"))
156
  exportMarkdownBtn = gr.Button(i18n("📝 导出为Markdown"))
@@ -159,12 +187,32 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
159
  with gr.Column():
160
  downloadFile = gr.File(interactive=True)
161
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  with gr.Tab(label=i18n("高级")):
163
- gr.Markdown(i18n("# ⚠️ 务必谨慎更改 ⚠️\n\n如果无法使用请恢复默认设置"))
164
- gr.HTML(get_html("appearance_switcher.html").format(label=i18n("切换亮暗色主题")), elem_classes="insert_block")
165
  use_streaming_checkbox = gr.Checkbox(
166
- label=i18n("实时传输回答"), value=True, visible=ENABLE_STREAMING_OPTION
167
  )
 
 
168
  with gr.Accordion(i18n("参数"), open=False):
169
  temperature_slider = gr.Slider(
170
  minimum=-0,
@@ -192,7 +240,7 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
192
  )
193
  stop_sequence_txt = gr.Textbox(
194
  show_label=True,
195
- placeholder=i18n("在这里输入停止符,用英文逗号隔开..."),
196
  label="stop",
197
  value="",
198
  lines=1,
@@ -244,25 +292,36 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
244
  lines=1,
245
  )
246
 
247
- with gr.Accordion(i18n("网络设置"), open=False, visible=False):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  # 优先展示自定义的api_host
249
  apihostTxt = gr.Textbox(
250
  show_label=True,
251
- placeholder=i18n("在这里输入API-Host..."),
252
- label="API-Host",
253
  value=config.api_host or shared.API_HOST,
254
  lines=1,
 
 
 
255
  )
256
- changeAPIURLBtn = gr.Button(i18n("🔄 切换API地址"))
257
- proxyTxt = gr.Textbox(
258
- show_label=True,
259
- placeholder=i18n("在这里输入代理地址..."),
260
- label=i18n("代理地址(示例:http://127.0.0.1:10809)"),
261
- value="",
262
- lines=2,
263
- )
264
- changeProxyBtn = gr.Button(i18n("🔄 设置代理地址"))
265
- default_btn = gr.Button(i18n("🔙 恢复默认设置"))
266
 
267
  gr.Markdown(CHUANHU_DESCRIPTION, elem_id="description")
268
  gr.HTML(get_html("footer.html").format(versions=versions_html()), elem_id="footer")
@@ -323,6 +382,10 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
323
  outputs=[saveFileName, systemPromptTxt, chatbot]
324
  )
325
 
 
 
 
 
326
 
327
  # Chatbot
328
  cancelBtn.click(interrupt, [current_model], [])
@@ -341,6 +404,7 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
341
  inputs=[current_model],
342
  outputs=[chatbot, status_display],
343
  show_progress=True,
 
344
  )
345
 
346
  retryBtn.click(**start_outputing_args).then(
@@ -391,7 +455,7 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
391
  keyTxt.change(set_key, [current_model, keyTxt], [user_api_key, status_display], api_name="set_key").then(**get_usage_args)
392
  keyTxt.submit(**get_usage_args)
393
  single_turn_checkbox.change(set_single_turn, [current_model, single_turn_checkbox], None)
394
- model_select_dropdown.change(get_model, [model_select_dropdown, lora_select_dropdown, user_api_key, temperature_slider, top_p_slider, systemPromptTxt, user_name], [current_model, status_display, chatbot, lora_select_dropdown], show_progress=True, api_name="get_model")
395
  model_select_dropdown.change(toggle_like_btn_visibility, [model_select_dropdown], [like_dislike_area], show_progress=False)
396
  lora_select_dropdown.change(get_model, [model_select_dropdown, lora_select_dropdown, user_api_key, temperature_slider, top_p_slider, systemPromptTxt, user_name], [current_model, status_display, chatbot], show_progress=True)
397
 
@@ -425,10 +489,23 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
425
  downloadFile,
426
  show_progress=True,
427
  )
428
- historyRefreshBtn.click(get_history_names, [gr.State(False), user_name], [historyFileSelectDropdown])
 
429
  historyFileSelectDropdown.change(**load_history_from_file_args)
430
  downloadFile.change(upload_chat_history, [current_model, downloadFile, user_name], [saveFileName, systemPromptTxt, chatbot])
431
 
 
 
 
 
 
 
 
 
 
 
 
 
432
  # Advanced
433
  max_context_length_slider.change(set_token_upper_limit, [current_model, max_context_length_slider], None)
434
  temperature_slider.change(set_temperature, [current_model, temperature_slider], None)
@@ -444,15 +521,24 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
444
  default_btn.click(
445
  reset_default, [], [apihostTxt, proxyTxt, status_display], show_progress=True
446
  )
447
- changeAPIURLBtn.click(
448
- change_api_host,
449
- [apihostTxt],
450
- [status_display],
451
- show_progress=True,
452
- )
453
- changeProxyBtn.click(
454
- change_proxy,
455
- [proxyTxt],
 
 
 
 
 
 
 
 
 
456
  [status_display],
457
  show_progress=True,
458
  )
@@ -469,5 +555,5 @@ if __name__ == "__main__":
469
  reload_javascript()
470
  demo.queue(concurrency_count=CONCURRENT_COUNT).launch(
471
  blocked_paths=["config.json"],
472
- favicon_path="./assets/favicon.ico"
473
  )
 
1
  # -*- coding:utf-8 -*-
 
2
  import logging
3
+ logging.basicConfig(
4
+ level=logging.INFO,
5
+ format="%(asctime)s [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s",
6
+ )
7
 
8
+ import colorama
9
  import gradio as gr
10
 
11
  from modules import config
 
13
  from modules.utils import *
14
  from modules.presets import *
15
  from modules.overwrites import *
16
+ from modules.webui import *
17
+ from modules.repo import *
18
+ from modules.train_func import *
19
  from modules.models.models import get_model
20
 
21
  logging.getLogger("httpx").setLevel(logging.WARNING)
 
23
  gr.Chatbot._postprocess_chat_messages = postprocess_chat_messages
24
  gr.Chatbot.postprocess = postprocess
25
 
26
+ # with open("web_assets/css/ChuanhuChat.css", "r", encoding="utf-8") as f:
27
+ # ChuanhuChatCSS = f.read()
28
 
29
  def create_new_model():
30
  return get_model(model_name = MODELS[DEFAULT_MODEL], access_key = my_api_key)[0]
31
 
32
+ with gr.Blocks(theme=small_and_beautiful_theme) as demo:
33
  user_name = gr.State("")
34
  promptTemplates = gr.State(load_template(get_template_names(plain=True)[0], mode=2))
35
  user_question = gr.State("")
 
40
  topic = gr.State(i18n("未命名对话历史记录"))
41
 
42
  with gr.Row():
43
+ gr.HTML(CHUANHU_TITLE, elem_id="app-title")
44
+ status_display = gr.Markdown(get_geoip(), elem_id="status-display")
45
+ with gr.Row(elem_id="float-display"):
46
+ user_info = gr.Markdown(value="getting user info...", elem_id="user-info")
47
+ config_info = gr.HTML(get_html("config_info.html").format(bot_avatar=config.bot_avatar, user_avatar=config.user_avatar), visible=False, elem_id="config-info")
48
+ update_info = gr.HTML(get_html("update.html").format(
49
+ current_version=repo_tag_html(),
50
+ version_time=version_time(),
51
+ cancel_btn=i18n("取消"),
52
+ update_btn=i18n("更新"),
53
+ seenew_btn=i18n("详情"),
54
+ ok_btn=i18n("好"),
55
+ ), visible=check_update)
56
+
57
+ with gr.Row(equal_height=True):
58
  with gr.Column(scale=5):
59
  with gr.Row():
60
+ chatbot = gr.Chatbot(label="Chuanhu Chat", elem_id="chuanhu-chatbot", latex_delimiters=latex_delimiters_set, height=700)
61
  with gr.Row():
62
  with gr.Column(min_width=225, scale=12):
63
  user_input = gr.Textbox(
64
+ elem_id="user-input-tb",
65
+ show_label=False, placeholder=i18n("在这里输入"),
66
+ container=False
67
+ )
68
  with gr.Column(min_width=42, scale=1):
69
+ submitBtn = gr.Button(value="", variant="primary", elem_id="submit-btn")
70
+ cancelBtn = gr.Button(value="", variant="secondary", visible=False, elem_id="cancel-btn")
71
+ with gr.Row(elem_id="chatbot-buttons"):
72
+ with gr.Column(min_width=120, scale=1):
73
+ emptyBtn = gr.Button(
74
+ i18n("🧹 新的对话"), elem_id="empty-btn"
75
+ )
76
+ with gr.Column(min_width=120, scale=1):
77
+ retryBtn = gr.Button(i18n("🔄 重新生成"))
78
+ with gr.Column(min_width=120, scale=1):
79
+ delFirstBtn = gr.Button(i18n("🗑️ 删除最旧对话"))
80
+ with gr.Column(min_width=120, scale=1):
81
+ delLastBtn = gr.Button(i18n("🗑️ 删除最新对话"))
82
  with gr.Row(visible=False) as like_dislike_area:
83
  with gr.Column(min_width=20, scale=1):
84
  likeBtn = gr.Button(i18n("👍"))
 
97
  label="API-Key",
98
  )
99
  if multi_api_key:
100
+ usageTxt = gr.Markdown(i18n("多账号模式已开启,无需输入key,可直接开始对话"), elem_id="usage-display", elem_classes="insert-block", visible=show_api_billing)
101
  else:
102
+ usageTxt = gr.Markdown(i18n("**发送消息** 或 **提交key** 以显示额度"), elem_id="usage-display", elem_classes="insert-block", visible=show_api_billing)
103
  model_select_dropdown = gr.Dropdown(
104
  label=i18n("选择模型"), choices=MODELS, multiselect=False, value=MODELS[DEFAULT_MODEL], interactive=True
105
  )
 
107
  label=i18n("选择LoRA模型"), choices=[], multiselect=False, interactive=True, visible=False
108
  )
109
  with gr.Row():
110
+ single_turn_checkbox = gr.Checkbox(label=i18n("单轮对话"), value=False, elem_classes="switch-checkbox")
111
+ use_websearch_checkbox = gr.Checkbox(label=i18n("使用在线搜索"), value=False, elem_classes="switch-checkbox")
112
  language_select_dropdown = gr.Dropdown(
113
  label=i18n("选择回复语言(针对搜索&索引功能)"),
114
  choices=REPLY_LANGUAGES,
115
  multiselect=False,
116
  value=REPLY_LANGUAGES[0],
117
  )
118
+ index_files = gr.Files(label=i18n("上传"), type="file", elem_id="upload-index-file")
119
  two_column = gr.Checkbox(label=i18n("双栏pdf"), value=advance_docs["pdf"].get("two_column", False))
120
  summarize_btn = gr.Button(i18n("总结"))
121
  # TODO: 公式ocr
 
127
  placeholder=i18n("在这里输入System Prompt..."),
128
  label="System prompt",
129
  value=INITIAL_SYSTEM_PROMPT,
130
+ lines=10
131
+ )
132
  with gr.Accordion(label=i18n("加载Prompt模板"), open=True):
133
  with gr.Column():
134
  with gr.Row():
 
138
  choices=get_template_names(plain=True),
139
  multiselect=False,
140
  value=get_template_names(plain=True)[0],
141
+ container=False,
142
+ )
143
  with gr.Column(scale=1):
144
  templateRefreshBtn = gr.Button(i18n("🔄 刷新"))
145
  with gr.Row():
 
150
  get_template_names(plain=True)[0], mode=1
151
  ),
152
  multiselect=False,
153
+ container=False,
154
+ )
155
 
156
  with gr.Tab(label=i18n("保存/加载")):
157
  with gr.Accordion(label=i18n("保存/加载对话历史记录"), open=True):
 
161
  historyFileSelectDropdown = gr.Dropdown(
162
  label=i18n("从列表中加载对话"),
163
  choices=get_history_names(plain=True),
164
+ multiselect=False,
165
+ container=False,
166
  )
167
+ with gr.Row():
168
+ with gr.Column(min_width=42, scale=1):
169
+ historyRefreshBtn = gr.Button(i18n("🔄 刷新"))
170
+ with gr.Column(min_width=42, scale=1):
171
+ historyDeleteBtn = gr.Button(i18n("🗑️ 删除"))
172
  with gr.Row():
173
  with gr.Column(scale=6):
174
  saveFileName = gr.Textbox(
 
176
  placeholder=i18n("设置文件名: 默认为.json,可选为.md"),
177
  label=i18n("设置保存文件名"),
178
  value=i18n("对话历史记录"),
179
+ elem_classes="no-container"
180
+ # container=False,
181
+ )
182
  with gr.Column(scale=1):
183
  saveHistoryBtn = gr.Button(i18n("💾 保存对话"))
184
  exportMarkdownBtn = gr.Button(i18n("📝 导出为Markdown"))
 
187
  with gr.Column():
188
  downloadFile = gr.File(interactive=True)
189
 
190
+ with gr.Tab(label=i18n("微调")):
191
+ openai_train_status = gr.Markdown(label=i18n("训练状态"), value=i18n("在这里[查看使用介绍](https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B#%E5%BE%AE%E8%B0%83-gpt-35)"))
192
+
193
+ with gr.Tab(label=i18n("准备数据集")):
194
+ dataset_preview_json = gr.JSON(label=i18n("数据集预览"), readonly=True)
195
+ dataset_selection = gr.Files(label = i18n("选择数据集"), file_types=[".xlsx", ".jsonl"], file_count="single")
196
+ upload_to_openai_btn = gr.Button(i18n("上传到OpenAI"), variant="primary", interactive=False)
197
+
198
+ with gr.Tab(label=i18n("训练")):
199
+ openai_ft_file_id = gr.Textbox(label=i18n("文件ID"), value="", lines=1, placeholder=i18n("上传到 OpenAI 后自动填充"))
200
+ openai_ft_suffix = gr.Textbox(label=i18n("模型名称后缀"), value="", lines=1, placeholder=i18n("可选,用于区分不同的模型"))
201
+ openai_train_epoch_slider = gr.Slider(label=i18n("训练轮数(Epochs)"), minimum=1, maximum=100, value=3, step=1, interactive=True)
202
+ openai_start_train_btn = gr.Button(i18n("开始训练"), variant="primary", interactive=False)
203
+
204
+ with gr.Tab(label=i18n("状态")):
205
+ openai_status_refresh_btn = gr.Button(i18n("刷新状态"))
206
+ openai_cancel_all_jobs_btn = gr.Button(i18n("取消所有任务"))
207
+ add_to_models_btn = gr.Button(i18n("添加训练好的模型到模型列表"), interactive=False)
208
+
209
  with gr.Tab(label=i18n("高级")):
210
+ gr.HTML(get_html("appearance_switcher.html").format(label=i18n("切换亮暗色主题")), elem_classes="insert-block")
 
211
  use_streaming_checkbox = gr.Checkbox(
212
+ label=i18n("实时传输回答"), value=True, visible=ENABLE_STREAMING_OPTION, elem_classes="switch-checkbox"
213
  )
214
+ checkUpdateBtn = gr.Button(i18n("🔄 检查更新..."), visible=check_update)
215
+ gr.Markdown(i18n("# ⚠️ 务必谨慎更改 ⚠️"), elem_id="advanced-warning")
216
  with gr.Accordion(i18n("参数"), open=False):
217
  temperature_slider = gr.Slider(
218
  minimum=-0,
 
240
  )
241
  stop_sequence_txt = gr.Textbox(
242
  show_label=True,
243
+ placeholder=i18n("停止符,用英文逗号隔开..."),
244
  label="stop",
245
  value="",
246
  lines=1,
 
292
  lines=1,
293
  )
294
 
295
+ with gr.Accordion(i18n("网络参数"), open=False):
296
+ gr.Markdown(i18n("---\n⚠️ 为保证API-Key安全,请在配置文件`config.json`中修改网络设置"), elem_id="netsetting-warning")
297
+ default_btn = gr.Button(i18n("🔙 恢复默认网络设置"))
298
+ # 网络代理
299
+ proxyTxt = gr.Textbox(
300
+ show_label=True,
301
+ placeholder=i18n("未设置代理..."),
302
+ label=i18n("代理地址"),
303
+ value=config.http_proxy,
304
+ lines=1,
305
+ interactive=False,
306
+ # container=False,
307
+ elem_classes="view-only-textbox no-container",
308
+ )
309
+ # changeProxyBtn = gr.Button(i18n("🔄 设置代理地址"))
310
+
311
  # 优先展示自定义的api_host
312
  apihostTxt = gr.Textbox(
313
  show_label=True,
314
+ placeholder="api.openai.com",
315
+ label="OpenAI API-Host",
316
  value=config.api_host or shared.API_HOST,
317
  lines=1,
318
+ interactive=False,
319
+ # container=False,
320
+ elem_classes="view-only-textbox no-container",
321
  )
322
+ # changeAPIURLBtn = gr.Button(i18n("🔄 切换API地址"))
323
+ updateChuanhuBtn = gr.Button(visible=False, elem_classes="invisible-btn", elem_id="update-chuanhu-btn")
324
+
 
 
 
 
 
 
 
325
 
326
  gr.Markdown(CHUANHU_DESCRIPTION, elem_id="description")
327
  gr.HTML(get_html("footer.html").format(versions=versions_html()), elem_id="footer")
 
382
  outputs=[saveFileName, systemPromptTxt, chatbot]
383
  )
384
 
385
+ refresh_history_args = dict(
386
+ fn=get_history_names, inputs=[gr.State(False), user_name], outputs=[historyFileSelectDropdown]
387
+ )
388
+
389
 
390
  # Chatbot
391
  cancelBtn.click(interrupt, [current_model], [])
 
404
  inputs=[current_model],
405
  outputs=[chatbot, status_display],
406
  show_progress=True,
407
+ _js='clearChatbot',
408
  )
409
 
410
  retryBtn.click(**start_outputing_args).then(
 
455
  keyTxt.change(set_key, [current_model, keyTxt], [user_api_key, status_display], api_name="set_key").then(**get_usage_args)
456
  keyTxt.submit(**get_usage_args)
457
  single_turn_checkbox.change(set_single_turn, [current_model, single_turn_checkbox], None)
458
+ model_select_dropdown.change(get_model, [model_select_dropdown, lora_select_dropdown, user_api_key, temperature_slider, top_p_slider, systemPromptTxt, user_name], [current_model, status_display, chatbot, lora_select_dropdown, user_api_key, keyTxt], show_progress=True, api_name="get_model")
459
  model_select_dropdown.change(toggle_like_btn_visibility, [model_select_dropdown], [like_dislike_area], show_progress=False)
460
  lora_select_dropdown.change(get_model, [model_select_dropdown, lora_select_dropdown, user_api_key, temperature_slider, top_p_slider, systemPromptTxt, user_name], [current_model, status_display, chatbot], show_progress=True)
461
 
 
489
  downloadFile,
490
  show_progress=True,
491
  )
492
+ historyRefreshBtn.click(**refresh_history_args)
493
+ historyDeleteBtn.click(delete_chat_history, [current_model, historyFileSelectDropdown, user_name], [status_display, historyFileSelectDropdown, chatbot], _js='(a,b,c)=>{return showConfirmationDialog(a, b, c);}')
494
  historyFileSelectDropdown.change(**load_history_from_file_args)
495
  downloadFile.change(upload_chat_history, [current_model, downloadFile, user_name], [saveFileName, systemPromptTxt, chatbot])
496
 
497
+ # Train
498
+ dataset_selection.upload(handle_dataset_selection, dataset_selection, [dataset_preview_json, upload_to_openai_btn, openai_train_status])
499
+ dataset_selection.clear(handle_dataset_clear, [], [dataset_preview_json, upload_to_openai_btn])
500
+ upload_to_openai_btn.click(upload_to_openai, [dataset_selection], [openai_ft_file_id, openai_train_status], show_progress=True)
501
+
502
+ openai_ft_file_id.change(lambda x: gr.update(interactive=True) if len(x) > 0 else gr.update(interactive=False), [openai_ft_file_id], [openai_start_train_btn])
503
+ openai_start_train_btn.click(start_training, [openai_ft_file_id, openai_ft_suffix, openai_train_epoch_slider], [openai_train_status])
504
+
505
+ openai_status_refresh_btn.click(get_training_status, [], [openai_train_status, add_to_models_btn])
506
+ add_to_models_btn.click(add_to_models, [], [model_select_dropdown, openai_train_status], show_progress=True)
507
+ openai_cancel_all_jobs_btn.click(cancel_all_jobs, [], [openai_train_status], show_progress=True)
508
+
509
  # Advanced
510
  max_context_length_slider.change(set_token_upper_limit, [current_model, max_context_length_slider], None)
511
  temperature_slider.change(set_temperature, [current_model, temperature_slider], None)
 
521
  default_btn.click(
522
  reset_default, [], [apihostTxt, proxyTxt, status_display], show_progress=True
523
  )
524
+ # changeAPIURLBtn.click(
525
+ # change_api_host,
526
+ # [apihostTxt],
527
+ # [status_display],
528
+ # show_progress=True,
529
+ # )
530
+ # changeProxyBtn.click(
531
+ # change_proxy,
532
+ # [proxyTxt],
533
+ # [status_display],
534
+ # show_progress=True,
535
+ # )
536
+ checkUpdateBtn.click(fn=None, _js='manualCheckUpdate')
537
+
538
+ # Invisible elements
539
+ updateChuanhuBtn.click(
540
+ update_chuanhu,
541
+ [],
542
  [status_display],
543
  show_progress=True,
544
  )
 
555
  reload_javascript()
556
  demo.queue(concurrency_count=CONCURRENT_COUNT).launch(
557
  blocked_paths=["config.json"],
558
+ favicon_path="./web_assets/favicon.ico",
559
  )
Dockerfile CHANGED
@@ -1,15 +1,18 @@
1
- FROM python:3.9 as builder
2
- RUN apt-get update && apt-get install -y build-essential
 
 
 
3
  COPY requirements.txt .
4
  COPY requirements_advanced.txt .
5
- RUN pip install --user -r requirements.txt
6
- # RUN pip install --user -r requirements_advanced.txt
7
 
8
- FROM python:3.9
9
- MAINTAINER iskoldt
10
  COPY --from=builder /root/.local /root/.local
11
  ENV PATH=/root/.local/bin:$PATH
12
  COPY . /app
13
  WORKDIR /app
14
- ENV dockerrun yes
15
- CMD ["python3", "-u", "ChuanhuChatbot.py", "2>&1", "|", "tee", "/var/log/application.log"]
 
1
+ FROM python:3.9-slim-buster as builder
2
+ RUN apt-get update \
3
+ && apt-get install -y build-essential \
4
+ && apt-get clean \
5
+ && rm -rf /var/lib/apt/lists/*
6
  COPY requirements.txt .
7
  COPY requirements_advanced.txt .
8
+ RUN pip install --user --no-cache-dir -r requirements.txt
9
+ # RUN pip install --user --no-cache-dir -r requirements_advanced.txt
10
 
11
+ FROM python:3.9-slim-buster
12
+ LABEL maintainer="iskoldt"
13
  COPY --from=builder /root/.local /root/.local
14
  ENV PATH=/root/.local/bin:$PATH
15
  COPY . /app
16
  WORKDIR /app
17
+ ENV dockerrun=yes
18
+ CMD ["python3", "-u", "ChuanhuChatbot.py","2>&1", "|", "tee", "/var/log/application.log"]
config_example.json CHANGED
@@ -1,24 +1,60 @@
1
  {
2
- // 你的OpenAI API Key,一般必填,
3
- // 若缺省填为 "openai_api_key": "" 则必须再在图形界面中填入API Key
4
- "openai_api_key": "",
5
- // 你的xmchat API Key,与OpenAI API Key不同
6
- "xmchat_api_key": "",
7
- "language": "auto",
8
- // 如果使用代理,请取消注释下面的两行,并替换代理URL
9
- // "https_proxy": "http://127.0.0.1:1079",
10
- // "http_proxy": "http://127.0.0.1:1079",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  "users": [], // 用户列表,[[用户名1, 密码1], [用户名2, 密码2], ...]
12
  "local_embedding": false, //是否在本地编制索引
 
 
13
  "default_model": "gpt-3.5-turbo", // 默认模型
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  "advance_docs": {
15
  "pdf": {
16
- // 是否认为PDF是双栏的
17
- "two_column": false,
18
- // 是否使用OCR识别PDF中的公式
19
- "formula_ocr": true
20
  }
21
  },
 
 
22
  // 是否多个API Key轮换使用
23
  "multi_api_key": false,
24
  "api_key_list": [
@@ -26,7 +62,12 @@
26
  "sk-xxxxxxxxxxxxxxxxxxxxxxxx2",
27
  "sk-xxxxxxxxxxxxxxxxxxxxxxxx3"
28
  ],
29
- // 如果使用自定义端口、自定义ip,请取消注释并替换对应内容
 
 
 
 
 
30
  // "server_name": "0.0.0.0",
31
  // "server_port": 7860,
32
  // 如果要share到gradio,设置为true
 
1
  {
2
+ // 各配置具体说明,见 [https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/使用教程#配置-configjson]
3
+
4
+ //== API 配置 ==
5
+ "openai_api_key": "", // 你的 OpenAI API Key,一般必填,若空缺则需在图形界面中填入API Key
6
+ "google_palm_api_key": "", // 你的 Google PaLM API Key,用于 Google PaLM 对话模型
7
+ "xmchat_api_key": "", // 你的 xmchat API Key,用于 XMChat 对话模型
8
+ "minimax_api_key": "", // 你的 MiniMax API Key,用于 MiniMax 对话模型
9
+ "minimax_group_id": "", // 你的 MiniMax Group ID,用于 MiniMax 对话模型
10
+ "midjourney_proxy_api_base": "https://xxx/mj", // 你的 https://github.com/novicezk/midjourney-proxy 代理地址
11
+ "midjourney_proxy_api_secret": "", // 你的 MidJourney Proxy API Secret,用于鉴权访问 api,可选
12
+ "midjourney_discord_proxy_url": "", // 你的 MidJourney Discord Proxy URL,用于对生成对图进行反代,可选
13
+ "midjourney_temp_folder": "./tmp", // 你的 MidJourney 临时文件夹,用于存放生成的图片,填空则关闭自动下载切图(直接显示MJ的四宫格图)
14
+
15
+
16
+ //== Azure ==
17
+ "openai_api_type": "openai", // 可选项:azure, openai
18
+ "azure_openai_api_key": "", // 你的 Azure OpenAI API Key,用于 Azure OpenAI 对话模型
19
+ "azure_openai_api_base_url": "", // 你的 Azure Base URL
20
+ "azure_openai_api_version": "2023-05-15", // 你的 Azure OpenAI API 版本
21
+ "azure_deployment_name": "", // 你的 Azure OpenAI Chat 模型 Deployment 名称
22
+ "azure_embedding_deployment_name": "", // 你的 Azure OpenAI Embedding 模型 Deployment 名称
23
+ "azure_embedding_model_name": "text-embedding-ada-002", // 你的 Azure OpenAI Embedding 模型名称
24
+
25
+ //== 基础配置 ==
26
+ "language": "auto", // 界面语言,可选"auto", "zh-CN", "en-US", "ja-JP", "ko-KR", "sv-SE"
27
  "users": [], // 用户列表,[[用户名1, 密码1], [用户名2, 密码2], ...]
28
  "local_embedding": false, //是否在本地编制索引
29
+ "hide_history_when_not_logged_in": false, //未登录情况下是否不展示对话历史
30
+ "check_update": true, //是否启用检查更新
31
  "default_model": "gpt-3.5-turbo", // 默认模型
32
+ "bot_avatar": "default", // 机器人头像,可填写图片链接、Data URL (base64),或者"none"(不显示头像)
33
+ "user_avatar": "default", // 用户头像,可填写图片链接、Data URL (base64),或者"none"(不显示头像)
34
+
35
+ //== API 用量 ==
36
+ "show_api_billing": false, //是否显示OpenAI API用量(启用需要填写sensitive_id)
37
+ "sensitive_id": "", // 你 OpenAI 账户的 Sensitive ID,用于查询 API 用量
38
+ "usage_limit": 120, // 该 OpenAI API Key 的当月限额,单位:美元,用于计算百分比和显示上限
39
+ "legacy_api_usage": false, // 是否使用旧版 API 用量查询接口(OpenAI现已关闭该接口,但是如果你在使用第三方 API,第三方可能仍然支持此接口)
40
+
41
+ //== 川虎助理设置 ==
42
+ "default_chuanhu_assistant_model": "gpt-4", //川虎助理使用的模型,可选gpt-3.5-turbo或者gpt-4等
43
+ "GOOGLE_CSE_ID": "", //谷歌搜索引擎ID,用于川虎助理Pro模式,获取方式请看 https://stackoverflow.com/questions/37083058/programmatically-searching-google-in-python-using-custom-search
44
+ "GOOGLE_API_KEY": "", //谷歌API Key,用于川虎助理Pro模式
45
+ "WOLFRAM_ALPHA_APPID": "", //Wolfram Alpha API Key,用于川虎助理Pro模式,获取方式请看 https://products.wolframalpha.com/api/
46
+ "SERPAPI_API_KEY": "", //SerpAPI API Key,用于川虎助理Pro模式,获取方式请看 https://serpapi.com/
47
+
48
+ //== 文档处理与显示 ==
49
+ "latex_option": "default", // LaTeX 公式渲染策略,可选"default", "strict", "all"或者"disabled"
50
  "advance_docs": {
51
  "pdf": {
52
+ "two_column": false, // 是否认为PDF是双栏的
53
+ "formula_ocr": true // 是否使用OCR识别PDF中的公式
 
 
54
  }
55
  },
56
+
57
+ //== 高级配置 ==
58
  // 是否多个API Key轮换使用
59
  "multi_api_key": false,
60
  "api_key_list": [
 
62
  "sk-xxxxxxxxxxxxxxxxxxxxxxxx2",
63
  "sk-xxxxxxxxxxxxxxxxxxxxxxxx3"
64
  ],
65
+ // 自定义OpenAI API Base
66
+ // "openai_api_base": "https://api.openai.com",
67
+ // 自定��使用代理(请替换代理URL)
68
+ // "https_proxy": "http://127.0.0.1:1079",
69
+ // "http_proxy": "http://127.0.0.1:1079",
70
+ // 自定义端口、自定义ip(请替换对应内容)
71
  // "server_name": "0.0.0.0",
72
  // "server_port": 7860,
73
  // 如果要share到gradio,设置为true
locale/en_US.json CHANGED
@@ -32,24 +32,33 @@
32
  "📝 导出为Markdown": "📝 Export as Markdown",
33
  "默认保存于history文件夹": "Default save in history folder",
34
  "高级": "Advanced",
35
- "# ⚠️ 务必谨慎更改 ⚠️\n\n如果无法使用请恢复默认设置": "# ⚠️ Caution: Changes require care. ⚠️\n\nIf unable to use, restore default settings.",
36
  "参数": "Parameters",
37
- "在这里输入停止符,用英文逗号隔开...": "Type in stop token here, separated by comma...",
38
  "用于定位滥用行为": "Used to locate abuse",
39
  "用户名": "Username",
40
- "网络设置": "Network Settings",
41
  "在这里输入API-Host...": "Type in API-Host here...",
42
  "🔄 切换API地址": "🔄 Switch API Address",
43
- "在这里输入代理地址...": "Type in proxy address here...",
44
- "代理地址(示例:http://127.0.0.1:10809)": "Proxy address (example: http://127.0.0.1:10809)",
45
  "🔄 设置代理地址": "🔄 Set Proxy Address",
46
- "🔙 恢复默认设置": "🔙 Restore Default Settings",
 
 
 
 
 
 
 
47
  "川虎Chat 🚀": "Chuanhu Chat 🚀",
48
  "开始实时传输回答……": "Start streaming output...",
49
  "Token 计数: ": "Token Count: ",
50
- ",本次对话累计消耗了 ": "Total cost for this dialogue is ",
51
  "**获取API使用情况失败**": "**Failed to get API usage**",
 
 
52
  "**本月使用金额** ": "**Monthly usage** ",
 
53
  "获取API使用情况失败:": "Failed to get API usage:",
54
  "API密钥更改为了": "The API key is changed to",
55
  "JSON解析错误,收到的内容: ": "JSON parsing error, received content: ",
@@ -64,10 +73,15 @@
64
  "API key为空,请检查是否输入正确。": "API key is empty, check whether it is entered correctly.",
65
  "请输入对话内容。": "Enter the content of the conversation.",
66
  "账单信息不适用": "Billing information is not applicable",
67
- "由Bilibili [土川虎虎虎](https://space.bilibili.com/29125536)[明昭MZhao](https://space.bilibili.com/24807452)开发<br />访问川虎Chat的 [GitHub项目](https://github.com/GaiZhenbiao/ChuanhuChatGPT) 下载最新版脚本": "developor: Bilibili [土川虎虎虎](https://space.bilibili.com/29125536) and [明昭MZhao](https://space.bilibili.com/24807452)\n\nDownload latest code from [GitHub](https://github.com/GaiZhenbiao/ChuanhuChatGPT)",
68
  "切换亮暗色主题": "Switch light/dark theme",
69
  "您的IP区域:未知。": "Your IP region: Unknown.",
70
  "获取IP地理位置失败。原因:": "Failed to get IP location. Reason: ",
71
  "。你仍然可以使用聊天功能。": ". You can still use the chat function.",
72
- "您的IP区域:": "Your IP region: "
 
 
 
 
 
73
  }
 
32
  "📝 导出为Markdown": "📝 Export as Markdown",
33
  "默认保存于history文件夹": "Default save in history folder",
34
  "高级": "Advanced",
35
+ "# ⚠️ 务必谨慎更改 ⚠️": "# ⚠️ Caution: Changes require care. ⚠️",
36
  "参数": "Parameters",
37
+ "停止符,用英文逗号隔开...": "Type in stop token here, separated by comma...",
38
  "用于定位滥用行为": "Used to locate abuse",
39
  "用户名": "Username",
 
40
  "在这里输入API-Host...": "Type in API-Host here...",
41
  "🔄 切换API地址": "🔄 Switch API Address",
42
+ "未设置代理...": "No proxy...",
43
+ "代理地址": "Proxy address",
44
  "🔄 设置代理地址": "🔄 Set Proxy Address",
45
+ "🔙 恢复默认网络设置": "🔙 Reset Network Settings",
46
+ "🔄 检查更新...": "🔄 Check for Update...",
47
+ "取消": "Cancel",
48
+ "更新": "Update",
49
+ "详情": "Details",
50
+ "好": "OK",
51
+ "更新成功,请重启本程序": "Updated successfully, please restart this program",
52
+ "更新失败,请尝试[手动更新](https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/使用教程#手动更新)": "Update failed, please try [manually updating](https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/使用教程#手动更新)",
53
  "川虎Chat 🚀": "Chuanhu Chat 🚀",
54
  "开始实时传输回答……": "Start streaming output...",
55
  "Token 计数: ": "Token Count: ",
56
+ ",本次对话累计消耗了 ": ", Total cost for this dialogue is ",
57
  "**获取API使用情况失败**": "**Failed to get API usage**",
58
+ "**获取API使用情况失败**,需在填写`config.json`中正确填写sensitive_id": "**Failed to get API usage**, correct sensitive_id needed in `config.json`",
59
+ "**获取API使用情况失败**,sensitive_id错误或已过期": "**Failed to get API usage**, wrong or expired sensitive_id",
60
  "**本月使用金额** ": "**Monthly usage** ",
61
+ "本月使用金额": "Monthly usage",
62
  "获取API使用情况失败:": "Failed to get API usage:",
63
  "API密钥更改为了": "The API key is changed to",
64
  "JSON解析错误,收到的内容: ": "JSON parsing error, received content: ",
 
73
  "API key为空,请检查是否输入正确。": "API key is empty, check whether it is entered correctly.",
74
  "请输入对话内容。": "Enter the content of the conversation.",
75
  "账单信息不适用": "Billing information is not applicable",
76
+ "由Bilibili [土川虎虎虎](https://space.bilibili.com/29125536)[明昭MZhao](https://space.bilibili.com/24807452) 和 [Keldos](https://github.com/Keldos-Li) 开发<br />访问川虎Chat的 [GitHub项目](https://github.com/GaiZhenbiao/ChuanhuChatGPT) 下载最新版脚本": "Developed by Bilibili [土川虎虎虎](https://space.bilibili.com/29125536), [明昭MZhao](https://space.bilibili.com/24807452) and [Keldos](https://github.com/Keldos-Li)\n\nDownload latest code from [GitHub](https://github.com/GaiZhenbiao/ChuanhuChatGPT)",
77
  "切换亮暗色主题": "Switch light/dark theme",
78
  "您的IP区域:未知。": "Your IP region: Unknown.",
79
  "获取IP地理位置失败。原因:": "Failed to get IP location. Reason: ",
80
  "。你仍然可以使用聊天功能。": ". You can still use the chat function.",
81
+ "您的IP区域:": "Your IP region: ",
82
+ "总结": "Summarize",
83
+ "生成内容总结中……": "Generating content summary...",
84
+ "由于下面的原因,Google 拒绝返回 PaLM 的回答:\n\n": "Due to the following reasons, Google refuses to provide an answer to PaLM: \n\n",
85
+ "---\n⚠️ 为保证API-Key安全,请在配置文件`config.json`中修改网络设置": "---\n⚠️ To ensure the security of API-Key, please modify the network settings in the configuration file `config.json`.",
86
+ "网络参数": "Network parameter"
87
  }
locale/ja_JP.json CHANGED
@@ -32,24 +32,33 @@
32
  "📝 导出为Markdown": "📝 Markdownでエクスポート",
33
  "默认保存于history文件夹": "デフォルトでhistoryフォルダに保存されます",
34
  "高级": "Advanced",
35
- "# ⚠️ 务必谨慎更改 ⚠️\n\n如果无法使用请恢复默认设置": "# ⚠️ 変更には慎重に ⚠️\n\nもし動作しない場合は、デフォルト設定に戻してください。",
36
  "参数": "パラメータ",
37
- "在这里输入停止符,用英文逗号隔开...": "ここにストップ文字を英語のカンマで区切って入力してください...",
38
  "用于定位滥用行为": "不正行為を特定するために使用されます",
39
  "用户名": "ユーザー名",
40
- "网络设置": "ネットワーク設定",
41
  "在这里输入API-Host...": "API-Hostを入力してください...",
42
  "🔄 切换API地址": "🔄 APIアドレスを切り替え",
43
- "在这里输入代理地址...": "プロキシアドレスを入力してください...",
44
- "代理地址(示例:http://127.0.0.1:10809)": "プロキシアドレス(例:http://127.0.0.1:10809)",
45
  "🔄 设置代理地址": "🔄 プロキシアドレスを設定",
46
- "🔙 恢复默认设置": "🔙 デフォルト設定に戻す",
 
 
 
 
 
 
 
47
  "川虎Chat 🚀": "川虎Chat 🚀",
48
  "开始实时传输回答……": "ストリーム出力開始……",
49
  "Token 计数: ": "Token数: ",
50
  ",本次对话累计消耗了 ": ", 今の会話で消費合計 ",
51
  "**获取API使用情况失败**": "**API使用状況の取得に失敗しました**",
 
 
52
  "**本月使用金额** ": "**今月の使用料金** ",
 
53
  "获取API使用情况失败:": "API使用状況の取得に失敗しました:",
54
  "API密钥更改为了": "APIキーが変更されました",
55
  "JSON解析错误,收到的内容: ": "JSON解析エラー、受信内容: ",
@@ -64,10 +73,15 @@
64
  "API key为空,请检查是否输入正确。": "APIキーが入力されていません。正しく入力されているか確認してください。",
65
  "请输入对话内容。": "会話内容を入力してください。",
66
  "账单信息不适用": "課金情報は対象外です",
67
- "由Bilibili [土川虎虎虎](https://space.bilibili.com/29125536)[明昭MZhao](https://space.bilibili.com/24807452)开发<br />访问川虎Chat的 [GitHub项目](https://github.com/GaiZhenbiao/ChuanhuChatGPT) 下载最新版脚本": "開発:Bilibili [土川虎虎虎](https://space.bilibili.com/29125536) と [明昭MZhao](https://space.bilibili.com/24807452)\n\n最新コードは川虎Chatのサイトへ [GitHubプロジェクト](https://github.com/GaiZhenbiao/ChuanhuChatGPT)",
68
  "切换亮暗色主题": "テーマの明暗切替",
69
  "您的IP区域:未知。": "あなたのIPアドレス地域:不明",
70
  "获取IP地理位置失败。原因:": "IPアドレス地域の取得に失敗しました。理由:",
71
  "。你仍然可以使用聊天功能。": "。あなたはまだチャット機能を使用できます。",
72
- "您的IP区域:": "あなたのIPアドレス地域:"
73
- }
 
 
 
 
 
 
32
  "📝 导出为Markdown": "📝 Markdownでエクスポート",
33
  "默认保存于history文件夹": "デフォルトでhistoryフォルダに保存されます",
34
  "高级": "Advanced",
35
+ "# ⚠️ 务必谨慎更改 ⚠️": "# ⚠️ 変更には慎重に ⚠️",
36
  "参数": "パラメータ",
37
+ "停止符,用英文逗号隔开...": "ここにストップ文字を英語のカンマで区切って入力してください...",
38
  "用于定位滥用行为": "不正行為を特定するために使用されます",
39
  "用户名": "ユーザー名",
 
40
  "在这里输入API-Host...": "API-Hostを入力してください...",
41
  "🔄 切换API地址": "🔄 APIアドレスを切り替え",
42
+ "未设置代理...": "代理が設定されていません...",
43
+ "代理地址": "プロキシアドレス",
44
  "🔄 设置代理地址": "🔄 プロキシアドレスを設定",
45
+ "🔙 恢复默认网络设置": "🔙 ネットワーク設定のリセット",
46
+ "🔄 检查更新...": "🔄 アップデートをチェック...",
47
+ "取消": "キャンセル",
48
+ "更新": "アップデート",
49
+ "详情": "詳細",
50
+ "好": "はい",
51
+ "更新成功,请重启本程序": "更新が成功しました、このプログラムを再起動してください",
52
+ "更新失败,请尝试[手动更新](https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/使用教程#手动更新)": "更新に失敗しました、[手動での更新](https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/使用教程#手动更新)をお試しください。",
53
  "川虎Chat 🚀": "川虎Chat 🚀",
54
  "开始实时传输回答……": "ストリーム出力開始……",
55
  "Token 计数: ": "Token数: ",
56
  ",本次对话累计消耗了 ": ", 今の会話で消費合計 ",
57
  "**获取API使用情况失败**": "**API使用状況の取得に失敗しました**",
58
+ "**获取API使用情况失败**,需在填写`config.json`中正确填写sensitive_id": "**API使用状況の取得に失敗しました**、`config.json`に正しい`sensitive_id`を入力する必要があります",
59
+ "**获取API使用情况失败**,sensitive_id错误或已过期": "**API使用状況の取得に失敗しました**、sensitive_idが間違っているか、期限切れです",
60
  "**本月使用金额** ": "**今月の使用料金** ",
61
+ "本月使用金额": "今月の使用料金",
62
  "获取API使用情况失败:": "API使用状況の取得に失敗しました:",
63
  "API密钥更改为了": "APIキーが変更されました",
64
  "JSON解析错误,收到的内容: ": "JSON解析エラー、受信内容: ",
 
73
  "API key为空,请检查是否输入正确。": "APIキーが入力されていません。正しく入力されているか確認してください。",
74
  "请输入对话内容。": "会話内容を入力してください。",
75
  "账单信息不适用": "課金情報は対象外です",
76
+ "由Bilibili [土川虎虎虎](https://space.bilibili.com/29125536)[明昭MZhao](https://space.bilibili.com/24807452) 和 [Keldos](https://github.com/Keldos-Li) 开发<br />访问川虎Chat的 [GitHub项目](https://github.com/GaiZhenbiao/ChuanhuChatGPT) 下载最新版脚本": "開発:Bilibili [土川虎虎虎](https://space.bilibili.com/29125536) と [明昭MZhao](https://space.bilibili.com/24807452) と [Keldos](https://github.com/Keldos-Li)\n\n最新コードは川虎Chatのサイトへ [GitHubプロジェクト](https://github.com/GaiZhenbiao/ChuanhuChatGPT)",
77
  "切换亮暗色主题": "テーマの明暗切替",
78
  "您的IP区域:未知。": "あなたのIPアドレス地域:不明",
79
  "获取IP地理位置失败。原因:": "IPアドレス地域の取得に失敗しました。理由:",
80
  "。你仍然可以使用聊天功能。": "。あなたはまだチャット機能を使用できます。",
81
+ "您的IP区域:": "あなたのIPアドレス地域:",
82
+ "总结": "要約する",
83
+ "生成内容总结中……": "コンテンツ概要を生成しています...",
84
+ "由于下面的原因,Google 拒绝返回 PaLM 的回答:\n\n": "Googleは以下の理由から、PaLMの回答を返すことを拒否しています:\n\n",
85
+ "---\n⚠️ 为保证API-Key安全,请在配置文件`config.json`中修改网络设置": "---\n⚠️ APIキーの安全性を確保するために、`config.json`ファイルでネットワーク設定を変更してください。",
86
+ "网络参数": "ネットワークパラメータ"
87
+ }
locale/ko_KR.json ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "未命名对话历史记录": "이름없는 대화 기록",
3
+ "在这里输入": "여기에 입력하세요",
4
+ "🧹 新的对话": "🧹 새로운 대화",
5
+ "🔄 重新生成": "🔄 재생성",
6
+ "🗑️ 删除最旧对话": "🗑️ 가장 오래된 대화 삭제",
7
+ "🗑️ 删除最新对话": "🗑️ 최신 대화 삭제",
8
+ "🗑️ 删除": "🗑️ 삭제",
9
+ "模型": "LLM 모델",
10
+ "多账号模式已开启,无需输入key,可直接开始对话": "다중 계정 모드가 활성화되어 있으므로 키를 입력할 필요가 없이 바로 대화를 시작할 수 있습니다",
11
+ "**发送消息** 或 **提交key** 以显示额度": "**메세지를 전송** 하거나 **Key를 입력**하여 크레딧 표시",
12
+ "选择模型": "모델 선택",
13
+ "选择LoRA模型": "LoRA 모델 선택",
14
+ "实时传输回答": "실시간 전송",
15
+ "单轮对话": "단일 대화",
16
+ "使用在线搜索": "온라인 검색 사용",
17
+ "选择回复语言(针对搜索&索引功能)": "답장 언어 선택 (검색 & 인덱스용)",
18
+ "上传索引文件": "업로드",
19
+ "双栏pdf": "2-column pdf",
20
+ "识别公式": "formula OCR",
21
+ "在这里输入System Prompt...": "여기에 시스템 프롬프트를 입력하세요...",
22
+ "加载Prompt模板": "프롬프트 템플릿 불러오기",
23
+ "选择Prompt模板集合文件": "프롬프트 콜렉션 파일 선택",
24
+ "🔄 刷新": "🔄 새로고침",
25
+ "从Prompt模板中加载": "프롬프트 템플릿에서 불러오기",
26
+ "保存/加载": "저장/불러오기",
27
+ "保存/加载对话历史记录": "대화 기록 저장/불러오기",
28
+ "从列表中加载对话": "리스트에서 대화 불러오기",
29
+ "设置文件名: 默认为.json,可选为.md": "파일 이름 설정: 기본값: .json, 선택: .md",
30
+ "设置保存文件名": "저장 파일명 설정",
31
+ "对话历史记录": "대화 기록",
32
+ "💾 保存对话": "💾 대화 저장",
33
+ "📝 导出为Markdown": "📝 마크다운으로 내보내기",
34
+ "默认保存于history文件夹": "히스토리 폴더에 기본 저장",
35
+ "高级": "고급",
36
+ "# ⚠️ 务必谨慎更改 ⚠️": "# ⚠️ 주의: 변경시 주의하세요. ⚠️",
37
+ "参数": "파라미터들",
38
+ "停止符,用英文逗号隔开...": "여기에 정지 토큰 입력, ','로 구분됨...",
39
+ "用于定位滥用行为": "악용 사례 파악에 활용됨",
40
+ "用户名": "사용자 이름",
41
+ "在这里输入API-Host...": "여기에 API host를 입력하세요...",
42
+ "🔄 切换API地址": "🔄 API 주소 변경",
43
+ "未设置代理...": "대리인이 설정되지 않았습니다...",
44
+ "代理地址": "프록시 주소",
45
+ "🔄 设置代理地址": "🔄 프록시 주소 설정",
46
+ "🔙 恢复默认网络设置": "🔙 네트워크 설정 초기화",
47
+ "🔄 检查更新...": "🔄 업데이트 확인...",
48
+ "取消": "취소",
49
+ "更新": "업데이트",
50
+ "详情": "상세",
51
+ "好": "예",
52
+ "更新成功,请重启本程序": "업데이트 성공, 이 프로그램을 재시작 해주세요",
53
+ "更新失败,请尝试[手动更新](https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/使用教程#手动更新)": "업데이트 실패, [수동 업데이트](https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/使用教程#手动更新)를 시도하십시오",
54
+ "川虎Chat 🚀": "Chuanhu Chat 🚀",
55
+ "开始实时传输回答……": "실시간 응답 출력 시작...",
56
+ "Token 计数: ": "토큰 수: ",
57
+ ",本次对话累计消耗了 ": ",이 대화의 전체 비용은 ",
58
+ "**获取API使用情况失败**": "**API 사용량 가져오기 실패**",
59
+ "**获取API使用情况失败**,需在填写`config.json`中正确填写sensitive_id": "**API 사용량 가져오기 실패**. `config.json`에 올바른 `sensitive_id`를 입력해야 합니다",
60
+ "**获取API使用情况失败**,sensitive_id错误或已过期": "**API 사용량 가져오기 실패**. sensitive_id가 잘못되었거나 만료되었습니다",
61
+ "**本月使用金额** ": "**이번 달 사용금액** ",
62
+ "本月使用金额": "이번 달 사용금액",
63
+ "获取API使用情况失败:": "API 사용량 가져오기 실패:",
64
+ "API密钥更改为了": "API 키가 변경되었습니다.",
65
+ "JSON解析错误,收到的内容: ": "JSON 파싱 에러, 응답: ",
66
+ "模型设置为了:": "설정된 모델: ",
67
+ "☹️发生了错误:": "☹️에러: ",
68
+ "获取对话时发生错误,请查看后台日志": "대화를 가져오는 중 에러가 발생했습니다. 백그라운드 로그를 확인하세요",
69
+ "请检查网络连接,或者API-Key是否有效。": "네트워크 연결 또는 API키가 유효한지 확인하세요",
70
+ "连接超时,无法获取对话。": "연결 시간 초과, 대화를 가져올 수 없습니다.",
71
+ "读取超时,无法获取对话。": "읽기 시간 초과, 대화를 가져올 수 없습니다.",
72
+ "代理错误,无法获取对话。": "프록시 에러, 대화를 가져올 수 없습니다.",
73
+ "SSL错误,无法获取对话。": "SSL 에러, 대화를 가져올 수 없습니다.",
74
+ "API key为空,请检查是否输入正确。": "API 키가 비어 있습니다. 올바르게 입력되었는지 확인하십세요.",
75
+ "请输入对话内容。": "대화 내용을 입력하세요.",
76
+ "账单信息不适用": "청구 정보를 가져올 수 없습니다",
77
+ "由Bilibili [土川虎虎虎](https://space.bilibili.com/29125536)、[明昭MZhao](https://space.bilibili.com/24807452) 和 [Keldos](https://github.com/Keldos-Li) 开发<br />访问川虎Chat的 [GitHub项目](https://github.com/GaiZhenbiao/ChuanhuChatGPT) 下载最新版脚本": "제작: Bilibili [土川虎虎虎](https://space.bilibili.com/29125536), [明昭MZhao](https://space.bilibili.com/24807452), [Keldos](https://github.com/Keldos-Li)\n\n최신 코드 다운로드: [GitHub](https://github.com/GaiZhenbiao/ChuanhuChatGPT)",
78
+ "切换亮暗色主题": "라이트/다크 테마 전환",
79
+ "您的IP区域:未知。": "IP 지역: 알 수 없음.",
80
+ "获取IP地理位置失败。原因:": "다음과 같은 이유로 IP 위치를 가져올 수 없습니다. 이유: ",
81
+ "。你仍然可以使用聊天功能。": ". 채팅 기능을 계속 사용할 수 있습니다.",
82
+ "您的IP区域:": "당신의 IP 지역: ",
83
+ "总结": "요약",
84
+ "生成内容总结中……": "콘텐츠 요약 생성중...",
85
+ "上传": "업로드",
86
+ "由于下面的原因,Google 拒绝返回 PaLM 的回答:\n\n": "구글은 다음과 같은 이유로 인해 PaLM의 응답을 거부합니다: \n\n",
87
+ "---\n⚠️ 为保证API-Key安全,请在配置文件`config.json`中修改网络设置": "---\n⚠️ API-Key의 안전을 보장하기 위해 네트워크 설정을 `config.json` 구성 파일에서 수정해주세요.",
88
+ "网络参数": "네트워크 매개변수"
89
+ }
locale/sv-SE.json ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "未命名对话历史记录": "Onämnd Dialoghistorik",
3
+ "在这里输入": "Skriv in här",
4
+ "🧹 新的对话": "🧹 Ny Dialog",
5
+ "🔄 重新生成": "🔄 Regenerera",
6
+ "🗑️ 删除最旧对话": "🗑️ Ta bort äldsta dialogen",
7
+ "🗑️ 删除最新对话": "🗑️ Ta bort senaste dialogen",
8
+ "模型": "Modell",
9
+ "多账号模式已开启,无需输入key,可直接开始对话": "Flerkontoläge är aktiverat, ingen nyckel behövs, du kan starta dialogen direkt",
10
+ "**发送消息** 或 **提交key** 以显示额度": "**Skicka meddelande** eller **Skicka in nyckel** för att visa kredit",
11
+ "选择模型": "Välj Modell",
12
+ "选择LoRA模型": "Välj LoRA Modell",
13
+ "实时传输回答": "Strömmande utdata",
14
+ "单轮对话": "Enkel dialog",
15
+ "使用在线搜索": "Använd online-sökning",
16
+ "选择回复语言(针对搜索&索引功能)": "Välj svarspråk (för sök- och indexfunktion)",
17
+ "上传索引文件": "Ladda upp",
18
+ "双栏pdf": "Två-kolumns pdf",
19
+ "识别公式": "Formel OCR",
20
+ "在这里输入System Prompt...": "Skriv in System Prompt här...",
21
+ "加载Prompt模板": "Ladda Prompt-mall",
22
+ "选择Prompt模板集合文件": "Välj Prompt-mall Samlingsfil",
23
+ "🔄 刷新": "🔄 Uppdatera",
24
+ "从Prompt模板中加载": "Ladda från Prompt-mall",
25
+ "保存/加载": "Spara/Ladda",
26
+ "保存/加载对话历史记录": "Spara/Ladda Dialoghistorik",
27
+ "从列表中加载对话": "Ladda dialog från lista",
28
+ "设置文件名: 默认为.json,可选为.md": "Ställ in filnamn: standard är .json, valfritt är .md",
29
+ "设置保存文件名": "Ställ in sparfilnamn",
30
+ "对话历史记录": "Dialoghistorik",
31
+ "💾 保存对话": "💾 Spara Dialog",
32
+ "📝 导出为Markdown": "📝 Exportera som Markdown",
33
+ "默认保存于history文件夹": "Sparas som standard i mappen history",
34
+ "高级": "Avancerat",
35
+ "# ⚠️ 务必谨慎更改 ⚠️": "# ⚠️ Var försiktig med ändringar. ⚠️",
36
+ "参数": "Parametrar",
37
+ "停止符,用英文逗号隔开...": "Skriv in stopptecken här, separerade med kommatecken...",
38
+ "用于定位滥用行为": "Används för att lokalisera missbruk",
39
+ "用户名": "Användarnamn",
40
+ "在这里输入API-Host...": "Skriv in API-Host här...",
41
+ "🔄 切换API地址": "🔄 Byt API-adress",
42
+ "未设置代理...": "Inte inställd proxy...",
43
+ "代理地址": "Proxyadress",
44
+ "🔄 设置代理地址": "🔄 Ställ in Proxyadress",
45
+ "🔙 恢复网络默认设置": "🔙 Återställ Nätverksinställningar",
46
+ "🔄 检查更新...": "🔄 Sök efter uppdateringar...",
47
+ "取消": "Avbryt",
48
+ "更新": "Uppdatera",
49
+ "详情": "Detaljer",
50
+ "好": "OK",
51
+ "更新成功,请重启本程序": "Uppdaterat framgångsrikt, starta om programmet",
52
+ "更新失败,请尝试[手动更新](https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/使用教程#手动更新)": "Uppdateringen misslyckades, prova att [uppdatera manuellt](https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/使用教程#手动更新)",
53
+ "川虎Chat 🚀": "Chuanhu Chat 🚀",
54
+ "开始实时传输回答……": "Börjar strömma utdata...",
55
+ "Token 计数: ": "Tokenräkning: ",
56
+ ",本次对话累计消耗了 ": ", Total kostnad för denna dialog är ",
57
+ "**获取API使用情况失败**": "**Misslyckades med att hämta API-användning**",
58
+ "**获取API使用情况失败**,需在填写`config.json`中正确填写sensitive_id": "**Misslyckades med att hämta API-användning**, korrekt sensitive_id behövs i `config.json`",
59
+ "**获取API使用情况失败**,sensitive_id错误或已过期": "**Misslyckades med att hämta API-användning**, felaktig eller utgången sensitive_id",
60
+ "**本月使用金额** ": "**Månadens användning** ",
61
+ "本月使用金额": "Månadens användning",
62
+ "获取API使用情况失败:": "Misslyckades med att hämta API-användning:",
63
+ "API密钥更改为了": "API-nyckeln har ändrats till",
64
+ "JSON解析错误,收到的内容: ": "JSON-tolkningsfel, mottaget innehåll: ",
65
+ "模型设置为了:": "Modellen är inställd på: ",
66
+ "☹️发生了错误:": "☹️Fel: ",
67
+ "获取对话时发生错误,请查看后台日志": "Ett fel uppstod när dialogen hämtades, kontrollera bakgrundsloggen",
68
+ "请检查网络连接,或者API-Key是否有效。": "Kontrollera nätverksanslutningen eller om API-nyckeln är giltig.",
69
+ "连接超时,无法获取对话。": "Anslutningen tog för lång tid, kunde inte hämta dialogen.",
70
+ "读取超时,无法获取对话。": "Läsningen tog för lång tid, kunde inte hämta dialogen.",
71
+ "代理错误,无法获取对话。": "Proxyfel, kunde inte hämta dialogen.",
72
+ "SSL错误,无法获取对话。": "SSL-fel, kunde inte hämta dialogen.",
73
+ "API key为空,请检查是否输入正确。": "API-nyckeln är tom, kontrollera om den är korrekt inmatad.",
74
+ "请输入对话内容。": "Ange dialoginnehåll.",
75
+ "账单信息不适用": "Faktureringsinformation är inte tillämplig",
76
+ "由Bilibili [土川虎虎虎](https://space.bilibili.com/29125536)、[明昭MZhao](https://space.bilibili.com/24807452) 和 [Keldos](https://github.com/Keldos-Li) 开发<br />访问川虎Chat的 [GitHub项目](https://github.com/GaiZhenbiao/ChuanhuChatGPT) 下载最新版脚本": "Utvecklad av Bilibili [土川虎虎虎](https://space.bilibili.com/29125536), [明昭MZhao](https://space.bilibili.com/24807452) och [Keldos](https://github.com/Keldos-Li)\n\nLadda ner senaste koden från [GitHub](https://github.com/GaiZhenbiao/ChuanhuChatGPT)",
77
+ "切换亮暗色主题": "Byt ljus/mörk tema",
78
+ "您的IP区域:未知。": "Din IP-region: Okänd.",
79
+ "获取IP地理位置失败。原因:": "Misslyckades med att hämta IP-plats. Orsak: ",
80
+ "。你仍然可以使用聊天功能。": ". Du kan fortfarande använda chattfunktionen.",
81
+ "您的IP区域:": "Din IP-region: ",
82
+ "总结": "Sammanfatta",
83
+ "生成内容总结中……": "Genererar innehållssammanfattning...",
84
+ "由于下面的原因,Google 拒绝返回 PaLM 的回答:\n\n": "På grund av följande skäl vägrar Google att ge ett svar till PaLM: \n\n",
85
+ "---\n⚠️ 为保证API-Key安全,请在配置文件`config.json`中修改网络设置": "---\n⚠️ För att säkerställa säkerheten för API-nyckeln, vänligen ändra nätverksinställningarna i konfigurationsfilen `config.json`.",
86
+ "网络参数": "nätverksparametrar"
87
+ }
modules/.DS_Store ADDED
Binary file (6.15 kB). View file
 
modules/__pycache__/config.cpython-311.pyc CHANGED
Binary files a/modules/__pycache__/config.cpython-311.pyc and b/modules/__pycache__/config.cpython-311.pyc differ
 
modules/__pycache__/config.cpython-39.pyc CHANGED
Binary files a/modules/__pycache__/config.cpython-39.pyc and b/modules/__pycache__/config.cpython-39.pyc differ
 
modules/__pycache__/index_func.cpython-311.pyc CHANGED
Binary files a/modules/__pycache__/index_func.cpython-311.pyc and b/modules/__pycache__/index_func.cpython-311.pyc differ
 
modules/__pycache__/index_func.cpython-39.pyc CHANGED
Binary files a/modules/__pycache__/index_func.cpython-39.pyc and b/modules/__pycache__/index_func.cpython-39.pyc differ
 
modules/__pycache__/overwrites.cpython-311.pyc CHANGED
Binary files a/modules/__pycache__/overwrites.cpython-311.pyc and b/modules/__pycache__/overwrites.cpython-311.pyc differ
 
modules/__pycache__/overwrites.cpython-39.pyc CHANGED
Binary files a/modules/__pycache__/overwrites.cpython-39.pyc and b/modules/__pycache__/overwrites.cpython-39.pyc differ
 
modules/__pycache__/pdf_func.cpython-311.pyc CHANGED
Binary files a/modules/__pycache__/pdf_func.cpython-311.pyc and b/modules/__pycache__/pdf_func.cpython-311.pyc differ
 
modules/__pycache__/presets.cpython-311.pyc CHANGED
Binary files a/modules/__pycache__/presets.cpython-311.pyc and b/modules/__pycache__/presets.cpython-311.pyc differ
 
modules/__pycache__/presets.cpython-39.pyc CHANGED
Binary files a/modules/__pycache__/presets.cpython-39.pyc and b/modules/__pycache__/presets.cpython-39.pyc differ
 
modules/__pycache__/repo.cpython-311.pyc ADDED
Binary file (14.1 kB). View file
 
modules/__pycache__/shared.cpython-311.pyc CHANGED
Binary files a/modules/__pycache__/shared.cpython-311.pyc and b/modules/__pycache__/shared.cpython-311.pyc differ
 
modules/__pycache__/shared.cpython-39.pyc CHANGED
Binary files a/modules/__pycache__/shared.cpython-39.pyc and b/modules/__pycache__/shared.cpython-39.pyc differ
 
modules/__pycache__/train_func.cpython-311.pyc ADDED
Binary file (11.7 kB). View file
 
modules/__pycache__/utils.cpython-311.pyc CHANGED
Binary files a/modules/__pycache__/utils.cpython-311.pyc and b/modules/__pycache__/utils.cpython-311.pyc differ
 
modules/__pycache__/utils.cpython-39.pyc CHANGED
Binary files a/modules/__pycache__/utils.cpython-39.pyc and b/modules/__pycache__/utils.cpython-39.pyc differ
 
modules/__pycache__/webui.cpython-311.pyc ADDED
Binary file (5.45 kB). View file
 
modules/config.py CHANGED
@@ -11,11 +11,11 @@ from . import presets
11
 
12
  __all__ = [
13
  "my_api_key",
 
14
  "authflag",
15
  "auth_list",
16
  "dockerflag",
17
  "retrieve_proxy",
18
- "log_level",
19
  "advance_docs",
20
  "update_doc_config",
21
  "usage_limit",
@@ -23,8 +23,11 @@ __all__ = [
23
  "server_name",
24
  "server_port",
25
  "share",
 
 
26
  "hide_history_when_not_logged_in",
27
- "default_chuanhu_assistant_model"
 
28
  ]
29
 
30
  # 添加一个统一的config文件,避免文件过多造成的疑惑(优先级最低)
@@ -35,10 +38,22 @@ if os.path.exists("config.json"):
35
  else:
36
  config = {}
37
 
 
 
 
 
 
 
 
 
38
  lang_config = config.get("language", "auto")
39
  language = os.environ.get("LANGUAGE", lang_config)
40
 
41
- hide_history_when_not_logged_in = config.get("hide_history_when_not_logged_in", False)
 
 
 
 
42
 
43
  if os.path.exists("api_key.txt"):
44
  logging.info("检测到api_key.txt文件,正在进行迁移...")
@@ -52,26 +67,44 @@ if os.path.exists("auth.json"):
52
  logging.info("检测到auth.json文件,正在进行迁移...")
53
  auth_list = []
54
  with open("auth.json", "r", encoding='utf-8') as f:
55
- auth = json.load(f)
56
- for _ in auth:
57
- if auth[_]["username"] and auth[_]["password"]:
58
- auth_list.append((auth[_]["username"], auth[_]["password"]))
59
- else:
60
- logging.error("请检查auth.json文件中的用户名和密码!")
61
- sys.exit(1)
62
  config["users"] = auth_list
63
  os.rename("auth.json", "auth(deprecated).json")
64
  with open("config.json", "w", encoding='utf-8') as f:
65
  json.dump(config, f, indent=4, ensure_ascii=False)
66
 
67
- ## 处理docker if we are running in Docker
68
  dockerflag = config.get("dockerflag", False)
69
  if os.environ.get("dockerrun") == "yes":
70
  dockerflag = True
71
 
72
- ## 处理 api-key 以及 允许的用户列表
73
  my_api_key = config.get("openai_api_key", "")
74
  my_api_key = os.environ.get("OPENAI_API_KEY", my_api_key)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  xmchat_api_key = config.get("xmchat_api_key", "")
77
  os.environ["XMCHAT_API_KEY"] = xmchat_api_key
@@ -81,11 +114,23 @@ os.environ["MINIMAX_API_KEY"] = minimax_api_key
81
  minimax_group_id = config.get("minimax_group_id", "")
82
  os.environ["MINIMAX_GROUP_ID"] = minimax_group_id
83
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
  usage_limit = os.environ.get("USAGE_LIMIT", config.get("usage_limit", 120))
86
 
87
- ## 多账户机制
88
- multi_api_key = config.get("multi_api_key", False) # 是否开启多账户机制
89
  if multi_api_key:
90
  api_key_list = config.get("api_key_list", [])
91
  if len(api_key_list) == 0:
@@ -93,21 +138,26 @@ if multi_api_key:
93
  sys.exit(1)
94
  shared.state.set_api_key_queue(api_key_list)
95
 
96
- auth_list = config.get("users", []) # 实际上是使用者的列表
97
  authflag = len(auth_list) > 0 # 是否开启认证的状态值,改为判断auth_list长度
98
 
99
  # 处理自定义的api_host,优先读环境变量的配置,如果存在则自动装配
100
- api_host = os.environ.get("OPENAI_API_BASE", config.get("openai_api_base", None))
 
101
  if api_host is not None:
102
  shared.state.set_api_host(api_host)
 
 
103
 
104
- default_chuanhu_assistant_model = config.get("default_chuanhu_assistant_model", "gpt-3.5-turbo")
 
105
  for x in ["GOOGLE_CSE_ID", "GOOGLE_API_KEY", "WOLFRAM_ALPHA_APPID", "SERPAPI_API_KEY"]:
106
  if config.get(x, None) is not None:
107
  os.environ[x] = config[x]
108
 
 
109
  @contextmanager
110
- def retrieve_openai_api(api_key = None):
111
  old_api_key = os.environ.get("OPENAI_API_KEY", "")
112
  if api_key is None:
113
  os.environ["OPENAI_API_KEY"] = my_api_key
@@ -117,24 +167,20 @@ def retrieve_openai_api(api_key = None):
117
  yield api_key
118
  os.environ["OPENAI_API_KEY"] = old_api_key
119
 
120
- ## 处理log
121
- log_level = config.get("log_level", "INFO")
122
- logging.basicConfig(
123
- level=log_level,
124
- format="%(asctime)s [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s",
125
- )
126
 
127
- ## 处理代理:
128
- http_proxy = config.get("http_proxy", "")
129
- https_proxy = config.get("https_proxy", "")
130
- http_proxy = os.environ.get("HTTP_PROXY", http_proxy)
131
- https_proxy = os.environ.get("HTTPS_PROXY", https_proxy)
 
132
 
133
  # 重置系统变量,在不需要设置的时候不设置环境变量,以免引起全局代理报错
134
  os.environ["HTTP_PROXY"] = ""
135
  os.environ["HTTPS_PROXY"] = ""
136
 
137
- local_embedding = config.get("local_embedding", False) # 是否使用本地embedding
 
138
 
139
  @contextmanager
140
  def retrieve_proxy(proxy=None):
@@ -151,22 +197,62 @@ def retrieve_proxy(proxy=None):
151
  old_var = os.environ["HTTP_PROXY"], os.environ["HTTPS_PROXY"]
152
  os.environ["HTTP_PROXY"] = http_proxy
153
  os.environ["HTTPS_PROXY"] = https_proxy
154
- yield http_proxy, https_proxy # return new proxy
155
 
156
  # return old proxy
157
  os.environ["HTTP_PROXY"], os.environ["HTTPS_PROXY"] = old_var
158
 
159
 
160
- ## 处理advance docs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  advance_docs = defaultdict(lambda: defaultdict(dict))
162
  advance_docs.update(config.get("advance_docs", {}))
 
 
163
  def update_doc_config(two_column_pdf):
164
  global advance_docs
165
  advance_docs["pdf"]["two_column"] = two_column_pdf
166
 
167
  logging.info(f"更新后的文件参数为:{advance_docs}")
168
 
169
- ## 处理gradio.launch参数
 
170
  server_name = config.get("server_name", None)
171
  server_port = config.get("server_port", None)
172
  if server_name is None:
@@ -188,3 +274,7 @@ except ValueError:
188
  pass
189
 
190
  share = config.get("share", False)
 
 
 
 
 
11
 
12
  __all__ = [
13
  "my_api_key",
14
+ "sensitive_id",
15
  "authflag",
16
  "auth_list",
17
  "dockerflag",
18
  "retrieve_proxy",
 
19
  "advance_docs",
20
  "update_doc_config",
21
  "usage_limit",
 
23
  "server_name",
24
  "server_port",
25
  "share",
26
+ "check_update",
27
+ "latex_delimiters_set",
28
  "hide_history_when_not_logged_in",
29
+ "default_chuanhu_assistant_model",
30
+ "show_api_billing"
31
  ]
32
 
33
  # 添加一个统一的config文件,避免文件过多造成的疑惑(优先级最低)
 
38
  else:
39
  config = {}
40
 
41
+
42
+ def load_config_to_environ(key_list):
43
+ global config
44
+ for key in key_list:
45
+ if key in config:
46
+ os.environ[key.upper()] = os.environ.get(key.upper(), config[key])
47
+
48
+
49
  lang_config = config.get("language", "auto")
50
  language = os.environ.get("LANGUAGE", lang_config)
51
 
52
+ hide_history_when_not_logged_in = config.get(
53
+ "hide_history_when_not_logged_in", False)
54
+ check_update = config.get("check_update", True)
55
+ show_api_billing = config.get("show_api_billing", False)
56
+ show_api_billing = bool(os.environ.get("SHOW_API_BILLING", show_api_billing))
57
 
58
  if os.path.exists("api_key.txt"):
59
  logging.info("检测到api_key.txt文件,正在进行迁移...")
 
67
  logging.info("检测到auth.json文件,正在进行迁移...")
68
  auth_list = []
69
  with open("auth.json", "r", encoding='utf-8') as f:
70
+ auth = json.load(f)
71
+ for _ in auth:
72
+ if auth[_]["username"] and auth[_]["password"]:
73
+ auth_list.append((auth[_]["username"], auth[_]["password"]))
74
+ else:
75
+ logging.error("请检查auth.json文件中的用户名和密码!")
76
+ sys.exit(1)
77
  config["users"] = auth_list
78
  os.rename("auth.json", "auth(deprecated).json")
79
  with open("config.json", "w", encoding='utf-8') as f:
80
  json.dump(config, f, indent=4, ensure_ascii=False)
81
 
82
+ # 处理docker if we are running in Docker
83
  dockerflag = config.get("dockerflag", False)
84
  if os.environ.get("dockerrun") == "yes":
85
  dockerflag = True
86
 
87
+ # 处理 api-key 以及 允许的用户列表
88
  my_api_key = config.get("openai_api_key", "")
89
  my_api_key = os.environ.get("OPENAI_API_KEY", my_api_key)
90
+ os.environ["OPENAI_API_KEY"] = my_api_key
91
+ os.environ["OPENAI_EMBEDDING_API_KEY"] = my_api_key
92
+
93
+ if config.get("legacy_api_usage", False):
94
+ sensitive_id = my_api_key
95
+ else:
96
+ sensitive_id = config.get("sensitive_id", "")
97
+ sensitive_id = os.environ.get("SENSITIVE_ID", sensitive_id)
98
+
99
+ # 模型配置
100
+ if "extra_models" in config:
101
+ presets.MODELS.extend(config["extra_models"])
102
+ logging.info(f"已添加额外的模型:{config['extra_models']}")
103
+
104
+ google_palm_api_key = config.get("google_palm_api_key", "")
105
+ google_palm_api_key = os.environ.get(
106
+ "GOOGLE_PALM_API_KEY", google_palm_api_key)
107
+ os.environ["GOOGLE_PALM_API_KEY"] = google_palm_api_key
108
 
109
  xmchat_api_key = config.get("xmchat_api_key", "")
110
  os.environ["XMCHAT_API_KEY"] = xmchat_api_key
 
114
  minimax_group_id = config.get("minimax_group_id", "")
115
  os.environ["MINIMAX_GROUP_ID"] = minimax_group_id
116
 
117
+ midjourney_proxy_api_base = config.get("midjourney_proxy_api_base", "")
118
+ os.environ["MIDJOURNEY_PROXY_API_BASE"] = midjourney_proxy_api_base
119
+ midjourney_proxy_api_secret = config.get("midjourney_proxy_api_secret", "")
120
+ os.environ["MIDJOURNEY_PROXY_API_SECRET"] = midjourney_proxy_api_secret
121
+ midjourney_discord_proxy_url = config.get("midjourney_discord_proxy_url", "")
122
+ os.environ["MIDJOURNEY_DISCORD_PROXY_URL"] = midjourney_discord_proxy_url
123
+ midjourney_temp_folder = config.get("midjourney_temp_folder", "")
124
+ os.environ["MIDJOURNEY_TEMP_FOLDER"] = midjourney_temp_folder
125
+
126
+ load_config_to_environ(["openai_api_type", "azure_openai_api_key", "azure_openai_api_base_url",
127
+ "azure_openai_api_version", "azure_deployment_name", "azure_embedding_deployment_name", "azure_embedding_model_name"])
128
+
129
 
130
  usage_limit = os.environ.get("USAGE_LIMIT", config.get("usage_limit", 120))
131
 
132
+ # 多账户机制
133
+ multi_api_key = config.get("multi_api_key", False) # 是否开启多账户机制
134
  if multi_api_key:
135
  api_key_list = config.get("api_key_list", [])
136
  if len(api_key_list) == 0:
 
138
  sys.exit(1)
139
  shared.state.set_api_key_queue(api_key_list)
140
 
141
+ auth_list = config.get("users", []) # 实际上是使用者的列表
142
  authflag = len(auth_list) > 0 # 是否开启认证的状态值,改为判断auth_list长度
143
 
144
  # 处理自定义的api_host,优先读环境变量的配置,如果存在则自动装配
145
+ api_host = os.environ.get(
146
+ "OPENAI_API_BASE", config.get("openai_api_base", None))
147
  if api_host is not None:
148
  shared.state.set_api_host(api_host)
149
+ os.environ["OPENAI_API_BASE"] = f"{api_host}/v1"
150
+ logging.info(f"OpenAI API Base set to: {os.environ['OPENAI_API_BASE']}")
151
 
152
+ default_chuanhu_assistant_model = config.get(
153
+ "default_chuanhu_assistant_model", "gpt-3.5-turbo")
154
  for x in ["GOOGLE_CSE_ID", "GOOGLE_API_KEY", "WOLFRAM_ALPHA_APPID", "SERPAPI_API_KEY"]:
155
  if config.get(x, None) is not None:
156
  os.environ[x] = config[x]
157
 
158
+
159
  @contextmanager
160
+ def retrieve_openai_api(api_key=None):
161
  old_api_key = os.environ.get("OPENAI_API_KEY", "")
162
  if api_key is None:
163
  os.environ["OPENAI_API_KEY"] = my_api_key
 
167
  yield api_key
168
  os.environ["OPENAI_API_KEY"] = old_api_key
169
 
 
 
 
 
 
 
170
 
171
+
172
+ # 处理代理:
173
+ http_proxy = os.environ.get("HTTP_PROXY", "")
174
+ https_proxy = os.environ.get("HTTPS_PROXY", "")
175
+ http_proxy = config.get("http_proxy", http_proxy)
176
+ https_proxy = config.get("https_proxy", https_proxy)
177
 
178
  # 重置系统变量,在不需要设置的时候不设置环境变量,以免引起全局代理报错
179
  os.environ["HTTP_PROXY"] = ""
180
  os.environ["HTTPS_PROXY"] = ""
181
 
182
+ local_embedding = config.get("local_embedding", False) # 是否使用本地embedding
183
+
184
 
185
  @contextmanager
186
  def retrieve_proxy(proxy=None):
 
197
  old_var = os.environ["HTTP_PROXY"], os.environ["HTTPS_PROXY"]
198
  os.environ["HTTP_PROXY"] = http_proxy
199
  os.environ["HTTPS_PROXY"] = https_proxy
200
+ yield http_proxy, https_proxy # return new proxy
201
 
202
  # return old proxy
203
  os.environ["HTTP_PROXY"], os.environ["HTTPS_PROXY"] = old_var
204
 
205
 
206
+ # 处理latex options
207
+ user_latex_option = config.get("latex_option", "default")
208
+ if user_latex_option == "default":
209
+ latex_delimiters_set = [
210
+ {"left": "$$", "right": "$$", "display": True},
211
+ {"left": "$", "right": "$", "display": False},
212
+ {"left": "\\(", "right": "\\)", "display": False},
213
+ {"left": "\\[", "right": "\\]", "display": True},
214
+ ]
215
+ elif user_latex_option == "strict":
216
+ latex_delimiters_set = [
217
+ {"left": "$$", "right": "$$", "display": True},
218
+ {"left": "\\(", "right": "\\)", "display": False},
219
+ {"left": "\\[", "right": "\\]", "display": True},
220
+ ]
221
+ elif user_latex_option == "all":
222
+ latex_delimiters_set = [
223
+ {"left": "$$", "right": "$$", "display": True},
224
+ {"left": "$", "right": "$", "display": False},
225
+ {"left": "\\(", "right": "\\)", "display": False},
226
+ {"left": "\\[", "right": "\\]", "display": True},
227
+ {"left": "\\begin{equation}", "right": "\\end{equation}", "display": True},
228
+ {"left": "\\begin{align}", "right": "\\end{align}", "display": True},
229
+ {"left": "\\begin{alignat}", "right": "\\end{alignat}", "display": True},
230
+ {"left": "\\begin{gather}", "right": "\\end{gather}", "display": True},
231
+ {"left": "\\begin{CD}", "right": "\\end{CD}", "display": True},
232
+ ]
233
+ elif user_latex_option == "disabled":
234
+ latex_delimiters_set = []
235
+ else:
236
+ latex_delimiters_set = [
237
+ {"left": "$$", "right": "$$", "display": True},
238
+ {"left": "$", "right": "$", "display": False},
239
+ {"left": "\\(", "right": "\\)", "display": False},
240
+ {"left": "\\[", "right": "\\]", "display": True},
241
+ ]
242
+
243
+ # 处理advance docs
244
  advance_docs = defaultdict(lambda: defaultdict(dict))
245
  advance_docs.update(config.get("advance_docs", {}))
246
+
247
+
248
  def update_doc_config(two_column_pdf):
249
  global advance_docs
250
  advance_docs["pdf"]["two_column"] = two_column_pdf
251
 
252
  logging.info(f"更新后的文件参数为:{advance_docs}")
253
 
254
+
255
+ # 处理gradio.launch参数
256
  server_name = config.get("server_name", None)
257
  server_port = config.get("server_port", None)
258
  if server_name is None:
 
274
  pass
275
 
276
  share = config.get("share", False)
277
+
278
+ # avatar
279
+ bot_avatar = config.get("bot_avatar", "default")
280
+ user_avatar = config.get("user_avatar", "default")
modules/index_func.py CHANGED
@@ -1,7 +1,7 @@
1
  import os
2
  import logging
3
 
4
- import colorama
5
  import PyPDF2
6
  from tqdm import tqdm
7
 
@@ -10,19 +10,6 @@ from modules.utils import *
10
  from modules.config import local_embedding
11
 
12
 
13
- def get_index_name(file_src):
14
- file_paths = [x.name for x in file_src]
15
- file_paths.sort(key=lambda x: os.path.basename(x))
16
-
17
- md5_hash = hashlib.md5()
18
- for file_path in file_paths:
19
- with open(file_path, "rb") as f:
20
- while chunk := f.read(8192):
21
- md5_hash.update(chunk)
22
-
23
- return md5_hash.hexdigest()
24
-
25
-
26
  def get_documents(file_src):
27
  from langchain.schema import Document
28
  from langchain.text_splitter import TokenTextSplitter
@@ -47,11 +34,12 @@ def get_documents(file_src):
47
  pdftext = parse_pdf(filepath, two_column).text
48
  except:
49
  pdftext = ""
50
- with open(filepath, "rb", encoding="utf-8") as pdfFileObj:
51
  pdfReader = PyPDF2.PdfReader(pdfFileObj)
52
  for page in tqdm(pdfReader.pages):
53
  pdftext += page.extract_text()
54
- texts = [Document(page_content=pdftext, metadata={"source": filepath})]
 
55
  elif file_type == ".docx":
56
  logging.debug("Loading Word...")
57
  from langchain.document_loaders import UnstructuredWordDocumentLoader
@@ -72,7 +60,8 @@ def get_documents(file_src):
72
  text_list = excel_to_string(filepath)
73
  texts = []
74
  for elem in text_list:
75
- texts.append(Document(page_content=elem, metadata={"source": filepath}))
 
76
  else:
77
  logging.debug("Loading text file...")
78
  from langchain.document_loaders import TextLoader
@@ -111,14 +100,20 @@ def construct_index(
111
  embedding_limit = None if embedding_limit == 0 else embedding_limit
112
  separator = " " if separator == "" else separator
113
 
114
- index_name = get_index_name(file_src)
115
  index_path = f"./index/{index_name}"
116
  if local_embedding:
117
  from langchain.embeddings.huggingface import HuggingFaceEmbeddings
118
- embeddings = HuggingFaceEmbeddings(model_name = "sentence-transformers/distiluse-base-multilingual-cased-v2")
 
119
  else:
120
  from langchain.embeddings import OpenAIEmbeddings
121
- embeddings = OpenAIEmbeddings(openai_api_base=os.environ.get("OPENAI_API_BASE", None), openai_api_key=os.environ.get("OPENAI_EMBEDDING_API_KEY", api_key))
 
 
 
 
 
122
  if os.path.exists(index_path):
123
  logging.info("找到了缓存的索引文件,加载中……")
124
  return FAISS.load_local(index_path, embeddings)
 
1
  import os
2
  import logging
3
 
4
+ import hashlib
5
  import PyPDF2
6
  from tqdm import tqdm
7
 
 
10
  from modules.config import local_embedding
11
 
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  def get_documents(file_src):
14
  from langchain.schema import Document
15
  from langchain.text_splitter import TokenTextSplitter
 
34
  pdftext = parse_pdf(filepath, two_column).text
35
  except:
36
  pdftext = ""
37
+ with open(filepath, "rb") as pdfFileObj:
38
  pdfReader = PyPDF2.PdfReader(pdfFileObj)
39
  for page in tqdm(pdfReader.pages):
40
  pdftext += page.extract_text()
41
+ texts = [Document(page_content=pdftext,
42
+ metadata={"source": filepath})]
43
  elif file_type == ".docx":
44
  logging.debug("Loading Word...")
45
  from langchain.document_loaders import UnstructuredWordDocumentLoader
 
60
  text_list = excel_to_string(filepath)
61
  texts = []
62
  for elem in text_list:
63
+ texts.append(Document(page_content=elem,
64
+ metadata={"source": filepath}))
65
  else:
66
  logging.debug("Loading text file...")
67
  from langchain.document_loaders import TextLoader
 
100
  embedding_limit = None if embedding_limit == 0 else embedding_limit
101
  separator = " " if separator == "" else separator
102
 
103
+ index_name = get_file_hash(file_src)
104
  index_path = f"./index/{index_name}"
105
  if local_embedding:
106
  from langchain.embeddings.huggingface import HuggingFaceEmbeddings
107
+ embeddings = HuggingFaceEmbeddings(
108
+ model_name="sentence-transformers/distiluse-base-multilingual-cased-v2")
109
  else:
110
  from langchain.embeddings import OpenAIEmbeddings
111
+ if os.environ.get("OPENAI_API_TYPE", "openai") == "openai":
112
+ embeddings = OpenAIEmbeddings(openai_api_base=os.environ.get(
113
+ "OPENAI_API_BASE", None), openai_api_key=os.environ.get("OPENAI_EMBEDDING_API_KEY", api_key))
114
+ else:
115
+ embeddings = OpenAIEmbeddings(deployment=os.environ["AZURE_EMBEDDING_DEPLOYMENT_NAME"], openai_api_key=os.environ["AZURE_OPENAI_API_KEY"],
116
+ model=os.environ["AZURE_EMBEDDING_MODEL_NAME"], openai_api_base=os.environ["AZURE_OPENAI_API_BASE_URL"], openai_api_type="azure")
117
  if os.path.exists(index_path):
118
  logging.info("找到了缓存的索引文件,加载中……")
119
  return FAISS.load_local(index_path, embeddings)
modules/models/Google_PaLM.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .base_model import BaseLLMModel
2
+ import google.generativeai as palm
3
+
4
+ class Google_PaLM_Client(BaseLLMModel):
5
+ def __init__(self, model_name, api_key, user_name="") -> None:
6
+ super().__init__(model_name=model_name, user=user_name)
7
+ self.api_key = api_key
8
+
9
+ def _get_palm_style_input(self):
10
+ new_history = []
11
+ for item in self.history:
12
+ if item["role"] == "user":
13
+ new_history.append({'author': '1', 'content': item["content"]})
14
+ else:
15
+ new_history.append({'author': '0', 'content': item["content"]})
16
+ return new_history
17
+
18
+ def get_answer_at_once(self):
19
+ palm.configure(api_key=self.api_key)
20
+ messages = self._get_palm_style_input()
21
+ response = palm.chat(context=self.system_prompt, messages=messages, temperature=self.temperature, top_p=self.top_p)
22
+ if response.last is not None:
23
+ return response.last, len(response.last)
24
+ else:
25
+ reasons = '\n\n'.join(reason['reason'].name for reason in response.filters)
26
+ return "由于下面的原因,Google 拒绝返回 PaLM 的回答:\n\n" + reasons, 0
modules/models/__pycache__/ChuanhuAgent.cpython-311.pyc CHANGED
Binary files a/modules/models/__pycache__/ChuanhuAgent.cpython-311.pyc and b/modules/models/__pycache__/ChuanhuAgent.cpython-311.pyc differ
 
modules/models/__pycache__/Google_PaLM.cpython-311.pyc ADDED
Binary file (2.64 kB). View file
 
modules/models/__pycache__/azure.cpython-311.pyc ADDED
Binary file (1.18 kB). View file
 
modules/models/__pycache__/base_model.cpython-311.pyc CHANGED
Binary files a/modules/models/__pycache__/base_model.cpython-311.pyc and b/modules/models/__pycache__/base_model.cpython-311.pyc differ
 
modules/models/__pycache__/base_model.cpython-39.pyc CHANGED
Binary files a/modules/models/__pycache__/base_model.cpython-39.pyc and b/modules/models/__pycache__/base_model.cpython-39.pyc differ
 
modules/models/__pycache__/models.cpython-311.pyc CHANGED
Binary files a/modules/models/__pycache__/models.cpython-311.pyc and b/modules/models/__pycache__/models.cpython-311.pyc differ
 
modules/models/__pycache__/models.cpython-39.pyc CHANGED
Binary files a/modules/models/__pycache__/models.cpython-39.pyc and b/modules/models/__pycache__/models.cpython-39.pyc differ
 
modules/models/azure.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.chat_models import AzureChatOpenAI
2
+ import os
3
+
4
+ from .base_model import Base_Chat_Langchain_Client
5
+
6
+ # load_config_to_environ(["azure_openai_api_key", "azure_api_base_url", "azure_openai_api_version", "azure_deployment_name"])
7
+
8
+ class Azure_OpenAI_Client(Base_Chat_Langchain_Client):
9
+ def setup_model(self):
10
+ # inplement this to setup the model then return it
11
+ return AzureChatOpenAI(
12
+ openai_api_base=os.environ["AZURE_OPENAI_API_BASE_URL"],
13
+ openai_api_version=os.environ["AZURE_OPENAI_API_VERSION"],
14
+ deployment_name=os.environ["AZURE_DEPLOYMENT_NAME"],
15
+ openai_api_key=os.environ["AZURE_OPENAI_API_KEY"],
16
+ openai_api_type="azure",
17
+ )
modules/models/base_model.py CHANGED
@@ -29,6 +29,8 @@ from langchain.input import print_text
29
  from langchain.schema import AgentAction, AgentFinish, LLMResult
30
  from threading import Thread, Condition
31
  from collections import deque
 
 
32
 
33
  from ..presets import *
34
  from ..index_func import *
@@ -36,6 +38,7 @@ from ..utils import *
36
  from .. import shared
37
  from ..config import retrieve_proxy
38
 
 
39
  class CallbackToIterator:
40
  def __init__(self):
41
  self.queue = deque()
@@ -52,7 +55,8 @@ class CallbackToIterator:
52
 
53
  def __next__(self):
54
  with self.cond:
55
- while not self.queue and not self.finished: # Wait for a value to be added to the queue.
 
56
  self.cond.wait()
57
  if not self.queue:
58
  raise StopIteration()
@@ -63,6 +67,7 @@ class CallbackToIterator:
63
  self.finished = True
64
  self.cond.notify() # Wake up the generator if it's waiting.
65
 
 
66
  def get_action_description(text):
67
  match = re.search('```(.*?)```', text, re.S)
68
  json_text = match.group(1)
@@ -72,10 +77,11 @@ def get_action_description(text):
72
  action_name = json_dict['action']
73
  action_input = json_dict['action_input']
74
  if action_name != "Final Answer":
75
- return f'<p style="font-size: smaller; color: gray;">{action_name}: {action_input}</p>'
76
  else:
77
  return ""
78
 
 
79
  class ChuanhuCallbackHandler(BaseCallbackHandler):
80
 
81
  def __init__(self, callback) -> None:
@@ -117,6 +123,10 @@ class ChuanhuCallbackHandler(BaseCallbackHandler):
117
  """Run on new LLM token. Only available when streaming is enabled."""
118
  self.callback(token)
119
 
 
 
 
 
120
 
121
  class ModelType(Enum):
122
  Unknown = -1
@@ -129,6 +139,9 @@ class ModelType(Enum):
129
  YuanAI = 6
130
  Minimax = 7
131
  ChuanhuAgent = 8
 
 
 
132
 
133
  @classmethod
134
  def get_type(cls, model_name: str):
@@ -152,6 +165,12 @@ class ModelType(Enum):
152
  model_type = ModelType.Minimax
153
  elif "川虎助理" in model_name_lower:
154
  model_type = ModelType.ChuanhuAgent
 
 
 
 
 
 
155
  else:
156
  model_type = ModelType.Unknown
157
  return model_type
@@ -161,7 +180,7 @@ class BaseLLMModel:
161
  def __init__(
162
  self,
163
  model_name,
164
- system_prompt="",
165
  temperature=1.0,
166
  top_p=1.0,
167
  n_choices=1,
@@ -201,7 +220,8 @@ class BaseLLMModel:
201
  conversations are stored in self.history, with the most recent question, in OpenAI format
202
  should return a generator, each time give the next word (str) in the answer
203
  """
204
- logging.warning("stream predict not implemented, using at once predict instead")
 
205
  response, _ = self.get_answer_at_once()
206
  yield response
207
 
@@ -212,7 +232,8 @@ class BaseLLMModel:
212
  the answer (str)
213
  total token count (int)
214
  """
215
- logging.warning("at once predict not implemented, using stream predict instead")
 
216
  response_iter = self.get_answer_stream_iter()
217
  count = 0
218
  for response in response_iter:
@@ -246,7 +267,8 @@ class BaseLLMModel:
246
  stream_iter = self.get_answer_stream_iter()
247
 
248
  if display_append:
249
- display_append = "<hr>" +display_append
 
250
  for partial_text in stream_iter:
251
  chatbot[-1] = (chatbot[-1][0], partial_text + display_append)
252
  self.all_token_counts[-1] += 1
@@ -273,9 +295,11 @@ class BaseLLMModel:
273
  self.history[-2] = construct_user(fake_input)
274
  chatbot[-1] = (chatbot[-1][0], ai_reply + display_append)
275
  if fake_input is not None:
276
- self.all_token_counts[-1] += count_token(construct_assistant(ai_reply))
 
277
  else:
278
- self.all_token_counts[-1] = total_token_count - sum(self.all_token_counts)
 
279
  status_text = self.token_message()
280
  return chatbot, status_text
281
 
@@ -299,10 +323,13 @@ class BaseLLMModel:
299
  from langchain.chat_models import ChatOpenAI
300
  from langchain.callbacks import StdOutCallbackHandler
301
  prompt_template = "Write a concise summary of the following:\n\n{text}\n\nCONCISE SUMMARY IN " + language + ":"
302
- PROMPT = PromptTemplate(template=prompt_template, input_variables=["text"])
 
303
  llm = ChatOpenAI()
304
- chain = load_summarize_chain(llm, chain_type="map_reduce", return_intermediate_steps=True, map_prompt=PROMPT, combine_prompt=PROMPT)
305
- summary = chain({"input_documents": list(index.docstore.__dict__["_dict"].values())}, return_only_outputs=True)["output_text"]
 
 
306
  print(i18n("总结") + f": {summary}")
307
  chatbot.append([i18n("上传了")+str(len(files))+"个文件", summary])
308
  return chatbot, status
@@ -323,9 +350,12 @@ class BaseLLMModel:
323
  msg = "索引获取成功,生成回答中……"
324
  logging.info(msg)
325
  with retrieve_proxy():
326
- retriever = VectorStoreRetriever(vectorstore=index, search_type="similarity_score_threshold",search_kwargs={"k":6, "score_threshold": 0.5})
327
- relevant_documents = retriever.get_relevant_documents(real_inputs)
328
- reference_results = [[d.page_content.strip("�"), os.path.basename(d.metadata["source"])] for d in relevant_documents]
 
 
 
329
  reference_results = add_source_numbers(reference_results)
330
  display_append = add_details(reference_results)
331
  display_append = "\n\n" + "".join(display_append)
@@ -348,10 +378,12 @@ class BaseLLMModel:
348
  reference_results.append([result['body'], result['href']])
349
  display_append.append(
350
  # f"{idx+1}. [{domain_name}]({result['href']})\n"
351
- f"<li><a href=\"{result['href']}\" target=\"_blank\">{result['title']}</a></li>\n"
352
  )
353
  reference_results = add_source_numbers(reference_results)
354
- display_append = "<ol>\n\n" + "".join(display_append) + "</ol>"
 
 
355
  real_inputs = (
356
  replace_today(WEBSEARCH_PTOMPT_TEMPLATE)
357
  .replace("{query}", real_inputs)
@@ -375,14 +407,16 @@ class BaseLLMModel:
375
 
376
  status_text = "开始生成回答……"
377
  logging.info(
378
- "用户" + f"{self.user_identifier}" + "的输入为:" + colorama.Fore.BLUE + f"{inputs}" + colorama.Style.RESET_ALL
 
379
  )
380
  if should_check_token_count:
381
  yield chatbot + [(inputs, "")], status_text
382
  if reply_language == "跟随问题语言(不稳定)":
383
  reply_language = "the same language as the question, such as English, 中文, 日本語, Español, Français, or Deutsch."
384
 
385
- limited_context, fake_inputs, display_append, inputs, chatbot = self.prepare_inputs(real_inputs=inputs, use_websearch=use_websearch, files=files, reply_language=reply_language, chatbot=chatbot)
 
386
  yield chatbot + [(fake_inputs, "")], status_text
387
 
388
  if (
@@ -434,7 +468,7 @@ class BaseLLMModel:
434
  yield chatbot, status_text
435
  except Exception as e:
436
  traceback.print_exc()
437
- status_text = STANDARD_ERROR_MSG + str(e)
438
  yield chatbot, status_text
439
 
440
  if len(self.history) > 1 and self.history[-1]["content"] != inputs:
@@ -568,10 +602,13 @@ class BaseLLMModel:
568
  self.system_prompt = new_system_prompt
569
 
570
  def set_key(self, new_access_key):
571
- self.api_key = new_access_key.strip()
572
- msg = i18n("API密钥更改为了") + hide_middle_chars(self.api_key)
573
- logging.info(msg)
574
- return self.api_key, msg
 
 
 
575
 
576
  def set_single_turn(self, new_single_turn):
577
  self.single_turn = new_single_turn
@@ -580,7 +617,8 @@ class BaseLLMModel:
580
  self.history = []
581
  self.all_token_counts = []
582
  self.interrupted = False
583
- pathlib.Path(os.path.join(HISTORY_DIR, self.user_identifier, new_auto_history_filename(os.path.join(HISTORY_DIR, self.user_identifier)))).touch()
 
584
  return [], self.token_message([0])
585
 
586
  def delete_first_conversation(self):
@@ -623,7 +661,8 @@ class BaseLLMModel:
623
 
624
  def auto_save(self, chatbot):
625
  history_file_path = get_history_filepath(self.user_identifier)
626
- save_file(history_file_path, self.system_prompt, self.history, chatbot, self.user_identifier)
 
627
 
628
  def export_markdown(self, filename, chatbot, user_name):
629
  if filename == "":
@@ -639,7 +678,8 @@ class BaseLLMModel:
639
  filename = filename.name
640
  try:
641
  if "/" not in filename:
642
- history_file_path = os.path.join(HISTORY_DIR, user_name, filename)
 
643
  else:
644
  history_file_path = filename
645
  with open(history_file_path, "r", encoding="utf-8") as f:
@@ -665,15 +705,33 @@ class BaseLLMModel:
665
  logging.info(f"没有找到对话历史记录 {filename}")
666
  return gr.update(), self.system_prompt, gr.update()
667
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
668
  def auto_load(self):
669
  if self.user_identifier == "":
670
  self.reset()
671
  return self.system_prompt, gr.update()
672
  history_file_path = get_history_filepath(self.user_identifier)
673
- filename, system_prompt, chatbot = self.load_chat_history(history_file_path, self.user_identifier)
 
674
  return system_prompt, chatbot
675
 
676
-
677
  def like(self):
678
  """like the last response, implement if needed
679
  """
@@ -683,3 +741,47 @@ class BaseLLMModel:
683
  """dislike the last response, implement if needed
684
  """
685
  return gr.update()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  from langchain.schema import AgentAction, AgentFinish, LLMResult
30
  from threading import Thread, Condition
31
  from collections import deque
32
+ from langchain.chat_models.base import BaseChatModel
33
+ from langchain.schema import HumanMessage, AIMessage, SystemMessage, BaseMessage
34
 
35
  from ..presets import *
36
  from ..index_func import *
 
38
  from .. import shared
39
  from ..config import retrieve_proxy
40
 
41
+
42
  class CallbackToIterator:
43
  def __init__(self):
44
  self.queue = deque()
 
55
 
56
  def __next__(self):
57
  with self.cond:
58
+ # Wait for a value to be added to the queue.
59
+ while not self.queue and not self.finished:
60
  self.cond.wait()
61
  if not self.queue:
62
  raise StopIteration()
 
67
  self.finished = True
68
  self.cond.notify() # Wake up the generator if it's waiting.
69
 
70
+
71
  def get_action_description(text):
72
  match = re.search('```(.*?)```', text, re.S)
73
  json_text = match.group(1)
 
77
  action_name = json_dict['action']
78
  action_input = json_dict['action_input']
79
  if action_name != "Final Answer":
80
+ return f'<!-- S O PREFIX --><p class="agent-prefix">{action_name}: {action_input}\n\n</p><!-- E O PREFIX -->'
81
  else:
82
  return ""
83
 
84
+
85
  class ChuanhuCallbackHandler(BaseCallbackHandler):
86
 
87
  def __init__(self, callback) -> None:
 
123
  """Run on new LLM token. Only available when streaming is enabled."""
124
  self.callback(token)
125
 
126
+ def on_chat_model_start(self, serialized: Dict[str, Any], messages: List[List[BaseMessage]], **kwargs: Any) -> Any:
127
+ """Run when a chat model starts running."""
128
+ pass
129
+
130
 
131
  class ModelType(Enum):
132
  Unknown = -1
 
139
  YuanAI = 6
140
  Minimax = 7
141
  ChuanhuAgent = 8
142
+ GooglePaLM = 9
143
+ LangchainChat = 10
144
+ Midjourney = 11
145
 
146
  @classmethod
147
  def get_type(cls, model_name: str):
 
165
  model_type = ModelType.Minimax
166
  elif "川虎助理" in model_name_lower:
167
  model_type = ModelType.ChuanhuAgent
168
+ elif "palm" in model_name_lower:
169
+ model_type = ModelType.GooglePaLM
170
+ elif "midjourney" in model_name_lower:
171
+ model_type = ModelType.Midjourney
172
+ elif "azure" in model_name_lower or "api" in model_name_lower:
173
+ model_type = ModelType.LangchainChat
174
  else:
175
  model_type = ModelType.Unknown
176
  return model_type
 
180
  def __init__(
181
  self,
182
  model_name,
183
+ system_prompt=INITIAL_SYSTEM_PROMPT,
184
  temperature=1.0,
185
  top_p=1.0,
186
  n_choices=1,
 
220
  conversations are stored in self.history, with the most recent question, in OpenAI format
221
  should return a generator, each time give the next word (str) in the answer
222
  """
223
+ logging.warning(
224
+ "stream predict not implemented, using at once predict instead")
225
  response, _ = self.get_answer_at_once()
226
  yield response
227
 
 
232
  the answer (str)
233
  total token count (int)
234
  """
235
+ logging.warning(
236
+ "at once predict not implemented, using stream predict instead")
237
  response_iter = self.get_answer_stream_iter()
238
  count = 0
239