MoDongbao commited on
Commit
e638625
1 Parent(s): 39b5b0f

Upload 79 files

Browse files
Files changed (50) hide show
  1. .gitattributes +0 -2
  2. .gitignore +5 -1
  3. Dockerfile +9 -2
  4. check_proxy.py +25 -10
  5. colorful.py +91 -0
  6. config.py +23 -11
  7. core_functional.py +1 -1
  8. crazy_functional.py +121 -30
  9. crazy_functions/Latex全文润色.py +175 -0
  10. crazy_functions/Latex全文翻译.py +175 -0
  11. crazy_functions/crazy_functions_test.py +130 -0
  12. crazy_functions/crazy_utils.py +452 -45
  13. crazy_functions/下载arxiv论文翻译摘要.py +19 -11
  14. crazy_functions/代码重写为全英文_多线程.py +18 -19
  15. crazy_functions/对话历史存档.py +42 -0
  16. crazy_functions/总结word文档.py +60 -60
  17. crazy_functions/批量Markdown翻译.py +161 -0
  18. crazy_functions/批量总结PDF文档.py +32 -20
  19. crazy_functions/批量总结PDF文档pdfminer.py +32 -23
  20. crazy_functions/批量翻译PDF文档_多线程.py +40 -112
  21. crazy_functions/理解PDF文档内容.py +67 -140
  22. crazy_functions/生成函数注释.py +15 -18
  23. crazy_functions/联网的ChatGPT.py +102 -0
  24. crazy_functions/解析JupyterNotebook.py +140 -0
  25. crazy_functions/解析项目源代码.py +192 -99
  26. crazy_functions/询问多个大语言模型.py +59 -0
  27. crazy_functions/读文章写摘要.py +16 -19
  28. crazy_functions/谷歌检索小助手.py +8 -8
  29. crazy_functions/高级功能函数模板.py +15 -6
  30. docs/Dockerfile+ChatGLM +59 -0
  31. docs/README_EN.md +291 -0
  32. docs/README_FR.md +296 -0
  33. docs/README_JP.md +302 -0
  34. docs/README_RS.md +291 -0
  35. docs/WithFastapi.md +43 -0
  36. docs/demo.jpg +0 -0
  37. docs/demo2.jpg +0 -0
  38. docs/logo.png +0 -0
  39. docs/self_analysis.md +256 -0
  40. main.py +206 -173
  41. request_llm/README.md +33 -15
  42. request_llm/bridge_all.py +230 -0
  43. request_llm/bridge_chatglm.py +143 -0
  44. request_llm/bridge_chatgpt.py +88 -85
  45. request_llm/bridge_tgui.py +36 -32
  46. request_llm/requirements_chatglm.txt +6 -0
  47. requirements.txt +6 -3
  48. theme.py +3 -1
  49. toolbox.py +196 -135
  50. version +2 -2
.gitattributes CHANGED
@@ -3,5 +3,3 @@
3
  *.tex linguist-detectable=false
4
  *.cs linguist-detectable=false
5
  *.tps linguist-detectable=false
6
- img/公式.gif filter=lfs diff=lfs merge=lfs -text
7
- img/润色.gif filter=lfs diff=lfs merge=lfs -text
 
3
  *.tex linguist-detectable=false
4
  *.cs linguist-detectable=false
5
  *.tps linguist-detectable=false
 
 
.gitignore CHANGED
@@ -132,6 +132,7 @@ dmypy.json
132
  .pyre/
133
 
134
  .vscode
 
135
 
136
  history
137
  ssr_conf
@@ -141,4 +142,7 @@ private.md
141
  private_upload
142
  other_llms
143
  cradle*
144
- debug*
 
 
 
 
132
  .pyre/
133
 
134
  .vscode
135
+ .idea
136
 
137
  history
138
  ssr_conf
 
142
  private_upload
143
  other_llms
144
  cradle*
145
+ debug*
146
+ private*
147
+ crazy_functions/test_project/pdf_and_word
148
+ crazy_functions/test_samples
Dockerfile CHANGED
@@ -1,3 +1,6 @@
 
 
 
1
  FROM python:3.11
2
 
3
  RUN echo '[global]' > /etc/pip.conf && \
@@ -5,9 +8,13 @@ RUN echo '[global]' > /etc/pip.conf && \
5
  echo 'trusted-host = mirrors.aliyun.com' >> /etc/pip.conf
6
 
7
 
8
- COPY . /gpt
9
  WORKDIR /gpt
 
10
  RUN pip3 install -r requirements.txt
11
 
 
12
 
13
- CMD ["python3", "main.py"]
 
 
 
 
1
+ # 此Dockerfile适用于“无本地模型”的环境构建,如果需要使用chatglm等本地模型,请参考 docs/Dockerfile+ChatGLM
2
+ # 如何构建: 先修改 `config.py`, 然后 docker build -t gpt-academic .
3
+ # 如何运行: docker run --rm -it --net=host gpt-academic
4
  FROM python:3.11
5
 
6
  RUN echo '[global]' > /etc/pip.conf && \
 
8
  echo 'trusted-host = mirrors.aliyun.com' >> /etc/pip.conf
9
 
10
 
 
11
  WORKDIR /gpt
12
+ COPY requirements.txt .
13
  RUN pip3 install -r requirements.txt
14
 
15
+ COPY . .
16
 
17
+ # 可选步骤,用于预热模块
18
+ RUN python3 -c 'from check_proxy import warm_up_modules; warm_up_modules()'
19
+
20
+ CMD ["python3", "-u", "main.py"]
check_proxy.py CHANGED
@@ -61,18 +61,25 @@ def patch_and_restart(path):
61
  import os
62
  import sys
63
  import time
 
64
  # if not using config_private, move origin config.py as config_private.py
65
  if not os.path.exists('config_private.py'):
66
- print('由于您没有设置config_private.py私密配置,现将您的现有配置移动至config_private.py以防止配置丢失,',
67
  '另外您可以随时在history子文件夹下找回旧版的程序。')
68
  shutil.copyfile('config.py', 'config_private.py')
69
  distutils.dir_util.copy_tree(path+'/chatgpt_academic-master', './')
70
- print('更新完成,您可以随时在history子文件夹下找回旧版的程序,5s之后重启')
71
- for i in reversed(range(5)):
72
- time.sleep(1)
73
- print(i)
 
 
 
 
 
74
  print(' ------------------------------ -----------------------------------')
75
- os.execl(sys.executable, 'python', 'main.py')
 
76
 
77
 
78
  def get_current_version():
@@ -96,7 +103,7 @@ def auto_update():
96
  import json
97
  proxies, = get_conf('proxies')
98
  response = requests.get(
99
- "https://raw.githubusercontent.com/binary-husky/chatgpt_academic/master/version", proxies=proxies, timeout=1)
100
  remote_json_data = json.loads(response.text)
101
  remote_version = remote_json_data['version']
102
  if remote_json_data["show_feature"]:
@@ -106,11 +113,12 @@ def auto_update():
106
  with open('./version', 'r', encoding='utf8') as f:
107
  current_version = f.read()
108
  current_version = json.loads(current_version)['version']
109
- if (remote_version - current_version) >= 0.05:
110
- print(
 
111
  f'\n新版本可用。新版本:{remote_version},当前版本:{current_version}。{new_feature}')
112
  print('(1)Github更新地址:\nhttps://github.com/binary-husky/chatgpt_academic\n')
113
- user_instruction = input('(2)是否一键更新代码(Y/y+回车=确认,输入其他/无输入+回车=不更新)?')
114
  if user_instruction in ['Y', 'y']:
115
  path = backup_and_download(current_version, remote_version)
116
  try:
@@ -125,6 +133,13 @@ def auto_update():
125
  except:
126
  print('自动更新程序:已禁用')
127
 
 
 
 
 
 
 
 
128
 
129
  if __name__ == '__main__':
130
  import os
 
61
  import os
62
  import sys
63
  import time
64
+ from colorful import print亮黄, print亮绿, print亮红
65
  # if not using config_private, move origin config.py as config_private.py
66
  if not os.path.exists('config_private.py'):
67
+ print亮黄('由于您没有设置config_private.py私密配置,现将您的现有配置移动至config_private.py以防止配置丢失,',
68
  '另外您可以随时在history子文件夹下找回旧版的程序。')
69
  shutil.copyfile('config.py', 'config_private.py')
70
  distutils.dir_util.copy_tree(path+'/chatgpt_academic-master', './')
71
+ import subprocess
72
+ print亮绿('代码已经更新,即将更新pip包依赖……')
73
+ for i in reversed(range(5)): time.sleep(1); print(i)
74
+ try:
75
+ subprocess.check_call([sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt'])
76
+ except:
77
+ print亮红('pip包依赖安装出现问题,需要手动安装新增的依赖库 `python -m pip install -r requirements.txt`,然后在用常规的`python main.py`的方式启动。')
78
+ print亮绿('更新完成,您可以随时在history子文件夹下找回旧版的程序,5s之后重启')
79
+ print亮红('假如重启失败,您可能需要手动安装新增的依赖库 `python -m pip install -r requirements.txt`,然后在用常规的`python main.py`的方式启动。')
80
  print(' ------------------------------ -----------------------------------')
81
+ for i in reversed(range(8)): time.sleep(1); print(i)
82
+ os.execl(sys.executable, sys.executable, *sys.argv)
83
 
84
 
85
  def get_current_version():
 
103
  import json
104
  proxies, = get_conf('proxies')
105
  response = requests.get(
106
+ "https://raw.githubusercontent.com/binary-husky/chatgpt_academic/master/version", proxies=proxies, timeout=5)
107
  remote_json_data = json.loads(response.text)
108
  remote_version = remote_json_data['version']
109
  if remote_json_data["show_feature"]:
 
113
  with open('./version', 'r', encoding='utf8') as f:
114
  current_version = f.read()
115
  current_version = json.loads(current_version)['version']
116
+ if (remote_version - current_version) >= 0.01:
117
+ from colorful import print亮黄
118
+ print亮黄(
119
  f'\n新版本可用。新版本:{remote_version},当前版本:{current_version}。{new_feature}')
120
  print('(1)Github更新地址:\nhttps://github.com/binary-husky/chatgpt_academic\n')
121
+ user_instruction = input('(2)是否一键更新代码(Y+回车=确认,输入其他/无输入+回车=不更新)?')
122
  if user_instruction in ['Y', 'y']:
123
  path = backup_and_download(current_version, remote_version)
124
  try:
 
133
  except:
134
  print('自动更新程序:已禁用')
135
 
136
+ def warm_up_modules():
137
+ print('正在执行一些模块的预热...')
138
+ from request_llm.bridge_all import model_info
139
+ enc = model_info["gpt-3.5-turbo"]['tokenizer']
140
+ enc.encode("模块预热", disallowed_special=())
141
+ enc = model_info["gpt-4"]['tokenizer']
142
+ enc.encode("模块预热", disallowed_special=())
143
 
144
  if __name__ == '__main__':
145
  import os
colorful.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import platform
2
+ from sys import stdout
3
+
4
+ if platform.system()=="Linux":
5
+ pass
6
+ else:
7
+ from colorama import init
8
+ init()
9
+
10
+ # Do you like the elegance of Chinese characters?
11
+ def print红(*kw,**kargs):
12
+ print("\033[0;31m",*kw,"\033[0m",**kargs)
13
+ def print绿(*kw,**kargs):
14
+ print("\033[0;32m",*kw,"\033[0m",**kargs)
15
+ def print黄(*kw,**kargs):
16
+ print("\033[0;33m",*kw,"\033[0m",**kargs)
17
+ def print蓝(*kw,**kargs):
18
+ print("\033[0;34m",*kw,"\033[0m",**kargs)
19
+ def print紫(*kw,**kargs):
20
+ print("\033[0;35m",*kw,"\033[0m",**kargs)
21
+ def print靛(*kw,**kargs):
22
+ print("\033[0;36m",*kw,"\033[0m",**kargs)
23
+
24
+ def print亮红(*kw,**kargs):
25
+ print("\033[1;31m",*kw,"\033[0m",**kargs)
26
+ def print亮绿(*kw,**kargs):
27
+ print("\033[1;32m",*kw,"\033[0m",**kargs)
28
+ def print亮黄(*kw,**kargs):
29
+ print("\033[1;33m",*kw,"\033[0m",**kargs)
30
+ def print亮蓝(*kw,**kargs):
31
+ print("\033[1;34m",*kw,"\033[0m",**kargs)
32
+ def print亮紫(*kw,**kargs):
33
+ print("\033[1;35m",*kw,"\033[0m",**kargs)
34
+ def print亮靛(*kw,**kargs):
35
+ print("\033[1;36m",*kw,"\033[0m",**kargs)
36
+
37
+
38
+
39
+ def print亮红(*kw,**kargs):
40
+ print("\033[1;31m",*kw,"\033[0m",**kargs)
41
+ def print亮绿(*kw,**kargs):
42
+ print("\033[1;32m",*kw,"\033[0m",**kargs)
43
+ def print亮黄(*kw,**kargs):
44
+ print("\033[1;33m",*kw,"\033[0m",**kargs)
45
+ def print亮蓝(*kw,**kargs):
46
+ print("\033[1;34m",*kw,"\033[0m",**kargs)
47
+ def print亮紫(*kw,**kargs):
48
+ print("\033[1;35m",*kw,"\033[0m",**kargs)
49
+ def print亮靛(*kw,**kargs):
50
+ print("\033[1;36m",*kw,"\033[0m",**kargs)
51
+
52
+ print_red = print红
53
+ print_green = print绿
54
+ print_yellow = print黄
55
+ print_blue = print蓝
56
+ print_purple = print紫
57
+ print_indigo = print靛
58
+
59
+ print_bold_red = print亮红
60
+ print_bold_green = print亮绿
61
+ print_bold_yellow = print亮黄
62
+ print_bold_blue = print亮蓝
63
+ print_bold_purple = print亮紫
64
+ print_bold_indigo = print亮靛
65
+
66
+ if not stdout.isatty():
67
+ # redirection, avoid a fucked up log file
68
+ print红 = print
69
+ print绿 = print
70
+ print黄 = print
71
+ print蓝 = print
72
+ print紫 = print
73
+ print靛 = print
74
+ print亮红 = print
75
+ print亮绿 = print
76
+ print亮黄 = print
77
+ print亮蓝 = print
78
+ print亮紫 = print
79
+ print亮靛 = print
80
+ print_red = print
81
+ print_green = print
82
+ print_yellow = print
83
+ print_blue = print
84
+ print_purple = print
85
+ print_indigo = print
86
+ print_bold_red = print
87
+ print_bold_green = print
88
+ print_bold_yellow = print
89
+ print_bold_blue = print
90
+ print_bold_purple = print
91
+ print_bold_indigo = print
config.py CHANGED
@@ -1,7 +1,7 @@
1
  import os
2
 
3
  # [step 1]>> 例如: API_KEY = "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" (此key无效)
4
- API_KEY = os.environ.get("GPT_KEY")
5
 
6
  # [step 2]>> 改为True应用代理,如果直接在海外服务器部署,此处不修改
7
  USE_PROXY = False
@@ -21,19 +21,23 @@ if USE_PROXY:
21
  else:
22
  proxies = None
23
 
 
 
 
24
 
25
- # [step 3]>> 以下配置可以优化体验,但大部分场合下并不需要修改
 
26
  # 对话窗的高度
27
- CHATBOT_HEIGHT = 600
28
 
29
  # 代码高亮
30
  CODE_HIGHLIGHT = True
31
 
32
  # 窗口布局
33
- LAYOUT = "TOP-DOWN" # "LEFT-RIGHT"(左右布局) # "TOP-DOWN"(上下布局)
34
 
35
  # 发送请求到OpenAI后,等待多久判定为超时
36
- TIMEOUT_SECONDS = 25
37
 
38
  # 网页的端口, -1代表随机端口
39
  WEB_PORT = -1
@@ -41,15 +45,23 @@ WEB_PORT = -1
41
  # 如果OpenAI不响应(网络卡顿、代理失败、KEY失效),重试的次数限制
42
  MAX_RETRY = 2
43
 
44
- # OpenAI模型选择是(gpt4现在只对申请成功的人开放)
45
- LLM_MODEL = "gpt-3.5-turbo"
 
46
 
47
- # OpenAI的API_URL
48
- API_URL = "https://api.openai.com/v1/chat/completions"
49
 
50
- # 设置并行使用的线程数
51
  CONCURRENT_COUNT = 100
52
 
53
- # 设置用户名和密码(相关功能不稳定,与gradio版本和网络都相关,如果本地使用不建议加这个)
54
  # [("username", "password"), ("username2", "password2"), ...]
55
  AUTHENTICATION = []
 
 
 
 
 
 
 
 
1
  import os
2
 
3
  # [step 1]>> 例如: API_KEY = "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" (此key无效)
4
+ API_KEY = os.environ.get("GPT_KEY") # 可同时填写多个API-KEY,用英文逗号分割,例如API_KEY = "sk-openaikey1,sk-openaikey2,fkxxxx-api2dkey1,fkxxxx-api2dkey2"
5
 
6
  # [step 2]>> 改为True应用代理,如果直接在海外服务器部署,此处不修改
7
  USE_PROXY = False
 
21
  else:
22
  proxies = None
23
 
24
+ # [step 3]>> 多线程函数插件中,默认允许多少路线程同时访问OpenAI。Free trial users的限制是每分钟3次,Pay-as-you-go users的限制是每分钟3500次
25
+ # 一言以蔽之:免费用户填3,OpenAI绑了信用卡的用户可以填 16 或者更高。提高限制请查询:https://platform.openai.com/docs/guides/rate-limits/overview
26
+ DEFAULT_WORKER_NUM = 3
27
 
28
+
29
+ # [step 4]>> 以下配置可以优化体验,但大部分场合下并不需要修改
30
  # 对话窗的高度
31
+ CHATBOT_HEIGHT = 1115
32
 
33
  # 代码高亮
34
  CODE_HIGHLIGHT = True
35
 
36
  # 窗口布局
37
+ LAYOUT = "LEFT-RIGHT" # "LEFT-RIGHT"(左右布局) # "TOP-DOWN"(上下布局)
38
 
39
  # 发送请求到OpenAI后,等待多久判定为超时
40
+ TIMEOUT_SECONDS = 30
41
 
42
  # 网页的端口, -1代表随机端口
43
  WEB_PORT = -1
 
45
  # 如果OpenAI不响应(网络卡顿、代理失败、KEY失效),重试的次数限制
46
  MAX_RETRY = 2
47
 
48
+ # OpenAI模型选择是(gpt4现在只对申请成功的人开放,体验gpt-4可以试试api2d)
49
+ LLM_MODEL = "gpt-3.5-turbo" # 可选 ↓↓↓
50
+ AVAIL_LLM_MODELS = ["gpt-3.5-turbo", "api2d-gpt-3.5-turbo", "gpt-4", "api2d-gpt-4", "chatglm"]
51
 
52
+ # 本地LLM模型如ChatGLM的执行方式 CPU/GPU
53
+ LOCAL_MODEL_DEVICE = "cpu" # 可选 "cuda"
54
 
55
+ # 设置gradio的并行线程数(不需要修改)
56
  CONCURRENT_COUNT = 100
57
 
58
+ # 设置用户名和密码(不需要修改)(相关功能不稳定,与gradio版本和网络都相关,如果本地使用不建议加这个)
59
  # [("username", "password"), ("username2", "password2"), ...]
60
  AUTHENTICATION = []
61
+
62
+ # 重新URL重新定向,实现更换API_URL的作用(常规情况下,不要修改!!)
63
+ # 格式 {"https://api.openai.com/v1/chat/completions": "重定向的URL"}
64
+ API_URL_REDIRECT = {}
65
+
66
+ # 如果需要在二级路径下运行(常规情况下,不要修改!!)(需要配合修改main.py才能生效!)
67
+ CUSTOM_PATH = "/"
core_functional.py CHANGED
@@ -56,7 +56,7 @@ def get_core_functions():
56
  "Color": "secondary",
57
  },
58
  "英译中": {
59
- "Prefix": r"请翻译成中文:" + "\n\n",
60
  "Suffix": r"",
61
  },
62
  "找图片": {
 
56
  "Color": "secondary",
57
  },
58
  "英译中": {
59
+ "Prefix": r"翻译成地道的中文:" + "\n\n",
60
  "Suffix": r"",
61
  },
62
  "找图片": {
crazy_functional.py CHANGED
@@ -3,7 +3,6 @@ from toolbox import HotReload # HotReload 的意思是热更新,修改函数
3
 
4
  def get_crazy_functions():
5
  ###################### 第一组插件 ###########################
6
- # [第一组插件]: 最早期编写的项目插件和一些demo
7
  from crazy_functions.读文章写摘要 import 读文章写摘要
8
  from crazy_functions.生成函数注释 import 批量生成函数注释
9
  from crazy_functions.解析项目源代码 import 解析项目本身
@@ -15,21 +14,38 @@ def get_crazy_functions():
15
  from crazy_functions.解析项目源代码 import 解析一个Rect项目
16
  from crazy_functions.高级功能函数模板 import 高阶功能模板函数
17
  from crazy_functions.代码重写为全英文_多线程 import 全项目切换英文
18
-
 
 
 
 
 
 
19
  function_plugins = {
20
- "请解析并解构此项目本身(源码自译解)": {
21
- "AsButton": False, # 加入下拉菜单中
22
- "Function": HotReload(解析项目本身)
23
- },
24
  "解析整个Python项目": {
25
  "Color": "stop", # 按钮颜色
26
  "Function": HotReload(解析一个Python项目)
27
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  "解析整个C++项目头文件": {
29
  "Color": "stop", # 按钮颜色
 
30
  "Function": HotReload(解析一个C项目的头文件)
31
  },
32
- "解析整个C++项目(.cpp/.h)": {
33
  "Color": "stop", # 按钮颜色
34
  "AsButton": False, # 加入下拉菜单中
35
  "Function": HotReload(解析一个C项目)
@@ -49,6 +65,16 @@ def get_crazy_functions():
49
  "AsButton": False, # 加入下拉菜单中
50
  "Function": HotReload(解析一个Rect项目)
51
  },
 
 
 
 
 
 
 
 
 
 
52
  "读Tex论文写摘要": {
53
  "Color": "stop", # 按钮颜色
54
  "Function": HotReload(读文章写摘要)
@@ -57,25 +83,32 @@ def get_crazy_functions():
57
  "Color": "stop", # 按钮颜色
58
  "Function": HotReload(批量生成函数注释)
59
  },
 
 
 
60
  "[多线程demo] 把本项目源代码切换成全英文": {
61
  # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
 
62
  "Function": HotReload(全项目切换英文)
63
  },
64
- "[函数插件模板demo] 历史上的今天": {
65
  # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
66
  "Function": HotReload(高阶功能模板函数)
67
  },
68
 
69
  }
70
  ###################### 第二组插件 ###########################
71
- # [第二组插件]: 经过充分测试,但功能上距离达到完美状态还差一点点
72
  from crazy_functions.批量总结PDF文档 import 批量总结PDF文档
73
  from crazy_functions.批量总结PDF文档pdfminer import 批量总结PDF文档pdfminer
74
- from crazy_functions.总结word文档 import 总结word文档
75
  from crazy_functions.批量翻译PDF文档_多线程 import 批量翻译PDF文档
76
  from crazy_functions.谷歌检索小助手 import 谷歌检索小助手
77
- from crazy_functions.理解PDF文档内容 import 理解PDF文档内容
78
  from crazy_functions.理解PDF文档内容 import 理解PDF文档内容标准文件输入
 
 
 
 
 
79
 
80
  function_plugins.update({
81
  "批量翻译PDF文档(多线程)": {
@@ -83,13 +116,17 @@ def get_crazy_functions():
83
  "AsButton": True, # 加入下拉菜单中
84
  "Function": HotReload(批量翻译PDF文档)
85
  },
86
- "[仅供开发调试] 批量总结PDF文档": {
 
 
 
 
87
  "Color": "stop",
88
  "AsButton": False, # 加入下拉菜单中
89
  # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
90
  "Function": HotReload(批量总结PDF文档)
91
  },
92
- "[仅供开发调试] 批量总结PDF文档pdfminer": {
93
  "Color": "stop",
94
  "AsButton": False, # 加入下拉菜单中
95
  "Function": HotReload(批量总结PDF文档pdfminer)
@@ -99,37 +136,91 @@ def get_crazy_functions():
99
  "AsButton": False, # 加入下拉菜单中
100
  "Function": HotReload(谷歌检索小助手)
101
  },
102
- "批量总结Word文档": {
 
 
103
  "Color": "stop",
104
- "Function": HotReload(总结word文档)
 
105
  },
106
- "理解PDF文档内容(Tk文件选择接口,仅本地)": {
107
  # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
 
108
  "AsButton": False, # 加入下拉菜单中
109
- "Function": HotReload(理解PDF文档内容)
110
  },
111
- "理解PDF文档内容(通用接口,读取文件输入区)": {
112
  # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
113
  "Color": "stop",
114
  "AsButton": False, # 加入下拉菜单中
115
- "Function": HotReload(理解PDF文档内容标准文件输入)
116
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  })
118
 
119
  ###################### 第三组插件 ###########################
120
  # [第三组插件]: 尚未充分测试的函数插件,放在这里
121
- try:
122
- from crazy_functions.下载arxiv论文翻译摘要 import 下载arxiv论文并翻译摘要
123
- function_plugins.update({
124
- "一键下载arxiv论文并翻译摘要(先在input输入编号,如1812.10695)": {
125
- "Color": "stop",
126
- "AsButton": False, # 加入下拉菜单中
127
- "Function": HotReload(下载arxiv论文并翻译摘要)
128
- }
129
- })
130
 
131
- except Exception as err:
132
- print(f'[下载arxiv论文并翻译摘要] 插件导入失败 {str(err)}')
 
 
 
 
 
 
133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  ###################### 第n组插件 ###########################
135
  return function_plugins
 
3
 
4
  def get_crazy_functions():
5
  ###################### 第一组插件 ###########################
 
6
  from crazy_functions.读文章写摘要 import 读文章写摘要
7
  from crazy_functions.生成函数注释 import 批量生成函数注释
8
  from crazy_functions.解析项目源代码 import 解析项目本身
 
14
  from crazy_functions.解析项目源代码 import 解析一个Rect项目
15
  from crazy_functions.高级功能函数模板 import 高阶功能模板函数
16
  from crazy_functions.代码重写为全英文_多线程 import 全项目切换英文
17
+ from crazy_functions.Latex全文润色 import Latex英文润色
18
+ from crazy_functions.询问多个大语言模型 import 同时问询
19
+ from crazy_functions.解析项目源代码 import 解析一个Lua项目
20
+ from crazy_functions.解析项目源代码 import 解析一个CSharp项目
21
+ from crazy_functions.总结word文档 import 总结word文档
22
+ from crazy_functions.解析JupyterNotebook import 解析ipynb文件
23
+ from crazy_functions.对话历史存档 import 对话历史存档
24
  function_plugins = {
25
+
 
 
 
26
  "解析整个Python项目": {
27
  "Color": "stop", # 按钮颜色
28
  "Function": HotReload(解析一个Python项目)
29
  },
30
+ "保存当前的对话": {
31
+ "AsButton":False,
32
+ "Function": HotReload(对话历史存档)
33
+ },
34
+ "[测试功能] 解析Jupyter Notebook文件": {
35
+ "Color": "stop",
36
+ "AsButton":False,
37
+ "Function": HotReload(解析ipynb文件),
38
+ },
39
+ "批量总结Word文档": {
40
+ "Color": "stop",
41
+ "Function": HotReload(总结word文档)
42
+ },
43
  "解析整个C++项目头文件": {
44
  "Color": "stop", # 按钮颜色
45
+ "AsButton": False, # 加入下拉菜单中
46
  "Function": HotReload(解析一个C项目的头文件)
47
  },
48
+ "解析整个C++项目(.cpp/.hpp/.c/.h)": {
49
  "Color": "stop", # 按钮颜色
50
  "AsButton": False, # 加入下拉菜单中
51
  "Function": HotReload(解析一个C项目)
 
65
  "AsButton": False, # 加入下拉菜单中
66
  "Function": HotReload(解析一个Rect项目)
67
  },
68
+ "解析整个Lua项目": {
69
+ "Color": "stop", # 按钮颜色
70
+ "AsButton": False, # 加入下拉菜单中
71
+ "Function": HotReload(解析一个Lua项目)
72
+ },
73
+ "解析整个CSharp项目": {
74
+ "Color": "stop", # 按钮颜色
75
+ "AsButton": False, # 加入下拉菜单中
76
+ "Function": HotReload(解析一个CSharp项目)
77
+ },
78
  "读Tex论文写摘要": {
79
  "Color": "stop", # 按钮颜色
80
  "Function": HotReload(读文章写摘要)
 
83
  "Color": "stop", # 按钮颜色
84
  "Function": HotReload(批量生成函数注释)
85
  },
86
+ "[多线程Demo] 解析此项目本身(源码自译解)": {
87
+ "Function": HotReload(解析项目本身)
88
+ },
89
  "[多线程demo] 把本项目源代码切换成全英文": {
90
  # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
91
+ "AsButton": False, # 加入下拉菜单中
92
  "Function": HotReload(全项目切换英文)
93
  },
94
+ "[函数插件模板Demo] 历史上的今天": {
95
  # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
96
  "Function": HotReload(高阶功能模板函数)
97
  },
98
 
99
  }
100
  ###################### 第二组插件 ###########################
101
+ # [第二组插件]: 经过充分测试
102
  from crazy_functions.批量总结PDF文档 import 批量总结PDF文档
103
  from crazy_functions.批量总结PDF文档pdfminer import 批量总结PDF文档pdfminer
 
104
  from crazy_functions.批量翻译PDF文档_多线程 import 批量翻译PDF文档
105
  from crazy_functions.谷歌检索小助手 import 谷歌检索小助手
 
106
  from crazy_functions.理解PDF文档内容 import 理解PDF文档内容标准文件输入
107
+ from crazy_functions.Latex全文润色 import Latex中文润色
108
+ from crazy_functions.Latex全文翻译 import Latex中译英
109
+ from crazy_functions.Latex全文翻译 import Latex英译中
110
+ from crazy_functions.批量Markdown翻译 import Markdown中译英
111
+ from crazy_functions.批量Markdown翻译 import Markdown英译中
112
 
113
  function_plugins.update({
114
  "批量翻译PDF文档(多线程)": {
 
116
  "AsButton": True, # 加入下拉菜单中
117
  "Function": HotReload(批量翻译PDF文档)
118
  },
119
+ "询问多个GPT模型": {
120
+ "Color": "stop", # 按钮颜色
121
+ "Function": HotReload(同时问询)
122
+ },
123
+ "[测试功能] 批量总结PDF文档": {
124
  "Color": "stop",
125
  "AsButton": False, # 加入下拉菜单中
126
  # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
127
  "Function": HotReload(批量总结PDF文档)
128
  },
129
+ "[测试功能] 批量总结PDF文档pdfminer": {
130
  "Color": "stop",
131
  "AsButton": False, # 加入下拉菜单中
132
  "Function": HotReload(批量总结PDF文档pdfminer)
 
136
  "AsButton": False, # 加入下拉菜单中
137
  "Function": HotReload(谷歌检索小助手)
138
  },
139
+
140
+ "理解PDF文档内容 (模仿ChatPDF)": {
141
+ # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
142
  "Color": "stop",
143
+ "AsButton": False, # 加入下拉菜单中
144
+ "Function": HotReload(理解PDF文档内容标准文件输入)
145
  },
146
+ "[测试功能] 英文Latex项目全文润色(输入路径或上传压缩包)": {
147
  # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
148
+ "Color": "stop",
149
  "AsButton": False, # 加入下拉菜单中
150
+ "Function": HotReload(Latex英文润色)
151
  },
152
+ "[测试功能] 中文Latex项目全文润色(输入路径或上传压缩包)": {
153
  # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
154
  "Color": "stop",
155
  "AsButton": False, # 加入下拉菜单中
156
+ "Function": HotReload(Latex中文润色)
157
  },
158
+ "[测试功能] Latex项目全文中译英(输入路径或上传压缩包)": {
159
+ # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
160
+ "Color": "stop",
161
+ "AsButton": False, # 加入下拉菜单中
162
+ "Function": HotReload(Latex中译英)
163
+ },
164
+ "[测试功能] Latex项目全文英译中(输入路径或上传压缩包)": {
165
+ # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
166
+ "Color": "stop",
167
+ "AsButton": False, # 加入下拉菜单中
168
+ "Function": HotReload(Latex英译中)
169
+ },
170
+ "[测试功能] 批量Markdown中译英(输入路径或上传压缩包)": {
171
+ # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
172
+ "Color": "stop",
173
+ "AsButton": False, # 加入下拉菜单中
174
+ "Function": HotReload(Markdown中译英)
175
+ },
176
+ "[测试功能] 批量Markdown英译中(输入路径或上传压缩包)": {
177
+ # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
178
+ "Color": "stop",
179
+ "AsButton": False, # 加入下拉菜单中
180
+ "Function": HotReload(Markdown英译中)
181
+ },
182
+
183
  })
184
 
185
  ###################### 第三组插件 ###########################
186
  # [第三组插件]: 尚未充分测试的函数插件,放在这里
187
+ from crazy_functions.下载arxiv论文翻译摘要 import 下载arxiv论文并翻译摘要
188
+ function_plugins.update({
189
+ "一键下载arxiv论文并翻译摘要(先在input输入编号,如1812.10695)": {
190
+ "Color": "stop",
191
+ "AsButton": False, # 加入下拉菜单中
192
+ "Function": HotReload(下载arxiv论文并翻译摘要)
193
+ }
194
+ })
 
195
 
196
+ from crazy_functions.联网的ChatGPT import 连接网络回答问题
197
+ function_plugins.update({
198
+ "连接网络回答问题(先输入问题,再点击按钮,需要访问谷歌)": {
199
+ "Color": "stop",
200
+ "AsButton": False, # 加入下拉菜单中
201
+ "Function": HotReload(连接网络回答问题)
202
+ }
203
+ })
204
 
205
+ from crazy_functions.解析项目源代码 import 解析任意code项目
206
+ function_plugins.update({
207
+ "解析项目源代码(手动指定和筛选源代码文件类型)": {
208
+ "Color": "stop",
209
+ "AsButton": False,
210
+ "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False)
211
+ "ArgsReminder": "输入时用逗号隔开, *代表通配符, 加了^代表不匹配; 不输入代表全部匹配。例如: \"*.c, ^*.cpp, config.toml, ^*.toml\"", # 高级参数输入区的显示提示
212
+ "Function": HotReload(解析任意code项目)
213
+ },
214
+ })
215
+ from crazy_functions.询问多个大语言模型 import 同时问询_指定模型
216
+ function_plugins.update({
217
+ "询问多个GPT模型(手动指定询问哪些模型)": {
218
+ "Color": "stop",
219
+ "AsButton": False,
220
+ "AdvancedArgs": True, # 调用时,唤起高级参数输入区(默认False)
221
+ "ArgsReminder": "支持任意数量的llm接口,用&符号分隔。例如chatglm&gpt-3.5-turbo&api2d-gpt-4", # 高级参数输入区的显示提示
222
+ "Function": HotReload(同时问询_指定模型)
223
+ },
224
+ })
225
  ###################### 第n组插件 ###########################
226
  return function_plugins
crazy_functions/Latex全文润色.py ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file
3
+ fast_debug = False
4
+
5
+ class PaperFileGroup():
6
+ def __init__(self):
7
+ self.file_paths = []
8
+ self.file_contents = []
9
+ self.sp_file_contents = []
10
+ self.sp_file_index = []
11
+ self.sp_file_tag = []
12
+
13
+ # count_token
14
+ from request_llm.bridge_all import model_info
15
+ enc = model_info["gpt-3.5-turbo"]['tokenizer']
16
+ def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
17
+ self.get_token_num = get_token_num
18
+
19
+ def run_file_split(self, max_token_limit=1900):
20
+ """
21
+ 将长文本分离开来
22
+ """
23
+ for index, file_content in enumerate(self.file_contents):
24
+ if self.get_token_num(file_content) < max_token_limit:
25
+ self.sp_file_contents.append(file_content)
26
+ self.sp_file_index.append(index)
27
+ self.sp_file_tag.append(self.file_paths[index])
28
+ else:
29
+ from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
30
+ segments = breakdown_txt_to_satisfy_token_limit_for_pdf(file_content, self.get_token_num, max_token_limit)
31
+ for j, segment in enumerate(segments):
32
+ self.sp_file_contents.append(segment)
33
+ self.sp_file_index.append(index)
34
+ self.sp_file_tag.append(self.file_paths[index] + f".part-{j}.tex")
35
+
36
+ print('Segmentation: done')
37
+
38
+ def 多文件润色(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en'):
39
+ import time, os, re
40
+ from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
41
+
42
+
43
+ # <-------- 读取Latex文件,删除其中的所有注释 ---------->
44
+ pfg = PaperFileGroup()
45
+
46
+ for index, fp in enumerate(file_manifest):
47
+ with open(fp, 'r', encoding='utf-8', errors='replace') as f:
48
+ file_content = f.read()
49
+ # 定义注释的正则表达式
50
+ comment_pattern = r'%.*'
51
+ # 使用正则表达式查找注释,并替换为空字符串
52
+ clean_tex_content = re.sub(comment_pattern, '', file_content)
53
+ # 记录删除注释后的文本
54
+ pfg.file_paths.append(fp)
55
+ pfg.file_contents.append(clean_tex_content)
56
+
57
+ # <-------- 拆分过长的latex文件 ---------->
58
+ pfg.run_file_split(max_token_limit=1024)
59
+ n_split = len(pfg.sp_file_contents)
60
+
61
+ # <-------- 抽取摘要 ---------->
62
+ # if language == 'en':
63
+ # abs_extract_inputs = f"Please write an abstract for this paper"
64
+
65
+ # # 单线,获取文章meta信息
66
+ # paper_meta_info = yield from request_gpt_model_in_new_thread_with_ui_alive(
67
+ # inputs=abs_extract_inputs,
68
+ # inputs_show_user=f"正在抽取摘要信息。",
69
+ # llm_kwargs=llm_kwargs,
70
+ # chatbot=chatbot, history=[],
71
+ # sys_prompt="Your job is to collect information from materials。",
72
+ # )
73
+
74
+ # <-------- 多线程润色开始 ---------->
75
+ if language == 'en':
76
+ inputs_array = ["Below is a section from an academic paper, polish this section to meet the academic standard, improve the grammar, clarity and overall readability, do not modify any latex command such as \section, \cite and equations:" +
77
+ f"\n\n{frag}" for frag in pfg.sp_file_contents]
78
+ inputs_show_user_array = [f"Polish {f}" for f in pfg.sp_file_tag]
79
+ sys_prompt_array = ["You are a professional academic paper writer." for _ in range(n_split)]
80
+ elif language == 'zh':
81
+ inputs_array = [f"以下是一篇学术论文中的一段内容,请将此部分润色以满足学术标准,提高语法、清晰度和整体可读性,不要修改任何LaTeX命令,例如\section,\cite和方程式:" +
82
+ f"\n\n{frag}" for frag in pfg.sp_file_contents]
83
+ inputs_show_user_array = [f"润色 {f}" for f in pfg.sp_file_tag]
84
+ sys_prompt_array=["你是一位专业的中文学术论文作家。" for _ in range(n_split)]
85
+
86
+
87
+ gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
88
+ inputs_array=inputs_array,
89
+ inputs_show_user_array=inputs_show_user_array,
90
+ llm_kwargs=llm_kwargs,
91
+ chatbot=chatbot,
92
+ history_array=[[""] for _ in range(n_split)],
93
+ sys_prompt_array=sys_prompt_array,
94
+ # max_workers=5, # 并行任务数量限制,最多同时执行5个,其他的排队等待
95
+ scroller_max_len = 80
96
+ )
97
+
98
+ # <-------- 整理结果,退出 ---------->
99
+ create_report_file_name = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + f"-chatgpt.polish.md"
100
+ res = write_results_to_file(gpt_response_collection, file_name=create_report_file_name)
101
+ history = gpt_response_collection
102
+ chatbot.append((f"{fp}完成了吗?", res))
103
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
104
+
105
+
106
+ @CatchException
107
+ def Latex英文润色(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
108
+ # 基本信息:功能、贡献者
109
+ chatbot.append([
110
+ "函数插件功能?",
111
+ "对整个Latex项目进行润色。函数插件贡献者: Binary-Husky"])
112
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
113
+
114
+ # 尝试导入依赖,如果缺少依赖,则给出安装建议
115
+ try:
116
+ import tiktoken
117
+ except:
118
+ report_execption(chatbot, history,
119
+ a=f"解析项目: {txt}",
120
+ b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
121
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
122
+ return
123
+ history = [] # 清空历史,以免输入溢出
124
+ import glob, os
125
+ if os.path.exists(txt):
126
+ project_folder = txt
127
+ else:
128
+ if txt == "": txt = '空空如也的输入栏'
129
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
130
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
131
+ return
132
+ file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)]
133
+ if len(file_manifest) == 0:
134
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
135
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
136
+ return
137
+ yield from 多文件润色(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en')
138
+
139
+
140
+
141
+
142
+
143
+
144
+ @CatchException
145
+ def Latex中文润色(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
146
+ # 基本信息:功能、贡献者
147
+ chatbot.append([
148
+ "函数插件功能?",
149
+ "对整个Latex项目进行润色。函数插件贡献者: Binary-Husky"])
150
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
151
+
152
+ # 尝试导入依赖,如果缺少依赖,则给出安装建议
153
+ try:
154
+ import tiktoken
155
+ except:
156
+ report_execption(chatbot, history,
157
+ a=f"解析项目: {txt}",
158
+ b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
159
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
160
+ return
161
+ history = [] # 清空历史,以免输入溢出
162
+ import glob, os
163
+ if os.path.exists(txt):
164
+ project_folder = txt
165
+ else:
166
+ if txt == "": txt = '空空如也的输入栏'
167
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
168
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
169
+ return
170
+ file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)]
171
+ if len(file_manifest) == 0:
172
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
173
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
174
+ return
175
+ yield from 多文件润色(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='zh')
crazy_functions/Latex全文翻译.py ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file
3
+ fast_debug = False
4
+
5
+ class PaperFileGroup():
6
+ def __init__(self):
7
+ self.file_paths = []
8
+ self.file_contents = []
9
+ self.sp_file_contents = []
10
+ self.sp_file_index = []
11
+ self.sp_file_tag = []
12
+
13
+ # count_token
14
+ from request_llm.bridge_all import model_info
15
+ enc = model_info["gpt-3.5-turbo"]['tokenizer']
16
+ def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
17
+ self.get_token_num = get_token_num
18
+
19
+ def run_file_split(self, max_token_limit=1900):
20
+ """
21
+ 将长文本分离开来
22
+ """
23
+ for index, file_content in enumerate(self.file_contents):
24
+ if self.get_token_num(file_content) < max_token_limit:
25
+ self.sp_file_contents.append(file_content)
26
+ self.sp_file_index.append(index)
27
+ self.sp_file_tag.append(self.file_paths[index])
28
+ else:
29
+ from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
30
+ segments = breakdown_txt_to_satisfy_token_limit_for_pdf(file_content, self.get_token_num, max_token_limit)
31
+ for j, segment in enumerate(segments):
32
+ self.sp_file_contents.append(segment)
33
+ self.sp_file_index.append(index)
34
+ self.sp_file_tag.append(self.file_paths[index] + f".part-{j}.tex")
35
+
36
+ print('Segmentation: done')
37
+
38
+ def 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en'):
39
+ import time, os, re
40
+ from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
41
+
42
+ # <-------- 读取Latex文件,删除其中的所有注释 ---------->
43
+ pfg = PaperFileGroup()
44
+
45
+ for index, fp in enumerate(file_manifest):
46
+ with open(fp, 'r', encoding='utf-8', errors='replace') as f:
47
+ file_content = f.read()
48
+ # 定义注释的正则表达式
49
+ comment_pattern = r'%.*'
50
+ # 使用正则表达式查找注释,并替换为空字符串
51
+ clean_tex_content = re.sub(comment_pattern, '', file_content)
52
+ # 记录删除注释后的文本
53
+ pfg.file_paths.append(fp)
54
+ pfg.file_contents.append(clean_tex_content)
55
+
56
+ # <-------- 拆分过长的latex文件 ---------->
57
+ pfg.run_file_split(max_token_limit=1024)
58
+ n_split = len(pfg.sp_file_contents)
59
+
60
+ # <-------- 抽取摘要 ---------->
61
+ # if language == 'en':
62
+ # abs_extract_inputs = f"Please write an abstract for this paper"
63
+
64
+ # # 单线,获取文章meta信息
65
+ # paper_meta_info = yield from request_gpt_model_in_new_thread_with_ui_alive(
66
+ # inputs=abs_extract_inputs,
67
+ # inputs_show_user=f"正在抽取摘要信息。",
68
+ # llm_kwargs=llm_kwargs,
69
+ # chatbot=chatbot, history=[],
70
+ # sys_prompt="Your job is to collect information from materials。",
71
+ # )
72
+
73
+ # <-------- 多线程润色开始 ---------->
74
+ if language == 'en->zh':
75
+ inputs_array = ["Below is a section from an English academic paper, translate it into Chinese, do not modify any latex command such as \section, \cite and equations:" +
76
+ f"\n\n{frag}" for frag in pfg.sp_file_contents]
77
+ inputs_show_user_array = [f"翻译 {f}" for f in pfg.sp_file_tag]
78
+ sys_prompt_array = ["You are a professional academic paper translator." for _ in range(n_split)]
79
+ elif language == 'zh->en':
80
+ inputs_array = [f"Below is a section from a Chinese academic paper, translate it into English, do not modify any latex command such as \section, \cite and equations:" +
81
+ f"\n\n{frag}" for frag in pfg.sp_file_contents]
82
+ inputs_show_user_array = [f"翻译 {f}" for f in pfg.sp_file_tag]
83
+ sys_prompt_array = ["You are a professional academic paper translator." for _ in range(n_split)]
84
+
85
+ gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
86
+ inputs_array=inputs_array,
87
+ inputs_show_user_array=inputs_show_user_array,
88
+ llm_kwargs=llm_kwargs,
89
+ chatbot=chatbot,
90
+ history_array=[[""] for _ in range(n_split)],
91
+ sys_prompt_array=sys_prompt_array,
92
+ # max_workers=5, # OpenAI所允许的最大并行过载
93
+ scroller_max_len = 80
94
+ )
95
+
96
+ # <-------- 整理结果,退出 ---------->
97
+ create_report_file_name = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + f"-chatgpt.polish.md"
98
+ res = write_results_to_file(gpt_response_collection, file_name=create_report_file_name)
99
+ history = gpt_response_collection
100
+ chatbot.append((f"{fp}完成了吗?", res))
101
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
102
+
103
+
104
+
105
+
106
+
107
+ @CatchException
108
+ def Latex英译中(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
109
+ # 基本信息:功能、贡献者
110
+ chatbot.append([
111
+ "函数插件功能?",
112
+ "对整个Latex项目进行翻译。函数插件贡献者: Binary-Husky"])
113
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
114
+
115
+ # 尝试导入依赖,如果缺少依赖,则给出安装建议
116
+ try:
117
+ import tiktoken
118
+ except:
119
+ report_execption(chatbot, history,
120
+ a=f"解析项目: {txt}",
121
+ b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
122
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
123
+ return
124
+ history = [] # 清空历史,以免输入溢出
125
+ import glob, os
126
+ if os.path.exists(txt):
127
+ project_folder = txt
128
+ else:
129
+ if txt == "": txt = '空空如也的输入栏'
130
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
131
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
132
+ return
133
+ file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)]
134
+ if len(file_manifest) == 0:
135
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
136
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
137
+ return
138
+ yield from 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en->zh')
139
+
140
+
141
+
142
+
143
+
144
+ @CatchException
145
+ def Latex中译英(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
146
+ # 基本信息:功能、贡献者
147
+ chatbot.append([
148
+ "函数插件功能?",
149
+ "对整个Latex项目进行翻译。函数插件贡献者: Binary-Husky"])
150
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
151
+
152
+ # 尝试导入依赖,如果缺少依赖,则给出安装建议
153
+ try:
154
+ import tiktoken
155
+ except:
156
+ report_execption(chatbot, history,
157
+ a=f"解析项目: {txt}",
158
+ b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
159
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
160
+ return
161
+ history = [] # 清空历史,以免输入溢出
162
+ import glob, os
163
+ if os.path.exists(txt):
164
+ project_folder = txt
165
+ else:
166
+ if txt == "": txt = '空空如也的输入栏'
167
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
168
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
169
+ return
170
+ file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)]
171
+ if len(file_manifest) == 0:
172
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
173
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
174
+ return
175
+ yield from 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='zh->en')
crazy_functions/crazy_functions_test.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ 这是什么?
3
+ 这个文件用于函数插件的单元测试
4
+ 运行方法 python crazy_functions/crazy_functions_test.py
5
+ """
6
+
7
+ def validate_path():
8
+ import os, sys
9
+ dir_name = os.path.dirname(__file__)
10
+ root_dir_assume = os.path.abspath(os.path.dirname(__file__) + '/..')
11
+ os.chdir(root_dir_assume)
12
+ sys.path.append(root_dir_assume)
13
+
14
+ validate_path() # validate path so you can run from base directory
15
+ from colorful import *
16
+ from toolbox import get_conf, ChatBotWithCookies
17
+ proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION, CHATBOT_HEIGHT, LAYOUT, API_KEY = \
18
+ get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION', 'CHATBOT_HEIGHT', 'LAYOUT', 'API_KEY')
19
+
20
+ llm_kwargs = {
21
+ 'api_key': API_KEY,
22
+ 'llm_model': LLM_MODEL,
23
+ 'top_p':1.0,
24
+ 'max_length': None,
25
+ 'temperature':1.0,
26
+ }
27
+ plugin_kwargs = { }
28
+ chatbot = ChatBotWithCookies(llm_kwargs)
29
+ history = []
30
+ system_prompt = "Serve me as a writing and programming assistant."
31
+ web_port = 1024
32
+
33
+
34
+ def test_解析一个Python项目():
35
+ from crazy_functions.解析项目源代码 import 解析一个Python项目
36
+ txt = "crazy_functions/test_project/python/dqn"
37
+ for cookies, cb, hist, msg in 解析一个Python项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
38
+ print(cb)
39
+
40
+ def test_解析一个Cpp项目():
41
+ from crazy_functions.解析项目源代码 import 解析一个C项目
42
+ txt = "crazy_functions/test_project/cpp/cppipc"
43
+ for cookies, cb, hist, msg in 解析一个C项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
44
+ print(cb)
45
+
46
+ def test_Latex英文润色():
47
+ from crazy_functions.Latex全文润色 import Latex英文润色
48
+ txt = "crazy_functions/test_project/latex/attention"
49
+ for cookies, cb, hist, msg in Latex英文润色(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
50
+ print(cb)
51
+
52
+ def test_Markdown中译英():
53
+ from crazy_functions.批量Markdown翻译 import Markdown中译英
54
+ txt = "README.md"
55
+ for cookies, cb, hist, msg in Markdown中译英(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
56
+ print(cb)
57
+
58
+ def test_批量翻译PDF文档():
59
+ from crazy_functions.批量翻译PDF文档_多线程 import 批量翻译PDF文档
60
+ txt = "crazy_functions/test_project/pdf_and_word"
61
+ for cookies, cb, hist, msg in 批量翻译PDF文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
62
+ print(cb)
63
+
64
+ def test_谷歌检索小助手():
65
+ from crazy_functions.谷歌检索小助手 import 谷歌检索小助手
66
+ txt = "https://scholar.google.com/scholar?hl=en&as_sdt=0%2C5&q=auto+reinforcement+learning&btnG="
67
+ for cookies, cb, hist, msg in 谷歌检索小助手(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
68
+ print(cb)
69
+
70
+ def test_总结word文档():
71
+ from crazy_functions.总结word文档 import 总结word文档
72
+ txt = "crazy_functions/test_project/pdf_and_word"
73
+ for cookies, cb, hist, msg in 总结word文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
74
+ print(cb)
75
+
76
+ def test_下载arxiv论文并翻译摘要():
77
+ from crazy_functions.下载arxiv论文翻译摘要 import 下载arxiv论文并翻译摘要
78
+ txt = "1812.10695"
79
+ for cookies, cb, hist, msg in 下载arxiv论文并翻译摘要(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
80
+ print(cb)
81
+
82
+ def test_联网回答问题():
83
+ from crazy_functions.联网的ChatGPT import 连接网络回答问题
84
+ # txt = "“我们称之为高效”是什么梗?"
85
+ # >> 从第0份、第1份、第2份搜索结果可以看出,“我们称之为高效”是指在游戏社区中,用户们用来形容一些游戏策略或行为非常高效且能够带来好的效果的用语。这个用语最初可能是在群星(Stellaris)这个游戏里面流行起来的,后来也传播到了其他游戏中,比如巨像(Titan)等游戏。其中第1份搜索结果中的一篇文章也指出,“我们称之为高效”这 一用语来源于群星(Stellaris)游戏中的一个情节。
86
+ # txt = "为什么说枪毙P社玩家没有一个冤枉的?"
87
+ # >> 它们都是关于一个知乎用户所发的帖子,引用了一群游戏玩家对于需要对P社玩家进行枪毙的讨论,这个话题的本质是玩家们对于P 社游戏中的政治与历史元素的不同看法,以及其中不少玩家以极端立场宣扬的想法和言论,因此有人就以枪毙这些玩家来回应此类言论。但是这个话题本身并没有实质内容,只是一个玩笑或者恶搞,并不应该被当做真实的态度或者观点,因此这种说法没有实际意义。
88
+ # txt = "谁是应急食品?"
89
+ # >> '根据以上搜索结果可以得知,应急食品是“原神”游戏中的角色派蒙的外号。'
90
+ # txt = "道路千万条,安全第一条。后面两句是?"
91
+ # >> '行车不规范,亲人两行泪。'
92
+ # txt = "What is in the canister?"
93
+ # >> Rainbow Six Siege 游戏中 Smoke 的 Canister 中装有何种物质相关的官方信息。
94
+ # txt = "失败的man是什么?"
95
+ # >> 根据第1份搜索结果,可以得知失败的man是指一位在B站购买了蜘蛛侠COS服后穿上后被网友嘲笑的UP主,而“失败的man”是蜘蛛侠英文名“spiderman”的谐音梗,并且网友们还 给这位UP主起了“苍蝇侠”的外号。因此,失败的man是指这位UP主在穿上蜘蛛侠COS服后被网友嘲笑的情况。
96
+ # txt = "老六是什么,起源于哪里?"
97
+ # >> 老六是网络流行语,最初起源于游戏《CSGO》,指游戏中玩家中独来独往、游离于队伍之外的“自由人”或玩得比较菜或者玩得比较阴险的人 ,后来逐渐演变成指玩得比较阴险的玩家。
98
+ # txt = "罗小黑战记因为什么经常被吐槽?"
99
+ # >> 3. 更新速度。罗小黑战记的更新时间不定,时而快时而慢,给观众留下了等待的时间过长的印象。
100
+ # txt = "沙特、伊朗最近的关系如何?"
101
+ # >> 最近在中国的斡旋下,沙特和伊朗于3月10日达成了恢复两国外交关系的协议,这表明两国关系已经重新回到正常化状态。
102
+ # txt = "You should have gone for the head. What does that mean?"
103
+ # >> The phrase "You should have gone for the head" is a quote from the Marvel movies, Avengers: Infinity War and Avengers: Endgame. It was spoken by the character Thanos in Infinity War and by Thor in Endgame.
104
+ txt = "AutoGPT是什么?"
105
+ # >> AutoGPT是一个基于GPT-4语言模型的开源应用程序。它可以根据用户需求自主执行任务,包括事件分析、营销方案撰写、代码编程、数学运算等等,并完全不需要用户插手。它可以自己思考,给出实现的步骤和实现细节,甚至可以自问自答执 行任务。最近它在GitHub上爆火,成为了业内最热门的项目之一。
106
+ # txt = "钟离带什么圣遗物?"
107
+ for cookies, cb, hist, msg in 连接网络回答问题(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
108
+ print("当前问答:", cb[-1][-1].replace("\n"," "))
109
+ for i, it in enumerate(cb): print亮蓝(it[0]); print亮黄(it[1])
110
+
111
+ def test_解析ipynb文件():
112
+ from crazy_functions.解析JupyterNotebook import 解析ipynb文件
113
+ txt = "crazy_functions/test_samples"
114
+ for cookies, cb, hist, msg in 解析ipynb文件(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
115
+ print(cb)
116
+
117
+
118
+ # test_解析一个Python项目()
119
+ # test_Latex英文润色()
120
+ # test_Markdown中译英()
121
+ # test_批量翻译PDF文档()
122
+ # test_谷歌检索小助手()
123
+ # test_总结word文档()
124
+ # test_下载arxiv论文并翻译摘要()
125
+ # test_解析一个Cpp项目()
126
+ # test_联网回答问题()
127
+ test_解析ipynb文件()
128
+
129
+ input("程序完成,回车退出。")
130
+ print("退出。")
crazy_functions/crazy_utils.py CHANGED
@@ -1,19 +1,120 @@
1
  import traceback
 
2
 
3
- def request_gpt_model_in_new_thread_with_ui_alive(inputs, inputs_show_user, top_p, temperature, chatbot, history, sys_prompt, refresh_interval=0.2):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  import time
5
  from concurrent.futures import ThreadPoolExecutor
6
- from request_llm.bridge_chatgpt import predict_no_ui_long_connection
7
  # 用户反馈
8
  chatbot.append([inputs_show_user, ""])
9
- msg = '正常'
10
- yield chatbot, [], msg
11
  executor = ThreadPoolExecutor(max_workers=16)
12
- mutable = ["", time.time()]
13
- future = executor.submit(lambda:
14
- predict_no_ui_long_connection(
15
- inputs=inputs, top_p=top_p, temperature=temperature, history=history, sys_prompt=sys_prompt, observe_window=mutable)
16
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  while True:
18
  # yield一次以刷新前端页面
19
  time.sleep(refresh_interval)
@@ -22,38 +123,134 @@ def request_gpt_model_in_new_thread_with_ui_alive(inputs, inputs_show_user, top_
22
  if future.done():
23
  break
24
  chatbot[-1] = [chatbot[-1][0], mutable[0]]
25
- msg = "正常"
26
- yield chatbot, [], msg
27
- return future.result()
28
 
 
 
 
 
29
 
30
- def request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(inputs_array, inputs_show_user_array, top_p, temperature, chatbot, history_array, sys_prompt_array, refresh_interval=0.2, max_workers=10, scroller_max_len=30):
31
- import time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  from concurrent.futures import ThreadPoolExecutor
33
- from request_llm.bridge_chatgpt import predict_no_ui_long_connection
34
  assert len(inputs_array) == len(history_array)
35
  assert len(inputs_array) == len(sys_prompt_array)
 
 
 
 
 
 
 
 
36
  executor = ThreadPoolExecutor(max_workers=max_workers)
37
  n_frag = len(inputs_array)
38
  # 用户反馈
39
  chatbot.append(["请开始多线程操作。", ""])
40
- msg = '正常'
41
- yield chatbot, [], msg
42
- # 异步原子
43
- mutable = [["", time.time()] for _ in range(n_frag)]
44
 
 
45
  def _req_gpt(index, inputs, history, sys_prompt):
46
- try:
47
- gpt_say = predict_no_ui_long_connection(
48
- inputs=inputs, top_p=top_p, temperature=temperature, history=history, sys_prompt=sys_prompt, observe_window=mutable[index]
49
- )
50
- except:
51
- # 收拾残局
52
- tb_str = '```\n' + traceback.format_exc() + '```'
53
- gpt_say = f"[Local Message] 线程{index}在执行过程中遭遇问题, Traceback:\n\n{tb_str}\n\n"
54
- if len(mutable[index][0]) > 0:
55
- gpt_say += "此线程失败前收到的回答:" + mutable[index][0]
56
- return gpt_say
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  # 异步任务开始
58
  futures = [executor.submit(_req_gpt, index, inputs, history, sys_prompt) for index, inputs, history, sys_prompt in zip(
59
  range(len(inputs_array)), inputs_array, history_array, sys_prompt_array)]
@@ -77,17 +274,27 @@ def request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(inp
77
  replace('\n', '').replace('```', '...').replace(
78
  ' ', '.').replace('<br/>', '.....').replace('$', '.')+"`... ]"
79
  observe_win.append(print_something_really_funny)
80
- stat_str = ''.join([f'执行中: {obs}\n\n' if not done else '已完成\n\n' for done, obs in zip(
81
- worker_done, observe_win)])
82
- chatbot[-1] = [chatbot[-1][0],
83
- f'多线程操作已经开始,完成情况: \n\n{stat_str}' + ''.join(['.']*(cnt % 10+1))]
84
- msg = "正常"
85
- yield chatbot, [], msg
 
 
86
  # 异步任务结束
87
  gpt_response_collection = []
88
  for inputs_show_user, f in zip(inputs_show_user_array, futures):
89
  gpt_res = f.result()
90
  gpt_response_collection.extend([inputs_show_user, gpt_res])
 
 
 
 
 
 
 
 
91
  return gpt_response_collection
92
 
93
 
@@ -109,7 +316,6 @@ def breakdown_txt_to_satisfy_token_limit(txt, get_token_fn, limit):
109
  if get_token_fn(prev) < limit:
110
  break
111
  if cnt == 0:
112
- print('what the fuck ?')
113
  raise RuntimeError("存在一行极长的文本!")
114
  # print(len(post))
115
  # 列表递归接龙
@@ -122,8 +328,18 @@ def breakdown_txt_to_satisfy_token_limit(txt, get_token_fn, limit):
122
  return cut(txt, must_break_at_empty_line=False)
123
 
124
 
 
 
 
 
 
 
 
 
 
125
  def breakdown_txt_to_satisfy_token_limit_for_pdf(txt, get_token_fn, limit):
126
- def cut(txt_tocut, must_break_at_empty_line): # 递归
 
127
  if get_token_fn(txt_tocut) <= limit:
128
  return [txt_tocut]
129
  else:
@@ -135,25 +351,216 @@ def breakdown_txt_to_satisfy_token_limit_for_pdf(txt, get_token_fn, limit):
135
  if must_break_at_empty_line:
136
  if lines[cnt] != "":
137
  continue
138
- print(cnt)
139
  prev = "\n".join(lines[:cnt])
140
  post = "\n".join(lines[cnt:])
141
  if get_token_fn(prev) < limit:
142
  break
143
  if cnt == 0:
144
- # print('what the fuck ? 存在一行极长的文本!')
145
- raise RuntimeError("存在一行极长的文本!")
 
 
146
  # print(len(post))
147
  # 列表递归接龙
148
  result = [prev]
149
- result.extend(cut(post, must_break_at_empty_line))
150
  return result
151
  try:
 
152
  return cut(txt, must_break_at_empty_line=True)
153
  except RuntimeError:
154
  try:
 
155
  return cut(txt, must_break_at_empty_line=False)
156
  except RuntimeError:
157
- # 这个中文的句号是故意的,作为一个标识而存在
158
- res = cut(txt.replace('.', '。\n'), must_break_at_empty_line=False)
159
- return [r.replace('。\n', '.') for r in res]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import traceback
2
+ from toolbox import update_ui, get_conf
3
 
4
+ def input_clipping(inputs, history, max_token_limit):
5
+ import numpy as np
6
+ from request_llm.bridge_all import model_info
7
+ enc = model_info["gpt-3.5-turbo"]['tokenizer']
8
+ def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
9
+
10
+ mode = 'input-and-history'
11
+ # 当 输入部分的token占比 小于 全文的一半时,只裁剪历史
12
+ input_token_num = get_token_num(inputs)
13
+ if input_token_num < max_token_limit//2:
14
+ mode = 'only-history'
15
+ max_token_limit = max_token_limit - input_token_num
16
+
17
+ everything = [inputs] if mode == 'input-and-history' else ['']
18
+ everything.extend(history)
19
+ n_token = get_token_num('\n'.join(everything))
20
+ everything_token = [get_token_num(e) for e in everything]
21
+ delta = max(everything_token) // 16 # 截断时的颗粒度
22
+
23
+ while n_token > max_token_limit:
24
+ where = np.argmax(everything_token)
25
+ encoded = enc.encode(everything[where], disallowed_special=())
26
+ clipped_encoded = encoded[:len(encoded)-delta]
27
+ everything[where] = enc.decode(clipped_encoded)[:-1] # -1 to remove the may-be illegal char
28
+ everything_token[where] = get_token_num(everything[where])
29
+ n_token = get_token_num('\n'.join(everything))
30
+
31
+ if mode == 'input-and-history':
32
+ inputs = everything[0]
33
+ else:
34
+ pass
35
+ history = everything[1:]
36
+ return inputs, history
37
+
38
+ def request_gpt_model_in_new_thread_with_ui_alive(
39
+ inputs, inputs_show_user, llm_kwargs,
40
+ chatbot, history, sys_prompt, refresh_interval=0.2,
41
+ handle_token_exceed=True,
42
+ retry_times_at_unknown_error=2,
43
+ ):
44
+ """
45
+ Request GPT model,请求GPT模型同时维持用户界面活跃。
46
+
47
+ 输入参数 Args (以_array结尾的输入变量都是列表,列表长度为子任务的数量,执行时,会把列表拆解,放到每个子线程中分别执行):
48
+ inputs (string): List of inputs (输入)
49
+ inputs_show_user (string): List of inputs to show user(展现在报告中的输入,借助此参数,在汇总报告中隐藏啰嗦的真实输入,增强报告的可读性)
50
+ top_p (float): Top p value for sampling from model distribution (GPT参数,浮点数)
51
+ temperature (float): Temperature value for sampling from model distribution(GPT参数,浮点数)
52
+ chatbot: chatbot inputs and outputs (用户界面对话窗口句柄,用于数据流可视化)
53
+ history (list): List of chat history (历史,对话历史列表)
54
+ sys_prompt (string): List of system prompts (系统输入,列表,用于输入给GPT的前提提示,比如你是翻译官怎样怎样)
55
+ refresh_interval (float, optional): Refresh interval for UI (default: 0.2) (刷新时间间隔频率,建议低于1,不可高于3,仅仅服务于视觉效果)
56
+ handle_token_exceed:是否自动处理token溢出的情况,如果选择自动处理,则会在溢出时暴力截断,默认开启
57
+ retry_times_at_unknown_error:失败时的重试次数
58
+
59
+ 输出 Returns:
60
+ future: 输出,GPT返回的结果
61
+ """
62
  import time
63
  from concurrent.futures import ThreadPoolExecutor
64
+ from request_llm.bridge_all import predict_no_ui_long_connection
65
  # 用户反馈
66
  chatbot.append([inputs_show_user, ""])
67
+ yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
 
68
  executor = ThreadPoolExecutor(max_workers=16)
69
+ mutable = ["", time.time(), ""]
70
+ def _req_gpt(inputs, history, sys_prompt):
71
+ retry_op = retry_times_at_unknown_error
72
+ exceeded_cnt = 0
73
+ while True:
74
+ # watchdog error
75
+ if len(mutable) >= 2 and (time.time()-mutable[1]) > 5:
76
+ raise RuntimeError("检测到程序终止。")
77
+ try:
78
+ # 【第一种情况】:顺利完成
79
+ result = predict_no_ui_long_connection(
80
+ inputs=inputs, llm_kwargs=llm_kwargs,
81
+ history=history, sys_prompt=sys_prompt, observe_window=mutable)
82
+ return result
83
+ except ConnectionAbortedError as token_exceeded_error:
84
+ # 【第二种情况】:Token溢出
85
+ if handle_token_exceed:
86
+ exceeded_cnt += 1
87
+ # 【选择处理】 尝试计算比例,尽可能多地保留文本
88
+ from toolbox import get_reduce_token_percent
89
+ p_ratio, n_exceed = get_reduce_token_percent(str(token_exceeded_error))
90
+ MAX_TOKEN = 4096
91
+ EXCEED_ALLO = 512 + 512 * exceeded_cnt
92
+ inputs, history = input_clipping(inputs, history, max_token_limit=MAX_TOKEN-EXCEED_ALLO)
93
+ mutable[0] += f'[Local Message] 警告,文本过长将进行截断,Token溢出数:{n_exceed}。\n\n'
94
+ continue # 返回重试
95
+ else:
96
+ # 【选择放弃】
97
+ tb_str = '```\n' + traceback.format_exc() + '```'
98
+ mutable[0] += f"[Local Message] 警告,在执行过程中遭遇问题, Traceback:\n\n{tb_str}\n\n"
99
+ return mutable[0] # 放弃
100
+ except:
101
+ # 【第三种情况】:其他错误:重试几次
102
+ tb_str = '```\n' + traceback.format_exc() + '```'
103
+ print(tb_str)
104
+ mutable[0] += f"[Local Message] 警告,在执行过程中遭遇问题, Traceback:\n\n{tb_str}\n\n"
105
+ if retry_op > 0:
106
+ retry_op -= 1
107
+ mutable[0] += f"[Local Message] 重试中,请稍等 {retry_times_at_unknown_error-retry_op}/{retry_times_at_unknown_error}:\n\n"
108
+ if ("Rate limit reached" in tb_str) or ("Too Many Requests" in tb_str):
109
+ time.sleep(30)
110
+ time.sleep(5)
111
+ continue # 返回重试
112
+ else:
113
+ time.sleep(5)
114
+ return mutable[0] # 放弃
115
+
116
+ # 提交任务
117
+ future = executor.submit(_req_gpt, inputs, history, sys_prompt)
118
  while True:
119
  # yield一次以刷新前端页面
120
  time.sleep(refresh_interval)
 
123
  if future.done():
124
  break
125
  chatbot[-1] = [chatbot[-1][0], mutable[0]]
126
+ yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
 
 
127
 
128
+ final_result = future.result()
129
+ chatbot[-1] = [chatbot[-1][0], final_result]
130
+ yield from update_ui(chatbot=chatbot, history=[]) # 如果最后成功了,则删除报错信息
131
+ return final_result
132
 
133
+
134
+ def request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
135
+ inputs_array, inputs_show_user_array, llm_kwargs,
136
+ chatbot, history_array, sys_prompt_array,
137
+ refresh_interval=0.2, max_workers=-1, scroller_max_len=30,
138
+ handle_token_exceed=True, show_user_at_complete=False,
139
+ retry_times_at_unknown_error=2,
140
+ ):
141
+ """
142
+ Request GPT model using multiple threads with UI and high efficiency
143
+ 请求GPT模型的[多线程]版。
144
+ 具备以下功能:
145
+ 实时在UI上反馈远程数据流
146
+ 使用线程池,可调节线程池的大小避免openai的流量限制错误
147
+ 处理中途中止的情况
148
+ 网络等出问题时,会把traceback和已经接收的数据转入输出
149
+
150
+ 输入参数 Args (以_array结尾的输入变量都是列表,列表长度为子任务的数量,执行时,会把列表拆解,放到每个子线程中分别执行):
151
+ inputs_array (list): List of inputs (每个子任务的输入)
152
+ inputs_show_user_array (list): List of inputs to show user(每个子任务展现在报告中的输入,借助此参数,在汇总报告中隐藏啰嗦的真实输入,增强报告的可读性)
153
+ llm_kwargs: llm_kwargs参数
154
+ chatbot: chatbot (用户界面对话窗口句柄,用于数据流可视化)
155
+ history_array (list): List of chat history (历史对话输入,双层列表,第一层列表是子任务分解,第二层列表是对话历史)
156
+ sys_prompt_array (list): List of system prompts (系统输入,列表,用于输入给GPT的前提提示,比如你是翻译官怎样怎样)
157
+ refresh_interval (float, optional): Refresh interval for UI (default: 0.2) (刷新时间间隔频率,建议低于1,不可高于3,仅仅服务于视觉效果)
158
+ max_workers (int, optional): Maximum number of threads (default: see config.py) (最大线程数,如果子任务非常多,需要用此选项防止高频地请求openai导致错误)
159
+ scroller_max_len (int, optional): Maximum length for scroller (default: 30)(数据流的显示最后收到的多少个字符,仅仅服务于视觉效果)
160
+ handle_token_exceed (bool, optional): (是否在输入过长时,自动缩减文本)
161
+ handle_token_exceed:是否自动处理token溢出的情况,如果选择自动处理,则会在溢出时暴力截断,默认开启
162
+ show_user_at_complete (bool, optional): (在结束时,把完整输入-输出结果显示在聊天框)
163
+ retry_times_at_unknown_error:子任务失败时的重试次数
164
+
165
+ 输出 Returns:
166
+ list: List of GPT model responses (每个子任务的输出汇总,如果某个子任务出错,response中会携带traceback报错信息,方便调试和定位问题。)
167
+ """
168
+ import time, random
169
  from concurrent.futures import ThreadPoolExecutor
170
+ from request_llm.bridge_all import predict_no_ui_long_connection
171
  assert len(inputs_array) == len(history_array)
172
  assert len(inputs_array) == len(sys_prompt_array)
173
+ if max_workers == -1: # 读取配置文件
174
+ try: max_workers, = get_conf('DEFAULT_WORKER_NUM')
175
+ except: max_workers = 8
176
+ if max_workers <= 0 or max_workers >= 20: max_workers = 8
177
+ # 屏蔽掉 chatglm的多线程,可能会导致严重卡顿
178
+ if not (llm_kwargs['llm_model'].startswith('gpt-') or llm_kwargs['llm_model'].startswith('api2d-')):
179
+ max_workers = 1
180
+
181
  executor = ThreadPoolExecutor(max_workers=max_workers)
182
  n_frag = len(inputs_array)
183
  # 用户反馈
184
  chatbot.append(["请开始多线程操作。", ""])
185
+ yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
186
+ # 跨线程传递
187
+ mutable = [["", time.time(), "等待中"] for _ in range(n_frag)]
 
188
 
189
+ # 子线程任务
190
  def _req_gpt(index, inputs, history, sys_prompt):
191
+ gpt_say = ""
192
+ retry_op = retry_times_at_unknown_error
193
+ exceeded_cnt = 0
194
+ mutable[index][2] = "执行中"
195
+ while True:
196
+ # watchdog error
197
+ if len(mutable[index]) >= 2 and (time.time()-mutable[index][1]) > 5:
198
+ raise RuntimeError("检测到程序终止。")
199
+ try:
200
+ # 【第一种情况】:顺利完成
201
+ # time.sleep(10); raise RuntimeError("测试")
202
+ gpt_say = predict_no_ui_long_connection(
203
+ inputs=inputs, llm_kwargs=llm_kwargs, history=history,
204
+ sys_prompt=sys_prompt, observe_window=mutable[index], console_slience=True
205
+ )
206
+ mutable[index][2] = "已成功"
207
+ return gpt_say
208
+ except ConnectionAbortedError as token_exceeded_error:
209
+ # 【第二种情况】:Token溢出,
210
+ if handle_token_exceed:
211
+ exceeded_cnt += 1
212
+ # 【选择处理】 尝试计算比例,尽可能多地保留文本
213
+ from toolbox import get_reduce_token_percent
214
+ p_ratio, n_exceed = get_reduce_token_percent(str(token_exceeded_error))
215
+ MAX_TOKEN = 4096
216
+ EXCEED_ALLO = 512 + 512 * exceeded_cnt
217
+ inputs, history = input_clipping(inputs, history, max_token_limit=MAX_TOKEN-EXCEED_ALLO)
218
+ gpt_say += f'[Local Message] 警告,文本过长将进行截断,Token溢出数:{n_exceed}。\n\n'
219
+ mutable[index][2] = f"截断重试"
220
+ continue # 返回重试
221
+ else:
222
+ # 【选择放弃】
223
+ tb_str = '```\n' + traceback.format_exc() + '```'
224
+ gpt_say += f"[Local Message] 警告,线程{index}在执行过程中遭遇问题, Traceback:\n\n{tb_str}\n\n"
225
+ if len(mutable[index][0]) > 0: gpt_say += "此线程失败前收到的回答:\n\n" + mutable[index][0]
226
+ mutable[index][2] = "输入过长已放弃"
227
+ return gpt_say # 放弃
228
+ except:
229
+ # 【第三种情况】:其他错误
230
+ tb_str = '```\n' + traceback.format_exc() + '```'
231
+ print(tb_str)
232
+ gpt_say += f"[Local Message] 警告,线程{index}在执行过程中遭遇问题, Traceback:\n\n{tb_str}\n\n"
233
+ if len(mutable[index][0]) > 0: gpt_say += "此线程失败前收到的回答:\n\n" + mutable[index][0]
234
+ if retry_op > 0:
235
+ retry_op -= 1
236
+ wait = random.randint(5, 20)
237
+ if ("Rate limit reached" in tb_str) or ("Too Many Requests" in tb_str):
238
+ wait = wait * 3
239
+ fail_info = "OpenAI绑定信用卡可解除频率限制 "
240
+ else:
241
+ fail_info = ""
242
+ # 也许等待十几秒后,情况会好转
243
+ for i in range(wait):
244
+ mutable[index][2] = f"{fail_info}等待重试 {wait-i}"; time.sleep(1)
245
+ # 开始重试
246
+ mutable[index][2] = f"重试中 {retry_times_at_unknown_error-retry_op}/{retry_times_at_unknown_error}"
247
+ continue # 返回重试
248
+ else:
249
+ mutable[index][2] = "已失败"
250
+ wait = 5
251
+ time.sleep(5)
252
+ return gpt_say # 放弃
253
+
254
  # 异步任务开始
255
  futures = [executor.submit(_req_gpt, index, inputs, history, sys_prompt) for index, inputs, history, sys_prompt in zip(
256
  range(len(inputs_array)), inputs_array, history_array, sys_prompt_array)]
 
274
  replace('\n', '').replace('```', '...').replace(
275
  ' ', '.').replace('<br/>', '.....').replace('$', '.')+"`... ]"
276
  observe_win.append(print_something_really_funny)
277
+ # 在前端打印些好玩的东西
278
+ stat_str = ''.join([f'`{mutable[thread_index][2]}`: {obs}\n\n'
279
+ if not done else f'`{mutable[thread_index][2]}`\n\n'
280
+ for thread_index, done, obs in zip(range(len(worker_done)), worker_done, observe_win)])
281
+ # 在前端打印些好玩的东西
282
+ chatbot[-1] = [chatbot[-1][0], f'多线程操作已经开始,完成情况: \n\n{stat_str}' + ''.join(['.']*(cnt % 10+1))]
283
+ yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
284
+
285
  # 异步任务结束
286
  gpt_response_collection = []
287
  for inputs_show_user, f in zip(inputs_show_user_array, futures):
288
  gpt_res = f.result()
289
  gpt_response_collection.extend([inputs_show_user, gpt_res])
290
+
291
+ # 是否在结束时,在界面上显示结果
292
+ if show_user_at_complete:
293
+ for inputs_show_user, f in zip(inputs_show_user_array, futures):
294
+ gpt_res = f.result()
295
+ chatbot.append([inputs_show_user, gpt_res])
296
+ yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
297
+ time.sleep(0.3)
298
  return gpt_response_collection
299
 
300
 
 
316
  if get_token_fn(prev) < limit:
317
  break
318
  if cnt == 0:
 
319
  raise RuntimeError("存在一行极长的文本!")
320
  # print(len(post))
321
  # 列表递归接龙
 
328
  return cut(txt, must_break_at_empty_line=False)
329
 
330
 
331
+ def force_breakdown(txt, limit, get_token_fn):
332
+ """
333
+ 当无法用标点、空行分割时,我们用最暴力的方法切割
334
+ """
335
+ for i in reversed(range(len(txt))):
336
+ if get_token_fn(txt[:i]) < limit:
337
+ return txt[:i], txt[i:]
338
+ return "Tiktoken未知错误", "Tiktoken未知错误"
339
+
340
  def breakdown_txt_to_satisfy_token_limit_for_pdf(txt, get_token_fn, limit):
341
+ # 递归
342
+ def cut(txt_tocut, must_break_at_empty_line, break_anyway=False):
343
  if get_token_fn(txt_tocut) <= limit:
344
  return [txt_tocut]
345
  else:
 
351
  if must_break_at_empty_line:
352
  if lines[cnt] != "":
353
  continue
 
354
  prev = "\n".join(lines[:cnt])
355
  post = "\n".join(lines[cnt:])
356
  if get_token_fn(prev) < limit:
357
  break
358
  if cnt == 0:
359
+ if break_anyway:
360
+ prev, post = force_breakdown(txt_tocut, limit, get_token_fn)
361
+ else:
362
+ raise RuntimeError(f"存在一行极长的文本!{txt_tocut}")
363
  # print(len(post))
364
  # 列表递归接龙
365
  result = [prev]
366
+ result.extend(cut(post, must_break_at_empty_line, break_anyway=break_anyway))
367
  return result
368
  try:
369
+ # 第1次尝试,将双空行(\n\n)作为切分点
370
  return cut(txt, must_break_at_empty_line=True)
371
  except RuntimeError:
372
  try:
373
+ # 第2次尝试,将单空行(\n)作为切分点
374
  return cut(txt, must_break_at_empty_line=False)
375
  except RuntimeError:
376
+ try:
377
+ # 第3次尝试,将英文句号(.)作为切分点
378
+ res = cut(txt.replace('.', '。\n'), must_break_at_empty_line=False) # 这个中文的句号是故意的,作为一个标识而存在
379
+ return [r.replace('。\n', '.') for r in res]
380
+ except RuntimeError as e:
381
+ try:
382
+ # 第4次尝试,将中文句号(。)作为切分点
383
+ res = cut(txt.replace('。', '。。\n'), must_break_at_empty_line=False)
384
+ return [r.replace('。。\n', '。') for r in res]
385
+ except RuntimeError as e:
386
+ # 第5次尝试,没办法了,随便切一下敷衍吧
387
+ return cut(txt, must_break_at_empty_line=False, break_anyway=True)
388
+
389
+
390
+
391
+ def read_and_clean_pdf_text(fp):
392
+ """
393
+ 这个函数用于分割pdf,用了很多trick,逻辑较乱,效果奇好
394
+
395
+ **输入参数说明**
396
+ - `fp`:需要读取和清理文本的pdf文件路径
397
+
398
+ **输出参数说明**
399
+ - `meta_txt`:清理后的文本内容字符串
400
+ - `page_one_meta`:第一页清理后的文本内容列表
401
+
402
+ **函数功能**
403
+ 读取pdf文件并清理其中的文本内容,清理规则包括:
404
+ - 提取所有块元的文本信息,并合并为一个字符串
405
+ - 去除短块(字符数小于100)并替换为回车符
406
+ - 清理多余的空行
407
+ - 合并小写字母开头的段落块并替换为空格
408
+ - 清除重复的换行
409
+ - 将每个换行符替换为两个换行符,使每个段落之间有两个换行符分隔
410
+ """
411
+ import fitz, copy
412
+ import re
413
+ import numpy as np
414
+ from colorful import print亮黄, print亮绿
415
+ fc = 0 # Index 0 文本
416
+ fs = 1 # Index 1 字体
417
+ fb = 2 # Index 2 框框
418
+ REMOVE_FOOT_NOTE = True # 是否丢弃掉 不是正文的内容 (比正文字体小,如参考文献、脚注、图注等)
419
+ REMOVE_FOOT_FFSIZE_PERCENT = 0.95 # 小于正文的?时,判定为不是正文(有些文章的正文部分字体大小不是100%统一的,有肉眼不可见的小变化)
420
+ def primary_ffsize(l):
421
+ """
422
+ 提取文本块主字体
423
+ """
424
+ fsize_statiscs = {}
425
+ for wtf in l['spans']:
426
+ if wtf['size'] not in fsize_statiscs: fsize_statiscs[wtf['size']] = 0
427
+ fsize_statiscs[wtf['size']] += len(wtf['text'])
428
+ return max(fsize_statiscs, key=fsize_statiscs.get)
429
+
430
+ def ffsize_same(a,b):
431
+ """
432
+ 提取字体大小是否近似相等
433
+ """
434
+ return abs((a-b)/max(a,b)) < 0.02
435
+
436
+ with fitz.open(fp) as doc:
437
+ meta_txt = []
438
+ meta_font = []
439
+
440
+ meta_line = []
441
+ meta_span = []
442
+ ############################## <第 1 步,搜集初始信息> ##################################
443
+ for index, page in enumerate(doc):
444
+ # file_content += page.get_text()
445
+ text_areas = page.get_text("dict") # 获取页面上的文本信息
446
+ for t in text_areas['blocks']:
447
+ if 'lines' in t:
448
+ pf = 998
449
+ for l in t['lines']:
450
+ txt_line = "".join([wtf['text'] for wtf in l['spans']])
451
+ if len(txt_line) == 0: continue
452
+ pf = primary_ffsize(l)
453
+ meta_line.append([txt_line, pf, l['bbox'], l])
454
+ for wtf in l['spans']: # for l in t['lines']:
455
+ meta_span.append([wtf['text'], wtf['size'], len(wtf['text'])])
456
+ # meta_line.append(["NEW_BLOCK", pf])
457
+ # 块元提取 for each word segment with in line for each line cross-line words for each block
458
+ meta_txt.extend([" ".join(["".join([wtf['text'] for wtf in l['spans']]) for l in t['lines']]).replace(
459
+ '- ', '') for t in text_areas['blocks'] if 'lines' in t])
460
+ meta_font.extend([np.mean([np.mean([wtf['size'] for wtf in l['spans']])
461
+ for l in t['lines']]) for t in text_areas['blocks'] if 'lines' in t])
462
+ if index == 0:
463
+ page_one_meta = [" ".join(["".join([wtf['text'] for wtf in l['spans']]) for l in t['lines']]).replace(
464
+ '- ', '') for t in text_areas['blocks'] if 'lines' in t]
465
+
466
+ ############################## <第 2 步,获取正文主字体> ##################################
467
+ fsize_statiscs = {}
468
+ for span in meta_span:
469
+ if span[1] not in fsize_statiscs: fsize_statiscs[span[1]] = 0
470
+ fsize_statiscs[span[1]] += span[2]
471
+ main_fsize = max(fsize_statiscs, key=fsize_statiscs.get)
472
+ if REMOVE_FOOT_NOTE:
473
+ give_up_fize_threshold = main_fsize * REMOVE_FOOT_FFSIZE_PERCENT
474
+
475
+ ############################## <第 3 步,切分和重新整合> ##################################
476
+ mega_sec = []
477
+ sec = []
478
+ for index, line in enumerate(meta_line):
479
+ if index == 0:
480
+ sec.append(line[fc])
481
+ continue
482
+ if REMOVE_FOOT_NOTE:
483
+ if meta_line[index][fs] <= give_up_fize_threshold:
484
+ continue
485
+ if ffsize_same(meta_line[index][fs], meta_line[index-1][fs]):
486
+ # 尝试识别段落
487
+ if meta_line[index][fc].endswith('.') and\
488
+ (meta_line[index-1][fc] != 'NEW_BLOCK') and \
489
+ (meta_line[index][fb][2] - meta_line[index][fb][0]) < (meta_line[index-1][fb][2] - meta_line[index-1][fb][0]) * 0.7:
490
+ sec[-1] += line[fc]
491
+ sec[-1] += "\n\n"
492
+ else:
493
+ sec[-1] += " "
494
+ sec[-1] += line[fc]
495
+ else:
496
+ if (index+1 < len(meta_line)) and \
497
+ meta_line[index][fs] > main_fsize:
498
+ # 单行 + 字体大
499
+ mega_sec.append(copy.deepcopy(sec))
500
+ sec = []
501
+ sec.append("# " + line[fc])
502
+ else:
503
+ # 尝试识别section
504
+ if meta_line[index-1][fs] > meta_line[index][fs]:
505
+ sec.append("\n" + line[fc])
506
+ else:
507
+ sec.append(line[fc])
508
+ mega_sec.append(copy.deepcopy(sec))
509
+
510
+ finals = []
511
+ for ms in mega_sec:
512
+ final = " ".join(ms)
513
+ final = final.replace('- ', ' ')
514
+ finals.append(final)
515
+ meta_txt = finals
516
+
517
+ ############################## <第 4 步,乱七八糟的后处理> ##################################
518
+ def 把字符太少的块清除为回车(meta_txt):
519
+ for index, block_txt in enumerate(meta_txt):
520
+ if len(block_txt) < 100:
521
+ meta_txt[index] = '\n'
522
+ return meta_txt
523
+ meta_txt = 把字符太少的块清除为回车(meta_txt)
524
+
525
+ def 清理多余的空行(meta_txt):
526
+ for index in reversed(range(1, len(meta_txt))):
527
+ if meta_txt[index] == '\n' and meta_txt[index-1] == '\n':
528
+ meta_txt.pop(index)
529
+ return meta_txt
530
+ meta_txt = 清理多余的空行(meta_txt)
531
+
532
+ def 合并小写开头的段落块(meta_txt):
533
+ def starts_with_lowercase_word(s):
534
+ pattern = r"^[a-z]+"
535
+ match = re.match(pattern, s)
536
+ if match:
537
+ return True
538
+ else:
539
+ return False
540
+ for _ in range(100):
541
+ for index, block_txt in enumerate(meta_txt):
542
+ if starts_with_lowercase_word(block_txt):
543
+ if meta_txt[index-1] != '\n':
544
+ meta_txt[index-1] += ' '
545
+ else:
546
+ meta_txt[index-1] = ''
547
+ meta_txt[index-1] += meta_txt[index]
548
+ meta_txt[index] = '\n'
549
+ return meta_txt
550
+ meta_txt = 合并小写开头的段落块(meta_txt)
551
+ meta_txt = 清理多余的空行(meta_txt)
552
+
553
+ meta_txt = '\n'.join(meta_txt)
554
+ # 清除重复的换行
555
+ for _ in range(5):
556
+ meta_txt = meta_txt.replace('\n\n', '\n')
557
+
558
+ # 换行 -> 双换行
559
+ meta_txt = meta_txt.replace('\n', '\n\n')
560
+
561
+ ############################## <第 5 步,展示分割效果> ##################################
562
+ # for f in finals:
563
+ # print亮黄(f)
564
+ # print亮绿('***************************')
565
+
566
+ return meta_txt, page_one_meta
crazy_functions/下载arxiv论文翻译摘要.py CHANGED
@@ -1,7 +1,7 @@
1
- from request_llm.bridge_chatgpt import predict_no_ui
2
- from toolbox import CatchException, report_execption, write_results_to_file, predict_no_ui_but_counting_down, get_conf
3
  import re, requests, unicodedata, os
4
-
5
  def download_arxiv_(url_pdf):
6
  if 'arxiv.org' not in url_pdf:
7
  if ('.' in url_pdf) and ('/' not in url_pdf):
@@ -132,7 +132,7 @@ def get_name(_url_):
132
 
133
 
134
  @CatchException
135
- def 下载arxiv论文并翻译摘要(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
136
 
137
  CRAZY_FUNCTION_INFO = "下载arxiv论文并翻译摘要,函数插件作者[binary-husky]。正在提取摘要并下载PDF文档……"
138
  import glob
@@ -140,7 +140,7 @@ def 下载arxiv论文并翻译摘要(txt, top_p, temperature, chatbot, history,
140
 
141
  # 基本信息:功能、贡献者
142
  chatbot.append(["函数插件功能?", CRAZY_FUNCTION_INFO])
143
- yield chatbot, history, '正常'
144
 
145
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
146
  try:
@@ -149,7 +149,7 @@ def 下载arxiv论文并翻译摘要(txt, top_p, temperature, chatbot, history,
149
  report_execption(chatbot, history,
150
  a = f"解析项目: {txt}",
151
  b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pdfminer beautifulsoup4```。")
152
- yield chatbot, history, '正常'
153
  return
154
 
155
  # 清空历史,以免输入溢出
@@ -162,25 +162,33 @@ def 下载arxiv论文并翻译摘要(txt, top_p, temperature, chatbot, history,
162
  report_execption(chatbot, history,
163
  a = f"解析项目: {txt}",
164
  b = f"下载pdf文件未成功")
165
- yield chatbot, history, '正常'
166
  return
167
 
168
  # 翻译摘要等
169
  i_say = f"请你阅读以下学术论文相关的材料,提取摘要,翻译为中文。材料如下:{str(info)}"
170
  i_say_show_user = f'请你阅读以下学术论文相关的材料,提取摘要,翻译为中文。论文:{pdf_path}'
171
  chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
172
- yield chatbot, history, '正常'
173
  msg = '正常'
174
  # ** gpt request **
175
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[]) # 带超时倒计时
 
 
 
 
 
 
 
 
176
  chatbot[-1] = (i_say_show_user, gpt_say)
177
  history.append(i_say_show_user); history.append(gpt_say)
178
- yield chatbot, history, msg
179
  # 写入文件
180
  import shutil
181
  # 重置文件的创建时间
182
  shutil.copyfile(pdf_path, f'./gpt_log/{os.path.basename(pdf_path)}'); os.remove(pdf_path)
183
  res = write_results_to_file(history)
184
  chatbot.append(("完成了吗?", res + "\n\nPDF文件也已经下载"))
185
- yield chatbot, history, msg
186
 
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file, get_conf
3
  import re, requests, unicodedata, os
4
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
5
  def download_arxiv_(url_pdf):
6
  if 'arxiv.org' not in url_pdf:
7
  if ('.' in url_pdf) and ('/' not in url_pdf):
 
132
 
133
 
134
  @CatchException
135
+ def 下载arxiv论文并翻译摘要(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
136
 
137
  CRAZY_FUNCTION_INFO = "下载arxiv论文并翻译摘要,函数插件作者[binary-husky]。正在提取摘要并下载PDF文档……"
138
  import glob
 
140
 
141
  # 基本信息:功能、贡献者
142
  chatbot.append(["函数插件功能?", CRAZY_FUNCTION_INFO])
143
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
144
 
145
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
146
  try:
 
149
  report_execption(chatbot, history,
150
  a = f"解析项目: {txt}",
151
  b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pdfminer beautifulsoup4```。")
152
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
153
  return
154
 
155
  # 清空历史,以免输入溢出
 
162
  report_execption(chatbot, history,
163
  a = f"解析项目: {txt}",
164
  b = f"下载pdf文件未成功")
165
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
166
  return
167
 
168
  # 翻译摘要等
169
  i_say = f"请你阅读以下学术论文相关的材料,提取摘要,翻译为中文。材料如下:{str(info)}"
170
  i_say_show_user = f'请你阅读以下学术论文相关的材料,提取摘要,翻译为中文。论文:{pdf_path}'
171
  chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
172
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
173
  msg = '正常'
174
  # ** gpt request **
175
+ # 单线,获取文章meta信息
176
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
177
+ inputs=i_say,
178
+ inputs_show_user=i_say_show_user,
179
+ llm_kwargs=llm_kwargs,
180
+ chatbot=chatbot, history=[],
181
+ sys_prompt="Your job is to collect information from materials and translate to Chinese。",
182
+ )
183
+
184
  chatbot[-1] = (i_say_show_user, gpt_say)
185
  history.append(i_say_show_user); history.append(gpt_say)
186
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
187
  # 写入文件
188
  import shutil
189
  # 重置文件的创建时间
190
  shutil.copyfile(pdf_path, f'./gpt_log/{os.path.basename(pdf_path)}'); os.remove(pdf_path)
191
  res = write_results_to_file(history)
192
  chatbot.append(("完成了吗?", res + "\n\nPDF文件也已经下载"))
193
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
194
 
crazy_functions/代码重写为全英文_多线程.py CHANGED
@@ -1,5 +1,6 @@
1
  import threading
2
- from request_llm.bridge_chatgpt import predict_no_ui_long_connection
 
3
  from toolbox import CatchException, write_results_to_file, report_execption
4
  from .crazy_utils import breakdown_txt_to_satisfy_token_limit
5
 
@@ -22,22 +23,22 @@ def break_txt_into_half_at_some_linebreak(txt):
22
 
23
 
24
  @CatchException
25
- def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt, WEB_PORT):
26
  # 第1步:清空历史,以免输入溢出
27
  history = []
28
 
29
  # 第2步:尝试导入依赖,如果缺少依赖,则给出安装建议
30
  try:
31
- import openai, transformers
32
  except:
33
  report_execption(chatbot, history,
34
  a = f"解析项目: {txt}",
35
- b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade openai transformers```。")
36
- yield chatbot, history, '正常'
37
  return
38
 
39
  # 第3步:集合文件
40
- import time, glob, os, shutil, re, openai
41
  os.makedirs('gpt_log/generated_english_version', exist_ok=True)
42
  os.makedirs('gpt_log/generated_english_version/crazy_functions', exist_ok=True)
43
  file_manifest = [f for f in glob.glob('./*.py') if ('test_project' not in f) and ('gpt_log' not in f)] + \
@@ -48,21 +49,19 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
48
  # 第4步:随便显示点什么防止卡顿的感觉
49
  for index, fp in enumerate(file_manifest):
50
  # if 'test_project' in fp: continue
51
- with open(fp, 'r', encoding='utf-8') as f:
52
  file_content = f.read()
53
  i_say_show_user =f'[{index}/{len(file_manifest)}] 接下来请将以下代码中包含的所有中文转化为英文,只输出转化后的英文代码,请用代码块输出代码: {os.path.abspath(fp)}'
54
  i_say_show_user_buffer.append(i_say_show_user)
55
  chatbot.append((i_say_show_user, "[Local Message] 等待多线程操作,中间过程不予显示."))
56
- yield chatbot, history, '正常'
57
 
58
 
59
  # 第5步:Token限制下的截断与处理
60
  MAX_TOKEN = 3000
61
- from transformers import GPT2TokenizerFast
62
- print('加载tokenizer')
63
- tokenizer = GPT2TokenizerFast.from_pretrained("gpt2")
64
- get_token_fn = lambda txt: len(tokenizer(txt)["input_ids"])
65
- print('加载tokenizer结束')
66
 
67
 
68
  # 第6步:任务函数
@@ -72,7 +71,7 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
72
  if index > 10:
73
  time.sleep(60)
74
  print('Openai 限制免费用户每分钟20次请求,降低请求频率中。')
75
- with open(fp, 'r', encoding='utf-8') as f:
76
  file_content = f.read()
77
  i_say_template = lambda fp, file_content: f'接下来请将以下代码中包含的所有中文转化为英文,只输出代码,文件名是{fp},文件代码是 ```{file_content}```'
78
  try:
@@ -82,7 +81,7 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
82
  for file_content_partial in file_content_breakdown:
83
  i_say = i_say_template(fp, file_content_partial)
84
  # # ** gpt request **
85
- gpt_say_partial = predict_no_ui_long_connection(inputs=i_say, top_p=top_p, temperature=temperature, history=[], sys_prompt=sys_prompt, observe_window=observe_window[index])
86
  gpt_say_partial = extract_code_block_carefully(gpt_say_partial)
87
  gpt_say += gpt_say_partial
88
  mutable_return[index] = gpt_say
@@ -97,7 +96,7 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
97
  h.daemon = True
98
  h.start()
99
  chatbot.append(('开始了吗?', f'多线程操作已经开始'))
100
- yield chatbot, history, '正常'
101
 
102
  # 第8步:循环轮询各个线程是否执行完毕
103
  cnt = 0
@@ -113,7 +112,7 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
113
  stat = [f'执行中: {obs}\n\n' if alive else '已完成\n\n' for alive, obs in zip(th_alive, observe_win)]
114
  stat_str = ''.join(stat)
115
  chatbot[-1] = (chatbot[-1][0], f'多线程操作已经开始,完成情况: \n\n{stat_str}' + ''.join(['.']*(cnt%10+1)))
116
- yield chatbot, history, '正常'
117
 
118
  # 第9步:把结果写入文件
119
  for index, h in enumerate(handles):
@@ -130,10 +129,10 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
130
  shutil.copyfile(file_manifest[index], where_to_relocate)
131
  chatbot.append((i_say_show_user, f'[Local Message] 已完成{os.path.abspath(fp)}的转化,\n\n存入{os.path.abspath(where_to_relocate)}'))
132
  history.append(i_say_show_user); history.append(gpt_say)
133
- yield chatbot, history, '正常'
134
  time.sleep(1)
135
 
136
  # 第10步:备份一个文件
137
  res = write_results_to_file(history)
138
  chatbot.append(("生成一份任务执行报告", res))
139
- yield chatbot, history, '正常'
 
1
  import threading
2
+ from request_llm.bridge_all import predict_no_ui_long_connection
3
+ from toolbox import update_ui
4
  from toolbox import CatchException, write_results_to_file, report_execption
5
  from .crazy_utils import breakdown_txt_to_satisfy_token_limit
6
 
 
23
 
24
 
25
  @CatchException
26
+ def 全项目切换英文(txt, llm_kwargs, plugin_kwargs, chatbot, history, sys_prompt, web_port):
27
  # 第1步:清空历史,以免输入溢出
28
  history = []
29
 
30
  # 第2步:尝试导入依赖,如果缺少依赖,则给出安装建议
31
  try:
32
+ import tiktoken
33
  except:
34
  report_execption(chatbot, history,
35
  a = f"解析项目: {txt}",
36
+ b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
37
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
38
  return
39
 
40
  # 第3步:集合文件
41
+ import time, glob, os, shutil, re
42
  os.makedirs('gpt_log/generated_english_version', exist_ok=True)
43
  os.makedirs('gpt_log/generated_english_version/crazy_functions', exist_ok=True)
44
  file_manifest = [f for f in glob.glob('./*.py') if ('test_project' not in f) and ('gpt_log' not in f)] + \
 
49
  # 第4步:随便显示点什么防止卡顿的感觉
50
  for index, fp in enumerate(file_manifest):
51
  # if 'test_project' in fp: continue
52
+ with open(fp, 'r', encoding='utf-8', errors='replace') as f:
53
  file_content = f.read()
54
  i_say_show_user =f'[{index}/{len(file_manifest)}] 接下来请将以下代码中包含的所有中文转化为英文,只输出转化后的英文代码,请用代码块输出代码: {os.path.abspath(fp)}'
55
  i_say_show_user_buffer.append(i_say_show_user)
56
  chatbot.append((i_say_show_user, "[Local Message] 等待多线程操作,中间过程不予显示."))
57
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
58
 
59
 
60
  # 第5步:Token限制下的截断与处理
61
  MAX_TOKEN = 3000
62
+ from request_llm.bridge_all import model_info
63
+ enc = model_info["gpt-3.5-turbo"]['tokenizer']
64
+ def get_token_fn(txt): return len(enc.encode(txt, disallowed_special=()))
 
 
65
 
66
 
67
  # 第6步:任务函数
 
71
  if index > 10:
72
  time.sleep(60)
73
  print('Openai 限制免费用户每分钟20次请求,降低请求频率中。')
74
+ with open(fp, 'r', encoding='utf-8', errors='replace') as f:
75
  file_content = f.read()
76
  i_say_template = lambda fp, file_content: f'接下来请将以下代码中包含的所有中文转化为英文,只输出代码,文件名是{fp},文件代码是 ```{file_content}```'
77
  try:
 
81
  for file_content_partial in file_content_breakdown:
82
  i_say = i_say_template(fp, file_content_partial)
83
  # # ** gpt request **
84
+ gpt_say_partial = predict_no_ui_long_connection(inputs=i_say, llm_kwargs=llm_kwargs, history=[], sys_prompt=sys_prompt, observe_window=observe_window[index])
85
  gpt_say_partial = extract_code_block_carefully(gpt_say_partial)
86
  gpt_say += gpt_say_partial
87
  mutable_return[index] = gpt_say
 
96
  h.daemon = True
97
  h.start()
98
  chatbot.append(('开始了吗?', f'多线程操作已经开始'))
99
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
100
 
101
  # 第8步:循环轮询各个线程是否执行完毕
102
  cnt = 0
 
112
  stat = [f'执行中: {obs}\n\n' if alive else '已完成\n\n' for alive, obs in zip(th_alive, observe_win)]
113
  stat_str = ''.join(stat)
114
  chatbot[-1] = (chatbot[-1][0], f'多线程操作已经开始,完成情况: \n\n{stat_str}' + ''.join(['.']*(cnt%10+1)))
115
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
116
 
117
  # 第9步:把结果写入文件
118
  for index, h in enumerate(handles):
 
129
  shutil.copyfile(file_manifest[index], where_to_relocate)
130
  chatbot.append((i_say_show_user, f'[Local Message] 已完成{os.path.abspath(fp)}的转化,\n\n存入{os.path.abspath(where_to_relocate)}'))
131
  history.append(i_say_show_user); history.append(gpt_say)
132
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
133
  time.sleep(1)
134
 
135
  # 第10步:备份一个文件
136
  res = write_results_to_file(history)
137
  chatbot.append(("生成一份任务执行报告", res))
138
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
crazy_functions/对话历史存档.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from toolbox import CatchException, update_ui
2
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
3
+
4
+ def write_chat_to_file(chatbot, file_name=None):
5
+ """
6
+ 将对话记录history以Markdown格式写入文件中。如果没有指定文件名,则使用当前时间生成文件名。
7
+ """
8
+ import os
9
+ import time
10
+ if file_name is None:
11
+ file_name = 'chatGPT对话历史' + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + '.html'
12
+ os.makedirs('./gpt_log/', exist_ok=True)
13
+ with open(f'./gpt_log/{file_name}', 'w', encoding='utf8') as f:
14
+ for i, contents in enumerate(chatbot):
15
+ for content in contents:
16
+ try: # 这个bug没找到触发条件,暂时先这样顶一下
17
+ if type(content) != str: content = str(content)
18
+ except:
19
+ continue
20
+ f.write(content)
21
+ f.write('\n\n')
22
+ f.write('<hr color="red"> \n\n')
23
+
24
+ res = '对话历史写入:' + os.path.abspath(f'./gpt_log/{file_name}')
25
+ print(res)
26
+ return res
27
+
28
+ @CatchException
29
+ def 对话历史存档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
30
+ """
31
+ txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径
32
+ llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行
33
+ plugin_kwargs 插件模型的参数,暂时没有用武之地
34
+ chatbot 聊天显示框的句柄,用于显示给用户
35
+ history 聊天历史,前情提要
36
+ system_prompt 给gpt的静默提醒
37
+ web_port 当前软件运行的端口号
38
+ """
39
+
40
+ chatbot.append(("保存当前对话", f"[Local Message] {write_chat_to_file(chatbot)}"))
41
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
42
+
crazy_functions/总结word文档.py CHANGED
@@ -1,14 +1,13 @@
1
- from request_llm.bridge_chatgpt import predict_no_ui
2
- from toolbox import CatchException, report_execption, write_results_to_file, predict_no_ui_but_counting_down
 
3
  fast_debug = False
4
 
5
 
6
- def 解析docx(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt):
7
  import time, os
8
  # pip install python-docx 用于docx格式,跨平台
9
  # pip install pywin32 用于doc格式,仅支持Win平台
10
-
11
- print('begin analysis on:', file_manifest)
12
  for index, fp in enumerate(file_manifest):
13
  if fp.split(".")[-1] == "docx":
14
  from docx import Document
@@ -28,65 +27,66 @@ def 解析docx(file_manifest, project_folder, top_p, temperature, chatbot, histo
28
  word.Quit()
29
 
30
  print(file_content)
31
-
32
- prefix = "接下来请你逐文件分析下面的论文文件," if index == 0 else ""
33
  # private_upload里面的文件名在解压zip后容易出现乱码(rar和7z格式正常),故可以只分析文章内容,不输入文件名
34
- i_say = prefix + f'请对下面的文章片段用中英文做概述,文件名是{os.path.relpath(fp, project_folder)},' \
35
- f'文章内容是 ```{file_content}```'
36
- i_say_show_user = prefix + f'[{index+1}/{len(file_manifest)}] 假设你是论文审稿专家,请对下面的文章片段做概述: {os.path.abspath(fp)}'
37
- chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
38
- yield chatbot, history, '正常'
39
-
40
- if not fast_debug:
41
- msg = '正常'
42
- # ** gpt request **
43
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature,
44
- history=[]) # 带超时倒计时
 
 
 
 
 
 
 
 
 
 
 
45
  chatbot[-1] = (i_say_show_user, gpt_say)
46
- history.append(i_say_show_user);
47
- history.append(gpt_say)
48
- yield chatbot, history, msg
49
- if not fast_debug: time.sleep(2)
50
-
51
- """
52
- # 可按需启用
53
- i_say = f'根据你上述的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一篇英文的。'
54
- chatbot.append((i_say, "[Local Message] waiting gpt response."))
55
- yield chatbot, history, '正常'
56
-
57
-
58
- i_say = f'我想让你做一个论文写作导师。您的任务是使用人工智能工具(例如自然语言处理)提供有关如何改进其上述文章的反馈。' \
59
- f'您还应该利用您在有效写作技巧方面的修辞知识和经验来建议作者可以更好地以书面形式表达他们的想法和想法的方法。' \
60
- f'根据你之前的分析,提出建议'
61
- chatbot.append((i_say, "[Local Message] waiting gpt response."))
62
- yield chatbot, history, '正常'
63
-
64
- """
65
-
66
- if not fast_debug:
67
- msg = '正常'
68
- # ** gpt request **
69
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say, chatbot, top_p, temperature,
70
- history=history) # 带超时倒计时
71
-
72
- chatbot[-1] = (i_say, gpt_say)
73
- history.append(i_say)
74
- history.append(gpt_say)
75
- yield chatbot, history, msg
76
  res = write_results_to_file(history)
77
  chatbot.append(("完成了吗?", res))
78
- yield chatbot, history, msg
 
 
 
 
79
 
80
 
81
  @CatchException
82
- def 总结word文档(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
83
  import glob, os
84
 
85
  # 基本信息:功能、贡献者
86
  chatbot.append([
87
  "函数插件功能?",
88
  "批量总结Word文档。函数插件贡献者: JasonGuo1"])
89
- yield chatbot, history, '正常'
90
 
91
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
92
  try:
@@ -95,7 +95,7 @@ def 总结word文档(txt, top_p, temperature, chatbot, history, systemPromptTxt,
95
  report_execption(chatbot, history,
96
  a=f"解析项目: {txt}",
97
  b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade python-docx pywin32```。")
98
- yield chatbot, history, '正常'
99
  return
100
 
101
  # 清空历史,以免输入溢出
@@ -107,21 +107,21 @@ def 总结word文档(txt, top_p, temperature, chatbot, history, systemPromptTxt,
107
  else:
108
  if txt == "": txt = '空空如也的输入栏'
109
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
110
- yield chatbot, history, '正常'
111
  return
112
 
113
  # 搜索需要处理的文件清单
114
- file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.docx', recursive=True)] + \
115
- [f for f in glob.glob(f'{project_folder}/**/*.doc', recursive=True)]
116
- # [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)] + \
117
- # [f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)] + \
118
- # [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
119
 
120
  # 如果没找到任何文件
121
  if len(file_manifest) == 0:
122
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何.docx或doc文件: {txt}")
123
- yield chatbot, history, '正常'
124
  return
125
 
126
  # 开始正式执行任务
127
- yield from 解析docx(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file
3
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
4
  fast_debug = False
5
 
6
 
7
+ def 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
8
  import time, os
9
  # pip install python-docx 用于docx格式,跨平台
10
  # pip install pywin32 用于doc格式,仅支持Win平台
 
 
11
  for index, fp in enumerate(file_manifest):
12
  if fp.split(".")[-1] == "docx":
13
  from docx import Document
 
27
  word.Quit()
28
 
29
  print(file_content)
 
 
30
  # private_upload里面的文件名在解压zip后容易出现乱码(rar和7z格式正常),故可以只分析文章内容,不输入文件名
31
+ from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
32
+ from request_llm.bridge_all import model_info
33
+ max_token = model_info[llm_kwargs['llm_model']]['max_token']
34
+ TOKEN_LIMIT_PER_FRAGMENT = max_token * 3 // 4
35
+ paper_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
36
+ txt=file_content,
37
+ get_token_fn=model_info[llm_kwargs['llm_model']]['token_cnt'],
38
+ limit=TOKEN_LIMIT_PER_FRAGMENT
39
+ )
40
+ this_paper_history = []
41
+ for i, paper_frag in enumerate(paper_fragments):
42
+ i_say = f'请对下面的文章片段用中文做概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{paper_frag}```'
43
+ i_say_show_user = f'请对下面的文章片段做概述: {os.path.abspath(fp)}的第{i+1}/{len(paper_fragments)}个片段。'
44
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
45
+ inputs=i_say,
46
+ inputs_show_user=i_say_show_user,
47
+ llm_kwargs=llm_kwargs,
48
+ chatbot=chatbot,
49
+ history=[],
50
+ sys_prompt="总结文章。"
51
+ )
52
+
53
  chatbot[-1] = (i_say_show_user, gpt_say)
54
+ history.extend([i_say_show_user,gpt_say])
55
+ this_paper_history.extend([i_say_show_user,gpt_say])
56
+
57
+ # 已经对该文章的所有片段总结完毕,如果文章被切分了,
58
+ if len(paper_fragments) > 1:
59
+ i_say = f"根据以上的对话��总结文章{os.path.abspath(fp)}的主要内容。"
60
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
61
+ inputs=i_say,
62
+ inputs_show_user=i_say,
63
+ llm_kwargs=llm_kwargs,
64
+ chatbot=chatbot,
65
+ history=this_paper_history,
66
+ sys_prompt="总结文章。"
67
+ )
68
+
69
+ history.extend([i_say,gpt_say])
70
+ this_paper_history.extend([i_say,gpt_say])
71
+
 
 
 
 
 
 
 
 
 
 
 
 
72
  res = write_results_to_file(history)
73
  chatbot.append(("完成了吗?", res))
74
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
75
+
76
+ res = write_results_to_file(history)
77
+ chatbot.append(("所有文件都总结完成了吗?", res))
78
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
79
 
80
 
81
  @CatchException
82
+ def 总结word文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
83
  import glob, os
84
 
85
  # 基本信息:功能、贡献者
86
  chatbot.append([
87
  "函数插件功能?",
88
  "批量总结Word文档。函数插件贡献者: JasonGuo1"])
89
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
90
 
91
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
92
  try:
 
95
  report_execption(chatbot, history,
96
  a=f"解析项目: {txt}",
97
  b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade python-docx pywin32```。")
98
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
99
  return
100
 
101
  # 清空历史,以免输入溢出
 
107
  else:
108
  if txt == "": txt = '空空如也的输入栏'
109
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
110
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
111
  return
112
 
113
  # 搜索需要处理的文件清单
114
+ if txt.endswith('.docx') or txt.endswith('.doc'):
115
+ file_manifest = [txt]
116
+ else:
117
+ file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.docx', recursive=True)] + \
118
+ [f for f in glob.glob(f'{project_folder}/**/*.doc', recursive=True)]
119
 
120
  # 如果没找到任何文件
121
  if len(file_manifest) == 0:
122
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何.docx或doc文件: {txt}")
123
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
124
  return
125
 
126
  # 开始正式执行任务
127
+ yield from 解析docx(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
crazy_functions/批量Markdown翻译.py ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file
3
+ fast_debug = False
4
+
5
+ class PaperFileGroup():
6
+ def __init__(self):
7
+ self.file_paths = []
8
+ self.file_contents = []
9
+ self.sp_file_contents = []
10
+ self.sp_file_index = []
11
+ self.sp_file_tag = []
12
+
13
+ # count_token
14
+ from request_llm.bridge_all import model_info
15
+ enc = model_info["gpt-3.5-turbo"]['tokenizer']
16
+ def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
17
+ self.get_token_num = get_token_num
18
+
19
+ def run_file_split(self, max_token_limit=1900):
20
+ """
21
+ 将长文本分离开来
22
+ """
23
+ for index, file_content in enumerate(self.file_contents):
24
+ if self.get_token_num(file_content) < max_token_limit:
25
+ self.sp_file_contents.append(file_content)
26
+ self.sp_file_index.append(index)
27
+ self.sp_file_tag.append(self.file_paths[index])
28
+ else:
29
+ from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
30
+ segments = breakdown_txt_to_satisfy_token_limit_for_pdf(file_content, self.get_token_num, max_token_limit)
31
+ for j, segment in enumerate(segments):
32
+ self.sp_file_contents.append(segment)
33
+ self.sp_file_index.append(index)
34
+ self.sp_file_tag.append(self.file_paths[index] + f".part-{j}.md")
35
+
36
+ print('Segmentation: done')
37
+
38
+ def 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en'):
39
+ import time, os, re
40
+ from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
41
+
42
+ # <-------- 读取Markdown文件,删除其中的所有注释 ---------->
43
+ pfg = PaperFileGroup()
44
+
45
+ for index, fp in enumerate(file_manifest):
46
+ with open(fp, 'r', encoding='utf-8', errors='replace') as f:
47
+ file_content = f.read()
48
+ # 记录删除注释后的文本
49
+ pfg.file_paths.append(fp)
50
+ pfg.file_contents.append(file_content)
51
+
52
+ # <-------- 拆分过长的Markdown文件 ---------->
53
+ pfg.run_file_split(max_token_limit=1500)
54
+ n_split = len(pfg.sp_file_contents)
55
+
56
+ # <-------- 多线程润色开始 ---------->
57
+ if language == 'en->zh':
58
+ inputs_array = ["This is a Markdown file, translate it into Chinese, do not modify any existing Markdown commands:" +
59
+ f"\n\n{frag}" for frag in pfg.sp_file_contents]
60
+ inputs_show_user_array = [f"翻译 {f}" for f in pfg.sp_file_tag]
61
+ sys_prompt_array = ["You are a professional academic paper translator." for _ in range(n_split)]
62
+ elif language == 'zh->en':
63
+ inputs_array = [f"This is a Markdown file, translate it into English, do not modify any existing Markdown commands:" +
64
+ f"\n\n{frag}" for frag in pfg.sp_file_contents]
65
+ inputs_show_user_array = [f"翻译 {f}" for f in pfg.sp_file_tag]
66
+ sys_prompt_array = ["You are a professional academic paper translator." for _ in range(n_split)]
67
+
68
+ gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
69
+ inputs_array=inputs_array,
70
+ inputs_show_user_array=inputs_show_user_array,
71
+ llm_kwargs=llm_kwargs,
72
+ chatbot=chatbot,
73
+ history_array=[[""] for _ in range(n_split)],
74
+ sys_prompt_array=sys_prompt_array,
75
+ # max_workers=5, # OpenAI所允许的最大并行过载
76
+ scroller_max_len = 80
77
+ )
78
+
79
+ # <-------- 整理结果,退出 ---------->
80
+ create_report_file_name = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + f"-chatgpt.polish.md"
81
+ res = write_results_to_file(gpt_response_collection, file_name=create_report_file_name)
82
+ history = gpt_response_collection
83
+ chatbot.append((f"{fp}完成了吗?", res))
84
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
85
+
86
+
87
+
88
+
89
+
90
+ @CatchException
91
+ def Markdown英译中(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
92
+ # 基本信息:功能、贡献者
93
+ chatbot.append([
94
+ "函数插件功能?",
95
+ "对整个Markdown项目进行翻译。函数插件贡献者: Binary-Husky"])
96
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
97
+
98
+ # 尝试导入依赖,如果缺少依赖,则给出安装建议
99
+ try:
100
+ import tiktoken
101
+ except:
102
+ report_execption(chatbot, history,
103
+ a=f"解析项目: {txt}",
104
+ b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
105
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
106
+ return
107
+ history = [] # 清空历史,以免输入溢出
108
+ import glob, os
109
+ if os.path.exists(txt):
110
+ project_folder = txt
111
+ else:
112
+ if txt == "": txt = '空空如也的输入栏'
113
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
114
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
115
+ return
116
+ file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.md', recursive=True)]
117
+ if len(file_manifest) == 0:
118
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.md文件: {txt}")
119
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
120
+ return
121
+ yield from 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='en->zh')
122
+
123
+
124
+
125
+
126
+
127
+ @CatchException
128
+ def Markdown中译英(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
129
+ # 基本信息:功能、贡献者
130
+ chatbot.append([
131
+ "函数插件功能?",
132
+ "对整个Markdown项目进行翻译。函数插件贡献者: Binary-Husky"])
133
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
134
+
135
+ # 尝试导入依赖,如果缺少依赖,则给出安装建议
136
+ try:
137
+ import tiktoken
138
+ except:
139
+ report_execption(chatbot, history,
140
+ a=f"解析项目: {txt}",
141
+ b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade tiktoken```。")
142
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
143
+ return
144
+ history = [] # 清空历史,以免输入溢出
145
+ import glob, os
146
+ if os.path.exists(txt):
147
+ project_folder = txt
148
+ else:
149
+ if txt == "": txt = '空空如也的输入栏'
150
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
151
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
152
+ return
153
+ if txt.endswith('.md'):
154
+ file_manifest = [txt]
155
+ else:
156
+ file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.md', recursive=True)]
157
+ if len(file_manifest) == 0:
158
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.md文件: {txt}")
159
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
160
+ return
161
+ yield from 多文件翻译(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, language='zh->en')
crazy_functions/批量总结PDF文档.py CHANGED
@@ -1,8 +1,9 @@
1
- from request_llm.bridge_chatgpt import predict_no_ui
2
- from toolbox import CatchException, report_execption, write_results_to_file, predict_no_ui_but_counting_down
3
  import re
4
  import unicodedata
5
  fast_debug = False
 
6
 
7
  def is_paragraph_break(match):
8
  """
@@ -57,7 +58,7 @@ def clean_text(raw_text):
57
 
58
  return final_text.strip()
59
 
60
- def 解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt):
61
  import time, glob, os, fitz
62
  print('begin analysis on:', file_manifest)
63
  for index, fp in enumerate(file_manifest):
@@ -72,49 +73,60 @@ def 解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, histor
72
  i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
73
  i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
74
  chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
75
- print('[1] yield chatbot, history')
76
- yield chatbot, history, '正常'
77
 
78
  if not fast_debug:
79
  msg = '正常'
80
  # ** gpt request **
81
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[]) # 带超时倒计时
 
 
 
 
 
 
 
 
82
 
83
- print('[2] end gpt req')
84
  chatbot[-1] = (i_say_show_user, gpt_say)
85
  history.append(i_say_show_user); history.append(gpt_say)
86
- print('[3] yield chatbot, history')
87
- yield chatbot, history, msg
88
- print('[4] next')
89
  if not fast_debug: time.sleep(2)
90
 
91
  all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
92
  i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
93
  chatbot.append((i_say, "[Local Message] waiting gpt response."))
94
- yield chatbot, history, '正常'
95
 
96
  if not fast_debug:
97
  msg = '正常'
98
  # ** gpt request **
99
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say, chatbot, top_p, temperature, history=history) # 带超时倒计时
 
 
 
 
 
 
 
100
 
101
  chatbot[-1] = (i_say, gpt_say)
102
  history.append(i_say); history.append(gpt_say)
103
- yield chatbot, history, msg
104
  res = write_results_to_file(history)
105
  chatbot.append(("完成了吗?", res))
106
- yield chatbot, history, msg
107
 
108
 
109
  @CatchException
110
- def 批量总结PDF文档(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
111
  import glob, os
112
 
113
  # 基本信息:功能、贡献者
114
  chatbot.append([
115
  "函数插件功能?",
116
  "批量总结PDF文档。函数插件贡献者: ValeriaWong,Eralien"])
117
- yield chatbot, history, '正常'
118
 
119
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
120
  try:
@@ -123,7 +135,7 @@ def 批量总结PDF文档(txt, top_p, temperature, chatbot, history, systemPromp
123
  report_execption(chatbot, history,
124
  a = f"解析项目: {txt}",
125
  b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
126
- yield chatbot, history, '正常'
127
  return
128
 
129
  # 清空历史,以免输入溢出
@@ -135,7 +147,7 @@ def 批量总结PDF文档(txt, top_p, temperature, chatbot, history, systemPromp
135
  else:
136
  if txt == "": txt = '空空如也的输入栏'
137
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
138
- yield chatbot, history, '正常'
139
  return
140
 
141
  # 搜索需要处理的文件清单
@@ -147,8 +159,8 @@ def 批量总结PDF文档(txt, top_p, temperature, chatbot, history, systemPromp
147
  # 如果没找到任何文件
148
  if len(file_manifest) == 0:
149
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex或.pdf文件: {txt}")
150
- yield chatbot, history, '正常'
151
  return
152
 
153
  # 开始正式执行任务
154
- yield from 解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file
3
  import re
4
  import unicodedata
5
  fast_debug = False
6
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
7
 
8
  def is_paragraph_break(match):
9
  """
 
58
 
59
  return final_text.strip()
60
 
61
+ def 解析PDF(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
62
  import time, glob, os, fitz
63
  print('begin analysis on:', file_manifest)
64
  for index, fp in enumerate(file_manifest):
 
73
  i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
74
  i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
75
  chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
76
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
 
77
 
78
  if not fast_debug:
79
  msg = '正常'
80
  # ** gpt request **
81
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
82
+ inputs=i_say,
83
+ inputs_show_user=i_say_show_user,
84
+ llm_kwargs=llm_kwargs,
85
+ chatbot=chatbot,
86
+ history=[],
87
+ sys_prompt="总结文章。"
88
+ ) # 带超时倒计时
89
+
90
 
 
91
  chatbot[-1] = (i_say_show_user, gpt_say)
92
  history.append(i_say_show_user); history.append(gpt_say)
93
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
 
 
94
  if not fast_debug: time.sleep(2)
95
 
96
  all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
97
  i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
98
  chatbot.append((i_say, "[Local Message] waiting gpt response."))
99
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
100
 
101
  if not fast_debug:
102
  msg = '正常'
103
  # ** gpt request **
104
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
105
+ inputs=i_say,
106
+ inputs_show_user=i_say,
107
+ llm_kwargs=llm_kwargs,
108
+ chatbot=chatbot,
109
+ history=history,
110
+ sys_prompt="总结文章。"
111
+ ) # 带超时倒计时
112
 
113
  chatbot[-1] = (i_say, gpt_say)
114
  history.append(i_say); history.append(gpt_say)
115
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
116
  res = write_results_to_file(history)
117
  chatbot.append(("完成了吗?", res))
118
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
119
 
120
 
121
  @CatchException
122
+ def 批量总结PDF文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
123
  import glob, os
124
 
125
  # 基本信息:功能、贡献者
126
  chatbot.append([
127
  "函数插件功能?",
128
  "批量总结PDF文档。函数插件贡献者: ValeriaWong,Eralien"])
129
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
130
 
131
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
132
  try:
 
135
  report_execption(chatbot, history,
136
  a = f"解析项目: {txt}",
137
  b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
138
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
139
  return
140
 
141
  # 清空历史,以免输入溢出
 
147
  else:
148
  if txt == "": txt = '空空如也的输入栏'
149
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
150
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
151
  return
152
 
153
  # 搜索需要处理的文件清单
 
159
  # 如果没找到任何文件
160
  if len(file_manifest) == 0:
161
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex或.pdf文件: {txt}")
162
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
163
  return
164
 
165
  # 开始正式执行任务
166
+ yield from 解析PDF(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
crazy_functions/批量总结PDF文档pdfminer.py CHANGED
@@ -1,5 +1,6 @@
1
- from request_llm.bridge_chatgpt import predict_no_ui
2
- from toolbox import CatchException, report_execption, write_results_to_file, predict_no_ui_but_counting_down
 
3
 
4
  fast_debug = False
5
 
@@ -61,13 +62,13 @@ def readPdf(pdfPath):
61
  return outTextList
62
 
63
 
64
- def 解析Paper(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt):
65
  import time, glob, os
66
  from bs4 import BeautifulSoup
67
  print('begin analysis on:', file_manifest)
68
  for index, fp in enumerate(file_manifest):
69
  if ".tex" in fp:
70
- with open(fp, 'r', encoding='utf-8') as f:
71
  file_content = f.read()
72
  if ".pdf" in fp.lower():
73
  file_content = readPdf(fp)
@@ -77,43 +78,51 @@ def 解析Paper(file_manifest, project_folder, top_p, temperature, chatbot, hist
77
  i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
78
  i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
79
  chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
80
- print('[1] yield chatbot, history')
81
- yield chatbot, history, '正常'
82
 
83
  if not fast_debug:
84
  msg = '正常'
85
  # ** gpt request **
86
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[]) # 带超时倒计时
87
-
88
- print('[2] end gpt req')
 
 
 
 
 
89
  chatbot[-1] = (i_say_show_user, gpt_say)
90
  history.append(i_say_show_user); history.append(gpt_say)
91
- print('[3] yield chatbot, history')
92
- yield chatbot, history, msg
93
- print('[4] next')
94
  if not fast_debug: time.sleep(2)
95
 
96
  all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
97
  i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
98
  chatbot.append((i_say, "[Local Message] waiting gpt response."))
99
- yield chatbot, history, '正常'
100
 
101
  if not fast_debug:
102
  msg = '正常'
103
  # ** gpt request **
104
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say, chatbot, top_p, temperature, history=history) # 带超时倒计时
105
-
 
 
 
 
 
 
106
  chatbot[-1] = (i_say, gpt_say)
107
  history.append(i_say); history.append(gpt_say)
108
- yield chatbot, history, msg
109
  res = write_results_to_file(history)
110
  chatbot.append(("完成了吗?", res))
111
- yield chatbot, history, msg
112
 
113
 
114
 
115
  @CatchException
116
- def 批量总结PDF文档pdfminer(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
117
  history = [] # 清空历史,以免输入溢出
118
  import glob, os
119
 
@@ -121,7 +130,7 @@ def 批量总结PDF文档pdfminer(txt, top_p, temperature, chatbot, history, sys
121
  chatbot.append([
122
  "函数插件功能?",
123
  "批量总结PDF文档,此版本使用pdfminer插件,带token约简功能。函数插件贡献者: Euclid-Jie。"])
124
- yield chatbot, history, '正常'
125
 
126
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
127
  try:
@@ -130,14 +139,14 @@ def 批量总结PDF文档pdfminer(txt, top_p, temperature, chatbot, history, sys
130
  report_execption(chatbot, history,
131
  a = f"解析项目: {txt}",
132
  b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pdfminer beautifulsoup4```。")
133
- yield chatbot, history, '正常'
134
  return
135
  if os.path.exists(txt):
136
  project_folder = txt
137
  else:
138
  if txt == "": txt = '空空如也的输入栏'
139
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
140
- yield chatbot, history, '正常'
141
  return
142
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)] + \
143
  [f for f in glob.glob(f'{project_folder}/**/*.pdf', recursive=True)] # + \
@@ -145,7 +154,7 @@ def 批量总结PDF文档pdfminer(txt, top_p, temperature, chatbot, history, sys
145
  # [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
146
  if len(file_manifest) == 0:
147
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex或pdf文件: {txt}")
148
- yield chatbot, history, '正常'
149
  return
150
- yield from 解析Paper(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
151
 
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file
3
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
4
 
5
  fast_debug = False
6
 
 
62
  return outTextList
63
 
64
 
65
+ def 解析Paper(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
66
  import time, glob, os
67
  from bs4 import BeautifulSoup
68
  print('begin analysis on:', file_manifest)
69
  for index, fp in enumerate(file_manifest):
70
  if ".tex" in fp:
71
+ with open(fp, 'r', encoding='utf-8', errors='replace') as f:
72
  file_content = f.read()
73
  if ".pdf" in fp.lower():
74
  file_content = readPdf(fp)
 
78
  i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
79
  i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
80
  chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
81
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
 
82
 
83
  if not fast_debug:
84
  msg = '正常'
85
  # ** gpt request **
86
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
87
+ inputs=i_say,
88
+ inputs_show_user=i_say_show_user,
89
+ llm_kwargs=llm_kwargs,
90
+ chatbot=chatbot,
91
+ history=[],
92
+ sys_prompt="总结文章。"
93
+ ) # 带超时倒计时
94
  chatbot[-1] = (i_say_show_user, gpt_say)
95
  history.append(i_say_show_user); history.append(gpt_say)
96
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
 
 
97
  if not fast_debug: time.sleep(2)
98
 
99
  all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
100
  i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
101
  chatbot.append((i_say, "[Local Message] waiting gpt response."))
102
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
103
 
104
  if not fast_debug:
105
  msg = '正常'
106
  # ** gpt request **
107
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
108
+ inputs=i_say,
109
+ inputs_show_user=i_say,
110
+ llm_kwargs=llm_kwargs,
111
+ chatbot=chatbot,
112
+ history=history,
113
+ sys_prompt="总结文章。"
114
+ ) # 带超时倒计时
115
  chatbot[-1] = (i_say, gpt_say)
116
  history.append(i_say); history.append(gpt_say)
117
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
118
  res = write_results_to_file(history)
119
  chatbot.append(("完成了吗?", res))
120
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
121
 
122
 
123
 
124
  @CatchException
125
+ def 批量总结PDF文档pdfminer(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
126
  history = [] # 清空历史,以免输入溢出
127
  import glob, os
128
 
 
130
  chatbot.append([
131
  "函数插件功能?",
132
  "批量总结PDF文档,此版本使用pdfminer插件,带token约简功能。函数插件贡献者: Euclid-Jie。"])
133
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
134
 
135
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
136
  try:
 
139
  report_execption(chatbot, history,
140
  a = f"解析项目: {txt}",
141
  b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pdfminer beautifulsoup4```。")
142
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
143
  return
144
  if os.path.exists(txt):
145
  project_folder = txt
146
  else:
147
  if txt == "": txt = '空空如也的输入栏'
148
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
149
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
150
  return
151
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)] + \
152
  [f for f in glob.glob(f'{project_folder}/**/*.pdf', recursive=True)] # + \
 
154
  # [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
155
  if len(file_manifest) == 0:
156
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex或pdf文件: {txt}")
157
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
158
  return
159
+ yield from 解析Paper(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
160
 
crazy_functions/批量翻译PDF文档_多线程.py CHANGED
@@ -1,102 +1,20 @@
1
  from toolbox import CatchException, report_execption, write_results_to_file
 
2
  from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
3
  from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
4
-
5
-
6
- def read_and_clean_pdf_text(fp):
7
- """
8
- **输入参数说明**
9
- - `fp`:需要读取和清理文本的pdf文件路径
10
-
11
- **输出参数说明**
12
- - `meta_txt`:清理后的文本内容字符串
13
- - `page_one_meta`:第一页清理后的文本内容列表
14
-
15
- **函数功能**
16
- 读取pdf文件并清理其中的文本内容,清理规则包括:
17
- - 提取所有块元的文本信息,并合并为一个字符串
18
- - 去除短块(字符数小于100)并替换为回车符
19
- - 清理多余的空行
20
- - 合并小写字母开头的段落块并替换为空格
21
- - 清除重复的换行
22
- - 将每个换行符替换为两个换行符,使每个段落之间有两个换行符分隔
23
- """
24
- import fitz
25
- import re
26
- import numpy as np
27
- # file_content = ""
28
- with fitz.open(fp) as doc:
29
- meta_txt = []
30
- meta_font = []
31
- for index, page in enumerate(doc):
32
- # file_content += page.get_text()
33
- text_areas = page.get_text("dict") # 获取页面上的文本信息
34
-
35
- # 块元提取 for each word segment with in line for each line cross-line words for each block
36
- meta_txt.extend([" ".join(["".join([wtf['text'] for wtf in l['spans']]) for l in t['lines']]).replace(
37
- '- ', '') for t in text_areas['blocks'] if 'lines' in t])
38
- meta_font.extend([np.mean([np.mean([wtf['size'] for wtf in l['spans']])
39
- for l in t['lines']]) for t in text_areas['blocks'] if 'lines' in t])
40
- if index == 0:
41
- page_one_meta = [" ".join(["".join([wtf['text'] for wtf in l['spans']]) for l in t['lines']]).replace(
42
- '- ', '') for t in text_areas['blocks'] if 'lines' in t]
43
-
44
- def 把字符太少的块清除为回车(meta_txt):
45
- for index, block_txt in enumerate(meta_txt):
46
- if len(block_txt) < 100:
47
- meta_txt[index] = '\n'
48
- return meta_txt
49
- meta_txt = 把字符太少的块清除为回车(meta_txt)
50
-
51
- def 清理多余的空行(meta_txt):
52
- for index in reversed(range(1, len(meta_txt))):
53
- if meta_txt[index] == '\n' and meta_txt[index-1] == '\n':
54
- meta_txt.pop(index)
55
- return meta_txt
56
- meta_txt = 清理多余的空行(meta_txt)
57
-
58
- def 合并小写开头的段落块(meta_txt):
59
- def starts_with_lowercase_word(s):
60
- pattern = r"^[a-z]+"
61
- match = re.match(pattern, s)
62
- if match:
63
- return True
64
- else:
65
- return False
66
- for _ in range(100):
67
- for index, block_txt in enumerate(meta_txt):
68
- if starts_with_lowercase_word(block_txt):
69
- if meta_txt[index-1] != '\n':
70
- meta_txt[index-1] += ' '
71
- else:
72
- meta_txt[index-1] = ''
73
- meta_txt[index-1] += meta_txt[index]
74
- meta_txt[index] = '\n'
75
- return meta_txt
76
- meta_txt = 合并小写开头的段落块(meta_txt)
77
- meta_txt = 清理多余的空行(meta_txt)
78
-
79
- meta_txt = '\n'.join(meta_txt)
80
- # 清除重复的换行
81
- for _ in range(5):
82
- meta_txt = meta_txt.replace('\n\n', '\n')
83
-
84
- # 换行 -> 双换行
85
- meta_txt = meta_txt.replace('\n', '\n\n')
86
-
87
- return meta_txt, page_one_meta
88
-
89
 
90
  @CatchException
91
- def 批量翻译PDF文档(txt, top_p, temperature, chatbot, history, sys_prompt, WEB_PORT):
92
  import glob
93
  import os
94
 
95
  # 基本信息:功能、贡献者
96
  chatbot.append([
97
  "函数插件功能?",
98
- "批量总结PDF文档。函数插件贡献者: Binary-Husky(二进制哈士奇)"])
99
- yield chatbot, history, '正常'
100
 
101
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
102
  try:
@@ -106,7 +24,7 @@ def 批量翻译PDF文档(txt, top_p, temperature, chatbot, history, sys_prompt,
106
  report_execption(chatbot, history,
107
  a=f"解析项目: {txt}",
108
  b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf tiktoken```。")
109
- yield chatbot, history, '正常'
110
  return
111
 
112
  # 清空历史,以免输入溢出
@@ -120,7 +38,7 @@ def 批量翻译PDF文档(txt, top_p, temperature, chatbot, history, sys_prompt,
120
  txt = '空空如也的输入栏'
121
  report_execption(chatbot, history,
122
  a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
123
- yield chatbot, history, '正常'
124
  return
125
 
126
  # 搜索需要处理的文件清单
@@ -131,63 +49,73 @@ def 批量翻译PDF文档(txt, top_p, temperature, chatbot, history, sys_prompt,
131
  if len(file_manifest) == 0:
132
  report_execption(chatbot, history,
133
  a=f"解析项目: {txt}", b=f"找不到任何.tex或.pdf文件: {txt}")
134
- yield chatbot, history, '正常'
135
  return
136
 
137
  # 开始正式执行任务
138
- yield from 解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, history, sys_prompt)
139
 
140
 
141
- def 解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, history, sys_prompt):
142
  import os
143
  import tiktoken
144
- TOKEN_LIMIT_PER_FRAGMENT = 1600
145
  generated_conclusion_files = []
146
  for index, fp in enumerate(file_manifest):
 
147
  # 读取PDF文件
148
  file_content, page_one = read_and_clean_pdf_text(fp)
 
149
  # 递归地切割PDF文件
150
  from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
151
- enc = tiktoken.get_encoding("gpt2")
152
- def get_token_num(txt): return len(enc.encode(txt))
153
- # 分解文本
154
  paper_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
155
  txt=file_content, get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT)
156
  page_one_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
157
  txt=str(page_one), get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT//4)
158
- # 为了更好的效果,我们剥离Introduction之后的部分
159
- paper_meta = page_one_fragments[0].split('introduction')[0].split(
160
- 'Introduction')[0].split('INTRODUCTION')[0]
 
161
  # 单线,获取文章meta信息
162
  paper_meta_info = yield from request_gpt_model_in_new_thread_with_ui_alive(
163
  inputs=f"以下是一篇学术论文的基础信息,请从中提取出“标题”、“收录会议或期刊”、“作者”、“摘要”、“编号”、“作者邮箱”这六个部分。请用markdown格式输出,最后用中文翻译摘要部分。请提取:{paper_meta}",
164
  inputs_show_user=f"请从{fp}中提取出“标题”、“收录会议或期刊”等基本信息。",
165
- top_p=top_p, temperature=temperature,
166
  chatbot=chatbot, history=[],
167
  sys_prompt="Your job is to collect information from materials。",
168
  )
 
169
  # 多线,翻译
170
  gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
171
  inputs_array=[
172
- f"以下是你需要翻译的文章段落:\n{frag}" for frag in paper_fragments],
173
- inputs_show_user_array=[f"" for _ in paper_fragments],
174
- top_p=top_p, temperature=temperature,
175
  chatbot=chatbot,
176
  history_array=[[paper_meta] for _ in paper_fragments],
177
  sys_prompt_array=[
178
- "请你作为一个学术翻译,把整个段落翻译成中文,要求语言简洁,禁止重复输出原文。" for _ in paper_fragments],
179
- max_workers=16 # OpenAI所允许的最大并行过载
180
  )
181
 
182
- final = ["", paper_meta_info + '\n\n---\n\n---\n\n---\n\n']
 
 
 
 
 
 
183
  final.extend(gpt_response_collection)
184
  create_report_file_name = f"{os.path.basename(fp)}.trans.md"
185
  res = write_results_to_file(final, file_name=create_report_file_name)
186
- generated_conclusion_files.append(
187
- f'./gpt_log/{create_report_file_name}')
 
188
  chatbot.append((f"{fp}完成了吗?", res))
189
- msg = "完成"
190
- yield chatbot, history, msg
191
 
192
  # 准备文件的下载
193
  import shutil
@@ -200,4 +128,4 @@ def 解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, histor
200
  if os.path.exists(pdf_path):
201
  os.remove(pdf_path)
202
  chatbot.append(("给出输出文件清单", str(generated_conclusion_files)))
203
- yield chatbot, history, msg
 
1
  from toolbox import CatchException, report_execption, write_results_to_file
2
+ from toolbox import update_ui
3
  from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
4
  from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
5
+ from .crazy_utils import read_and_clean_pdf_text
6
+ from colorful import *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
  @CatchException
9
+ def 批量翻译PDF文档(txt, llm_kwargs, plugin_kwargs, chatbot, history, sys_prompt, web_port):
10
  import glob
11
  import os
12
 
13
  # 基本信息:功能、贡献者
14
  chatbot.append([
15
  "函数插件功能?",
16
+ "批量翻译PDF文档。函数插件贡献者: Binary-Husky"])
17
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
18
 
19
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
20
  try:
 
24
  report_execption(chatbot, history,
25
  a=f"解析项目: {txt}",
26
  b=f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf tiktoken```。")
27
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
28
  return
29
 
30
  # 清空历史,以免输入溢出
 
38
  txt = '空空如也的输入栏'
39
  report_execption(chatbot, history,
40
  a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
41
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
42
  return
43
 
44
  # 搜索需要处理的文件清单
 
49
  if len(file_manifest) == 0:
50
  report_execption(chatbot, history,
51
  a=f"解析项目: {txt}", b=f"找不到任何.tex或.pdf文件: {txt}")
52
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
53
  return
54
 
55
  # 开始正式执行任务
56
+ yield from 解析PDF(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, sys_prompt)
57
 
58
 
59
+ def 解析PDF(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, sys_prompt):
60
  import os
61
  import tiktoken
62
+ TOKEN_LIMIT_PER_FRAGMENT = 1280
63
  generated_conclusion_files = []
64
  for index, fp in enumerate(file_manifest):
65
+
66
  # 读取PDF文件
67
  file_content, page_one = read_and_clean_pdf_text(fp)
68
+
69
  # 递归地切割PDF文件
70
  from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
71
+ from request_llm.bridge_all import model_info
72
+ enc = model_info["gpt-3.5-turbo"]['tokenizer']
73
+ def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
74
  paper_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
75
  txt=file_content, get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT)
76
  page_one_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
77
  txt=str(page_one), get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT//4)
78
+
79
+ # 为了更好的效果,我们剥离Introduction之后的部分(如果有)
80
+ paper_meta = page_one_fragments[0].split('introduction')[0].split('Introduction')[0].split('INTRODUCTION')[0]
81
+
82
  # 单线,获取文章meta信息
83
  paper_meta_info = yield from request_gpt_model_in_new_thread_with_ui_alive(
84
  inputs=f"以下是一篇学术论文的基础信息,请从中提取出“标题”、“收录会议或期刊”、“作者”、“摘要”、“编号”、“作者邮箱”这六个部分。请用markdown格式输出,最后用中文翻译摘要部分。请提取:{paper_meta}",
85
  inputs_show_user=f"请从{fp}中提取出“标题”、“收录会议或期刊”等基本信息。",
86
+ llm_kwargs=llm_kwargs,
87
  chatbot=chatbot, history=[],
88
  sys_prompt="Your job is to collect information from materials。",
89
  )
90
+
91
  # 多线,翻译
92
  gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
93
  inputs_array=[
94
+ f"你需要翻译以下内容:\n{frag}" for frag in paper_fragments],
95
+ inputs_show_user_array=[f"\n---\n 原文: \n\n {frag.replace('#', '')} \n---\n 翻译:\n " for frag in paper_fragments],
96
+ llm_kwargs=llm_kwargs,
97
  chatbot=chatbot,
98
  history_array=[[paper_meta] for _ in paper_fragments],
99
  sys_prompt_array=[
100
+ "请你作为一个学术翻译,负责把学术论文准确翻译成中文。注意文章中的每一句话都要翻译。" for _ in paper_fragments],
101
+ # max_workers=5 # OpenAI所允许的最大并行过载
102
  )
103
 
104
+ # 整理报告的格式
105
+ for i,k in enumerate(gpt_response_collection):
106
+ if i%2==0:
107
+ gpt_response_collection[i] = f"\n\n---\n\n ## 原文[{i//2}/{len(gpt_response_collection)//2}]: \n\n {paper_fragments[i//2].replace('#', '')} \n\n---\n\n ## 翻译[{i//2}/{len(gpt_response_collection)//2}]:\n "
108
+ else:
109
+ gpt_response_collection[i] = gpt_response_collection[i]
110
+ final = ["一、论文概况\n\n---\n\n", paper_meta_info.replace('# ', '### ') + '\n\n---\n\n', "二、论文翻译", ""]
111
  final.extend(gpt_response_collection)
112
  create_report_file_name = f"{os.path.basename(fp)}.trans.md"
113
  res = write_results_to_file(final, file_name=create_report_file_name)
114
+
115
+ # 更新UI
116
+ generated_conclusion_files.append(f'./gpt_log/{create_report_file_name}')
117
  chatbot.append((f"{fp}完成了吗?", res))
118
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
 
119
 
120
  # 准备文件的下载
121
  import shutil
 
128
  if os.path.exists(pdf_path):
129
  os.remove(pdf_path)
130
  chatbot.append(("给出输出文件清单", str(generated_conclusion_files)))
131
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
crazy_functions/理解PDF文档内容.py CHANGED
@@ -1,152 +1,79 @@
1
- from request_llm.bridge_chatgpt import predict_no_ui
2
- from toolbox import CatchException, report_execption, write_results_to_file, predict_no_ui_but_counting_down
3
- import re
4
- import unicodedata
5
  fast_debug = False
6
 
7
- def is_paragraph_break(match):
8
- """
9
- 根据给定的匹配结果来判断换行符是否表示段落分隔。
10
- 如果换行符前为句子结束标志(句号,感叹号,问号),且下一个字符为大写字母,则换行符更有可能表示段落分隔。
11
- 也可以根据之前的内容长度来判断段落是否已经足够长。
12
- """
13
- prev_char, next_char = match.groups()
14
 
15
- # 句子结束标志
16
- sentence_endings = ".!?"
17
-
18
- # 设定一个最小段落长度阈值
19
- min_paragraph_length = 140
20
-
21
- if prev_char in sentence_endings and next_char.isupper() and len(match.string[:match.start(1)]) > min_paragraph_length:
22
- return "\n\n"
23
- else:
24
- return " "
25
-
26
- def normalize_text(text):
27
- """
28
- 通过把连字(ligatures)等文本特殊符号转换为其基本形式来对文本进行归一化处理。
29
- 例如,将连字 "fi" 转换为 "f" 和 "i"。
30
- """
31
- # 对文本进行归一化处理,分解连字
32
- normalized_text = unicodedata.normalize("NFKD", text)
33
-
34
- # 替换其他特殊字符
35
- cleaned_text = re.sub(r'[^\x00-\x7F]+', '', normalized_text)
36
-
37
- return cleaned_text
38
-
39
- def clean_text(raw_text):
40
- """
41
- 对从 PDF 提取出的原始文本进行清洗和格式化处理。
42
- 1. 对原始文本进行归一化处理。
43
- 2. 替换跨行的连词,例如 “Espe-\ncially” 转换为 “Especially”。
44
- 3. 根据 heuristic 规则判断换行符是否是段落分隔,并相应地进行替换。
45
- """
46
- # 对文本进行归一化处理
47
- normalized_text = normalize_text(raw_text)
48
-
49
- # 替换跨行的连词
50
- text = re.sub(r'(\w+-\n\w+)', lambda m: m.group(1).replace('-\n', ''), normalized_text)
51
-
52
- # 根据前后相邻字符的特点,找到原文本中的换行符
53
- newlines = re.compile(r'(\S)\n(\S)')
54
-
55
- # 根据 heuristic 规则,用空格或段落分隔符替换原换行符
56
- final_text = re.sub(newlines, lambda m: m.group(1) + is_paragraph_break(m) + m.group(2), text)
57
-
58
- return final_text.strip()
59
-
60
- def 解析PDF(file_name, top_p, temperature, chatbot, history, systemPromptTxt):
61
- import time, glob, os, fitz
62
  print('begin analysis on:', file_name)
63
 
64
- with fitz.open(file_name) as doc:
65
- file_content = ""
66
- for page in doc:
67
- file_content += page.get_text()
68
- file_content = clean_text(file_content)
69
- # print(file_content)
70
- split_number = 10000
71
- split_group = (len(file_content)//split_number)+1
72
- for i in range(0,split_group):
73
- if i==0:
74
- prefix = "接下来请你仔细分析下面的论文,学习里面的内容(专业术语、公式、数学概念).并且注意:由于论文内容较多,将分批次发送,每次发送完之后,你只需要回答“接受完成”"
75
- i_say = prefix + f'文件名是{file_name},文章内容第{i+1}部分是 ```{file_content[i*split_number:(i+1)*split_number]}```'
76
- i_say_show_user = f'文件名是:\n{file_name},\n由于论文内容过长,将分批请求(共{len(file_content)}字符,将分为{split_group}批,每批{split_number}字符)。\n当前发送{i+1}/{split_group}部分'
77
- elif i==split_group-1:
78
- i_say = f'你只需要回答“所有论文接受完成,请进行下一步”。文章内容第{i+1}/{split_group}部分是 ```{file_content[i*split_number:]}```'
79
- i_say_show_user = f'当前发送{i+1}/{split_group}部分'
80
- else:
81
- i_say = f'你只需要回答“接受完成”。文章内容第{i+1}/{split_group}部分是 ```{file_content[i*split_number:(i+1)*split_number]}```'
82
- i_say_show_user = f'当前发送{i+1}/{split_group}部分'
83
- chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
84
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[]) # 带超时倒计时
85
- while "完成" not in gpt_say:
86
- i_say = f'你只需要回答“接受完成”。文章内容第{i+1}/{split_group}部分是 ```{file_content[i*split_number:(i+1)*split_number]}```'
87
- i_say_show_user = f'出现error,重新发送{i+1}/{split_group}部分'
88
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[]) # 带超时倒计时
89
- time.sleep(1)
90
- chatbot[-1] = (i_say_show_user, gpt_say)
91
- history.append(i_say_show_user); history.append(gpt_say)
92
- yield chatbot, history, '正常'
93
- time.sleep(2)
94
-
95
- i_say = f'接下来,请你扮演一名专业的学术教授,利用你的所有知识并且结合这篇文章,回答我的问题。(请牢记:1.直到我说“退出”,你才能结束任务;2.所有问题需要紧密围绕文章内容;3.如果有公式,请使用tex渲染)'
96
- chatbot.append((i_say, "[Local Message] waiting gpt response."))
97
- yield chatbot, history, '正常'
98
-
99
- # ** gpt request **
100
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say, chatbot, top_p, temperature, history=history) # 带超时倒计时
101
- chatbot[-1] = (i_say, gpt_say)
102
- history.append(i_say); history.append(gpt_say)
103
- yield chatbot, history, '正常'
104
-
105
-
106
- @CatchException
107
- def 理解PDF文档内容(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
108
- import glob, os
109
-
110
- # 基本信息:功能、贡献者
111
- chatbot.append([
112
- "函数插件功能?",
113
- "理解PDF论文内容,并且将结合上下文内容,进行学术解答。函数插件贡献者: Hanzoe。"])
114
- yield chatbot, history, '正常'
115
-
116
- import tkinter as tk
117
- from tkinter import filedialog
118
-
119
- root = tk.Tk()
120
- root.withdraw()
121
- txt = filedialog.askopenfilename()
122
-
123
- # 尝试导入依赖,如果缺少依赖,则给出安装建议
124
- try:
125
- import fitz
126
- except:
127
- report_execption(chatbot, history,
128
- a = f"解析项目: {txt}",
129
- b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
130
- yield chatbot, history, '正常'
131
- return
132
-
133
- # 清空历史,以免输入溢出
134
- history = []
135
-
136
- # 开始正式执行任务
137
- yield from 解析PDF(txt, top_p, temperature, chatbot, history, systemPromptTxt)
138
-
139
 
140
 
141
  @CatchException
142
- def 理解PDF文档内容标准文件输入(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
143
  import glob, os
144
 
145
  # 基本信息:功能、贡献者
146
  chatbot.append([
147
  "函数插件功能?",
148
- "理解PDF论文内容,并且将结合上下文内容,进行学术解答。函数插件贡献者: Hanzoe"])
149
- yield chatbot, history, '正常'
150
 
151
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
152
  try:
@@ -155,7 +82,7 @@ def 理解PDF文档内容标准文件输入(txt, top_p, temperature, chatbot, hi
155
  report_execption(chatbot, history,
156
  a = f"解析项目: {txt}",
157
  b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
158
- yield chatbot, history, '正常'
159
  return
160
 
161
  # 清空历史,以免输入溢出
@@ -169,7 +96,7 @@ def 理解PDF文档内容标准文件输入(txt, top_p, temperature, chatbot, hi
169
  txt = '空空如也的输入栏'
170
  report_execption(chatbot, history,
171
  a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
172
- yield chatbot, history, '正常'
173
  return
174
 
175
  # 搜索需要处理的文件清单
@@ -178,8 +105,8 @@ def 理解PDF文档内容标准文件输入(txt, top_p, temperature, chatbot, hi
178
  if len(file_manifest) == 0:
179
  report_execption(chatbot, history,
180
  a=f"解析项目: {txt}", b=f"找不到任何.tex或.pdf文件: {txt}")
181
- yield chatbot, history, '正常'
182
  return
183
  txt = file_manifest[0]
184
  # 开始正式执行任务
185
- yield from 解析PDF(txt, top_p, temperature, chatbot, history, systemPromptTxt)
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption
3
+ from .crazy_utils import read_and_clean_pdf_text
4
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
5
  fast_debug = False
6
 
 
 
 
 
 
 
 
7
 
8
+ def 解析PDF(file_name, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
9
+ import tiktoken
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  print('begin analysis on:', file_name)
11
 
12
+ ############################## <第 0 步,切割PDF> ##################################
13
+ # 递归地切割PDF文件,每一块(尽量是完整的一个section,比如introduction,experiment等,必要时再进行切割)
14
+ # 的长度必须小于 2500 个 Token
15
+ file_content, page_one = read_and_clean_pdf_text(file_name) # (尝试)按照章节切割PDF
16
+
17
+ TOKEN_LIMIT_PER_FRAGMENT = 2500
18
+
19
+ from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
20
+ from request_llm.bridge_all import model_info
21
+ enc = model_info["gpt-3.5-turbo"]['tokenizer']
22
+ def get_token_num(txt): return len(enc.encode(txt, disallowed_special=()))
23
+ paper_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
24
+ txt=file_content, get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT)
25
+ page_one_fragments = breakdown_txt_to_satisfy_token_limit_for_pdf(
26
+ txt=str(page_one), get_token_fn=get_token_num, limit=TOKEN_LIMIT_PER_FRAGMENT//4)
27
+ # 为了更好的效果,我们剥离Introduction之后的部分(如果有)
28
+ paper_meta = page_one_fragments[0].split('introduction')[0].split('Introduction')[0].split('INTRODUCTION')[0]
29
+
30
+ ############################## <第 1 步,从摘要中提取高价值信息,放到history中> ##################################
31
+ final_results = []
32
+ final_results.append(paper_meta)
33
+
34
+ ############################## <第 2 步,迭代地历遍整个文章,提取精炼信息> ##################################
35
+ i_say_show_user = f'首先你在英文语境下通读整篇论文。'; gpt_say = "[Local Message] 收到。" # 用户提示
36
+ chatbot.append([i_say_show_user, gpt_say]); yield from update_ui(chatbot=chatbot, history=[]) # 更新UI
37
+
38
+ iteration_results = []
39
+ last_iteration_result = paper_meta # 初始值是摘要
40
+ MAX_WORD_TOTAL = 4096
41
+ n_fragment = len(paper_fragments)
42
+ if n_fragment >= 20: print('文章极长,不能达到预期效果')
43
+ for i in range(n_fragment):
44
+ NUM_OF_WORD = MAX_WORD_TOTAL // n_fragment
45
+ i_say = f"Read this section, recapitulate the content of this section with less than {NUM_OF_WORD} words: {paper_fragments[i]}"
46
+ i_say_show_user = f"[{i+1}/{n_fragment}] Read this section, recapitulate the content of this section with less than {NUM_OF_WORD} words: {paper_fragments[i][:200]}"
47
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(i_say, i_say_show_user, # i_say=真正给chatgpt的提问, i_say_show_user=给用户看的提问
48
+ llm_kwargs, chatbot,
49
+ history=["The main idea of the previous section is?", last_iteration_result], # 迭代上一次的结果
50
+ sys_prompt="Extract the main idea of this section." # 提示
51
+ )
52
+ iteration_results.append(gpt_say)
53
+ last_iteration_result = gpt_say
54
+
55
+ ############################## <第 3 步,整理history> ##################################
56
+ final_results.extend(iteration_results)
57
+ final_results.append(f'接下来,你是一名专业的学术教授,利用以上信息,使用中文回答我的问题。')
58
+ # 接下来两句话只显示在界面上,不起实际作用
59
+ i_say_show_user = f'接下来,你是一名专业的学术教授,利用以上信息,使用中文回答我的问题。'; gpt_say = "[Local Message] 收到。"
60
+ chatbot.append([i_say_show_user, gpt_say])
61
+
62
+ ############################## <第 4 步,设置一个token上限,防止回答时Token溢出> ##################################
63
+ from .crazy_utils import input_clipping
64
+ _, final_results = input_clipping("", final_results, max_token_limit=3200)
65
+ yield from update_ui(chatbot=chatbot, history=final_results) # 注意这里的历史记录被替代了
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
 
68
  @CatchException
69
+ def 理解PDF文档内容标准文件输入(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
70
  import glob, os
71
 
72
  # 基本信息:功能、贡献者
73
  chatbot.append([
74
  "函数插件功能?",
75
+ "理解PDF论文内容,并且将结合上下文内容,进行学术解答。函数插件贡献者: Hanzoe, binary-husky"])
76
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
77
 
78
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
79
  try:
 
82
  report_execption(chatbot, history,
83
  a = f"解析项目: {txt}",
84
  b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
85
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
86
  return
87
 
88
  # 清空历史,以免输入溢出
 
96
  txt = '空空如也的输入栏'
97
  report_execption(chatbot, history,
98
  a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
99
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
100
  return
101
 
102
  # 搜索需要处理的文件清单
 
105
  if len(file_manifest) == 0:
106
  report_execption(chatbot, history,
107
  a=f"解析项目: {txt}", b=f"找不到任何.tex或.pdf文件: {txt}")
108
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
109
  return
110
  txt = file_manifest[0]
111
  # 开始正式执行任务
112
+ yield from 解析PDF(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
crazy_functions/生成函数注释.py CHANGED
@@ -1,43 +1,40 @@
1
- from request_llm.bridge_chatgpt import predict_no_ui
2
- from toolbox import CatchException, report_execption, write_results_to_file, predict_no_ui_but_counting_down
 
3
  fast_debug = False
4
 
5
-
6
- def 生成函数注释(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt):
7
- import time, glob, os
8
  print('begin analysis on:', file_manifest)
9
  for index, fp in enumerate(file_manifest):
10
- with open(fp, 'r', encoding='utf-8') as f:
11
  file_content = f.read()
12
 
13
  i_say = f'请对下面的程序文件做一个概述,并对文件中的所有函数生成注释,使用markdown表格输出结果,文件名是{os.path.relpath(fp, project_folder)},文件内容是 ```{file_content}```'
14
  i_say_show_user = f'[{index}/{len(file_manifest)}] 请对下面的程序文件做一个概述,并对文件中的所有函数生成注释: {os.path.abspath(fp)}'
15
  chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
16
- print('[1] yield chatbot, history')
17
- yield chatbot, history, '正常'
18
 
19
  if not fast_debug:
20
  msg = '正常'
21
  # ** gpt request **
22
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[]) # 带超时倒计时
 
23
 
24
- print('[2] end gpt req')
25
  chatbot[-1] = (i_say_show_user, gpt_say)
26
  history.append(i_say_show_user); history.append(gpt_say)
27
- print('[3] yield chatbot, history')
28
- yield chatbot, history, msg
29
- print('[4] next')
30
  if not fast_debug: time.sleep(2)
31
 
32
  if not fast_debug:
33
  res = write_results_to_file(history)
34
  chatbot.append(("完成了吗?", res))
35
- yield chatbot, history, msg
36
 
37
 
38
 
39
  @CatchException
40
- def 批量生成函数注释(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
41
  history = [] # 清空历史,以免输入溢出
42
  import glob, os
43
  if os.path.exists(txt):
@@ -45,13 +42,13 @@ def 批量生成函数注释(txt, top_p, temperature, chatbot, history, systemPr
45
  else:
46
  if txt == "": txt = '空空如也的输入栏'
47
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
48
- yield chatbot, history, '正常'
49
  return
50
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.py', recursive=True)] + \
51
  [f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)]
52
 
53
  if len(file_manifest) == 0:
54
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
55
- yield chatbot, history, '正常'
56
  return
57
- yield from 生成函数注释(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file
3
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
4
  fast_debug = False
5
 
6
+ def 生成函数注释(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
7
+ import time, os
 
8
  print('begin analysis on:', file_manifest)
9
  for index, fp in enumerate(file_manifest):
10
+ with open(fp, 'r', encoding='utf-8', errors='replace') as f:
11
  file_content = f.read()
12
 
13
  i_say = f'请对下面的程序文件做一个概述,并对文件中的所有函数生成注释,使用markdown表格输出结果,文件名是{os.path.relpath(fp, project_folder)},文件内容是 ```{file_content}```'
14
  i_say_show_user = f'[{index}/{len(file_manifest)}] 请对下面的程序文件做一个概述,并对文件中的所有函数生成注释: {os.path.abspath(fp)}'
15
  chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
16
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
 
17
 
18
  if not fast_debug:
19
  msg = '正常'
20
  # ** gpt request **
21
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
22
+ i_say, i_say_show_user, llm_kwargs, chatbot, history=[], sys_prompt=system_prompt) # 带超时倒计时
23
 
 
24
  chatbot[-1] = (i_say_show_user, gpt_say)
25
  history.append(i_say_show_user); history.append(gpt_say)
26
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
 
 
27
  if not fast_debug: time.sleep(2)
28
 
29
  if not fast_debug:
30
  res = write_results_to_file(history)
31
  chatbot.append(("完成了吗?", res))
32
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
33
 
34
 
35
 
36
  @CatchException
37
+ def 批量生成函数注释(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
38
  history = [] # 清空历史,以免输入溢出
39
  import glob, os
40
  if os.path.exists(txt):
 
42
  else:
43
  if txt == "": txt = '空空如也的输入栏'
44
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
45
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
46
  return
47
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.py', recursive=True)] + \
48
  [f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)]
49
 
50
  if len(file_manifest) == 0:
51
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
52
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
53
  return
54
+ yield from 生成函数注释(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
crazy_functions/联网的ChatGPT.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from toolbox import CatchException, update_ui
2
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive, input_clipping
3
+ import requests
4
+ from bs4 import BeautifulSoup
5
+ from request_llm.bridge_all import model_info
6
+
7
+ def google(query, proxies):
8
+ query = query # 在此处替换您要搜索的关键词
9
+ url = f"https://www.google.com/search?q={query}"
10
+ headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'}
11
+ response = requests.get(url, headers=headers, proxies=proxies)
12
+ soup = BeautifulSoup(response.content, 'html.parser')
13
+ results = []
14
+ for g in soup.find_all('div', class_='g'):
15
+ anchors = g.find_all('a')
16
+ if anchors:
17
+ link = anchors[0]['href']
18
+ if link.startswith('/url?q='):
19
+ link = link[7:]
20
+ if not link.startswith('http'):
21
+ continue
22
+ title = g.find('h3').text
23
+ item = {'title': title, 'link': link}
24
+ results.append(item)
25
+
26
+ for r in results:
27
+ print(r['link'])
28
+ return results
29
+
30
+ def scrape_text(url, proxies) -> str:
31
+ """Scrape text from a webpage
32
+
33
+ Args:
34
+ url (str): The URL to scrape text from
35
+
36
+ Returns:
37
+ str: The scraped text
38
+ """
39
+ headers = {
40
+ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36',
41
+ 'Content-Type': 'text/plain',
42
+ }
43
+ try:
44
+ response = requests.get(url, headers=headers, proxies=proxies, timeout=8)
45
+ if response.encoding == "ISO-8859-1": response.encoding = response.apparent_encoding
46
+ except:
47
+ return "无法连接到该网页"
48
+ soup = BeautifulSoup(response.text, "html.parser")
49
+ for script in soup(["script", "style"]):
50
+ script.extract()
51
+ text = soup.get_text()
52
+ lines = (line.strip() for line in text.splitlines())
53
+ chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
54
+ text = "\n".join(chunk for chunk in chunks if chunk)
55
+ return text
56
+
57
+ @CatchException
58
+ def 连接网络回答问题(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
59
+ """
60
+ txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径
61
+ llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行
62
+ plugin_kwargs 插件模型的参数,暂时没有用武之地
63
+ chatbot 聊天显示框的句柄,用于显示给用户
64
+ history 聊天历史,前情提要
65
+ system_prompt 给gpt的静默提醒
66
+ web_port 当前软件运行的端口号
67
+ """
68
+ history = [] # 清空历史,以免输入溢出
69
+ chatbot.append((f"请结合互联网信息回答以下问题:{txt}",
70
+ "[Local Message] 请注意,您正在调用一个[函数插件]的模板,该模板可以实现ChatGPT联网信息综合。该函数面向希望实现更多有趣功能的开发者,它可以作为创建新功能函数的模板。您若希望分享新的功能模组,请不吝PR!"))
71
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
72
+
73
+ # ------------- < 第1步:爬取搜索引擎的结果 > -------------
74
+ from toolbox import get_conf
75
+ proxies, = get_conf('proxies')
76
+ urls = google(txt, proxies)
77
+ history = []
78
+
79
+ # ------------- < 第2步:依次访问网页 > -------------
80
+ max_search_result = 5 # 最多收纳多少个网页的结果
81
+ for index, url in enumerate(urls[:max_search_result]):
82
+ res = scrape_text(url['link'], proxies)
83
+ history.extend([f"第{index}份搜索结果:", res])
84
+ chatbot.append([f"第{index}份搜索结果:", res[:500]+"......"])
85
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
86
+
87
+ # ------------- < 第3步:ChatGPT综合 > -------------
88
+ i_say = f"从以上搜索结果中抽取信息,然后回答问题:{txt}"
89
+ i_say, history = input_clipping( # 裁剪输入,从最长的条目开始裁剪,防止爆token
90
+ inputs=i_say,
91
+ history=history,
92
+ max_token_limit=model_info[llm_kwargs['llm_model']]['max_token']*3//4
93
+ )
94
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
95
+ inputs=i_say, inputs_show_user=i_say,
96
+ llm_kwargs=llm_kwargs, chatbot=chatbot, history=history,
97
+ sys_prompt="请从给定的若干条搜索结果中抽取信息,对最相关的两个搜索结果进行总结,然后回答问题。"
98
+ )
99
+ chatbot[-1] = (i_say, gpt_say)
100
+ history.append(i_say);history.append(gpt_say)
101
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 界面更新
102
+
crazy_functions/解析JupyterNotebook.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file
3
+ fast_debug = True
4
+
5
+
6
+ class PaperFileGroup():
7
+ def __init__(self):
8
+ self.file_paths = []
9
+ self.file_contents = []
10
+ self.sp_file_contents = []
11
+ self.sp_file_index = []
12
+ self.sp_file_tag = []
13
+
14
+ # count_token
15
+ from request_llm.bridge_all import model_info
16
+ enc = model_info["gpt-3.5-turbo"]['tokenizer']
17
+ def get_token_num(txt): return len(
18
+ enc.encode(txt, disallowed_special=()))
19
+ self.get_token_num = get_token_num
20
+
21
+ def run_file_split(self, max_token_limit=1900):
22
+ """
23
+ 将长文本分离开来
24
+ """
25
+ for index, file_content in enumerate(self.file_contents):
26
+ if self.get_token_num(file_content) < max_token_limit:
27
+ self.sp_file_contents.append(file_content)
28
+ self.sp_file_index.append(index)
29
+ self.sp_file_tag.append(self.file_paths[index])
30
+ else:
31
+ from .crazy_utils import breakdown_txt_to_satisfy_token_limit_for_pdf
32
+ segments = breakdown_txt_to_satisfy_token_limit_for_pdf(
33
+ file_content, self.get_token_num, max_token_limit)
34
+ for j, segment in enumerate(segments):
35
+ self.sp_file_contents.append(segment)
36
+ self.sp_file_index.append(index)
37
+ self.sp_file_tag.append(
38
+ self.file_paths[index] + f".part-{j}.txt")
39
+
40
+
41
+
42
+ def parseNotebook(filename, enable_markdown=1):
43
+ import json
44
+
45
+ CodeBlocks = []
46
+ with open(filename, 'r', encoding='utf-8', errors='replace') as f:
47
+ notebook = json.load(f)
48
+ for cell in notebook['cells']:
49
+ if cell['cell_type'] == 'code' and cell['source']:
50
+ # remove blank lines
51
+ cell['source'] = [line for line in cell['source'] if line.strip()
52
+ != '']
53
+ CodeBlocks.append("".join(cell['source']))
54
+ elif enable_markdown and cell['cell_type'] == 'markdown' and cell['source']:
55
+ cell['source'] = [line for line in cell['source'] if line.strip()
56
+ != '']
57
+ CodeBlocks.append("Markdown:"+"".join(cell['source']))
58
+
59
+ Code = ""
60
+ for idx, code in enumerate(CodeBlocks):
61
+ Code += f"This is {idx+1}th code block: \n"
62
+ Code += code+"\n"
63
+
64
+ return Code
65
+
66
+
67
+ def ipynb解释(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
68
+ from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
69
+
70
+ pfg = PaperFileGroup()
71
+
72
+ print(file_manifest)
73
+ for fp in file_manifest:
74
+ file_content = parseNotebook(fp, enable_markdown=1)
75
+ pfg.file_paths.append(fp)
76
+ pfg.file_contents.append(file_content)
77
+
78
+ # <-------- 拆分过长的IPynb文件 ---------->
79
+ pfg.run_file_split(max_token_limit=1024)
80
+ n_split = len(pfg.sp_file_contents)
81
+
82
+ inputs_array = [r"This is a Jupyter Notebook file, tell me about Each Block in Chinese. Focus Just On Code." +
83
+ r"If a block starts with `Markdown` which means it's a markdown block in ipynbipynb. " +
84
+ r"Start a new line for a block and block num use Chinese." +
85
+ f"\n\n{frag}" for frag in pfg.sp_file_contents]
86
+ inputs_show_user_array = [f"{f}的分析如下" for f in pfg.sp_file_tag]
87
+ sys_prompt_array = ["You are a professional programmer."] * n_split
88
+
89
+ gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
90
+ inputs_array=inputs_array,
91
+ inputs_show_user_array=inputs_show_user_array,
92
+ llm_kwargs=llm_kwargs,
93
+ chatbot=chatbot,
94
+ history_array=[[""] for _ in range(n_split)],
95
+ sys_prompt_array=sys_prompt_array,
96
+ # max_workers=5, # OpenAI所允许的最大并行过载
97
+ scroller_max_len=80
98
+ )
99
+
100
+ # <-------- 整理结果,退出 ---------->
101
+ block_result = " \n".join(gpt_response_collection)
102
+ chatbot.append(("解析的结果如下", block_result))
103
+ history.extend(["解析的结果如下", block_result])
104
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
105
+
106
+ # <-------- 写入文件,退出 ---------->
107
+ res = write_results_to_file(history)
108
+ chatbot.append(("完成了吗?", res))
109
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
110
+
111
+ @CatchException
112
+ def 解析ipynb文件(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
113
+ chatbot.append([
114
+ "函数插件功能?",
115
+ "对IPynb文件进行解析。Contributor: codycjy."])
116
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
117
+
118
+ history = [] # 清空历史
119
+ import glob
120
+ import os
121
+ if os.path.exists(txt):
122
+ project_folder = txt
123
+ else:
124
+ if txt == "":
125
+ txt = '空空如也的输入栏'
126
+ report_execption(chatbot, history,
127
+ a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
128
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
129
+ return
130
+ if txt.endswith('.ipynb'):
131
+ file_manifest = [txt]
132
+ else:
133
+ file_manifest = [f for f in glob.glob(
134
+ f'{project_folder}/**/*.ipynb', recursive=True)]
135
+ if len(file_manifest) == 0:
136
+ report_execption(chatbot, history,
137
+ a=f"解析项目: {txt}", b=f"找不到任何.ipynb文件: {txt}")
138
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
139
+ return
140
+ yield from ipynb解释(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, )
crazy_functions/解析项目源代码.py CHANGED
@@ -1,96 +1,103 @@
1
- from request_llm.bridge_chatgpt import predict_no_ui
2
- from toolbox import CatchException, report_execption, write_results_to_file, predict_no_ui_but_counting_down
3
- fast_debug = False
4
 
5
- def 解析源代码(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt):
6
- import time, glob, os
7
- print('begin analysis on:', file_manifest)
 
 
 
 
 
 
 
 
 
 
8
  for index, fp in enumerate(file_manifest):
9
- with open(fp, 'r', encoding='utf-8') as f:
 
10
  file_content = f.read()
11
-
12
  prefix = "接下来请你逐文件分析下面的工程" if index==0 else ""
13
  i_say = prefix + f'请对下面的程序文件做一个概述文件名是{os.path.relpath(fp, project_folder)},文件代码是 ```{file_content}```'
14
  i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的程序文件做一个概述: {os.path.abspath(fp)}'
15
- chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
16
- yield chatbot, history, '正常'
17
-
18
- if not fast_debug:
19
- msg = '正常'
20
-
21
- # ** gpt request **
22
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[]) # 带超时倒计时
23
 
24
- chatbot[-1] = (i_say_show_user, gpt_say)
25
- history.append(i_say_show_user); history.append(gpt_say)
26
- yield chatbot, history, msg
27
- if not fast_debug: time.sleep(2)
 
 
 
 
 
 
28
 
29
- all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
30
- i_say = f'根据以上你自己的分析,对程序的整体功能和构架做出概括。然后用一张markdown表格整理每个文件的功能(包括{all_file})。'
31
- chatbot.append((i_say, "[Local Message] waiting gpt response."))
32
- yield chatbot, history, '正常'
 
 
33
 
34
- if not fast_debug:
35
- msg = '正常'
36
- # ** gpt request **
37
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say, chatbot, top_p, temperature, history=history) # 带超时倒计时
38
-
39
- chatbot[-1] = (i_say, gpt_say)
40
- history.append(i_say); history.append(gpt_say)
41
- yield chatbot, history, msg
42
- res = write_results_to_file(history)
43
- chatbot.append(("完成了吗?", res))
44
- yield chatbot, history, msg
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
 
 
46
 
 
 
 
 
 
47
 
48
 
49
  @CatchException
50
- def 解析项目本身(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
51
  history = [] # 清空历史,以免输入溢出
52
- import time, glob, os
53
  file_manifest = [f for f in glob.glob('./*.py') if ('test_project' not in f) and ('gpt_log' not in f)] + \
54
- [f for f in glob.glob('./crazy_functions/*.py') if ('test_project' not in f) and ('gpt_log' not in f)]
55
- for index, fp in enumerate(file_manifest):
56
- # if 'test_project' in fp: continue
57
- with open(fp, 'r', encoding='utf-8') as f:
58
- file_content = f.read()
59
-
60
- prefix = "接下来请你分析自己的程序构成,别紧张," if index==0 else ""
61
- i_say = prefix + f'请对下面的程序文件做一个概述文件名是{fp},文件代码是 ```{file_content}```'
62
- i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的程序文件做一个概述: {os.path.abspath(fp)}'
63
- chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
64
- yield chatbot, history, '正常'
65
-
66
- if not fast_debug:
67
- # ** gpt request **
68
- # gpt_say = predict_no_ui(inputs=i_say, top_p=top_p, temperature=temperature)
69
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[], long_connection=True) # 带超时倒计时
70
-
71
- chatbot[-1] = (i_say_show_user, gpt_say)
72
- history.append(i_say_show_user); history.append(gpt_say)
73
- yield chatbot, history, '正常'
74
- time.sleep(2)
75
-
76
- i_say = f'根据以上你自己的分析,对程序的整体功能和构架做出概括。然后用一张markdown表格整理每个文件的功能(包括{file_manifest})。'
77
- chatbot.append((i_say, "[Local Message] waiting gpt response."))
78
- yield chatbot, history, '正常'
79
-
80
- if not fast_debug:
81
- # ** gpt request **
82
- # gpt_say = predict_no_ui(inputs=i_say, top_p=top_p, temperature=temperature, history=history)
83
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say, chatbot, top_p, temperature, history=history, long_connection=True) # 带超时倒计时
84
-
85
- chatbot[-1] = (i_say, gpt_say)
86
- history.append(i_say); history.append(gpt_say)
87
- yield chatbot, history, '正常'
88
- res = write_results_to_file(history)
89
- chatbot.append(("完成了吗?", res))
90
- yield chatbot, history, '正常'
91
 
92
  @CatchException
93
- def 解析一个Python项目(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
94
  history = [] # 清空历史,以免输入溢出
95
  import glob, os
96
  if os.path.exists(txt):
@@ -98,18 +105,18 @@ def 解析一个Python项目(txt, top_p, temperature, chatbot, history, systemPr
98
  else:
99
  if txt == "": txt = '空空如也的输入栏'
100
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
101
- yield chatbot, history, '正常'
102
  return
103
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.py', recursive=True)]
104
  if len(file_manifest) == 0:
105
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何python文件: {txt}")
106
- yield chatbot, history, '正常'
107
  return
108
- yield from 解析源代码(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
109
 
110
 
111
  @CatchException
112
- def 解析一个C项目的头文件(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
113
  history = [] # 清空历史,以免输入溢出
114
  import glob, os
115
  if os.path.exists(txt):
@@ -117,19 +124,19 @@ def 解析一个C项目的头文件(txt, top_p, temperature, chatbot, history, s
117
  else:
118
  if txt == "": txt = '空空如也的输入栏'
119
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
120
- yield chatbot, history, '正常'
121
  return
122
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.h', recursive=True)] + \
123
  [f for f in glob.glob(f'{project_folder}/**/*.hpp', recursive=True)] #+ \
124
  # [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
125
  if len(file_manifest) == 0:
126
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.h头文件: {txt}")
127
- yield chatbot, history, '正常'
128
  return
129
- yield from 解析源代码(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
130
 
131
  @CatchException
132
- def 解析一个C项目(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
133
  history = [] # 清空历史,以免输入溢出
134
  import glob, os
135
  if os.path.exists(txt):
@@ -137,7 +144,7 @@ def 解析一个C项目(txt, top_p, temperature, chatbot, history, systemPromptT
137
  else:
138
  if txt == "": txt = '空空如也的输入栏'
139
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
140
- yield chatbot, history, '正常'
141
  return
142
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.h', recursive=True)] + \
143
  [f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)] + \
@@ -145,13 +152,13 @@ def 解析一个C项目(txt, top_p, temperature, chatbot, history, systemPromptT
145
  [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
146
  if len(file_manifest) == 0:
147
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.h头文件: {txt}")
148
- yield chatbot, history, '正常'
149
  return
150
- yield from 解析源代码(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
151
 
152
 
153
  @CatchException
154
- def 解析一���Java项目(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
155
  history = [] # 清空历史,以免输入溢出
156
  import glob, os
157
  if os.path.exists(txt):
@@ -159,7 +166,7 @@ def 解析一个Java项目(txt, top_p, temperature, chatbot, history, systemProm
159
  else:
160
  if txt == "": txt = '空空如也的输入栏'
161
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
162
- yield chatbot, history, '正常'
163
  return
164
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.java', recursive=True)] + \
165
  [f for f in glob.glob(f'{project_folder}/**/*.jar', recursive=True)] + \
@@ -167,13 +174,13 @@ def 解析一个Java项目(txt, top_p, temperature, chatbot, history, systemProm
167
  [f for f in glob.glob(f'{project_folder}/**/*.sh', recursive=True)]
168
  if len(file_manifest) == 0:
169
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何java文件: {txt}")
170
- yield chatbot, history, '正常'
171
  return
172
- yield from 解析源代码(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
173
 
174
 
175
  @CatchException
176
- def 解析一个Rect项目(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
177
  history = [] # 清空历史,以免输入溢出
178
  import glob, os
179
  if os.path.exists(txt):
@@ -181,7 +188,7 @@ def 解析一个Rect项目(txt, top_p, temperature, chatbot, history, systemProm
181
  else:
182
  if txt == "": txt = '空空如也的输入栏'
183
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
184
- yield chatbot, history, '正常'
185
  return
186
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.ts', recursive=True)] + \
187
  [f for f in glob.glob(f'{project_folder}/**/*.tsx', recursive=True)] + \
@@ -190,13 +197,13 @@ def 解析一个Rect项目(txt, top_p, temperature, chatbot, history, systemProm
190
  [f for f in glob.glob(f'{project_folder}/**/*.jsx', recursive=True)]
191
  if len(file_manifest) == 0:
192
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何Rect文件: {txt}")
193
- yield chatbot, history, '正常'
194
  return
195
- yield from 解析源代码(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
196
 
197
 
198
  @CatchException
199
- def 解析一个Golang项目(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
200
  history = [] # 清空历史,以免输入溢出
201
  import glob, os
202
  if os.path.exists(txt):
@@ -204,11 +211,97 @@ def 解析一个Golang项目(txt, top_p, temperature, chatbot, history, systemPr
204
  else:
205
  if txt == "": txt = '空空如也的输入栏'
206
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
207
- yield chatbot, history, '正常'
208
  return
209
- file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.go', recursive=True)]
 
 
 
210
  if len(file_manifest) == 0:
211
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何golang文件: {txt}")
212
- yield chatbot, history, '正常'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  return
214
- yield from 解析源代码(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file
 
3
 
4
+ def 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
5
+ import os, copy
6
+ from .crazy_utils import request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency
7
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
8
+ msg = '正常'
9
+ inputs_array = []
10
+ inputs_show_user_array = []
11
+ history_array = []
12
+ sys_prompt_array = []
13
+ report_part_1 = []
14
+
15
+ assert len(file_manifest) <= 512, "源文件太多(超过512个), 请缩减输入文件的数量。或者,您也可以选择删除此行警告,并修改代码拆分file_manifest列表,从而实现分批次处理。"
16
+ ############################## <第一步,逐个文件分析,多线程> ##################################
17
  for index, fp in enumerate(file_manifest):
18
+ # 读取文件
19
+ with open(fp, 'r', encoding='utf-8', errors='replace') as f:
20
  file_content = f.read()
 
21
  prefix = "接下来请你逐文件分析下面的工程" if index==0 else ""
22
  i_say = prefix + f'请对下面的程序文件做一个概述文件名是{os.path.relpath(fp, project_folder)},文件代码是 ```{file_content}```'
23
  i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的程序文件做一个概述: {os.path.abspath(fp)}'
24
+ # 装载请求内容
25
+ inputs_array.append(i_say)
26
+ inputs_show_user_array.append(i_say_show_user)
27
+ history_array.append([])
28
+ sys_prompt_array.append("你是一个程序架构分析师,正在分析一个源代码项目。你的回答必须简单明了。")
 
 
 
29
 
30
+ # 文件读取完成,对每一个源代码文件,生成一个请求线程,发送到chatgpt进行分析
31
+ gpt_response_collection = yield from request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency(
32
+ inputs_array = inputs_array,
33
+ inputs_show_user_array = inputs_show_user_array,
34
+ history_array = history_array,
35
+ sys_prompt_array = sys_prompt_array,
36
+ llm_kwargs = llm_kwargs,
37
+ chatbot = chatbot,
38
+ show_user_at_complete = True
39
+ )
40
 
41
+ # 全部文件解析完成,结果写入文件,准备对工程源代码进行汇总分析
42
+ report_part_1 = copy.deepcopy(gpt_response_collection)
43
+ history_to_return = report_part_1
44
+ res = write_results_to_file(report_part_1)
45
+ chatbot.append(("完成?", "逐个文件分析已完成。" + res + "\n\n正在开始汇总。"))
46
+ yield from update_ui(chatbot=chatbot, history=history_to_return) # 刷新界面
47
 
48
+ ############################## <第二步,综合,单线程,分组+迭代处理> ##################################
49
+ batchsize = 16 # 10个文件为一组
50
+ report_part_2 = []
51
+ previous_iteration_files = []
52
+ last_iteration_result = ""
53
+ while True:
54
+ if len(file_manifest) == 0: break
55
+ this_iteration_file_manifest = file_manifest[:batchsize]
56
+ this_iteration_gpt_response_collection = gpt_response_collection[:batchsize*2]
57
+ file_rel_path = [os.path.relpath(fp, project_folder) for index, fp in enumerate(this_iteration_file_manifest)]
58
+ # 把“请对下面的程序文件做一个概述” 替换成 精简的 "文件名:{all_file[index]}"
59
+ for index, content in enumerate(this_iteration_gpt_response_collection):
60
+ if index%2==0: this_iteration_gpt_response_collection[index] = f"{file_rel_path[index//2]}" # 只保留文件名节省token
61
+ previous_iteration_files.extend([os.path.relpath(fp, project_folder) for index, fp in enumerate(this_iteration_file_manifest)])
62
+ previous_iteration_files_string = ', '.join(previous_iteration_files)
63
+ current_iteration_focus = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(this_iteration_file_manifest)])
64
+ i_say = f'根据以上分析,对程序的整体功能和构架重新做出概括。然后用一张markdown表格整理每个文件的功能(包括{previous_iteration_files_string})。'
65
+ inputs_show_user = f'根据以上分析,对程序的整体功能和构架重新做出概括,由于输入长度限制,可能需要分组处理,本组文件为 {current_iteration_focus} + 已经汇总的文件组。'
66
+ this_iteration_history = copy.deepcopy(this_iteration_gpt_response_collection)
67
+ this_iteration_history.append(last_iteration_result)
68
+ result = yield from request_gpt_model_in_new_thread_with_ui_alive(
69
+ inputs=i_say, inputs_show_user=inputs_show_user, llm_kwargs=llm_kwargs, chatbot=chatbot,
70
+ history=this_iteration_history, # 迭代之前的分析
71
+ sys_prompt="你是一个程序架构分析师,正在分析一个项目的源代码。")
72
+ report_part_2.extend([i_say, result])
73
+ last_iteration_result = result
74
 
75
+ file_manifest = file_manifest[batchsize:]
76
+ gpt_response_collection = gpt_response_collection[batchsize*2:]
77
 
78
+ ############################## <END> ##################################
79
+ history_to_return.extend(report_part_2)
80
+ res = write_results_to_file(history_to_return)
81
+ chatbot.append(("完成了吗?", res))
82
+ yield from update_ui(chatbot=chatbot, history=history_to_return) # 刷新界面
83
 
84
 
85
  @CatchException
86
+ def 解析项目本身(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
87
  history = [] # 清空历史,以免输入溢出
88
+ import glob
89
  file_manifest = [f for f in glob.glob('./*.py') if ('test_project' not in f) and ('gpt_log' not in f)] + \
90
+ [f for f in glob.glob('./crazy_functions/*.py') if ('test_project' not in f) and ('gpt_log' not in f)]+ \
91
+ [f for f in glob.glob('./request_llm/*.py') if ('test_project' not in f) and ('gpt_log' not in f)]
92
+ project_folder = './'
93
+ if len(file_manifest) == 0:
94
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何python文件: {txt}")
95
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
96
+ return
97
+ yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
  @CatchException
100
+ def 解析一个Python项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
101
  history = [] # 清空历史,以免输入溢出
102
  import glob, os
103
  if os.path.exists(txt):
 
105
  else:
106
  if txt == "": txt = '空空如也的输入栏'
107
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
108
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
109
  return
110
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.py', recursive=True)]
111
  if len(file_manifest) == 0:
112
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何python文件: {txt}")
113
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
114
  return
115
+ yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
116
 
117
 
118
  @CatchException
119
+ def 解析一个C项目的头文件(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
120
  history = [] # 清空历史,以免输入溢出
121
  import glob, os
122
  if os.path.exists(txt):
 
124
  else:
125
  if txt == "": txt = '空空如也的输入栏'
126
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
127
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
128
  return
129
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.h', recursive=True)] + \
130
  [f for f in glob.glob(f'{project_folder}/**/*.hpp', recursive=True)] #+ \
131
  # [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
132
  if len(file_manifest) == 0:
133
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.h头文件: {txt}")
134
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
135
  return
136
+ yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
137
 
138
  @CatchException
139
+ def 解析一个C项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
140
  history = [] # 清空历史,以免输入溢出
141
  import glob, os
142
  if os.path.exists(txt):
 
144
  else:
145
  if txt == "": txt = '空空如也的输入栏'
146
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
147
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
148
  return
149
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.h', recursive=True)] + \
150
  [f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)] + \
 
152
  [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
153
  if len(file_manifest) == 0:
154
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.h头文件: {txt}")
155
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
156
  return
157
+ yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
158
 
159
 
160
  @CatchException
161
+ def 解析一个Java项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
162
  history = [] # 清空历史,以免输入溢出
163
  import glob, os
164
  if os.path.exists(txt):
 
166
  else:
167
  if txt == "": txt = '空空如也的输入栏'
168
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
169
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
170
  return
171
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.java', recursive=True)] + \
172
  [f for f in glob.glob(f'{project_folder}/**/*.jar', recursive=True)] + \
 
174
  [f for f in glob.glob(f'{project_folder}/**/*.sh', recursive=True)]
175
  if len(file_manifest) == 0:
176
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何java文件: {txt}")
177
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
178
  return
179
+ yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
180
 
181
 
182
  @CatchException
183
+ def 解析一个Rect项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
184
  history = [] # 清空历史,以免输入溢出
185
  import glob, os
186
  if os.path.exists(txt):
 
188
  else:
189
  if txt == "": txt = '空空如也的输入栏'
190
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
191
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
192
  return
193
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.ts', recursive=True)] + \
194
  [f for f in glob.glob(f'{project_folder}/**/*.tsx', recursive=True)] + \
 
197
  [f for f in glob.glob(f'{project_folder}/**/*.jsx', recursive=True)]
198
  if len(file_manifest) == 0:
199
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何Rect文件: {txt}")
200
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
201
  return
202
+ yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
203
 
204
 
205
  @CatchException
206
+ def 解析一个Golang项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
207
  history = [] # 清空历史,以免输入溢出
208
  import glob, os
209
  if os.path.exists(txt):
 
211
  else:
212
  if txt == "": txt = '空空如也的输入栏'
213
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到本地项目或无权访问: {txt}")
214
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
215
  return
216
+ file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.go', recursive=True)] + \
217
+ [f for f in glob.glob(f'{project_folder}/**/go.mod', recursive=True)] + \
218
+ [f for f in glob.glob(f'{project_folder}/**/go.sum', recursive=True)] + \
219
+ [f for f in glob.glob(f'{project_folder}/**/go.work', recursive=True)]
220
  if len(file_manifest) == 0:
221
  report_execption(chatbot, history, a=f"解析项目: {txt}", b=f"找不到任何golang文件: {txt}")
222
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
223
+ return
224
+ yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
225
+
226
+
227
+ @CatchException
228
+ def 解析一个Lua项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
229
+ history = [] # 清空历史,以免输入溢出
230
+ import glob, os
231
+ if os.path.exists(txt):
232
+ project_folder = txt
233
+ else:
234
+ if txt == "": txt = '空空如也的输入栏'
235
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
236
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
237
+ return
238
+ file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.lua', recursive=True)] + \
239
+ [f for f in glob.glob(f'{project_folder}/**/*.xml', recursive=True)] + \
240
+ [f for f in glob.glob(f'{project_folder}/**/*.json', recursive=True)] + \
241
+ [f for f in glob.glob(f'{project_folder}/**/*.toml', recursive=True)]
242
+ if len(file_manifest) == 0:
243
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何lua文件: {txt}")
244
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
245
+ return
246
+ yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
247
+
248
+
249
+ @CatchException
250
+ def 解析一个CSharp项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
251
+ history = [] # 清空历史,以免输入溢出
252
+ import glob, os
253
+ if os.path.exists(txt):
254
+ project_folder = txt
255
+ else:
256
+ if txt == "": txt = '空空如也的输入栏'
257
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
258
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
259
+ return
260
+ file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.cs', recursive=True)] + \
261
+ [f for f in glob.glob(f'{project_folder}/**/*.csproj', recursive=True)]
262
+ if len(file_manifest) == 0:
263
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何CSharp文件: {txt}")
264
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
265
+ return
266
+ yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
267
+
268
+
269
+ @CatchException
270
+ def 解析任意code项目(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
271
+ txt_pattern = plugin_kwargs.get("advanced_arg")
272
+ txt_pattern = txt_pattern.replace(",", ",")
273
+ # 将要匹配的模式(例如: *.c, *.cpp, *.py, config.toml)
274
+ pattern_include = [_.lstrip(" ,").rstrip(" ,") for _ in txt_pattern.split(",") if _ != "" and not _.strip().startswith("^")]
275
+ if not pattern_include: pattern_include = ["*"] # 不输入即全部匹配
276
+ # 将要忽略匹配的文件后缀(例如: ^*.c, ^*.cpp, ^*.py)
277
+ pattern_except_suffix = [_.lstrip(" ^*.,").rstrip(" ,") for _ in txt_pattern.split(" ") if _ != "" and _.strip().startswith("^*.")]
278
+ pattern_except_suffix += ['zip', 'rar', '7z', 'tar', 'gz'] # 避免解析压缩文件
279
+ # 将要忽略匹配的文件名(例如: ^README.md)
280
+ pattern_except_name = [_.lstrip(" ^*,").rstrip(" ,").replace(".", "\.") for _ in txt_pattern.split(" ") if _ != "" and _.strip().startswith("^") and not _.strip().startswith("^*.")]
281
+ # 生成正则表达式
282
+ pattern_except = '/[^/]+\.(' + "|".join(pattern_except_suffix) + ')$'
283
+ pattern_except += '|/(' + "|".join(pattern_except_name) + ')$' if pattern_except_name != [] else ''
284
+
285
+ history.clear()
286
+ import glob, os, re
287
+ if os.path.exists(txt):
288
+ project_folder = txt
289
+ else:
290
+ if txt == "": txt = '空空如也的输入栏'
291
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
292
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
293
+ return
294
+ # 若上传压缩文件, 先寻找到解压的文件夹路径, 从而避免解析压缩文件
295
+ maybe_dir = [f for f in glob.glob(f'{project_folder}/*') if os.path.isdir(f)]
296
+ if len(maybe_dir)>0 and maybe_dir[0].endswith('.extract'):
297
+ extract_folder_path = maybe_dir[0]
298
+ else:
299
+ extract_folder_path = project_folder
300
+ # 按输入的匹配模式寻找上传的非压缩文件和已解压的文件
301
+ file_manifest = [f for pattern in pattern_include for f in glob.glob(f'{extract_folder_path}/**/{pattern}', recursive=True) if "" != extract_folder_path and \
302
+ os.path.isfile(f) and (not re.search(pattern_except, f) or pattern.endswith('.' + re.search(pattern_except, f).group().split('.')[-1]))]
303
+ if len(file_manifest) == 0:
304
+ report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何文件: {txt}")
305
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
306
  return
307
+ yield from 解析源代码新(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
crazy_functions/询问多个大语言模型.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from toolbox import CatchException, update_ui
2
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
3
+ import datetime
4
+ @CatchException
5
+ def 同时问询(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
6
+ """
7
+ txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径
8
+ llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行
9
+ plugin_kwargs 插件模型的参数,如温度和top_p等,一般原样传递下去就行
10
+ chatbot 聊天显示框的句柄,用于显示给用户
11
+ history 聊天历史,前情提要
12
+ system_prompt 给gpt的静默提醒
13
+ web_port 当前软件运行的端口号
14
+ """
15
+ history = [] # 清空历史,以免输入溢出
16
+ chatbot.append((txt, "正在同时咨询ChatGPT和ChatGLM……"))
17
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
18
+
19
+ # llm_kwargs['llm_model'] = 'chatglm&gpt-3.5-turbo&api2d-gpt-3.5-turbo' # 支持任意数量的llm接口,用&符号分隔
20
+ llm_kwargs['llm_model'] = 'chatglm&gpt-3.5-turbo' # 支持任意数量的llm接口,用&符号分隔
21
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
22
+ inputs=txt, inputs_show_user=txt,
23
+ llm_kwargs=llm_kwargs, chatbot=chatbot, history=history,
24
+ sys_prompt=system_prompt,
25
+ retry_times_at_unknown_error=0
26
+ )
27
+
28
+ history.append(txt)
29
+ history.append(gpt_say)
30
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 界面更新
31
+
32
+
33
+ @CatchException
34
+ def 同时问询_指定模型(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
35
+ """
36
+ txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径
37
+ llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行
38
+ plugin_kwargs 插件模型的参数,如温度和top_p等,一般原样传递下去就行
39
+ chatbot 聊天显示框的句柄,用于显示给用户
40
+ history 聊天历史,前情提要
41
+ system_prompt 给gpt的静默提醒
42
+ web_port 当前软件运行的端口号
43
+ """
44
+ history = [] # 清空历史,以免输入溢出
45
+ chatbot.append((txt, "正在同时咨询ChatGPT和ChatGLM……"))
46
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
47
+
48
+ # llm_kwargs['llm_model'] = 'chatglm&gpt-3.5-turbo&api2d-gpt-3.5-turbo' # 支持任意数量的llm接口,用&符号分隔
49
+ llm_kwargs['llm_model'] = plugin_kwargs.get("advanced_arg", 'chatglm&gpt-3.5-turbo') # 'chatglm&gpt-3.5-turbo' # 支持任意数量的llm接口,用&符号分隔
50
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
51
+ inputs=txt, inputs_show_user=txt,
52
+ llm_kwargs=llm_kwargs, chatbot=chatbot, history=history,
53
+ sys_prompt=system_prompt,
54
+ retry_times_at_unknown_error=0
55
+ )
56
+
57
+ history.append(txt)
58
+ history.append(gpt_say)
59
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 界面更新
crazy_functions/读文章写摘要.py CHANGED
@@ -1,56 +1,53 @@
1
- from request_llm.bridge_chatgpt import predict_no_ui
2
- from toolbox import CatchException, report_execption, write_results_to_file, predict_no_ui_but_counting_down
 
3
  fast_debug = False
4
 
5
 
6
- def 解析Paper(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt):
7
  import time, glob, os
8
  print('begin analysis on:', file_manifest)
9
  for index, fp in enumerate(file_manifest):
10
- with open(fp, 'r', encoding='utf-8') as f:
11
  file_content = f.read()
12
 
13
  prefix = "接下来请你逐文件分析下面的论文文件,概括其内容" if index==0 else ""
14
  i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
15
  i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
16
  chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
17
- print('[1] yield chatbot, history')
18
- yield chatbot, history, '正常'
19
 
20
  if not fast_debug:
21
  msg = '正常'
22
  # ** gpt request **
23
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[]) # 带超时倒计时
24
 
25
- print('[2] end gpt req')
26
  chatbot[-1] = (i_say_show_user, gpt_say)
27
  history.append(i_say_show_user); history.append(gpt_say)
28
- print('[3] yield chatbot, history')
29
- yield chatbot, history, msg
30
- print('[4] next')
31
  if not fast_debug: time.sleep(2)
32
 
33
  all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
34
  i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
35
  chatbot.append((i_say, "[Local Message] waiting gpt response."))
36
- yield chatbot, history, '正常'
37
 
38
  if not fast_debug:
39
  msg = '正常'
40
  # ** gpt request **
41
- gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say, chatbot, top_p, temperature, history=history) # 带超时倒计时
42
 
43
  chatbot[-1] = (i_say, gpt_say)
44
  history.append(i_say); history.append(gpt_say)
45
- yield chatbot, history, msg
46
  res = write_results_to_file(history)
47
  chatbot.append(("完成了吗?", res))
48
- yield chatbot, history, msg
49
 
50
 
51
 
52
  @CatchException
53
- def 读文章写摘要(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
54
  history = [] # 清空历史,以免输入溢出
55
  import glob, os
56
  if os.path.exists(txt):
@@ -58,13 +55,13 @@ def 读文章写摘要(txt, top_p, temperature, chatbot, history, systemPromptTx
58
  else:
59
  if txt == "": txt = '空空如也的输入栏'
60
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
61
- yield chatbot, history, '正常'
62
  return
63
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)] # + \
64
  # [f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)] + \
65
  # [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
66
  if len(file_manifest) == 0:
67
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
68
- yield chatbot, history, '正常'
69
  return
70
- yield from 解析Paper(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
 
1
+ from toolbox import update_ui
2
+ from toolbox import CatchException, report_execption, write_results_to_file
3
+ from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
4
  fast_debug = False
5
 
6
 
7
+ def 解析Paper(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt):
8
  import time, glob, os
9
  print('begin analysis on:', file_manifest)
10
  for index, fp in enumerate(file_manifest):
11
+ with open(fp, 'r', encoding='utf-8', errors='replace') as f:
12
  file_content = f.read()
13
 
14
  prefix = "接下来请你逐文件分析下面的论文文件,概括其内容" if index==0 else ""
15
  i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
16
  i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
17
  chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
18
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
 
19
 
20
  if not fast_debug:
21
  msg = '正常'
22
  # ** gpt request **
23
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(i_say, i_say_show_user, llm_kwargs, chatbot, history=[], sys_prompt=system_prompt) # 带超时倒计时
24
 
 
25
  chatbot[-1] = (i_say_show_user, gpt_say)
26
  history.append(i_say_show_user); history.append(gpt_say)
27
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
 
 
28
  if not fast_debug: time.sleep(2)
29
 
30
  all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
31
  i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
32
  chatbot.append((i_say, "[Local Message] waiting gpt response."))
33
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
34
 
35
  if not fast_debug:
36
  msg = '正常'
37
  # ** gpt request **
38
+ gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(i_say, i_say, llm_kwargs, chatbot, history=history, sys_prompt=system_prompt) # 带超时倒计时
39
 
40
  chatbot[-1] = (i_say, gpt_say)
41
  history.append(i_say); history.append(gpt_say)
42
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
43
  res = write_results_to_file(history)
44
  chatbot.append(("完成了吗?", res))
45
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
46
 
47
 
48
 
49
  @CatchException
50
+ def 读文章写摘要(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
51
  history = [] # 清空历史,以免输入溢出
52
  import glob, os
53
  if os.path.exists(txt):
 
55
  else:
56
  if txt == "": txt = '空空如也的输入栏'
57
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
58
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
59
  return
60
  file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)] # + \
61
  # [f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)] + \
62
  # [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
63
  if len(file_manifest) == 0:
64
  report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex文件: {txt}")
65
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
66
  return
67
+ yield from 解析Paper(file_manifest, project_folder, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt)
crazy_functions/谷歌检索小助手.py CHANGED
@@ -1,5 +1,6 @@
1
  from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
2
  from toolbox import CatchException, report_execption, write_results_to_file
 
3
 
4
  def get_meta_information(url, chatbot, history):
5
  import requests
@@ -55,17 +56,16 @@ def get_meta_information(url, chatbot, history):
55
  })
56
 
57
  chatbot[-1] = [chatbot[-1][0], title + f'\n\n是否在arxiv中(不在arxiv中无法获取完整摘要):{is_paper_in_arxiv}\n\n' + abstract]
58
- msg = "正常"
59
- yield chatbot, [], msg
60
  return profile
61
 
62
  @CatchException
63
- def 谷歌检索小助手(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
64
  # 基本信息:功能、贡献者
65
  chatbot.append([
66
  "函数插件功能?",
67
  "分析用户提供的谷歌学术(google scholar)搜索页面中,出现的所有文章: binary-husky,插件初始化中..."])
68
- yield chatbot, history, '正常'
69
 
70
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
71
  try:
@@ -75,7 +75,7 @@ def 谷歌检索小助手(txt, top_p, temperature, chatbot, history, systemPromp
75
  report_execption(chatbot, history,
76
  a = f"解析项目: {txt}",
77
  b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade beautifulsoup4 arxiv```。")
78
- yield chatbot, history, '正常'
79
  return
80
 
81
  # 清空历史,以免输入溢出
@@ -91,7 +91,7 @@ def 谷歌检索小助手(txt, top_p, temperature, chatbot, history, systemPromp
91
  inputs_show_user = f"请分析此页面中出现的所有文章:{txt}"
92
  gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
93
  inputs=i_say, inputs_show_user=inputs_show_user,
94
- top_p=top_p, temperature=temperature, chatbot=chatbot, history=[],
95
  sys_prompt="你是一个学术翻译,请从数据中提取信息。你必须使用Markdown格式。你必须逐个文献进行处理。"
96
  )
97
 
@@ -100,7 +100,7 @@ def 谷歌检索小助手(txt, top_p, temperature, chatbot, history, systemPromp
100
 
101
  chatbot.append(["状态?", "已经全部完成"])
102
  msg = '正常'
103
- yield chatbot, history, msg
104
  res = write_results_to_file(history)
105
  chatbot.append(("完成了吗?", res));
106
- yield chatbot, history, msg
 
1
  from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
2
  from toolbox import CatchException, report_execption, write_results_to_file
3
+ from toolbox import update_ui
4
 
5
  def get_meta_information(url, chatbot, history):
6
  import requests
 
56
  })
57
 
58
  chatbot[-1] = [chatbot[-1][0], title + f'\n\n是否在arxiv中(不在arxiv中无法获取完整摘要):{is_paper_in_arxiv}\n\n' + abstract]
59
+ yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面
 
60
  return profile
61
 
62
  @CatchException
63
+ def 谷歌检索小助手(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
64
  # 基本信息:功能、贡献者
65
  chatbot.append([
66
  "函数插件功能?",
67
  "分析用户提供的谷歌学术(google scholar)搜索页面中,出现的所有文章: binary-husky,插件初始化中..."])
68
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
69
 
70
  # 尝试导入依赖,如果缺少依赖,则给出安装建议
71
  try:
 
75
  report_execption(chatbot, history,
76
  a = f"解析项目: {txt}",
77
  b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade beautifulsoup4 arxiv```。")
78
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
79
  return
80
 
81
  # 清空历史,以免输入溢出
 
91
  inputs_show_user = f"请分析此页面中出现的所有文章:{txt}"
92
  gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
93
  inputs=i_say, inputs_show_user=inputs_show_user,
94
+ llm_kwargs=llm_kwargs, chatbot=chatbot, history=[],
95
  sys_prompt="你是一个学术翻译,请从数据中提取信息。你必须使用Markdown格式。你必须逐个文献进行处理。"
96
  )
97
 
 
100
 
101
  chatbot.append(["状态?", "已经全部完成"])
102
  msg = '正常'
103
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
104
  res = write_results_to_file(history)
105
  chatbot.append(("完成了吗?", res));
106
+ yield from update_ui(chatbot=chatbot, history=history, msg=msg) # 刷新界面
crazy_functions/高级功能函数模板.py CHANGED
@@ -1,20 +1,29 @@
1
- from toolbox import CatchException
2
  from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
3
  import datetime
4
  @CatchException
5
- def 高阶功能模板函数(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
 
 
 
 
 
 
 
 
 
6
  history = [] # 清空历史,以免输入溢出
7
- chatbot.append(("这是什么功能?", "[Local Message] 请注意,您正在调用一个[函数插件]的模板,该函数面向希望实现更多有趣功能的开发者,它可以作为创建新功能函数的模板(该函数只有20行代码)。此外我们也提供可同步处理大量文件的多线程Demo供您参考。您若希望分享新的功能模组,请不吝PR!"))
8
- yield chatbot, history, '正常' # 由于请求gpt需要一段时间,我们先及时地做一次状态显示
9
  for i in range(5):
10
  currentMonth = (datetime.date.today() + datetime.timedelta(days=i)).month
11
  currentDay = (datetime.date.today() + datetime.timedelta(days=i)).day
12
  i_say = f'历史中哪些事件发生在{currentMonth}月{currentDay}日?列举两条并发送相关图片。发送图片时,请使用Markdown,将Unsplash API中的PUT_YOUR_QUERY_HERE替换成描述该事件的一个最重要的单词。'
13
  gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
14
  inputs=i_say, inputs_show_user=i_say,
15
- top_p=top_p, temperature=temperature, chatbot=chatbot, history=[],
16
  sys_prompt="当你想发送一张照片时,请使用Markdown, 并且不要有反斜线, 不要用代码块。使用 Unsplash API (https://source.unsplash.com/1280x720/? < PUT_YOUR_QUERY_HERE >)。"
17
  )
18
  chatbot[-1] = (i_say, gpt_say)
19
  history.append(i_say);history.append(gpt_say)
20
- yield chatbot, history, '正常'
 
1
+ from toolbox import CatchException, update_ui
2
  from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive
3
  import datetime
4
  @CatchException
5
+ def 高阶功能模板函数(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port):
6
+ """
7
+ txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径
8
+ llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行
9
+ plugin_kwargs 插件模型的参数,暂时没有用武之地
10
+ chatbot 聊天显示框的句柄,用于显示给用户
11
+ history 聊天历史,前情提要
12
+ system_prompt 给gpt的静默提醒
13
+ web_port 当前软件运行的端口号
14
+ """
15
  history = [] # 清空历史,以免输入溢出
16
+ chatbot.append(("这是什么功能?", "[Local Message] 请注意,您正在调用一个[函数插件]的模板,该函数面向希望实现更多有趣功能的开发者,它可以作为创建新功能函数的模板(该函数只有20多行代码)。此外我们也提供可同步处理大量文件的多线程Demo供您参考。您若希望分享新的功能模组,请不吝PR!"))
17
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 由于请求gpt需要一段时间,我们先及时地做一次界面更新
18
  for i in range(5):
19
  currentMonth = (datetime.date.today() + datetime.timedelta(days=i)).month
20
  currentDay = (datetime.date.today() + datetime.timedelta(days=i)).day
21
  i_say = f'历史中哪些事件发生在{currentMonth}月{currentDay}日?列举两条并发送相关图片。发送图片时,请使用Markdown,将Unsplash API中的PUT_YOUR_QUERY_HERE替换成描述该事件的一个最重要的单词。'
22
  gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive(
23
  inputs=i_say, inputs_show_user=i_say,
24
+ llm_kwargs=llm_kwargs, chatbot=chatbot, history=[],
25
  sys_prompt="当你想发送一张照片时,请使用Markdown, 并且不要有反斜线, 不要用代码块。使用 Unsplash API (https://source.unsplash.com/1280x720/? < PUT_YOUR_QUERY_HERE >)。"
26
  )
27
  chatbot[-1] = (i_say, gpt_say)
28
  history.append(i_say);history.append(gpt_say)
29
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 界面更新
docs/Dockerfile+ChatGLM ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # How to build | 如何构建: docker build -t gpt-academic --network=host -f Dockerfile+ChatGLM .
2
+ # How to run | 如何运行 (1) 直接运行(选择0号GPU): docker run --rm -it --net=host --gpus="0" gpt-academic
3
+ # How to run | 如何运行 (2) 我想运行之前进容器做一些调整: docker run --rm -it --net=host --gpus="0" gpt-academic bash
4
+
5
+ # 从NVIDIA源,从而支持显卡运损(检查宿主的nvidia-smi中的cuda版本必须>=11.3)
6
+ FROM nvidia/cuda:11.3.1-runtime-ubuntu20.04
7
+ ARG useProxyNetwork=''
8
+ RUN apt-get update
9
+ RUN apt-get install -y curl proxychains curl
10
+ RUN apt-get install -y git python python3 python-dev python3-dev --fix-missing
11
+
12
+ # 配置代理网络(构建Docker镜像时使用)
13
+ # # comment out below if you do not need proxy network | 如果不需要翻墙 - 从此行向下删除
14
+ RUN $useProxyNetwork curl cip.cc
15
+ RUN sed -i '$ d' /etc/proxychains.conf
16
+ RUN sed -i '$ d' /etc/proxychains.conf
17
+ RUN echo "socks5 127.0.0.1 10880" >> /etc/proxychains.conf
18
+ ARG useProxyNetwork=proxychains
19
+ # # comment out above if you do not need proxy network | 如果不需要翻墙 - 从此行向上删除
20
+
21
+
22
+ # use python3 as the system default python
23
+ RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.8
24
+
25
+ # 下载分支
26
+ WORKDIR /gpt
27
+ RUN $useProxyNetwork git clone https://github.com/binary-husky/chatgpt_academic.git
28
+ WORKDIR /gpt/chatgpt_academic
29
+ RUN $useProxyNetwork python3 -m pip install -r requirements.txt
30
+ RUN $useProxyNetwork python3 -m pip install -r request_llm/requirements_chatglm.txt
31
+ RUN $useProxyNetwork python3 -m pip install torch --extra-index-url https://download.pytorch.org/whl/cu113
32
+
33
+ # 预热CHATGLM参数(非必要 可选步骤)
34
+ RUN echo ' \n\
35
+ from transformers import AutoModel, AutoTokenizer \n\
36
+ chatglm_tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True) \n\
37
+ chatglm_model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).float() ' >> warm_up_chatglm.py
38
+ RUN python3 -u warm_up_chatglm.py
39
+
40
+ # 禁用缓存,确保更新代码
41
+ ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache
42
+ RUN $useProxyNetwork git pull
43
+
44
+ # 预热Tiktoken模块
45
+ RUN python3 -c 'from check_proxy import warm_up_modules; warm_up_modules()'
46
+
47
+ # 为chatgpt-academic配置代理和API-KEY (非必要 可选步骤)
48
+ # 可同时填写多个API-KEY,支持openai的key和api2d的key共存,用英文逗号分割,例如API_KEY = "sk-openaikey1,fkxxxx-api2dkey2,........"
49
+ # LLM_MODEL 是选择初始的模型
50
+ # LOCAL_MODEL_DEVICE 是选择chatglm等本地模型运行的设备,可选 cpu 和 cuda
51
+ RUN echo ' \n\
52
+ API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,fkxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \n\
53
+ USE_PROXY = True \n\
54
+ LLM_MODEL = "chatglm" \n\
55
+ LOCAL_MODEL_DEVICE = "cuda" \n\
56
+ proxies = { "http": "socks5h://localhost:10880", "https": "socks5h://localhost:10880", } ' >> config_private.py
57
+
58
+ # 启动
59
+ CMD ["python3", "-u", "main.py"]
docs/README_EN.md ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ > **Note**
2
+ >
3
+ > This English README is automatically generated by the markdown translation plugin in this project, and may not be 100% correct.
4
+ >
5
+
6
+ # <img src="logo.png" width="40" > ChatGPT Academic Optimization
7
+
8
+ **If you like this project, please give it a Star. If you've come up with more useful academic shortcuts or functional plugins, feel free to open an issue or pull request. We also have a [README in English](docs/README_EN.md) translated by this project itself.**
9
+
10
+ > **Note**
11
+ >
12
+ > 1. Please note that only **functions with red color** supports reading files, some functions are located in the **dropdown menu** of plugins. Additionally, we welcome and prioritize any new plugin PRs with **highest priority**!
13
+ >
14
+ > 2. The functionality of each file in this project is detailed in the self-translation report [`self_analysis.md`](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A) of the project. With the iteration of the version, you can also click on the relevant function plugins at any time to call GPT to regenerate the self-analysis report of the project. The FAQ summary is in the [`wiki`](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) section.
15
+ >
16
+
17
+
18
+ <div align="center">
19
+
20
+ Function | Description
21
+ --- | ---
22
+ One-Click Polish | Supports one-click polishing and finding grammar errors in academic papers.
23
+ One-Key Translation Between Chinese and English | One-click translation between Chinese and English.
24
+ One-Key Code Interpretation | Can correctly display and interpret code.
25
+ [Custom Shortcut Keys](https://www.bilibili.com/video/BV14s4y1E7jN) | Supports custom shortcut keys.
26
+ [Configure Proxy Server](https://www.bilibili.com/video/BV1rc411W7Dr) | Supports configuring proxy servers.
27
+ Modular Design | Supports custom high-order function plugins and [function plugins], and plugins support [hot updates](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%87%BD%E6%95%B0%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97).
28
+ [Self-programming Analysis](https://www.bilibili.com/video/BV1cj411A7VW) | [Function Plugin] [One-Key Read] (https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A) The source code of this project is analyzed.
29
+ [Program Analysis](https://www.bilibili.com/video/BV1cj411A7VW) | [Function Plugin] One-click can analyze the project tree of other Python/C/C++/Java/Lua/... projects
30
+ Read the Paper | [Function Plugin] One-click interpretation of the full text of latex paper and generation of abstracts
31
+ Latex Full Text Translation, Proofreading | [Function Plugin] One-click translation or proofreading of latex papers.
32
+ Batch Comment Generation | [Function Plugin] One-click batch generation of function comments
33
+ Chat Analysis Report Generation | [Function Plugin] After running, an automatic summary report will be generated
34
+ [Arxiv Assistant](https://www.bilibili.com/video/BV1LM4y1279X) | [Function Plugin] Enter the arxiv article url to translate the abstract and download the PDF with one click
35
+ [Full-text Translation Function of PDF Paper](https://www.bilibili.com/video/BV1KT411x7Wn) | [Function Plugin] Extract the title & abstract of the PDF paper + translate the full text (multithreading)
36
+ [Google Scholar Integration Assistant](https://www.bilibili.com/video/BV19L411U7ia) | [Function Plugin] Given any Google Scholar search page URL, let gpt help you choose interesting articles.
37
+ Formula / Picture / Table Display | Can display both the tex form and the rendering form of formulas at the same time, support formula and code highlighting
38
+ Multithreaded Function Plugin Support | Supports multi-threaded calling chatgpt, one-click processing of massive text or programs
39
+ Start Dark Gradio [Theme](https://github.com/binary-husky/chatgpt_academic/issues/173) | Add ```/?__dark-theme=true``` at the end of the browser url to switch to dark theme
40
+ [Multiple LLM Models](https://www.bilibili.com/video/BV1wT411p7yf) support, [API2D](https://api2d.com/) interface support | It must feel nice to be served by both GPT3.5, GPT4, and [Tsinghua ChatGLM](https://github.com/THUDM/ChatGLM-6B)!
41
+ Huggingface non-Science Net [Online Experience](https://huggingface.co/spaces/qingxu98/gpt-academic) | After logging in to huggingface, copy [this space](https://huggingface.co/spaces/qingxu98/gpt-academic)
42
+ ... | ...
43
+
44
+ </div>
45
+
46
+
47
+ - New interface (switch between "left-right layout" and "up-down layout" by modifying the LAYOUT option in config.py)
48
+ <div align="center">
49
+ <img src="https://user-images.githubusercontent.com/96192199/230361456-61078362-a966-4eb5-b49e-3c62ef18b860.gif" width="700" >
50
+ </div>
51
+
52
+
53
+ - All buttons are dynamically generated by reading functional.py and can add custom functionality at will, freeing up clipboard
54
+ <div align="center">
55
+ <img src="https://user-images.githubusercontent.com/96192199/231975334-b4788e91-4887-412f-8b43-2b9c5f41d248.gif" width="700" >
56
+ </div>
57
+
58
+ - Proofreading / correcting
59
+ <div align="center">
60
+ <img src="https://user-images.githubusercontent.com/96192199/231980294-f374bdcb-3309-4560-b424-38ef39f04ebd.gif" width="700" >
61
+ </div>
62
+
63
+ - If the output contains formulas, it will be displayed in both the tex form and the rendering form at the same time, which is convenient for copying and reading
64
+ <div align="center">
65
+ <img src="https://user-images.githubusercontent.com/96192199/230598842-1d7fcddd-815d-40ee-af60-baf488a199df.png" width="700" >
66
+ </div>
67
+
68
+ - Don't want to read the project code? Just take the whole project to chatgpt
69
+ <div align="center">
70
+ <img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="700" >
71
+ </div>
72
+
73
+ - Multiple major language model mixing calls (ChatGLM + OpenAI-GPT3.5 + [API2D](https://api2d.com/)-GPT4)
74
+ <div align="center">
75
+ <img src="https://user-images.githubusercontent.com/96192199/232537274-deca0563-7aa6-4b5d-94a2-b7c453c47794.png" width="700" >
76
+ </div>
77
+
78
+ Multiple major language model mixing call [huggingface beta version](https://huggingface.co/spaces/qingxu98/academic-chatgpt-beta) (the huggingface version does not support chatglm)
79
+
80
+
81
+ ---
82
+
83
+ ## Installation-Method 1: Run directly (Windows, Linux or MacOS)
84
+
85
+ 1. Download project
86
+ ```sh
87
+ git clone https://github.com/binary-husky/chatgpt_academic.git
88
+ cd chatgpt_academic
89
+ ```
90
+
91
+ 2. Configure API_KEY and proxy settings
92
+
93
+
94
+ In `config.py`, configure the overseas Proxy and OpenAI API KEY as follows:
95
+ ```
96
+ 1. If you are in China, you need to set up an overseas proxy to use the OpenAI API smoothly. Please read config.py carefully for setup details (1. Modify USE_PROXY to True; 2. Modify proxies according to the instructions).
97
+ 2. Configure the OpenAI API KEY. You need to register and obtain an API KEY on the OpenAI website. Once you get the API KEY, you can configure it in the config.py file.
98
+ 3. Issues related to proxy networks (network timeouts, proxy failures) are summarized at https://github.com/binary-husky/chatgpt_academic/issues/1
99
+ ```
100
+ (P.S. When the program runs, it will first check whether there is a private configuration file named `config_private.py` and use the same-name configuration in `config.py` to overwrite it. Therefore, if you can understand our configuration reading logic, we strongly recommend that you create a new configuration file named `config_private.py` next to `config.py` and transfer (copy) the configuration in `config.py` to` config_private.py`. `config_private.py` is not controlled by git and can make your privacy information more secure.))
101
+
102
+
103
+ 3. Install dependencies
104
+ ```sh
105
+ # (Option One) Recommended
106
+ python -m pip install -r requirements.txt
107
+
108
+ # (Option Two) If you use anaconda, the steps are similar:
109
+ # (Option Two.1) conda create -n gptac_venv python=3.11
110
+ # (Option Two.2) conda activate gptac_venv
111
+ # (Option Two.3) python -m pip install -r requirements.txt
112
+
113
+ # Note: Use official pip source or Ali pip source. Other pip sources (such as some university pips) may have problems, and temporary replacement methods are as follows:
114
+ # python -m pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
115
+ ```
116
+
117
+ If you need to support Tsinghua ChatGLM, you need to install more dependencies (if you are not familiar with python or your computer configuration is not good, we recommend not to try):
118
+ ```sh
119
+ python -m pip install -r request_llm/requirements_chatglm.txt
120
+ ```
121
+
122
+ 4. Run
123
+ ```sh
124
+ python main.py
125
+ ```
126
+
127
+ 5. Test function plugins
128
+ ```
129
+ - Test Python project analysis
130
+ In the input area, enter `./crazy_functions/test_project/python/dqn`, and then click "Analyze the entire Python project"
131
+ - Test self-code interpretation
132
+ Click "[Multithreading Demo] Interpretation of This Project Itself (Source Code Interpretation)"
133
+ - Test experimental function template function (requires gpt to answer what happened today in history). You can use this function as a template to implement more complex functions.
134
+ Click "[Function Plugin Template Demo] Today in History"
135
+ - There are more functions to choose from in the function plugin area drop-down menu.
136
+ ```
137
+
138
+ ## Installation-Method 2: Use Docker (Linux)
139
+
140
+ 1. ChatGPT only (recommended for most people)
141
+ ``` sh
142
+ # download project
143
+ git clone https://github.com/binary-husky/chatgpt_academic.git
144
+ cd chatgpt_academic
145
+ # configure overseas Proxy and OpenAI API KEY
146
+ Edit config.py with any text editor
147
+ # Install
148
+ docker build -t gpt-academic .
149
+ # Run
150
+ docker run --rm -it --net=host gpt-academic
151
+
152
+ # Test function plug-in
153
+ ## Test function plugin template function (requires gpt to answer what happened today in history). You can use this function as a template to implement more complex functions.
154
+ Click "[Function Plugin Template Demo] Today in History"
155
+ ## Test Abstract Writing for Latex Projects
156
+ Enter ./crazy_functions/test_project/latex/attention in the input area, and then click "Read Tex Paper and Write Abstract"
157
+ ## Test Python Project Analysis
158
+ Enter ./crazy_functions/test_project/python/dqn in the input area and click "Analyze the entire Python project."
159
+
160
+ More functions are available in the function plugin area drop-down menu.
161
+ ```
162
+
163
+ 2. ChatGPT+ChatGLM (requires strong familiarity with docker + strong computer configuration)
164
+
165
+ ``` sh
166
+ # Modify dockerfile
167
+ cd docs && nano Dockerfile+ChatGLM
168
+ # How to build | 如何构建 (Dockerfile+ChatGLM在docs路径下,请先cd docs)
169
+ docker build -t gpt-academic --network=host -f Dockerfile+ChatGLM .
170
+ # How to run | 如何运行 (1) 直接运行:
171
+ docker run --rm -it --net=host --gpus=all gpt-academic
172
+ # How to run | 如何运行 (2) 我想运行之前进容器做一些调整:
173
+ docker run --rm -it --net=host --gpus=all gpt-academic bash
174
+ ```
175
+
176
+
177
+ ## Installation-Method 3: Other Deployment Methods
178
+
179
+ 1. Remote Cloud Server Deployment
180
+ Please visit [Deployment Wiki-1] (https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%9C%E7%A8%8B%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97)
181
+
182
+ 2. Use WSL2 (Windows Subsystem for Linux)
183
+ Please visit [Deployment Wiki-2](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BD%BF%E7%94%A8WSL2%EF%BC%88Windows-Subsystem-for-Linux-%E5%AD%90%E7%B3%BB%E7%BB%9F%EF%BC%89%E9%83%A8%E7%BD%B2)
184
+
185
+
186
+ ## Installation-Proxy Configuration
187
+ ### Method 1: Conventional method
188
+ [Configure Proxy](https://github.com/binary-husky/chatgpt_academic/issues/1)
189
+
190
+ ### Method Two: Step-by-step tutorial for newcomers
191
+ [Step-by-step tutorial for newcomers](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BB%A3%E7%90%86%E8%BD%AF%E4%BB%B6%E9%97%AE%E9%A2%98%E7%9A%84%E6%96%B0%E6%89%8B%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%EF%BC%88%E6%96%B9%E6%B3%95%E5%8F%AA%E9%80%82%E7%94%A8%E4%BA%8E%E6%96%B0%E6%89%8B%EF%BC%89)
192
+
193
+ ---
194
+
195
+ ## Customizing Convenient Buttons (Customizing Academic Shortcuts)
196
+ Open `core_functional.py` with any text editor and add an item as follows, then restart the program (if the button has been successfully added and visible, both the prefix and suffix support hot modification without the need to restart the program to take effect). For example:
197
+ ```
198
+ "Super English to Chinese translation": {
199
+ # Prefix, which will be added before your input. For example, to describe your requirements, such as translation, code interpretation, polishing, etc.
200
+ "Prefix": "Please translate the following content into Chinese and use a markdown table to interpret the proprietary terms in the text one by one:\n\n",
201
+
202
+ # Suffix, which will be added after your input. For example, combined with the prefix, you can put your input content in quotes.
203
+ "Suffix": "",
204
+ },
205
+ ```
206
+ <div align="center">
207
+ <img src="https://user-images.githubusercontent.com/96192199/226899272-477c2134-ed71-4326-810c-29891fe4a508.png" width="500" >
208
+ </div>
209
+
210
+ ---
211
+
212
+
213
+ ## Some Function Displays
214
+
215
+ ### Image Display:
216
+
217
+
218
+ You are a professional academic paper translator.
219
+
220
+ <div align="center">
221
+ <img src="https://user-images.githubusercontent.com/96192199/228737599-bf0a9d9c-1808-4f43-ae15-dfcc7af0f295.png" width="800" >
222
+ </div>
223
+
224
+ ### If a program can understand and analyze itself:
225
+
226
+ <div align="center">
227
+ <img src="https://user-images.githubusercontent.com/96192199/226936850-c77d7183-0749-4c1c-9875-fd4891842d0c.png" width="800" >
228
+ </div>
229
+
230
+ <div align="center">
231
+ <img src="https://user-images.githubusercontent.com/96192199/226936618-9b487e4b-ab5b-4b6e-84c6-16942102e917.png" width="800" >
232
+ </div>
233
+
234
+ ### Analysis of any Python/Cpp project:
235
+ <div align="center">
236
+ <img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="800" >
237
+ </div>
238
+
239
+ <div align="center">
240
+ <img src="https://user-images.githubusercontent.com/96192199/226969067-968a27c1-1b9c-486b-8b81-ab2de8d3f88a.png" width="800" >
241
+ </div>
242
+
243
+ ### One-click reading comprehension and summary generation of Latex papers
244
+ <div align="center">
245
+ <img src="https://user-images.githubusercontent.com/96192199/227504406-86ab97cd-f208-41c3-8e4a-7000e51cf980.png" width="800" >
246
+ </div>
247
+
248
+ ### Automatic report generation
249
+ <div align="center">
250
+ <img src="https://user-images.githubusercontent.com/96192199/227503770-fe29ce2c-53fd-47b0-b0ff-93805f0c2ff4.png" height="300" >
251
+ <img src="https://user-images.githubusercontent.com/96192199/227504617-7a497bb3-0a2a-4b50-9a8a-95ae60ea7afd.png" height="300" >
252
+ <img src="https://user-images.githubusercontent.com/96192199/227504005-efeaefe0-b687-49d0-bf95-2d7b7e66c348.png" height="300" >
253
+ </div>
254
+
255
+ ### Modular functional design
256
+ <div align="center">
257
+ <img src="https://user-images.githubusercontent.com/96192199/229288270-093643c1-0018-487a-81e6-1d7809b6e90f.png" height="400" >
258
+ <img src="https://user-images.githubusercontent.com/96192199/227504931-19955f78-45cd-4d1c-adac-e71e50957915.png" height="400" >
259
+ </div>
260
+
261
+ ### Source code translation to English
262
+
263
+ <div align="center">
264
+ <img src="https://user-images.githubusercontent.com/96192199/229720562-fe6c3508-6142-4635-a83d-21eb3669baee.png" height="400" >
265
+ </div>
266
+
267
+ ## Todo and version planning:
268
+ - version 3.2+ (todo): Function plugin supports more parameter interfaces
269
+ - version 3.1: Support for inquiring multiple GPT models at the same time! Support for api2d, support for multiple apikeys load balancing
270
+ - version 3.0: Support for chatglm and other small llms
271
+ - version 2.6: Refactored the plugin structure, improved interactivity, added more plugins
272
+ - version 2.5: Self-updating, solves the problem of text being too long and token overflowing when summarizing large project source code
273
+ - version 2.4: (1) Added PDF full text translation function; (2) Added function to switch input area position; (3) Added vertical layout option; (4) Multi-threaded function plugin optimization.
274
+ - version 2.3: Enhanced multi-threaded interactivity
275
+ - version 2.2: Function plugin supports hot reloading
276
+ - version 2.1: Foldable layout
277
+ - version 2.0: Introduction of modular function plugins
278
+ - version 1.0: Basic functions
279
+
280
+ ## Reference and learning
281
+
282
+ ```
283
+ The code design of this project has referenced many other excellent projects, including:
284
+
285
+ # Reference project 1: Borrowed many tips from ChuanhuChatGPT
286
+ https://github.com/GaiZhenbiao/ChuanhuChatGPT
287
+
288
+ # Reference project 2: Tsinghua ChatGLM-6B:
289
+ https://github.com/THUDM/ChatGLM-6B
290
+ ```
291
+
docs/README_FR.md ADDED
@@ -0,0 +1,296 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ > **Note**
2
+ >
3
+ > Ce fichier README est généré automatiquement par le plugin de traduction markdown de ce projet et n'est peut - être pas correct à 100%.
4
+ >
5
+
6
+ # <img src="logo.png" width="40" > ChatGPT Optimisation Académique
7
+
8
+ **Si vous aimez ce projet, donnez-lui une étoile; si vous avez inventé des raccourcis académiques plus utiles ou des plugins fonctionnels, n'hésitez pas à ouvrir une demande ou une demande de traction. Nous avons également un fichier README en [anglais|](docs/README_EN.md)[japonais|](docs/README_JP.md)[russe|](docs/README_RS.md)[français](docs/README_FR.md) traduit par ce projet lui-même.**
9
+
10
+ > **Note**
11
+ >
12
+ > 1. Veuillez noter que seuls les plugins de fonction signalés en **rouge** sont capables de lire les fichiers, certains plugins se trouvent dans le **menu déroulant** de la section plugin. Nous sommes également les bienvenus avec la plus haute priorité pour traiter et accepter tout nouveau PR de plugin!
13
+ >
14
+ > 2. Chaque fichier dans ce projet est expliqué en détail dans l'auto-analyse [self_analysis.md](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A). Avec l'itération des versions, vous pouvez également cliquer sur les plugins fonctionnels pertinents pour appeler GPT et générer un rapport d'auto-analyse projet mis à jour. Les questions fréquemment posées sont résumées dans le [wiki](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98).
15
+ >
16
+
17
+ <div align="center">
18
+
19
+ Fonctionnalité | Description
20
+ --- | ---
21
+ Polissage en un clic | Prend en charge la correction en un clic et la recherche d'erreurs de syntaxe dans les documents de recherche.
22
+ Traduction Chinois-Anglais en un clic | Une touche pour traduire la partie chinoise en anglais ou celle anglaise en chinois.
23
+ Explication de code en un clic | Affiche et explique correctement le code.
24
+ [Raccourcis clavier personnalisables](https://www.bilibili.com/video/BV14s4y1E7jN) | Prend en charge les raccourcis clavier personnalisables.
25
+ [Configuration du serveur proxy](https://www.bilibili.com/video/BV1rc411W7Dr) | Prend en charge la configuration du serveur proxy.
26
+ Conception modulaire | Prend en charge la personnalisation des plugins de fonctions et des [plugins] de fonctions hiérarchiques personnalisés, et les plugins prennent en charge [la mise à jour à chaud](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%87%BD%E6%95%B0%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97).
27
+ [Auto-analyse du programme](https://www.bilibili.com/video/BV1cj411A7VW) | [Plugins] [Lire en un clic](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A) le code source de ce projet.
28
+ [Analyse de programme](https://www.bilibili.com/video/BV1cj411A7VW) | [Plugins] En un clic, les projets Python/C/C++/Java/Lua/... peuvent être analysés.
29
+ Lire le document de recherche | [Plugins] Lisez le résumé de l'article en latex et générer un résumé.
30
+ Traduction et polissage de l'article complet en LaTeX | [Plugins] Une touche pour traduire ou corriger en LaTeX
31
+ Génération Commentaire de fonction en vrac | [Plugins] Lisez en un clic les fonctions et générez des commentaires de fonction.
32
+ Rapport d'analyse automatique des chats générés | [Plugins] Génère un rapport de synthèse après l'exécution.
33
+ [Assistant arxiv](https://www.bilibili.com/video/BV1LM4y1279X) | [Plugins] Entrez l'url de l'article arxiv pour traduire le résumé + télécharger le PDF en un clic
34
+ [Traduction complète des articles PDF](https://www.bilibili.com/video/BV1KT411x7Wn) | [Plugins] Extraire le titre et le résumé de l'article PDF + Traduire le texte entier (multithread)
35
+ [Aide à la recherche Google Academ](https://www.bilibili.com/video/BV19L411U7ia) | [Plugins] Donnez à GPT l'URL de n'importe quelle page de recherche Google Academ pour vous aider à sélectionner des articles intéressants
36
+ Affichage de formules/images/tableaux | Afficher la forme traduite et rendue d'une formule en même temps, plusieurs formules et surlignage du code prend en charge
37
+ Prise en charge des plugins multithread | Prise en charge de l'appel multithread de chatgpt, traitement en masse de texte ou de programmes en un clic
38
+ Activer le thème Gradio sombre [theme](https://github.com/binary-husky/chatgpt_academic/issues/173) au démarrage | Ajoutez ```/?__dark-theme=true``` à l'URL du navigateur pour basculer vers le thème sombre
39
+ [Prise en charge de plusieurs modèles LLM](https://www.bilibili.com/video/BV1wT411p7yf), [prise en charge de l'interface API2D](https://api2d.com/) | Comment cela serait-il de se faire servir par GPT3.5, GPT4 et la [ChatGLM de Tsinghua](https://github.com/THUDM/ChatGLM-6B) en même temps?
40
+ Expérience en ligne d'huggingface sans science | Après vous être connecté à huggingface, copiez [cet espace](https://huggingface.co/spaces/qingxu98/gpt-academic)
41
+ ... | ...
42
+
43
+ </div>
44
+
45
+
46
+ Vous êtes un traducteur professionnel d'articles universitaires en français.
47
+
48
+ Ceci est un fichier Markdown, veuillez le traduire en français sans modifier les commandes Markdown existantes :
49
+
50
+ - Nouvelle interface (modifiable en modifiant l'option de mise en page dans config.py pour basculer entre les mises en page gauche-droite et haut-bas)
51
+ <div align="center">
52
+ <img src="https://user-images.githubusercontent.com/96192199/230361456-61078362-a966-4eb5-b49e-3c62ef18b860.gif" width="700" >
53
+ </div>
54
+
55
+
56
+ - Tous les boutons sont générés dynamiquement en lisant functional.py, les utilisateurs peuvent ajouter librement des fonctions personnalisées pour libérer le presse-papiers.
57
+ <div align="center">
58
+ <img src="https://user-images.githubusercontent.com/96192199/231975334-b4788e91-4887-412f-8b43-2b9c5f41d248.gif" width="700" >
59
+ </div>
60
+
61
+ - Correction/amélioration
62
+ <div align="center">
63
+ <img src="https://user-images.githubusercontent.com/96192199/231980294-f374bdcb-3309-4560-b424-38ef39f04ebd.gif" width="700" >
64
+ </div>
65
+
66
+ - Si la sortie contient des formules, elles seront affichées simultanément sous forme de de texte brut et de forme rendue pour faciliter la copie et la lecture.
67
+ <div align="center">
68
+ <img src="https://user-images.githubusercontent.com/96192199/230598842-1d7fcddd-815d-40ee-af60-baf488a199df.png" width="700" >
69
+ </div>
70
+
71
+ - Pas envie de lire le code du projet ? Faites votre propre démo avec ChatGPT.
72
+ <div align="center">
73
+ <img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="700" >
74
+ </div>
75
+
76
+ - Utilisation combinée de plusieurs modèles de langage sophistiqués (ChatGLM + OpenAI-GPT3.5 + [API2D](https://api2d.com/)-GPT4)
77
+ <div align="center">
78
+ <img src="https://user-images.githubusercontent.com/96192199/232537274-deca0563-7aa6-4b5d-94a2-b7c453c47794.png" width="700" >
79
+ </div>
80
+
81
+ Utilisation combinée de plusieurs modèles de langage sophistiqués en version de test [huggingface](https://huggingface.co/spaces/qingxu98/academic-chatgpt-beta) (la version huggingface ne prend pas en charge Chatglm).
82
+
83
+
84
+ ---
85
+
86
+ ## Installation - Méthode 1 : Exécution directe (Windows, Linux or MacOS)
87
+
88
+ 1. Téléchargez le projet
89
+ ```sh
90
+ git clone https://github.com/binary-husky/chatgpt_academic.git
91
+ cd chatgpt_academic
92
+ ```
93
+
94
+ 2. Configuration de l'API_KEY et des paramètres de proxy
95
+
96
+ Dans `config.py`, configurez les paramètres de proxy et de clé d'API OpenAI, comme indiqué ci-dessous
97
+ ```
98
+ 1. Si vous êtes en Chine, vous devez configurer un proxy étranger pour utiliser l'API OpenAI en toute transparence. Pour ce faire, veuillez lire attentivement le fichier config.py (1. Modifiez l'option USE_PROXY ; 2. Modifiez les paramètres de proxies comme indiqué dans les instructions).
99
+ 2. Configurez votre clé API OpenAI. Vous devez vous inscrire sur le site web d'OpenAI pour obtenir une clé API. Une fois que vous avez votre clé API, vous pouvez la configurer dans le fichier config.py.
100
+ 3. Tous les problèmes liés aux réseaux de proxy (temps d'attente, non-fonctionnement des proxies) sont résumés dans https://github.com/binary-husky/chatgpt_academic/issues/1.
101
+ ```
102
+ (Remarque : le programme vérifie d'abord s'il existe un fichier de configuration privé nommé `config_private.py`, et utilise les configurations de celui-ci à la place de celles du fichier `config.py`. Par conséquent, si vous comprenez notre logique de lecture de configuration, nous vous recommandons fortement de créer un nouveau fichier de configuration nommé `config_private.py` à côté de `config.py` et de transférer (copier) les configurations de celui-ci dans `config_private.py`. `config_private.py` n'est pas contrôlé par git et rend vos informations personnelles plus sûres.)
103
+
104
+ 3. Installation des dépendances
105
+ ```sh
106
+ # (Option 1) Recommandé
107
+ python -m pip install -r requirements.txt
108
+
109
+ # (Option 2) Si vous utilisez anaconda, les étapes sont similaires :
110
+ # (Option 2.1) conda create -n gptac_venv python=3.11
111
+ # (Option 2.2) conda activate gptac_venv
112
+ # (Option 2.3) python -m pip install -r requirements.txt
113
+
114
+ # note : Utilisez la source pip officielle ou la source pip Alibaba. D'autres sources (comme celles des universités) pourraient poser problème. Pour utiliser temporairement une autre source, utilisez :
115
+ # python -m pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
116
+ ```
117
+
118
+ Si vous avez besoin de soutenir ChatGLM de Tsinghua, vous devez installer plus de dépendances (si vous n'êtes pas familier avec Python ou que votre ordinateur n'est pas assez performant, nous vous recommandons de ne pas essayer) :
119
+ ```sh
120
+ python -m pip install -r request_llm/requirements_chatglm.txt
121
+ ```
122
+
123
+ 4. Exécution
124
+ ```sh
125
+ python main.py
126
+ ```
127
+
128
+ 5. Tester les plugins de fonctions
129
+ ```
130
+ - Test Python Project Analysis
131
+ Dans la zone de saisie, entrez `./crazy_functions/test_project/python/dqn`, puis cliquez sur "Parse Entire Python Project"
132
+ - Test d'auto-lecture du code
133
+ Cliquez sur "[Démo multi-thread] Parser ce projet lui-même (auto-traduction de la source)"
134
+ - Test du modèle de fonctionnalité expérimentale (exige une réponse de l'IA à ce qui est arrivé aujourd'hui dans l'histoire). Vous pouvez utiliser cette fonctionnalité comme modèle pour des fonctions plus complexes.
135
+ Cliquez sur "[Démo modèle de plugin de fonction] Histoire du Jour"
136
+ - Le menu déroulant de la zone de plugin de fonctionnalité contient plus de fonctionnalités à sélectionner.
137
+ ```
138
+
139
+ ## Installation - Méthode 2 : Utilisation de docker (Linux)
140
+
141
+
142
+ Vous êtes un traducteur professionnel d'articles académiques en français.
143
+
144
+ 1. ChatGPT seul (recommandé pour la plupart des gens)
145
+ ``` sh
146
+ # Télécharger le projet
147
+ git clone https://github.com/binary-husky/chatgpt_academic.git
148
+ cd chatgpt_academic
149
+ # Configurer le proxy outre-mer et la clé API OpenAI
150
+ Modifier le fichier config.py avec n'importe quel éditeur de texte
151
+ # Installer
152
+ docker build -t gpt-academic .
153
+ # Exécuter
154
+ docker run --rm -it --net=host gpt-academic
155
+
156
+ # Tester les modules de fonction
157
+ ## Tester la fonction modèle des modules (requiert la réponse de GPT à "qu'est-ce qui s'est passé dans l'histoire aujourd'hui ?"), vous pouvez utiliser cette fonction en tant que modèle pour implémenter des fonctions plus complexes.
158
+ Cliquez sur "[Exemple de modèle de module] Histoire d'aujourd'hui"
159
+ ## Tester le résumé écrit pour le projet LaTeX
160
+ Dans la zone de saisie, tapez ./crazy_functions/test_project/latex/attention, puis cliquez sur "Lire le résumé de l'article de recherche LaTeX"
161
+ ## Tester l'analyse du projet Python
162
+ Dans la zone de saisie, tapez ./crazy_functions/test_project/python/dqn, puis cliquez sur "Analyser l'ensemble du projet Python"
163
+
164
+ D'autres fonctions sont disponibles dans la liste déroulante des modules de fonction.
165
+ ```
166
+
167
+ 2. ChatGPT+ChatGLM (nécessite une grande connaissance de docker et une configuration informatique suffisamment puissante)
168
+ ``` sh
169
+ # Modifier le dockerfile
170
+ cd docs && nano Dockerfile+ChatGLM
171
+ # Comment construire | 如何构建 (Dockerfile+ChatGLM在docs路径下,请先cd docs)
172
+ docker build -t gpt-academic --network=host -f Dockerfile+ChatGLM .
173
+ # Comment exécuter | 如何运行 (1) Directement exécuter :
174
+ docker run --rm -it --net=host --gpus=all gpt-academic
175
+ # Comment exécuter | 如何运行 (2) Je veux effectuer quelques ajustements dans le conteneur avant de lancer :
176
+ docker run --rm -it --net=host --gpus=all gpt-academic bash
177
+ ```
178
+
179
+ ## Installation - Méthode 3 : Autres méthodes de déploiement
180
+
181
+ 1. Déploiement sur un cloud serveur distant
182
+ Veuillez consulter le [wiki de déploiement-1](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%9C%E7%A8%8B%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97)
183
+
184
+ 2. Utilisation de WSL2 (Windows Subsystem for Linux)
185
+ Veuillez consulter le [wiki de déploiement-2](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BD%BF%E7%94%A8WSL2%EF%BC%88Windows-Subsystem-for-Linux-%E5%AD%90%E7%B3%BB%E7%BB%9F%EF%BC%89%E9%83%A8%E7%BD%B2)
186
+
187
+
188
+ ## Configuration de la procuration de l'installation
189
+ ### Méthode 1 : Méthode conventionnelle
190
+ [Configuration de la procuration](https://github.com/binary-husky/chatgpt_academic/issues/1)
191
+
192
+ ### Méthode 2 : Tutoriel pour débutant pur
193
+ [Tutoriel pour débutant pur](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BB%A3%E7%90%86%E8%BD%AF%E4%BB%B6%E9%97%AE%E9%A2%98%E7%9A%84%E6%96%B0%E6%89%8B%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%EF%BC%88%E6%96%B9%E6%B3%95%E5%8F%AA%E9%80%82%E7%94%A8%E4%BA%8E%E6%96%B0%E6%89%8B%EF%BC%89)
194
+
195
+
196
+ ---
197
+
198
+ ## Personnalisation des nouveaux boutons pratiques (personnalisation des raccourcis académiques)
199
+ Ouvrez le fichier `core_functional.py` avec n'importe quel éditeur de texte, ajoutez les éléments suivants, puis redémarrez le programme. (Si le bouton a déjà été ajouté avec succès et est visible, le préfixe et le suffixe pris en charge peuvent être modifiés à chaud sans avoir besoin de redémarrer le programme.)
200
+ Par exemple:
201
+ ```
202
+ "Traduction Français-Chinois": {
203
+ # Préfixe, qui sera ajouté avant votre saisie. Par exemple, pour décrire votre demande, telle que la traduction, le débogage de code, l'amélioration, etc.
204
+ "Prefix": "Veuillez traduire le contenu ci-dessous en chinois, puis expliquer chaque terme propre mentionné dans un tableau Markdown :\n\n",
205
+
206
+ # Suffixe, qui sera ajouté après votre saisie. Par exemple, en combinaison avec un préfixe, vous pouvez mettre le contenu de votre saisie entre guillemets.
207
+ "Suffix": "",
208
+ },
209
+ ```
210
+
211
+ <div align="center">
212
+ <img src="https://user-images.githubusercontent.com/96192199/226899272-477c2134-ed71-4326-810c-29891fe4a508.png" width="500" >
213
+ </div>
214
+
215
+ ---
216
+
217
+
218
+ ## Présentation de certaines fonctionnalités
219
+
220
+ ### Affichage des images:
221
+
222
+ <div align="center">
223
+ <img src="https://user-images.githubusercontent.com/96192199/228737599-bf0a9d9c-1808-4f43-ae15-dfcc7af0f295.png" width="800" >
224
+ </div>
225
+
226
+
227
+ ### Si un programme peut comprendre et décomposer lui-même :
228
+
229
+ <div align="center">
230
+ <img src="https://user-images.githubusercontent.com/96192199/226936850-c77d7183-0749-4c1c-9875-fd4891842d0c.png" width="800" >
231
+ </div>
232
+
233
+ <div align="center">
234
+ <img src="https://user-images.githubusercontent.com/96192199/226936618-9b487e4b-ab5b-4b6e-84c6-16942102e917.png" width="800" >
235
+ </div>
236
+
237
+
238
+ ### Analyse de tout projet Python/Cpp quelconque :
239
+ <div align="center">
240
+ <img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="800" >
241
+ </div>
242
+
243
+ <div align="center">
244
+ <img src="https://user-images.githubusercontent.com/96192199/226969067-968a27c1-1b9c-486b-8b81-ab2de8d3f88a.png" width="800" >
245
+ </div>
246
+
247
+ ### Lecture et résumé générés automatiquement pour les articles en Latex
248
+ <div align="center">
249
+ <img src="https://user-images.githubusercontent.com/96192199/227504406-86ab97cd-f208-41c3-8e4a-7000e51cf980.png" width="800" >
250
+ </div>
251
+
252
+ ### Génération de rapports automatique
253
+ <div align="center">
254
+ <img src="https://user-images.githubusercontent.com/96192199/227503770-fe29ce2c-53fd-47b0-b0ff-93805f0c2ff4.png" height="300" >
255
+ <img src="https://user-images.githubusercontent.com/96192199/227504617-7a497bb3-0a2a-4b50-9a8a-95ae60ea7afd.png" height="300" >
256
+ <img src="https://user-images.githubusercontent.com/96192199/227504005-efeaefe0-b687-49d0-bf95-2d7b7e66c348.png" height="300" >
257
+ </div>
258
+
259
+ ### Conception de fonctionnalités modulaires
260
+ <div align="center">
261
+ <img src="https://user-images.githubusercontent.com/96192199/229288270-093643c1-0018-487a-81e6-1d7809b6e90f.png" height="400" >
262
+ <img src="https://user-images.githubusercontent.com/96192199/227504931-19955f78-45cd-4d1c-adac-e71e50957915.png" height="400" >
263
+ </div>
264
+
265
+
266
+ ### Traduction de code source en anglais
267
+
268
+ <div align="center">
269
+ <img src="https://user-images.githubusercontent.com/96192199/229720562-fe6c3508-6142-4635-a83d-21eb3669baee.png" height="400" >
270
+ </div>
271
+
272
+ ## À faire et planification de version :
273
+ - version 3.2+ (à faire) : Prise en charge de plus de paramètres d'interface de plugin de fonction
274
+ - version 3.1 : Prise en charge de l'interrogation simultanée de plusieurs modèles GPT ! Prise en charge de l'API2d, prise en charge de la répartition de charge de plusieurs clés API
275
+ - version 3.0 : Prise en charge de chatglm et d'autres petits llm
276
+ - version 2.6 : Réorganisation de la structure du plugin, amélioration de l'interactivité, ajout de plus de plugins
277
+ - version 2.5 : Mise à jour automatique, résolution du problème de dépassement de jeton et de texte trop long lors de la compilation du code source complet
278
+ - version 2.4 : (1) Ajout de la fonctionnalité de traduction intégrale de PDF ; (2) Ajout d'une fonctionnalité de changement de position de zone de saisie ; (3) Ajout d'une option de disposition verticale ; (4) Optimisation du plugin de fonction multi-thread.
279
+ - version 2.3 : Amélioration de l'interactivité multi-thread
280
+ - version 2.2 : Prise en charge du rechargement à chaud du plugin de fonction
281
+ - version 2.1 : Mise en page pliable
282
+ - version 2.0 : Introduction du plugin de fonction modulaire
283
+ - version 1.0 : Fonctionnalité de base
284
+
285
+ ## Références et apprentissage
286
+
287
+ ```
288
+ De nombreux designs d'autres projets exceptionnels ont été utilisés pour référence dans le code, notamment :
289
+
290
+ # Projet 1 : De nombreuses astuces ont été empruntées à ChuanhuChatGPT
291
+ https://github.com/GaiZhenbiao/ChuanhuChatGPT
292
+
293
+ # Projet 2 : ChatGLM-6B de Tsinghua :
294
+ https://github.com/THUDM/ChatGLM-6B
295
+ ```
296
+
docs/README_JP.md ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ > **Note**
2
+ >
3
+ > このReadmeファイルは、このプロジェクトのmarkdown翻訳プラグインによって自動的に生成されたもので、100%正確ではない可能性があります。
4
+ >
5
+
6
+ # <img src="logo.png" width="40" > ChatGPT 学術最適化
7
+
8
+ **このプロジェクトが好きだったら、スターをつけてください。もし、より使いやすい学術用のショートカットキーまたはファンクションプラグインを発明した場合は、issueを発行するかpull requestを作成してください。また、このプロジェクト自体によって翻訳されたREADMEは[英語説明書|](docs/README_EN.md)[日本語説明書|](docs/README_JP.md)[ロシア語説明書|](docs/README_RS.md)[フランス語説明書](docs/README_FR.md)もあります。**
9
+
10
+ > **注意事項**
11
+ >
12
+ > 1. **赤色**のラベルが付いているファンクションプラグイン(ボタン)のみファイルを読み込めます。一部のプラグインはプラグインエリアのドロップダウンメニューにあります。新しいプラグインのPRを歓迎いたします!
13
+ >
14
+ > 2. このプロジェクトの各ファイルの機能は`self_analysis.md`(自己解析レポート)で詳しく説明されています。バージョンが追加されると、関連するファンクションプラグインをクリックして、GPTを呼び出して自己解析レポートを再生成することができます。一般的な質問は`wiki`にまとめられています。(`https://github.com/binary-husky/chatgpt_academic/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98`)
15
+
16
+
17
+ <div align="center">
18
+
19
+ 機能 | 説明
20
+ --- | ---
21
+ ワンクリック整形 | 論文の文法エラーを一括で正確に修正できます。
22
+ ワンクリック日英翻訳 | 日英翻訳には、ワンクリックで対応できます。
23
+ ワンクリックコード説明 | コードの正しい表示と説明が可能です。
24
+ [カスタムショートカットキー](https://www.bilibili.com/video/BV14s4y1E7jN) | カスタムショートカットキーをサポートします。
25
+ [プロキシサーバーの設定](https://www.bilibili.com/video/BV1rc411W7Dr) | プロキシサーバーの設定をサポートします。
26
+ モジュラーデザイン | カスタム高階関数プラグインと[関数プラグイン]、プラグイン[ホット更新]のサポートが可能です。詳細は[こちら](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%87%BD%E6%95%B0%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97)
27
+ [自己プログラム解析](https://www.bilibili.com/video/BV1cj411A7VW) | [関数プラグイン][ワンクリック理解](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A)このプロジェクトのソースコード
28
+ [プログラム解析機能](https://www.bilibili.com/video/BV1cj411A7VW) | [関数プラグイン] ワンクリックで別のPython/C/C++/Java/Lua/...プロジェクトツリーを解析できます。
29
+ 論文読解 | [関数プラグイン] LaTeX論文の全文をワンクリックで解読し、要約を生成します。
30
+ LaTeX全文翻訳、整形 | [関数プラグイン] ワンクリックでLaTeX論文を翻訳または整形できます。
31
+ 注釈生成 | [関数プラグイン] ワンクリックで関数の注釈を大量に生成できます。
32
+ チャット分析レポート生成 | [関数プラグイン] 実行後、まとめレポートを自動生成します。
33
+ [arxivヘルパー](https://www.bilibili.com/video/BV1LM4y1279X) | [関数プラグイン] 入力したarxivの記事URLで要約をワンクリック翻訳+PDFダウンロードができます。
34
+ [PDF論文全文翻訳機能](https://www.bilibili.com/video/BV1KT411x7Wn) | [関数プラグイン] PDF論文タイトルと要約を抽出し、全文を翻訳します(マルチスレッド)。
35
+ [Google Scholar Integratorヘルパー](https://www.bilibili.com/video/BV19L411U7ia) | [関数プラグイン] 任意のGoogle Scholar検索ページURLを指定すると、gptが興味深い記事を選択します。
36
+ 数式/画像/テーブル表示 | 数式のTex形式とレンダリング形式を同時に表示できます。数式、コードのハイライトをサポートしています。
37
+ マルチスレッド関数プラグインサポート | ChatGPTをマルチスレッドで呼び出すことができ、大量のテキストやプログラムを簡単に処理できます。
38
+ ダークグラジオ[テーマ](https://github.com/binary-husky/chatgpt_academic/issues/173)の起動 | 「/?__dark-theme=true」というURLをブラウザに追加することで、ダークテーマに切り替えることができます。
39
+ [多数のLLMモデル](https://www.bilibili.com/video/BV1wT411p7yf)をサポート、[API2D](https://api2d.com/)インターフェースをサポート | GPT3.5、GPT4、[清華ChatGLM](https://github.com/THUDM/ChatGLM-6B)による同時サポートは、と���も素晴らしいですね!
40
+ huggingface免科学上网[オンライン版](https://huggingface.co/spaces/qingxu98/gpt-academic) | huggingfaceにログイン後、[このスペース](https://huggingface.co/spaces/qingxu98/gpt-academic)をコピーしてください。
41
+ ...... | ......
42
+
43
+
44
+ </div>
45
+
46
+
47
+ - 新しいインターフェース(config.pyのLAYOUTオプションを変更するだけで、「左右レイアウト」と「上下レイアウト」を切り替えることができます)
48
+ <div align="center">
49
+ <img src="https://user-images.githubusercontent.com/96192199/230361456-61078362-a966-4eb5-b49e-3c62ef18b860.gif" width="700" >
50
+ </div>
51
+
52
+
53
+ - すべてのボタンは、functional.pyを読み込んで動的に生成されます。カスタム機能を自由に追加して、クリップボードを解放します
54
+ <div align="center">
55
+ <img src="https://user-images.githubusercontent.com/96192199/231975334-b4788e91-4887-412f-8b43-2b9c5f41d248.gif" width="700" >
56
+ </div>
57
+
58
+ - 色を修正/修正
59
+ <div align="center">
60
+ <img src="https://user-images.githubusercontent.com/96192199/231980294-f374bdcb-3309-4560-b424-38ef39f04ebd.gif" width="700" >
61
+ </div>
62
+
63
+ - 出力に数式が含まれている場合、TeX形式とレンダリング形式の両方が表示され、コピーと読み取りが容易になります
64
+ <div align="center">
65
+ <img src="https://user-images.githubusercontent.com/96192199/230598842-1d7fcddd-815d-40ee-af60-baf488a199df.png" width="700" >
66
+ </div>
67
+
68
+ - プロジェクトのコードを見るのが面倒?chatgptに整備されたプロジェクトを直接与えましょう
69
+ <div align="center">
70
+ <img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="700" >
71
+ </div>
72
+
73
+ - 多数の大規模言語モデルの混合呼び出し(ChatGLM + OpenAI-GPT3.5 + [API2D](https://api2d.com/)-GPT4)
74
+ <div align="center">
75
+ <img src="https://user-images.githubusercontent.com/96192199/232537274-deca0563-7aa6-4b5d-94a2-b7c453c47794.png" width="700" >
76
+ </div>
77
+
78
+ 多数の大規模言語モデルの混合呼び出し[huggingfaceテスト版](https://huggingface.co/spaces/qingxu98/academic-chatgpt-beta)(huggigface版はchatglmをサポートしていません)
79
+
80
+
81
+ ---
82
+
83
+ ## インストール-方法1:直接運転 (Windows、LinuxまたはMacOS)
84
+
85
+ 1. プロジェクトをダウンロードします。
86
+ ```sh
87
+ git clone https://github.com/binary-husky/chatgpt_academic.git
88
+ cd chatgpt_academic
89
+ ```
90
+
91
+ 2. API_KEYとプロキシ設定を構成する
92
+
93
+ `config.py`で、海外のProxyとOpenAI API KEYを構成して説明します。
94
+ ```
95
+ 1.あなたが中国にいる場合、OpenAI APIをスムーズに使用するには海外プロキシを設定する必要があります。構成の詳細については、config.py(1.その中のUSE_PROXYをTrueに変更し、2.手順に従ってプロキシを変更する)を詳細に読んでください。
96
+ 2. OpenAI API KEYを構成する。OpenAIのウェブサイトでAPI KEYを取得してください。一旦API KEYを手に入れると、config.pyファイルで設定するだけです。
97
+ 3.プロキシネットワークに関連する問題(ネットワークタイムアウト、プロキシが動作しない)をhttps://github.com/binary-husky/chatgpt_academic/issues/1にまとめました。
98
+ ```
99
+ (P.S. プログラム実行時にconfig.pyの隣にconfig_private.pyという名前のプライバシー設定ファイルを作成し、同じ名前の設定を上書きするconfig_private.pyが存在するかどうかを優先的に確認します。そのため、私たちの構成読み取りロジックを理解できる場合は、config.pyの隣にconfig_private.pyという名前の新しい設定ファイルを作成し、その中のconfig.pyから設定を移動してください。config_private.pyはgitで保守されていないため、プライバシー情報をより安全にすることができます。)
100
+
101
+ 3. 依存関係をインストールします。
102
+ ```sh
103
+ # 選択肢があります。
104
+ python -m pip install -r requirements.txt
105
+
106
+
107
+ # (選択肢2) もしAnacondaを使用する場合、手順は同様です:
108
+ # (選択肢2.1) conda create -n gptac_venv python=3.11
109
+ # (選択肢2.2) conda activate gptac_venv
110
+ # (選択肢2.3) python -m pip install -r requirements.txt
111
+
112
+ # 注: 公式のpipソースまたはAlibabaのpipソースを使用してください。 別のpipソース(例:一部の大学のpip)は問題が発生する可能性があります。 一時的なソースの切り替え方法:
113
+ # python -m pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
114
+ ```
115
+
116
+ もしあなたが清華ChatGLMをサポートする必要がある場合、さらに多くの依存関係をインストールする必要があります(Pythonに慣れない方やコンピューターの設定が十分でない方は、試みないことをお勧めします):
117
+ ```sh
118
+ python -m pip install -r request_llm/requirements_chatglm.txt
119
+ ```
120
+
121
+ 4. 実行
122
+ ```sh
123
+ python main.py
124
+ ```
125
+
126
+ 5. 関数プラグインのテスト
127
+ ```
128
+ - Pythonプロジェクト分析のテスト
129
+ 入力欄に `./crazy_functions/test_project/python/dqn` と入力し、「Pythonプロジェクト全体の解析」をクリックします。
130
+ - 自己コード解読のテスト
131
+ 「[マルチスレッドデモ] このプロジェクト自体を解析します(ソースを翻訳して解読します)」をクリックします。
132
+ - 実験的な機能テンプレート関数のテスト(GPTが「今日の歴史」に何が起こったかを回答することが求められます)。この関数をテンプレートとして使用して、より複雑な機能を実装できます。
133
+ 「[関数プラグインテンプレートデモ] 今日の歴史」をクリックします。
134
+ - 関数プラグインエリアのドロップダウンメニューには他にも選択肢があります。
135
+ ```
136
+
137
+ ## インストール方法2:Dockerを使用する(Linux)
138
+
139
+ 1. ChatGPTのみ(大多数の人にお勧めです)
140
+ ``` sh
141
+ # プロジェクトのダウンロード
142
+ git clone https://github.com/binary-husky/chatgpt_academic.git
143
+ cd chatgpt_academic
144
+ # 海外プロキシとOpenAI API KEYの設定
145
+ config.pyを任意のテキストエディタで編集する
146
+ # インストール
147
+ docker build -t gpt-academic .
148
+ # 実行
149
+ docker run --rm -it --net=host gpt-academic
150
+
151
+ # 関数プラグインのテスト
152
+ ## 関数プラグインテンプレート関数のテスト(GPTが「今日の歴史」に何が起こったかを回答することが求められます)。この関数をテンプレートとして使用して、より複雑な機能を実装できます。
153
+ 「[関数プラグインテンプレートデモ] 今日の歴史」をクリックします。
154
+ ## Latexプロジェクトの要約を書くテスト
155
+ 入力欄に./crazy_functions/test_project/latex/attentionと入力し、「テックス論文を読んで要約を書く」をクリックします。
156
+ ## Pythonプロジェクト分析のテスト
157
+ 入力欄に./crazy_functions/test_project/python/dqnと入力し、[Pythonプロジェクトの全解析]をクリックします。
158
+
159
+ 関数プラグインエリアのドロップダウンメニューには他にも選択肢があります。
160
+ ```
161
+
162
+ 2. ChatGPT + ChatGLM(Dockerに非常に詳しい人+十分なコンピューター設定が必要)
163
+
164
+
165
+
166
+ ```sh
167
+ # Dockerfileの編集
168
+ cd docs && nano Dockerfile+ChatGLM
169
+ # ビルド方法
170
+ docker build -t gpt-academic --network=host -f Dockerfile+ChatGLM .
171
+ # 実行方法 (1) 直接実行:
172
+ docker run --rm -it --net=host --gpus=all gpt-academic
173
+ # 実行方法 (2) コンテナに入って調整する:
174
+ docker run --rm -it --net=host --gpus=all gpt-academic bash
175
+ ```
176
+
177
+ ## インストール方法3:その他のデプロイ方法
178
+
179
+ 1. クラウドサーバーデプロイ
180
+ [デプロイwiki-1](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%9C%E7%A8%8B%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97)
181
+
182
+ 2. WSL2を使用 (Windows Subsystem for Linux)
183
+ [デプロイwiki-2](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BD%BF%E7%94%A8WSL2%EF%BC%88Windows-Subsystem-for-Linux-%E5%AD%90%E7%B3%BB%E7%BB%9F%EF%BC%89%E9%83%A8%E7%BD%B2)
184
+
185
+
186
+ ## インストール-プロキシ設定
187
+ 1. 通常の方法
188
+ [プロキシを設定する](https://github.com/binary-husky/chatgpt_academic/issues/1)
189
+
190
+ 2. 初心者向けチュートリアル
191
+ [初心者向けチュートリアル](https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BB%A3%E7%90%86%E8%BD%AF%E4%BB%B6%E9%97%AE%E9%A2%98%E7%9A%84%E6%96%B0%E6%89%8B%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%EF%BC%88%E6%96%B9%E6%B3%95%E5%8F%AA%E9%80%82%E7%94%A8%E4%BA%8E%E6%96%B0%E6%89%8B%EF%BC%89)
192
+
193
+
194
+ ---
195
+
196
+ ## カスタムボタンの追加(学術ショートカットキー)
197
+
198
+ `core_functional.py`を任意のテキストエディタで開き、以下のエントリーを追加し、プログラムを再起動してください。(ボタンが追加されて表示される場合、前置詞と後置詞はホット編集がサポートされているため、プログラムを再起動せずに即座に有効になります。)
199
+
200
+ 例:
201
+ ```
202
+ "超级英译中": {
203
+ # 前置詞 - あなたの要求を説明するために使用されます。翻訳、コードの説明、編集など。
204
+ "Prefix": "以下のコンテンツを中国語に翻訳して、マークダウンテーブルを使用して専門用語を説明してください。\n\n",
205
+
206
+ # 後置詞 - プレフィックスと共に使用すると、入力内容を引用符で囲むことができます。
207
+ "Suffix": "",
208
+ },
209
+ ```
210
+
211
+ <div align="center">
212
+ <img src="https://user-images.githubusercontent.com/96192199/226899272-477c2134-ed71-4326-810c-29891fe4a508.png" width="500" >
213
+ </div>
214
+
215
+
216
+ ---
217
+
218
+ ## いくつかの機能の例
219
+
220
+ ### 画像表示:
221
+
222
+ <div align="center">
223
+ <img src="https://user-images.githubusercontent.com/96192199/228737599-bf0a9d9c-1808-4f43-ae15-dfcc7af0f295.png" width="800" >
224
+ </div>
225
+
226
+
227
+ ### プログラムが自己解析できる場合:
228
+
229
+ <div align="center">
230
+ <img src="https://user-images.githubusercontent.com/96192199/226936850-c77d7183-0749-4c1c-9875-fd4891842d0c.png" width="800" >
231
+ </div>
232
+
233
+ <div align="center">
234
+ <img src="https://user-images.githubusercontent.com/96192199/226936618-9b487e4b-ab5b-4b6e-84c6-16942102e917.png" width="800" >
235
+ </div>
236
+
237
+ ### 他のPython/Cppプロジェクトの解析:
238
+
239
+ <div align="center">
240
+ <img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="800" >
241
+ </div>
242
+
243
+ <div align="center">
244
+ <img src="https://user-images.githubusercontent.com/96192199/226969067-968a27c1-1b9c-486b-8b81-ab2de8d3f88a.png" width="800" >
245
+ </div>
246
+
247
+ ### Latex論文の一括読解と要約生成
248
+
249
+ <div align="center">
250
+ <img src="https://user-images.githubusercontent.com/96192199/227504406-86ab97cd-f208-41c3-8e4a-7000e51cf980.png" width="800" >
251
+ </div>
252
+
253
+ ### 自動報告生成
254
+
255
+ <div align="center">
256
+ <img src="https://user-images.githubusercontent.com/96192199/227503770-fe29ce2c-53fd-47b0-b0ff-93805f0c2ff4.png" height="300" >
257
+ <img src="https://user-images.githubusercontent.com/96192199/227504617-7a497bb3-0a2a-4b50-9a8a-95ae60ea7afd.png" height="300" >
258
+ <img src="https://user-images.githubusercontent.com/96192199/227504005-efeaefe0-b687-49d0-bf95-2d7b7e66c348.png" height="300" >
259
+ </div>
260
+
261
+ ### モジュール化された機能デザイン
262
+
263
+ <div align="center">
264
+ <img src="https://user-images.githubusercontent.com/96192199/229288270-093643c1-0018-487a-81e6-1d7809b6e90f.png" height="400" >
265
+ <img src="https://user-images.githubusercontent.com/96192199/227504931-19955f78-45cd-4d1c-adac-e71e50957915.png" height="400" >
266
+ </div>
267
+
268
+
269
+ ### ソースコードの英語翻訳
270
+
271
+ <div align="center">
272
+ <img src="https://user-images.githubusercontent.com/96192199/229720562-fe6c3508-6142-4635-a83d-21eb3669baee.png" height="400" >
273
+ </div>
274
+
275
+ ## Todo およびバージョン計画:
276
+ - version 3.2+ (todo): 関数プラグインがより多くのパラメーターインターフェースをサポートするようになります。
277
+ - version 3.1: 複数のgptモデルを同時にクエリし、api2dをサポートし、複数のapikeyの負荷分散をサポートします。
278
+ - version 3.0: chatglmおよび他の小型llmのサポート
279
+ - version 2.6: プラグイン構造を再構成し、相互作用性を高め、より多くのプラグインを追加しました。
280
+ - version 2.5: 自己更新。総括的な大規模プロジェクトのソースコードをまとめた場合、テキストが長すぎる、トークンがオーバーフローする問題を解決します。
281
+ - version 2.4: (1)PDF全文翻訳機能を追加。(2)入力エリアの位置を切り替える機能を追加。(3)垂直レイアウトオプションを追加。(4)マルチスレッド関数プラグインの最適化。
282
+ - version 2.3: 多スレッドの相互作用性を向上させました。
283
+ - version 2.2: 関数プラグインでホットリロードをサポート
284
+ - version 2.1: 折りたたみ式レイアウト
285
+ - version 2.0: モジュール化された関数プラグインを導入
286
+ - version 1.0: 基本機能
287
+
288
+ ## 参考および学習
289
+
290
+
291
+ 以下は中国語のマークダウンファイルです。日本語に翻訳してください。既存のマークダウンコマンドを変更しないでください:
292
+
293
+ ```
294
+ 多くの優秀なプロジェクトの設計を参考にしています。主なものは以下の通りです:
295
+
296
+ # 参考プロジェクト1:ChuanhuChatGPTから多くのテクニックを借用
297
+ https://github.com/GaiZhenbiao/ChuanhuChatGPT
298
+
299
+ # 参考プロジェクト2:清華ChatGLM-6B:
300
+ https://github.com/THUDM/ChatGLM-6B
301
+ ```
302
+
docs/README_RS.md ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ > **Note**
2
+ >
3
+ > Этот файл самовыражения автоматически генерируется модулем перевода markdown в этом проекте и может быть не на 100% правильным.
4
+ >
5
+
6
+ # <img src="logo.png" width="40" > ChatGPT Academic Optimization
7
+
8
+ **Если вам понравился этот проект, пожалуйста, поставьте ему звезду. Если вы придумали более полезные академические ярлыки или функциональные плагины, не стесняйтесь создавать запросы на изменение или пул-запросы. Мы также имеем [README на английском языке](docs/README_EN.md), переведенный этим же проектом.
9
+
10
+ > **Примечание**
11
+ >
12
+ > 1. Пожалуйста, обратите внимание, что только функциonal plugins (buttons) с **красным цветом** могут читать файлы, некоторые из которых находятся в **выпадающем меню** плагинов. Кроме того, мы приветствуем и обрабатываем любые новые плагины с **наивысшим приоритетом**!
13
+ >
14
+ > 2. Функции каждого файла в этом проекте подробно описаны в собственном анализе [`self_analysis.md`](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A) . При повторных итерациях вы также можете вызывать обновленный отчет функций проекта, щелкнув соответствующий функциональный плагин GPT. Часто задаваемые вопросы собраны в [`wiki`](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) .
15
+
16
+ <div align="center">
17
+
18
+ Функция | Описание
19
+ --- | ---
20
+ Редактирование одним кликом | Поддержка редактирования одним кликом, поиск грамматических ошибок в академических статьях
21
+ Переключение языков "Английский-Китайский" одним кликом | Одним кликом переключайте языки "Английский-Китайский"
22
+ Разъяснение программного кода одним кликом | Вы можете правильно отобразить и объяснить программный код.
23
+ [Настраиваемые сочетания клавиш](https://www.bilibili.com/video/BV14s4y1E7jN) | Поддержка настраиваемых сочетаний клавиш
24
+ [Настройка сервера-прокси](https://www.bilibili.com/video/BV1rc411W7Dr) | Поддержка настройки сервера-прокси
25
+ Модульный дизайн | Поддержка настраиваемых функциональных плагинов высших порядков и функциональных плагинов, поддерживающих [горячее обновление](https://github.com/binary-husky/chatgpt_academic/wiki/%E5%87%BD%E6%95%B0%E6%8F%92%E4%BB%B6%E6%8C%87%E5%8D%97)
26
+ [Автоанализ программы](https://www.bilibili.com/video/BV1cj411A7VW) | [Функциональный плагин] [Прочтение в один клик](https://github.com/binary-husky/chatgpt_academic/wiki/chatgpt-academic%E9%A1%B9%E7%9B%AE%E8%87%AA%E8%AF%91%E8%A7%A3%E6%8A%A5%E5%91%8A) кода программы проекта
27
+ [Анализ программы](https://www.bilibili.com/video/BV1cj411A7VW) | [Функциональный плагин] Один клик для проанализирования дерева других проектов Python/C/C++/Java/Lua/...
28
+ Чтение статей| [Функциональный плагин] Одним кликом прочитайте весь латех (LaTex) текст статьи и сгенерируйте краткое описание
29
+ Перевод и редактирование всех статей из LaTex | [Функциональный плагин] Перевод или редактирование LaTex-статьи всего одним нажатием кнопки
30
+ Генерация комментариев в пакетном режиме | [Функциональный плагин] Одним кликом сгенерируйте комментарии к функциям в пакетном режиме
31
+ Генерация отчетов пакета CHAT | [Функциональный плагин] Автоматически создавайте сводные отчеты после выполнения
32
+ [Помощник по arxiv](https://www.bilibili.com/video/BV1LM4y1279X) | [Функциональный плагин] Введите URL статьи arxiv, чтобы легко перевести резюме и загрузить PDF-файл
33
+ [Перевод полного текста статьи в формате PDF](https://www.bilibili.com/video/BV1KT411x7Wn) | [Функциональный плагин] Извлеките заголовок статьи, резюме и переведите весь текст статьи (многопоточно)
34
+ [Помощник интеграции Google Scholar](https://www.bilibili.com/video/BV19L411U7ia) | [Функциональный плагин] Дайте GPT выбрать для вас интересные статьи на любой странице поиска Google Scholar.
35
+ Отображение формул/изображений/таблиц | Одновременно отображается tex-форма и рендер-форма формул, поддержка формул, высокоскоростных кодов
36
+ Поддержка функциональных плагинов многопоточности | Поддержка многопоточной работы с плагинами, обрабатывайте огромные объемы текста или программы одним кликом
37
+ Запуск темной темы gradio[подробнее](https://github.com/binary-husky/chatgpt_academic/issues/173) | Добавьте / ?__dark-theme=true в конец URL браузера, чтобы переключиться на темную тему.
38
+ [Поддержка нескольких моделей LLM](https://www.bilibili.com/video/BV1wT411p7yf), поддержка API2D | Находиться между GPT3.5, GPT4 и [清华ChatGLM](https://github.com/THUDM/ChatGLM-6B) должно быть очень приятно, не так ли?
39
+ Альтернатива huggingface без использования научной сети [Онлайн-эксперимент](https://huggingface.co/spaces/qingxu98/gpt-academic) | Войдите в систему, скопируйте пространство [этот пространственный URL](https://huggingface.co/spaces/qingxu98/gpt-academic)
40
+ …… | ……
41
+
42
+
43
+ </div>
44
+
45
+ - Новый интерфейс (вы можете изменить настройку LAYOUT в config.py, чтобы переключаться между "горизонтальным расположением" и "вертикальным расположением")
46
+ <div align="center">
47
+ <img src="https://user-images.githubusercontent.com/96192199/230361456-61078362-a966-4eb5-b49e-3c62ef18b860.gif" width="700" >
48
+ </div>
49
+
50
+
51
+ Вы профессиональный переводчик научных статей.
52
+
53
+ - Все кнопки генерируются динамически путем чтения functional.py и могут быть легко настроены под пользовательские потребности, освобождая буфер обмена.
54
+ <div align="center">
55
+ <img src="https://user-images.githubusercontent.com/96192199/231975334-b4788e91-4887-412f-8b43-2b9c5f41d248.gif" width="700" >
56
+ </div>
57
+
58
+ - Редактирование/корректирование
59
+ <div align="center">
60
+ <img src="https://user-images.githubusercontent.com/96192199/231980294-f374bdcb-3309-4560-b424-38ef39f04ebd.gif" width="700" >
61
+ </div>
62
+
63
+ - Если вывод содержит формулы, они отображаются одновременно как в формате tex, так и в рендеринговом формате для удобства копирования и чтения.
64
+ <div align="center">
65
+ <img src="https://user-images.githubusercontent.com/96192199/230598842-1d7fcddd-815d-40ee-af60-baf488a199df.png" width="700" >
66
+ </div>
67
+
68
+ - Лень смотреть код проекта? Просто покажите chatgpt.
69
+ <div align="center">
70
+ <img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="700" >
71
+ </div>
72
+
73
+ - Несколько моделей больших языковых моделей смешиваются (ChatGLM + OpenAI-GPT3.5 + [API2D] (https://api2d.com/) -GPT4)
74
+ <div align="center">
75
+ <img src="https://user-images.githubusercontent.com/96192199/232537274-deca0563-7aa6-4b5d-94a2-b7c453c47794.png" width="700" >
76
+ </div>
77
+
78
+ Несколько моделей больших языковых моделей смешиваются в [бета-версии huggingface] (https://huggingface.co/spaces/qingxu98/academic-chatgpt-beta) (huggingface-версия не поддерживает chatglm).
79
+
80
+
81
+ ---
82
+
83
+ ## Установка - Метод 1: Запуск (Windows, Linux или MacOS)
84
+
85
+ 1. Скачайте проект
86
+ ```sh
87
+ git clone https://github.com/binary-husky/chatgpt_academic.git
88
+ cd chatgpt_academic
89
+ ```
90
+
91
+ 2. Настройка API_KEY и настройки прокси
92
+
93
+ В файле `config.py` настройте зарубежный прокси и OpenAI API KEY, пояснения ниже
94
+ ```
95
+ 1. Если вы находитесь в Китае, вам нужно настроить зарубежный прокси, чтобы использовать OpenAI API. Пожалуйста, внимательно прочитайте config.py для получения инструкций (1. Измените USE_PROXY на True; 2. Измените прокси в соответствии с инструкциями).
96
+ 2. Настройка API KEY OpenAI. Вам необходимо зарегистрироваться на сайте OpenAI и получить API KEY. После получения API KEY настройте его в файле config.py.
97
+ 3. Вопросы, связанные с сетевыми проблемами (тайм-аут сети, прокси не работает), можно найти здесь: https://github.com/binary-husky/chatgpt_academic/issues/1
98
+ ```
99
+ (Примечание: при запуске программы будет проверяться наличие конфиденциального файла конфигурации с именем `config_private.py` и использоваться в нем конфигурация параметров, которая перезаписывает параметры с такими же именами в `config.py`. Поэтому, если вы понимаете логику чтения нашей конфигурации, мы настоятельно рекомендуем вам создать новый файл конфигурации с именем `config_private.py` рядом с `config.py` и переместить (скопировать) настройки из `config.py` в `config_private.py`. `config_private.py` не подвергается контролю git, что делает конфиденциальную информацию более безопасной.)
100
+
101
+
102
+ 3. Установить зависимости
103
+ ```sh
104
+ # (Выбор 1) Рекомендуется
105
+ python -m pip install -r requirements.txt
106
+
107
+ # (Выбор 2) Если вы используете anaconda, то шаги будут аналогичны:
108
+ # (Шаг 2.1) conda create -n gptac_venv python=3.11
109
+ # (Шаг 2.2) conda activate gptac_venv
110
+ # (Шаг 2.3) python -m pip install -r requirements.txt
111
+
112
+ # Примечание: используйте официальный источник pip или источник pip.aliyun.com. Другие источники pip могут вызывать проблемы. временный метод замены источника:
113
+ # python -m pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
114
+ ```
115
+
116
+ Если требуется поддержка TUNA ChatGLM, необходимо установить дополнительные зависимости (если вы неудобны с python, необходимо иметь хорошую конфигурацию компьютера):
117
+ ```sh
118
+ python -m pip install -r request_llm/requirements_chatglm.txt
119
+ ```
120
+
121
+ 4. Запустите
122
+ ```sh
123
+ python main.py
124
+ ```
125
+
126
+ 5. Тестовые функции плагина
127
+ ```
128
+ - Тестирвоание анализа проекта Python
129
+ В основной области введите `./crazy_functions/test_project/python/dqn` , а затем нажмите "Анализировать весь проект Python"
130
+ - Тестирование самостоятельного чтения кода
131
+ Щелкните " [Демонстрационный режим многопоточности] Проанализируйте сам проект (расшифровка источника кода)"
132
+ - Тестирование функций шаблонного плагина (вы можете использовать эту функцию как шаблон для более сложных функций, требующих ответа от gpt в связи с тем, что произошло сегодня в истории)
133
+ Щелкните " [Функции шаблонного плагина] День в истории"
134
+ - На нижней панели дополнительные функции для выбора
135
+ ```
136
+
137
+ ## Установка - Метод 2: Использование docker (Linux)
138
+
139
+
140
+ 1. Только ChatGPT (рекомендуется для большинства пользователей):
141
+ ``` sh
142
+ # Скачать проект
143
+ git clone https://github.com/binary-husky/chatgpt_academic.git
144
+ cd chatgpt_academic
145
+ # Настроить прокси за границей и OpenAI API KEY
146
+ Отредактируйте файл config.py в любом текстовом редакторе.
147
+ # Установка
148
+ docker build -t gpt-academic .
149
+ # Запустить
150
+ docker run --rm -it --net=host gpt-academic
151
+
152
+ # Проверка функциональности плагина
153
+ ## Прове��ка шаблонной функции плагина (требуется, чтобы gpt ответил, что произошло "в истории на этот день"), вы можете использовать эту функцию в качестве шаблона для реализации более сложных функций.
154
+ Нажмите "[Шаблонный демонстрационный плагин] История на этот день".
155
+ ## Тест абстрактного резюме для проекта на Latex
156
+ В области ввода введите ./crazy_functions/test_project/latex/attention, а затем нажмите "Чтение реферата о тезисах статьи на LaTeX".
157
+ ## Тестовый анализ проекта на Python
158
+ Введите в область ввода ./crazy_functions/test_project/python/dqn, затем нажмите "Проанализировать весь проект на Python".
159
+
160
+ Выбирайте больше функциональных плагинов в нижнем выпадающем меню.
161
+ ```
162
+
163
+ 2. ChatGPT + ChatGLM (требуется глубокое знание Docker и достаточно мощное компьютерное оборудование):
164
+
165
+ ``` sh
166
+ # Изменение Dockerfile
167
+ cd docs && nano Dockerfile+ChatGLM
168
+ # Как построить | Как запустить (Dockerfile+ChatGLM в пути docs, сначала перейдите в папку с помощью cd docs)
169
+ docker build -t gpt-academic --network=host -f Dockerfile+ChatGLM .
170
+ # Как запустить | Как запустить (2) я хочу войти в контейнер и сделать какие-то настройки до запуска:
171
+ docker run --rm -it --net=host --gpus=all gpt-academic bash
172
+ ```
173
+
174
+
175
+ ## Установка-Метод 3: Другие способы развертывания
176
+
177
+ 1. Развертывание на удаленном облачном сервере
178
+ Пожалуйста, посетите [Deploy Wiki-1] (https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%9C%E7%A8%8B%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97)
179
+
180
+ 2. Использование WSL2 (Windows Subsystem for Linux)
181
+ Пожалуйста, посетите [Deploy Wiki-2] (https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BD%BF%E7%94%A8WSL2%EF%BC%88Windows-Subsystem-for-Linux-%E5%AD%90%E7%B3%BB%E7%BB%9F%EF%BC%89%E9%83%A8%E7%BD%B2)
182
+
183
+
184
+ ## Установка-Настройки прокси
185
+ ### Метод 1: Обычный способ
186
+ [Конфигурация прокси] (https://github.com/binary-husky/chatgpt_academic/issues/1)
187
+
188
+ ### Метод 2: Руководство новичка
189
+ [Руководство новичка] (https://github.com/binary-husky/chatgpt_academic/wiki/%E4%BB%A3%E7%90%86%E8%BD%AF%E4%BB%B6%E9%97%AE%E9%A2%98%E7%9A%84%E6%96%B0%E6%89%8B%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%EF%BC%88%E6%96%B9%E6%B3%95%E5%8F%AA%E9%80%82%E7%94%A8%E4%BA%8E%E6%96%B0%E6%89%8B%EF%BC%89)
190
+
191
+
192
+ ---
193
+
194
+ ## Настройка новой удобной кнопки (настройка быстрой клавиши для научной работы)
195
+ Откройте `core_functional.py` любым текстовым редактором, добавьте элементы, как показано ниже, затем перезапустите программу. (Если кнопка уже успешно добавлена и видна, то префикс и суффикс поддерживают горячее изменение, чтобы они оказались в действии, не нужно перезапускать программу.)
196
+ например
197
+ ```
198
+ "Супер анг-рус": {
199
+ # Префикс, будет добавлен перед вашим вводом. Например, используется для описания ваших потребностей, таких как перевод, кодинг, редактирование и т. д.
200
+ "Prefix": "Пожалуйста, переведите этот фрагмент на русский язык, а затем создайте пошаговую таблицу в markdown, чтобы объяснить все специализированные термины, которые встречаются в тексте:\n\n",
201
+
202
+ # Суффикс, будет добавлен после вашего ввода. Например, совместно с префиксом можно обрамить ваш ввод в кавычки.
203
+ "Suffix": "",
204
+ },
205
+ ```
206
+ <div align="center">
207
+ <img src="https://user-images.githubusercontent.com/96192199/226899272-477c2134-ed71-4326-810c-29891fe4a508.png" width="500" >
208
+ </div>
209
+
210
+ ---
211
+
212
+
213
+ ## Демонстрация некоторых возможностей
214
+
215
+ ### Отображение изображений:
216
+
217
+ <div align="center">
218
+ <img src="https://user-images.githubusercontent.com/96192199/228737599-bf0a9d9c-1808-4f43-ae15-dfcc7af0f295.png" width="800" >
219
+ </div>
220
+
221
+
222
+ ### Если программа может понимать и разбирать сама себя:
223
+
224
+ <div align="center">
225
+ <img src="https://user-images.githubusercontent.com/96192199/226936850-c77d7183-0749-4c1c-9875-fd4891842d0c.png" width="800" >
226
+ </div>
227
+
228
+ <div align="center">
229
+ <img src="https://user-images.githubusercontent.com/96192199/226936618-9b487e4b-ab5b-4b6e-84c6-16942102e917.png" width="800" >
230
+ </div>
231
+
232
+
233
+ ### Анализ других проектов на Python/Cpp:
234
+ <div align="center">
235
+ <img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="800" >
236
+ </div>
237
+
238
+ <div align="center">
239
+ <img src="https://user-images.githubusercontent.com/96192199/226969067-968a27c1-1b9c-486b-8b81-ab2de8d3f88a.png" width="800" >
240
+ </div>
241
+
242
+ ### Генерация понимания и абстрактов с помощью Латех статей в один клик
243
+ <div align="center">
244
+ <img src="https://user-images.githubusercontent.com/96192199/227504406-86ab97cd-f208-41c3-8e4a-7000e51cf980.png" width="800" >
245
+ </div>
246
+
247
+ ### Автоматическое создание отчетов
248
+ <div align="center">
249
+ <img src="https://user-images.githubusercontent.com/96192199/227503770-fe29ce2c-53fd-47b0-b0ff-93805f0c2ff4.png" height="300" >
250
+ <img src="https://user-images.githubusercontent.com/96192199/227504617-7a497bb3-0a2a-4b50-9a8a-95ae60ea7afd.png" height="300" >
251
+ <img src="https://user-images.githubusercontent.com/96192199/227504005-efeaefe0-b687-49d0-bf95-2d7b7e66c348.png" height="300" >
252
+ </div>
253
+
254
+ ### Модульный дизайн функций
255
+ <div align="center">
256
+ <img src="https://user-images.githubusercontent.com/96192199/229288270-093643c1-0018-487a-81e6-1d7809b6e90f.png" height="400" >
257
+ <img src="https://user-images.githubusercontent.com/96192199/227504931-19955f78-45cd-4d1c-adac-e71e50957915.png" height="400" >
258
+ </div>
259
+
260
+
261
+ ### Трансляция исходного кода на английский язык
262
+
263
+ <div align="center">
264
+ <img src="https://user-images.githubusercontent.com/96192199/229720562-fe6c3508-6142-4635-a83d-21eb3669baee.png" height="400" >
265
+ </div>
266
+
267
+ ## Todo и планирование версий:
268
+ - version 3.2+ (todo): функция плагины поддерживают более многочисленные интерфейсы параметров
269
+ - version 3.1: поддержка одновременного опроса нескольких моделей gpt! Поддержка api2d, поддержка балансировки нагрузки множества apikey.
270
+ - version 3.0: поддержка chatglm и других маленьких llm
271
+ - version 2.6: реструктурировал структуру плагинов, повысил интерактивность, добавил больше плагинов
272
+ - version 2.5: само обновление, решение проблемы слишком длинного текста и переполнения токена при переводе всего проекта исходного кода
273
+ - version 2.4: (1) добавлена функция перевода всего PDF-документа; (2) добавлена функция изменения положения входной области; (3) добавлена опция вертикального макета; (4) оптимизация функций многопоточности плагина.
274
+ - version 2.3: улучшение многопоточной интерактивности
275
+ - version 2.2: функция плагинов поддерживает горячую перезагрузку
276
+ - version 2.1: блочная раскладка
277
+ - version 2.0: модульный дизайн функций плагина
278
+ - version 1.0: основные функции
279
+
280
+ ## Ссылки на изучение и обучение
281
+
282
+ ```
283
+ В коде использовано много хороших дизайнерских решений из других отличных проектов, в том числе:
284
+
285
+ # Project1: использование многих приемов из ChuanhuChatGPT
286
+ https://github.com/GaiZhenbiao/ChuanhuChatGPT
287
+
288
+ # Project2: ChatGLM-6B в Тхуде:
289
+ https://github.com/THUDM/ChatGLM-6B
290
+ ```
291
+
docs/WithFastapi.md ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Running with fastapi
2
+
3
+ We currently support fastapi in order to solve sub-path deploy issue.
4
+
5
+ 1. change CUSTOM_PATH setting in `config.py`
6
+
7
+ ``` sh
8
+ nano config.py
9
+ ```
10
+
11
+ 2. Edit main.py
12
+
13
+ ```diff
14
+ auto_opentab_delay()
15
+ - demo.queue(concurrency_count=CONCURRENT_COUNT).launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png")
16
+ + demo.queue(concurrency_count=CONCURRENT_COUNT)
17
+
18
+ - # 如果需要在二级路径下运行
19
+ - # CUSTOM_PATH, = get_conf('CUSTOM_PATH')
20
+ - # if CUSTOM_PATH != "/":
21
+ - # from toolbox import run_gradio_in_subpath
22
+ - # run_gradio_in_subpath(demo, auth=AUTHENTICATION, port=PORT, custom_path=CUSTOM_PATH)
23
+ - # else:
24
+ - # demo.launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png")
25
+
26
+ + 如果需要在二级路径下运行
27
+ + CUSTOM_PATH, = get_conf('CUSTOM_PATH')
28
+ + if CUSTOM_PATH != "/":
29
+ + from toolbox import run_gradio_in_subpath
30
+ + run_gradio_in_subpath(demo, auth=AUTHENTICATION, port=PORT, custom_path=CUSTOM_PATH)
31
+ + else:
32
+ + demo.launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png")
33
+
34
+ if __name__ == "__main__":
35
+ main()
36
+ ```
37
+
38
+
39
+ 3. Go!
40
+
41
+ ``` sh
42
+ python main.py
43
+ ```
docs/demo.jpg ADDED
docs/demo2.jpg ADDED
docs/logo.png ADDED
docs/self_analysis.md ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # chatgpt-academic项目自译解报告
2
+ (Author补充:以下分析均由本项目调用ChatGPT一键生成,如果有不准确的地方,全怪GPT😄)
3
+
4
+ ## 对程序的整体功能和构架做出概括。然后用一张markdown表格整理每个文件的功能。
5
+
6
+ 整体概括:
7
+
8
+ 该程序是一个基于自然语言处理和机器学习的科学论文辅助工具,主要功能包括聊天机器人、批量总结PDF文档、批量翻译PDF文档、生成函数注释、解析项目源代码等。程序基于 Gradio 构建 Web 服务,并集成了代理和自动更新功能,提高了用户的使用体验。
9
+
10
+ 文件功能表格:
11
+
12
+ | 文件名 | 文件功能 |
13
+ | --- | --- |
14
+ | check_proxy.py | 用于检查代理的正确性和可用性 |
15
+ | colorful.py | 包含不同预设置颜色的常量,并用于多种UI元素 |
16
+ | config.py | 用于全局配置的类 |
17
+ | config_private.py | 与config.py文件一起使用的另一个配置文件,用于更改私密信息 |
18
+ | core_functional.py | 包含一些TextFunctional类和基础功能函数 |
19
+ | crazy_functional.py | 包含大量高级功能函数和实验性的功能函数 |
20
+ | main.py | 程序的主入口,包含GUI主窗口和主要的UI管理功能 |
21
+ | theme.py | 包含一些预设置主题的颜色 |
22
+ | toolbox.py | 提供了一些有用的工具函数 |
23
+ | crazy_functions\crazy_utils.py | 包含一些用于实现高级功能的辅助函数 |
24
+ | crazy_functions\Latex全文润色.py | 实现了对LaTeX文件中全文的润色和格式化功能 |
25
+ | crazy_functions\Latex全文翻译.py | 实现了对LaTeX文件中的内容进行翻译的功能 |
26
+ | crazy_functions\_\_init\_\_.py | 用于导入crazy_functional.py中的功能函数 |
27
+ | crazy_functions\下载arxiv论文翻译摘要.py | 从Arxiv上下载论文并提取重要信息 |
28
+ | crazy_functions\代码重写为全英文_多线程.py | 针对中文Python文件,将其翻译为全英文 |
29
+ | crazy_functions\总结word文档.py | 提取Word文件的重要内容来生成摘要 |
30
+ | crazy_functions\批量Markdown翻译.py | 批量翻译Markdown文件 |
31
+ | crazy_functions\批量总结PDF文档.py | 批量从PDF文件中提取摘要 |
32
+ | crazy_functions\批量总结PDF文档pdfminer.py | 批量从PDF文件中提取摘要 |
33
+ | crazy_functions\批量翻译PDF文档_多线程.py | 批量翻译PDF文件 |
34
+ | crazy_functions\理解PDF文档内容.py | 批量分析PDF文件并提取摘要 |
35
+ | crazy_functions\生成函数注释.py | 自动生成Python文件中函数的注释 |
36
+ | crazy_functions\解析项目源代码.py | 解析并分析给定项目的源代码 |
37
+ | crazy_functions\询问多个大语言模型.py | 向多个大语言模型询问输入文本并进行处理 |
38
+ | crazy_functions\读文献写摘要.py | 根据用户输入读取文献内容并生成摘要 |
39
+ | crazy_functions\谷歌检索小助手.py | 利用谷歌学术检索用户提供的论文信息并提取相关信息 |
40
+ | crazy_functions\高级功能函数模板.py | 实现高级功能的模板函数 |
41
+ | request_llm\bridge_all.py | 处理与LLM的交互 |
42
+ | request_llm\bridge_chatglm.py | 使用ChatGLM模型进行聊天 |
43
+ | request_llm\bridge_chatgpt.py | 实现对话生成的各项功能 |
44
+ | request_llm\bridge_tgui.py | 在Websockets中与用户进行交互并生成文本输出 |
45
+
46
+
47
+
48
+ ## [0/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\check_proxy.py
49
+
50
+ 该文件主要包括四个函数:check_proxy、backup_and_download、patch_and_restart 和 auto_update。其中,check_proxy 函数用于检查代理是否可用;backup_and_download 用于进行一键更新备份和下载;patch_and_restart 是一键更新协议的重要函数,用于覆盖和重启;auto_update 函数用于查询版本和用户意见,并自动进行一键更新。该文件主要使用了 requests、json、shutil、zipfile、distutils、subprocess 等 Python 标准库和 toolbox 和 colorful 两个第三方库。
51
+
52
+ ## [1/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\colorful.py
53
+
54
+ 该程序文件实现了一些打印文本的函数,使其具有不同的颜色输出。当系统为Linux时直接跳过,否则使用colorama库来实现颜色输出。程序提供了深色和亮色两种颜色输出方式,同时也提供了对打印函数的别名。对于不是终端输出的情况,对所有的打印函数进行重复定义,以便在重定向时能够避免打印错误日志。
55
+
56
+ ## [2/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\config.py
57
+
58
+ 该程序文件是一个配置文件,其主要功能是提供使用API密钥等信息,以及对程序的体验进行优化,例如定义对话框高度、布局等。还包含一些其他的设置,例如设置并行使用的线程数、重试次数限制等等。
59
+
60
+ ## [3/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\config_private.py
61
+
62
+ 这是一个名为config_private.py的Python文件,它用于配置API_KEY和代理信息。API_KEY是一个私密密钥,用于访���某些受保护的API。USE_PROXY变量设置为True以应用代理,proxies变量配置了代理网络的地址和协议。在使用该文件时,需要填写正确的API_KEY和代理信息。
63
+
64
+ ## [4/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\core_functional.py
65
+
66
+ 该文件是一个Python模块,名为"core_functional.py"。模块中定义了一个字典,包含了各种核心功能的配置信息,如英语学术润色、中文学术润色、查找语法错误等。每个功能都包含一些前言和后语,在前言中描述了该功能的任务和要求,在后语中提供一些附加信息。此外,有些功能还定义了一些特定的处理函数和按钮颜色。
67
+
68
+ ## [5/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functional.py
69
+
70
+ 这是一个Python程序文件,文件名是crazy_functional.py。它导入了一个名为HotReload的工具箱,并定义了一个名为get_crazy_functions()的函数。这个函数包括三个部分的插件组,分别是已经编写完成的第一组插件、已经测试但距离完美状态还差一点点的第二组插件和尚未充分测试的第三组插件。每个插件都有一个名称、一个按钮颜色、一个函数和一个是否加入下拉菜单中的标志位。这些插件提供了多种功能,包括生成函数注释、解析项目源代码、批量翻译PDF文档、谷歌检索、PDF文档内容理解和Latex文档的全文润色、翻译等功能。其中第三组插件可能还存在一定的bug。
71
+
72
+ ## [6/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\main.py
73
+
74
+ 该Python脚本代码实现了一个用于交互式对话的Chatbot机器人。它使用了Gradio框架来构建一个Web界面,并在此基础之上嵌入了一个文本输入框和与Chatbot进行交互的其他控件,包括提交、重置、停止和清除按钮、选择框和滑块等。此外,它还包括了一些类和函数和一些用于编程分析的工具和方法。整个程序文件的结构清晰,注释丰富,并提供了很多技术细节,使得开发者可以很容易地在其基础上进行二次开发、修改、扩展和集成。
75
+
76
+ ## [7/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\theme.py
77
+
78
+ 该程序文件名为theme.py,主要功能为调节Gradio的全局样式。在该文件中,调节了Gradio的主题颜色、字体、阴影、边框、渐变等等样式。同时,该文件还添加了一些高级CSS样式,比如调整表格单元格的背景和边框,设定聊天气泡的圆角、最大宽度和阴影等等。如果CODE_HIGHLIGHT为True,则还进行了代码高亮显示。
79
+
80
+ ## [8/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\toolbox.py
81
+
82
+ 这是一个名为`toolbox.py`的源代码文件。该文件包含了一系列工具函数和装饰器,用于聊天Bot的开发和调试。其中有一些功能包括将输入参数进行重组、捕捉函数中的异常并记录到历史记录中、生成Markdown格式的聊天记录报告等。该文件中还包含了一些与转换Markdown文本相关的函数。
83
+
84
+ ## [9/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\crazy_utils.py
85
+
86
+ 这是一个Python程序文件 `crazy_utils.py`,它包含了两个函数:
87
+
88
+ - `input_clipping(inputs, history, max_token_limit)`:这个函数接收三个参数,inputs 是一个字符串,history 是一个列表,max_token_limit 是一个整数。它使用 `tiktoken` 、`numpy` 和 `toolbox` 模块,处理输入文本和历史记录,将其裁剪到指定的最大标记数,避免输入过长导致的性能问题。如果 inputs 长度不超过 max_token_limit 的一半,则只裁剪历史;否则,同时裁剪输入和历史。
89
+ - `request_gpt_model_in_new_thread_with_ui_alive(inputs, inputs_show_user, llm_kwargs, chatbot, history, sys_prompt, refresh_interval=0.2, handle_token_exceed=True, retry_times_at_unknown_error=2)`:这个函数接收八个参数,其中后三个是列表类型,其他为标量或句柄等。它提供对话窗口和刷新控制,执行 `predict_no_ui_long_connection` 方法,将输入数据发送至 GPT 模型并获取结果,如果子任务出错,返回相应的错误信息,否则返回结果。
90
+
91
+ ## [10/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\Latex全文润色.py
92
+
93
+ 这是一个名为"crazy_functions\Latex全文润色.py"的程序文件,其中包含了两个函数"Latex英文润色"和"Latex中文润色",以及其他辅助函数。这些函数能够对 Latex 项目进行润色处理,其中 "多文件润色" 函数是一个主要函数,它调用了其他辅助函数用于读取和处理 Latex 项目中的文件。函数使用了多线程和机器学习模型进行自然语言处理,对文件进行简化和排版来满足学术标准。注释已删除并可以在函数内部查找。
94
+
95
+ ## [11/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\Latex全文翻译.py
96
+
97
+ 这个程序文件包括一个用于对整个Latex项目进行翻译的函数 `Latex英译中` 和一个用于将中文翻译为英文的函数 `Latex中译英`。这两个函数都会尝试导入依赖库 tiktoken, 若无法导入则会提示用户安装。`Latex英译中` 函数会对 Latex 项目中的文件进行分离并去除注释,然后运行多线程翻译。`Latex中译英` 也做同样的事情,只不过是将中文翻译为英文。这个程序文件还包括其他一些帮助函数。
98
+
99
+ ## [12/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\__init__.py
100
+
101
+ 这是一个 Python 包,包名为 `crazy_functions`,在 `__init__.py` 文件中定义了一些函数,包含以下函数:
102
+
103
+ - `crazy_addition(a, b)`:对两个数进行加法运算,并将结果返回。
104
+ - `crazy_multiplication(a, b)`:对两个数进行乘法运算,并将结果返回。
105
+ - `crazy_subtraction(a, b)`:对两个数进行减法运算,并将结果返回。
106
+ - `crazy_division(a, b)`:对两个数进行除法运算,并将结果返回。
107
+ - `crazy_factorial(n)`:计算 `n` 的阶乘并返回结果。
108
+
109
+ 这些函数可能会有一些奇怪或者不符合常规的实现方式(由函数名可以看出来),所以这个包的名称为 `crazy_functions`,可能是暗示这些函数会有一些“疯狂”的实现方式。
110
+
111
+ ## [13/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\下载arxiv论文翻译摘要.py
112
+
113
+ 该程序实现了一个名为“下载arxiv论文并翻译摘要”的函数插件,作者是“binary-husky”。该函数的功能是,在输入一篇arxiv论文的链接后,提取摘要、下载PDF文档、翻译摘要为中文,并将翻译结果保存到文件中。程序使用了一些Python库,如requests、pdfminer和beautifulsoup4等。程序入口是名为“下载arxiv论文并翻译摘要”的函数,其中使用了自定义的辅助函数download_arxiv_和get_name。程序中还使用了其他非函数的辅助函数和变量,如update_ui、CatchException、report_exception和get_conf等。
114
+
115
+ ## [14/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\代码重写为全英文_多线程.py
116
+
117
+ 该文件是一个多线程Python脚本,包含多个函数和利用第三方库进行的API请求。主要功能是将给定文件夹内的Python代码文件中所有中文转化为英文,然后输出转化后的英文代码。重要的功能和步骤包括:
118
+
119
+ 1. 清空历史,以免输入溢出
120
+ 2. 尝试导入依赖,如果缺少依赖,则给出安装建议
121
+ 3. 集合文件
122
+ 4. 显示随意内容以防卡顿的感觉
123
+ 5. Token限制下的截断与处理
124
+ 6. 多线程操作请求转换中文变为英文的代码
125
+ 7. 所有线程同时开始执行任务函数
126
+ 8. 循环轮询各个线程是否执行完毕
127
+ 9. 把结果写入文件
128
+ 10. 备份一个文件
129
+
130
+ ## [15/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\总结word文档.py
131
+
132
+ 这是一个名为"总结word文档.py"的程序文件,使用python编写。该文件导入了"toolbox"和"crazy_utils"模块,实现了解析docx格式和doc格式的文件的功能。该文件包含了一个名为"解析docx"的函数,通过对文件内容应用自然语言处理技术,生成文章片段的中英文概述。具体实现过程中,该函数使用了"docx"模块和"win32com.client"模块来实现对docx和doc格式文件的解析,同时使用了"request_gpt_model_in_new_thread_with_ui_alive"函数来向GPT模型发起请求。最后,该文件还实现了一个名为"总结word文档"的函数来批量总结Word文档。
133
+
134
+ ## [16/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\批量Markdown翻译.py
135
+
136
+ 这个程序文件实现了一个批量Markdown翻译功能,可以将一个源代码项目中的Markdown文本翻译成指定语言(目前支持中<-英和英<-中)。程序主要分为三个函数,`PaperFileGroup`类用于处理长文本的拆分,`多文件翻译`是主要函数调用了`request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency`函数进行多线程翻译并输出结果,`Markdown英译中`和`Markdown中译外`分别是英译中和中译英的入口函数,用于解析项目路径和调用翻译函数。程序依赖于tiktoken等库实现。
137
+
138
+ ## [17/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\批量总结PDF文档.py
139
+
140
+ 这是一个名为“批量总结PDF文档”的Python脚本,包含了多个函数。其中有一个函数名为“clean_text”,可以对PDF提取出的原始文本进行清洗和格式化处理,将连字转换为其基本形式,并根据heuristic规则判断换行符是否是段落分隔,并相应地进行替换。另一个函数名为“解析PDF”,可以接收一个PDF文件清单,并对清单中的每一个PDF进行解析,提取��文本并调用“clean_text”函数进行清洗和格式化处理,然后向用户发送一个包含文章简介信息的问题并等待用户回答。最后,该脚本也包含一个名为“批量总结PDF文档”的主函数,其中调用了“解析PDF”函数来完成对PDF文件的批量处理。
141
+
142
+ ## [18/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\批量总结PDF文档pdfminer.py
143
+
144
+ 这个文件是一个Python模块,文件名为pdfminer.py,它定义了一个函数批量总结PDF文档。该函数接受一些参数,然后尝试导入pdfminer和beautifulsoup4库。该函数将读取pdf文件或tex文件中的内容,对其进行分析,并使用GPT模型进行自然语言摘要。文件中还有一个辅助函数readPdf,用于读取pdf文件中的内容。
145
+
146
+ ## [19/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\批量翻译PDF文档_多线程.py
147
+
148
+ 这是一个Python脚本,文件名是crazy_functions\批量翻译PDF文档_多线程.py。该脚本提供了一个名为“批量翻译PDF文档”的函数,可以批量翻译PDF文件并生成报告文件。该函数使用了多个模块和函数(如toolbox、crazy_utils、update_ui等),使用了Python的异常处理和多线程功能,还使用了一些文本处理函数和第三方库(如fitz和tiktoken)。在函数执行过程中,它会进行一些参数检查、读取和清理PDF文本、递归地切割PDF文件、获取文章meta信息、多线程翻译、整理报告格式等操作,并更新UI界面和生成报告文件。
149
+
150
+ ## [20/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\理解PDF文档内容.py
151
+
152
+ 这是一个解析PDF文件内容的Python程序,程序文件名为"理解PDF文档内容.py",程序主要由5个步骤组成:第0步是切割PDF文件;第1步是从摘要中提取高价值信息,放到history中;第2步是迭代地历遍整个文章,提取精炼信息;第3步是整理history;第4步是设置一个token上限,防止回答时Token溢出。程序主要用到了Python中的各种模块和函数库,如:toolbox, tiktoken, pymupdf等。
153
+
154
+ ## [21/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\生成函数注释.py
155
+
156
+ 这是一个名为"生成函数注释"的函数,带有一个装饰器"@CatchException",可以捕获异常。该函数接受文件路径、参数和聊天机器人等参数,用于对多个Python或C++文件进行函数注释,使用了"toolbox"和"crazy_utils"模块中的函数。该函数会逐个读取指定文件中的内容,并使用聊天机器人进行交互,向用户请求注释信息,然后将生成的注释与原文件内容一起输出到一个markdown表格中。最后,该函数返回一个字符串,指示任务是否已完成。另外还包含一个名为"批量生成函数注释"的函数,它与"生成函数注释"函数一起用于批量处理多个文件。
157
+
158
+ ## [22/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\解析项目源代码.py
159
+
160
+ 这个程序文件实现了对一个源代码项目进行分析的功能。其中,函数`解析项目本身`、`解析一个Python项目`、`解析一个C项目的头文件`、`解析一个C项目`、`解析一个Java项目`和`解析一个Rect项目`分别用于解析不同类型的项目。函数`解析源代码新`实现了对每一个源代码文件的分析,并将分析结果汇总,同时还实现了分组和迭代处理,提高了效率。最后,函数`write_results_to_file`将所有分析结果写入文件。中间,还用到了`request_gpt_model_multi_threads_with_very_awesome_ui_and_high_efficiency`和`request_gpt_model_in_new_thread_with_ui_alive`来完成请求和响应,并用`update_ui`实时更新界面。
161
+
162
+ ## [23/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\询问多个大语言模型.py
163
+
164
+ 这是一个Python程序,文件名为"crazy_functions\询问多个大语言模型.py"。该程序实现了一个同时向多个大语言模型询问的功能,接收用户输入文本以及模型参数,向ChatGPT和ChatGLM模型发出请求,并将对话记录显示在聊天框中,同时刷新界面。
165
+
166
+ ## [24/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\读文章写摘要.py
167
+
168
+ 该程序文件是一个Python模块,文件名为"读文章写摘要.py",主要包含两个函数:"解析Paper"和"读文章写摘要"。其中,"解析Paper"函数接受文件路径、参数等参数,逐个打印文件内容并使用GPT模型生成对该文件的摘要;"读文章写摘要"函数则接受一段文本内容和参数,将该文本内容及其所有.tex文件逐个传递给"解析Paper"函数进行处理,并使用GPT模型生成文章的中英文摘要。文件还导入了一些工具函数,如异常处理、信息上报和文件写入等。
169
+
170
+ ## [25/31] 请对下面��程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\谷歌检索小助手.py
171
+
172
+ 该文件代码包含了一个名为`get_meta_information`的函数和一个名为`谷歌检索小助手`的装饰器函数,用于从谷歌学术中抓取文章元信息,并从用户提供的搜索页面中分析所有文章的相关信息。该文件使用了许多第三方库,如requests、arxiv、BeautifulSoup等。其中`get_meta_information`函数中还定义了一个名为`string_similar`的辅助函数,用于比较字符串相似度。
173
+
174
+ ## [26/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\crazy_functions\高级功能函数模板.py
175
+
176
+ 该程序文件是一个 Python 模块,包含一个名为“高阶功能模板函数”的函数。该函数接受多个参数,其中包括输入文本、GPT 模型参数、插件模型参数、聊天显示框、聊天历史等。 该函数的主要功能是根据输入文本,使用 GPT 模型生成一些问题,并等待用户回答这些问题(使用 Markdown 格式),然后将用户回答加入到聊天历史中,并更新聊天显示框。该函数还包含了一些异常处理和多线程的相关操作。该程序文件还引用了另一个 Python 模块中的两个函数,分别为“CatchException”和“update_ui”,并且还引用了一个名为“request_gpt_model_in_new_thread_with_ui_alive”的自定义函数。
177
+
178
+ ## [27/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\request_llm\bridge_all.py
179
+
180
+ 这个文件是用来处理与LLM的交互的。包含两个函数,一个是 predict_no_ui_long_connection 用来处理长文本的输出,可以多线程调用;另一个是 predict 用来处理基础的对话功能。这个文件会导入其他文件中定义的方法进行调用,具体调用哪个方法取决于传入的参数。函数中还有一些装饰器和管理多线程的逻辑。
181
+
182
+ ## [28/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\request_llm\bridge_chatglm.py
183
+
184
+ 这个程序文件实现了一个使用ChatGLM模型进行聊天的功能。具体实现过程是:首先进行初始化,然后使用GetGLMHandle类进行ChatGLM模型的加载和运行。predict_no_ui_long_connection函数用于多线程聊天,而predict函数用于单线程聊天,它们的不同之处在于前者不会更新UI界面,后者会。这个文件还导入了其他模块和库,例如transformers、time、importlib等,并使用了多进程Pipe。
185
+
186
+ ## [29/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\request_llm\bridge_chatgpt.py
187
+
188
+ 这个程序文件是用于对话生成的,主要包含三个函数:predict、predict_no_ui、predict_no_ui_long_connection。其中,predict是用于普通对话的函数,具备完备的交互功能,但不具备多线程能力;predict_no_ui是高级实验性功能模块调用的函数,参数简单,可以多线程并行,方便实现复杂的功能逻辑;predict_no_ui_long_connection解决了predict_no_ui在处理长文档时容易断开连接的问题,同样支持多线程。程序中还包含一些常量和工具函数,用于整合信息,选择LLM模型,生成http请求,发送请求,接收响应等。它需要配置一个config文件,包含代理网址、API等敏感信息。
189
+
190
+ ## [30/31] 请对下面的程序文件做一个概述: H:\chatgpt_academic_resolve\request_llm\bridge_tgui.py
191
+
192
+ 该程序文件实现了一个基于Websockets的文本生成服务和对话功能。其中,有三个函数:`run()`、`predict()`和`predict_no_ui_long_connection()`。`run()`函数用于连接到Websocket服务并生成文本结果;`predict()`函数用于将用户输入作为文本生成的输入,同时在UI上显示对话历史记录,并在不断更新UI的过程中不断更新生成的文本输出;`predict_no_ui_long_connection()`函数与`predict()`函数类似,但没有UI,并在一段时间内返回单个生成的文本。整个程序还引入了多个Python模块来完成相关功能,例如`asyncio`、`websockets`、`json`等等。
193
+
194
+ ## 根据以上分析,对程序的整体功能和构架重新做出概括。然后用一张markdown表格整理每个文件的功能(包括check_proxy.py, colorful.py, config.py, config_private.py, core_functional.py, crazy_functional.py, main.py, theme.py, toolbox.py, crazy_functions\crazy_utils.py, crazy_functions\Latex全文润色.py, crazy_functions\Latex全文翻译.py, crazy_functions\__init__.py, crazy_functions\下载arxiv论文翻译摘要.py, crazy_functions\代码重写为全英文_多线程.py, crazy_functions\总结word文档.py)。
195
+
196
+ 程序功能概括:该程序是一个聊天机器人,可以通过 Web 界面与用户进行交互。它包含了丰富的功能,如文本润色、翻译、代码重写、在线查找等,并且支持多线程处理。用户可以通过 Gradio 框架提供的 Web 界面进行交互,程序还提供了一些调试工具,如toolbox 模块,方便程序开发和调试。
197
+
198
+ ���表概述了每个文件的功能:
199
+
200
+ | 文件名 | 功能 |
201
+ | ----------------------------------------------------------- | ------------------------------------------------------------ |
202
+ | check_proxy.py | 检查代理是否可用 |
203
+ | colorful.py | 用于打印文本的字体颜色输出模块 |
204
+ | config.py | 用于程序中的各种设置,如并行线程数量和重试次数的限制等 |
205
+ | config_private.py | 配置API_KEY和代理信息的文件 |
206
+ | core_functional.py | 包含具体的文本处理功能的模块 |
207
+ | crazy_functional.py | 包括各种插件函数的模块,提供了多种文本处理功能 |
208
+ | main.py | 包含 Chatbot 机器人主程序的模块 |
209
+ | theme.py | 用于调节全局样式的模块 |
210
+ | toolbox.py | 包含工具函数和装饰器,用于聊天Bot的开发和调试 |
211
+ | crazy_functions\crazy_utils.py | 包含一些辅助函数,如文本裁剪和消息捕捉等 |
212
+ | crazy_functions\Latex全文润色.py | 对 Latex 项目进行润色处理的功能模块 |
213
+ | crazy_functions\Latex全文翻译.py | 对 Latex 项目进行翻译的功能模块 |
214
+ | crazy_functions\__init__.py | 定义一些奇特的数学函数等 |
215
+ | crazy_functions\下载arxiv论文翻译摘要.py | 下载 Arxiv 论文并翻译摘要的功能模块 |
216
+ | crazy_functions\代码重写为全英文_多线程.py | 将Python程序中所有中文转化为英文的功能模块 |
217
+ | crazy_functions\总结word文档.py | 解析 docx 和 doc 格式的文件,生成文章片段的中英文概述的功能模块 |
218
+
219
+ ## 根据以上分析,对程序的整体功能和构架重新做出概括。然后用一张markdown表格整理每个文件的功能(包括check_proxy.py, colorful.py, config.py, config_private.py, core_functional.py, crazy_functional.py, main.py, theme.py, toolbox.py, crazy_functions\crazy_utils.py, crazy_functions\Latex全文润色.py, crazy_functions\Latex全文翻译.py, crazy_functions\__init__.py, crazy_functions\下载arxiv论文翻译摘要.py, crazy_functions\代码重写为全英文_多线程.py, crazy_functions\总结word文档.py, crazy_functions\批量Markdown翻译.py, crazy_functions\批量总结PDF文档.py, crazy_functions\批量总结PDF文档pdfminer.py, crazy_functions\批量翻译PDF文档_多线程.py, crazy_functions\理解PDF文档内容.py, crazy_functions\生成函数注释.py, crazy_functions\解析项目源代码.py, crazy_functions\询问多个大语言模型.py, crazy_functions\读文章写摘要.py, crazy_functions\谷歌检索小助手.py, crazy_functions\高级功能函数模板.py, request_llm\bridge_all.py, request_llm\bridge_chatglm.py, request_llm\bridge_chatgpt.py, request_llm\bridge_tgui.py)。
220
+
221
+ 根据以上分析,整个程序是一个集成了多个有用工具和功能的文本处理和生成工具,提供了多种在不同场景下使用的功能,包括但不限于对话生成、文本摘要、PDF文件批量处理、代码翻译和实用工具等。主要的Python模块包括"toolbox.py"、"config.py"、"core_functional.py"和"crazy_functional.py"等,并且还使用了许多第三方库和模块实现相关功能。以下是每个程序文件的功能:
222
+
223
+ | 文件名 | 文件功能 |
224
+ | --- | --- |
225
+ | check_proxy.py | 用于检查代理的正确性和可用性 |
226
+ | colorful.py | 包含不同预设置颜色的常量,并用于多种UI元素 |
227
+ | config.py | 用于全局配置的类 |
228
+ | config_private.py | 与config.py文件一起使用的另一个配置文件,用于更改私密信息 |
229
+ | core_functional.py | 包含一些TextFunctional类和基础功能函数 |
230
+ | crazy_functional.py | 包含大量高级功能函数和实验性的功能函数 |
231
+ | main.py | 程序的主入口,包含GUI主窗口和主要的UI管理功能 |
232
+ | theme.py | 包含一些预设置主题的颜色 |
233
+ | toolbox.py | 提供了一些有用的工具函数 |
234
+ | crazy_functions\crazy_utils.py | 包含一些用于实现高级功能的辅助函数 |
235
+ | crazy_functions\Latex全文润色.py | 实现了对LaTeX文件中全文的润色和格式化功能 |
236
+ | crazy_functions\Latex全文翻译.py | 实现了对LaTeX文件中的内容进行翻译的功能 |
237
+ | crazy_functions\_\_init\_\_.py | 用于导入crazy_functional.py中的功能函数 |
238
+ | crazy_functions\下载arxiv论文翻译摘要.py | 从Arxiv上下载论文并提取重要信息 |
239
+ | crazy_functions\代码重写为全英文_多线程.py | 针对中文Python文件,将其翻译为全英文 |
240
+ | crazy_functions\总结word文档.py | 提取Word文件的重要内容来生成摘要 |
241
+ | crazy_functions\批量Markdown翻译.py | 批量翻译Markdown文件 |
242
+ | crazy_functions\批量总结PDF文档.py | 批量从PDF文件中提取摘要 |
243
+ | crazy_functions\批量总结PDF文档pdfminer.py | 批量从PDF文件中提取摘要 |
244
+ | crazy_functions\批量翻译PDF文档_多线程.py | 批量翻译PDF文件 |
245
+ | crazy_functions\理解PDF文档内容.py | 批量分析PDF文件并提取摘要 |
246
+ | crazy_functions\生成函数注释.py | 自动生成Python文件中函数的注释 |
247
+ | crazy_functions\解析项目源代码.py | 解析并分析给定项目的源代码 |
248
+ | crazy_functions\询问多个大语言模型.py | 向多个大语言模型询问输入文本并进行处理 |
249
+ | crazy_functions\读文献写摘要.py | 根据用户输入读取文献内容并生成摘要 |
250
+ | crazy_functions\谷歌检索小助手.py | 利用谷歌学术检索用户提供的论文信息并提取相关信息 |
251
+ | crazy_functions\高级功能函数模板.py | 实现高级功能的模板函数 |
252
+ | request_llm\bridge_all.py | 处理与LLM的交互 |
253
+ | request_llm\bridge_chatglm.py | 使用ChatGLM模型进行聊天 |
254
+ | request_llm\bridge_chatgpt.py | 实现对话生成的各项功能 |
255
+ | request_llm\bridge_tgui.py | 在Websockets中与用户进行交互并生成文本输出 |
256
+
main.py CHANGED
@@ -1,176 +1,209 @@
1
  import os; os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染
2
- import gradio as gr
3
- from request_llm.bridge_chatgpt import predict
4
- from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated, get_conf, ArgsGeneralWrapper, DummyWith
5
-
6
- # 建议您复制一个config_private.py放自己的秘密, 如API和代理网址, 避免不小心传github被别人看到
7
- proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION, CHATBOT_HEIGHT, LAYOUT = \
8
- get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION', 'CHATBOT_HEIGHT', 'LAYOUT')
9
-
10
- # 如果WEB_PORT是-1, 则随机选取WEB端口
11
- PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT
12
- if not AUTHENTICATION: AUTHENTICATION = None
13
-
14
- from check_proxy import get_current_version
15
- initial_prompt = "Serve me as a writing and programming assistant."
16
- title_html = f"<h1 align=\"left\">ChatGPT 学术优化 Version{get_current_version()}</h1>"
17
- description = """代码开源更新[地址🚀](https://github.com/binary-husky/chatgpt_academic),感谢热情的[开发者们❤️](https://github.com/binary-husky/chatgpt_academic/graphs/contributors)"""
18
-
19
- # 问询记录, python 版本建议3.9+(越新越好)
20
- import logging
21
- os.makedirs("gpt_log", exist_ok=True)
22
- try:logging.basicConfig(filename="gpt_log/chat_secrets.log", level=logging.INFO, encoding="utf-8")
23
- except:logging.basicConfig(filename="gpt_log/chat_secrets.log", level=logging.INFO)
24
- print("所有问询记录将自动保存在本地目录./gpt_log/chat_secrets.log, 请注意自我隐私保护哦!")
25
-
26
- # 一些普通功能模块
27
- from core_functional import get_core_functions
28
- functional = get_core_functions()
29
-
30
- # 高级函数插件
31
- from crazy_functional import get_crazy_functions
32
- crazy_fns = get_crazy_functions()
33
-
34
- # 处理markdown文本格式的转变
35
- gr.Chatbot.postprocess = format_io
36
-
37
- # 做一些外观色彩上的调整
38
- from theme import adjust_theme, advanced_css
39
- set_theme = adjust_theme()
40
-
41
- # 代理与自动更新
42
- from check_proxy import check_proxy, auto_update
43
- proxy_info = check_proxy(proxies)
44
-
45
- gr_L1 = lambda: gr.Row().style()
46
- gr_L2 = lambda scale: gr.Column(scale=scale)
47
- if LAYOUT == "TOP-DOWN":
48
- gr_L1 = lambda: DummyWith()
49
- gr_L2 = lambda scale: gr.Row()
50
- CHATBOT_HEIGHT /= 2
51
-
52
- cancel_handles = []
53
- with gr.Blocks(title="ChatGPT 学术优化", theme=set_theme, analytics_enabled=False, css=advanced_css) as demo:
54
- gr.HTML(title_html)
55
- with gr_L1():
56
- with gr_L2(scale=2):
57
- chatbot = gr.Chatbot()
58
- chatbot.style(height=CHATBOT_HEIGHT)
59
- history = gr.State([])
60
- with gr_L2(scale=1):
61
- with gr.Accordion("用户输入", open=True, visible=False) as area_input_primary:
62
- with gr.Row():
63
- txt = gr.Textbox(show_label=False, placeholder="Input question here.").style(container=False)
64
- with gr.Row():
65
- submitBtn = gr.Button("提交", variant="primary")
66
- with gr.Row():
67
- resetBtn = gr.Button("重置", variant="secondary"); resetBtn.style(size="sm")
68
- stopBtn = gr.Button("停止", variant="secondary"); stopBtn.style(size="sm")
69
- with gr.Row():
70
- status = gr.Markdown(f"Tips: 按Enter提交, 按Shift+Enter换行。\n当前模型: {LLM_MODEL}")
71
- with gr.Accordion("基础功能", open=True) as area_basic_fn:
72
- with gr.Row():
73
- for k in functional:
74
- variant = functional[k]["Color"] if "Color" in functional[k] else "secondary"
75
- functional[k]["Button"] = gr.Button(k, variant=variant)
76
- with gr.Accordion("函数插件区", open=True, visible=False) as area_crazy_fn:
77
- with gr.Row():
78
- gr.Markdown("注意:以下“红颜色”标识的函数插件需从输入区读取路径作为参数.")
79
- with gr.Row():
80
- for k in crazy_fns:
81
- if not crazy_fns[k].get("AsButton", True): continue
82
- variant = crazy_fns[k]["Color"] if "Color" in crazy_fns[k] else "secondary"
83
- crazy_fns[k]["Button"] = gr.Button(k, variant=variant)
84
- crazy_fns[k]["Button"].style(size="sm")
85
- with gr.Row():
86
- with gr.Accordion("更多函数插件", open=True):
87
- dropdown_fn_list = [k for k in crazy_fns.keys() if not crazy_fns[k].get("AsButton", True)]
88
- with gr.Column(scale=1):
89
- dropdown = gr.Dropdown(dropdown_fn_list, value=r"打开插件列表", label="").style(container=False)
90
- with gr.Column(scale=1):
91
- switchy_bt = gr.Button(r"请先从插件列表中选择", variant="secondary")
92
- with gr.Row():
93
- with gr.Accordion("点击展开“文件上传区”。上传本地文件可供红色函数插件调用。", open=False) as area_file_up:
94
- file_upload = gr.Files(label="任何文件, 但推荐上传压缩文件(zip, tar)", file_count="multiple")
95
- with gr.Accordion("SysPrompt & 交互界面布局", open=(LAYOUT == "TOP-DOWN")):
96
- system_prompt = gr.Textbox(show_label=True, lines=2, placeholder=f"System Prompt", label="System prompt", value=initial_prompt)
97
- top_p = gr.Slider(minimum=-0, maximum=1.0, value=1.0, step=0.01,interactive=True, label="Top-p (nucleus sampling)",)
98
- temperature = gr.Slider(minimum=-0, maximum=2.0, value=1.0, step=0.01, interactive=True, label="Temperature",)
99
- checkboxes = gr.CheckboxGroup(["基础功能区", "函数插件区", "底部输入区"], value=["基础功能区", "底部输入区"], label="显示/隐藏功能区")
100
- gr.Markdown(description)
101
- with gr.Accordion("用户输入", open=True, visible=True) as area_input_secondary:
102
- with gr.Row():
103
- txt2 = gr.Textbox(show_label=True, placeholder="Input question here.", label="Question").style(container=False)
104
- with gr.Row():
105
- submitBtn2 = gr.Button("提交", variant="primary")
106
- with gr.Row():
107
- resetBtn2 = gr.Button("重置", variant="secondary"); resetBtn.style(size="sm")
108
- stopBtn2 = gr.Button("停止", variant="secondary"); stopBtn.style(size="sm")
109
- with gr.Row():
110
- status = gr.Markdown(f"Tips: 按Enter提交, 按Shift+Enter换行。\n当前模型: {LLM_MODEL}")
111
- # 功能区显示开关与功能区的互动
112
- def fn_area_visibility(a):
113
- ret = {}
114
- ret.update({area_basic_fn: gr.update(visible=("基础功能区" in a))})
115
- ret.update({area_crazy_fn: gr.update(visible=("函数插件区" in a))})
116
- ret.update({area_input_primary: gr.update(visible=("底部输入区" not in a))})
117
- ret.update({area_input_secondary: gr.update(visible=("底部输入区" in a))})
118
- if "底部输入区" in a: ret.update({txt: gr.update(value="")})
119
- return ret
120
- checkboxes.select(fn_area_visibility, [checkboxes], [area_basic_fn, area_crazy_fn, area_input_primary, area_input_secondary, txt, txt2] )
121
- # 整理反复出现的控件句柄组合
122
- input_combo = [txt, txt2, top_p, temperature, chatbot, history, system_prompt]
123
- output_combo = [chatbot, history, status]
124
- predict_args = dict(fn=ArgsGeneralWrapper(predict), inputs=input_combo, outputs=output_combo)
125
- # 提交按钮、重置按钮
126
- cancel_handles.append(txt.submit(**predict_args))
127
- cancel_handles.append(txt2.submit(**predict_args))
128
- cancel_handles.append(submitBtn.click(**predict_args))
129
- cancel_handles.append(submitBtn2.click(**predict_args))
130
- resetBtn.click(lambda: ([], [], "已重置"), None, output_combo)
131
- resetBtn2.click(lambda: ([], [], "已重置"), None, output_combo)
132
- # 基础功能区的回调函数注册
133
- for k in functional:
134
- click_handle = functional[k]["Button"].click(fn=ArgsGeneralWrapper(predict), inputs=[*input_combo, gr.State(True), gr.State(k)], outputs=output_combo)
135
- cancel_handles.append(click_handle)
136
- # 文件上传区,接收文件后与chatbot的互动
137
- file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt], [chatbot, txt])
138
- # 函数插件-固定按钮区
139
- for k in crazy_fns:
140
- if not crazy_fns[k].get("AsButton", True): continue
141
- click_handle = crazy_fns[k]["Button"].click(ArgsGeneralWrapper(crazy_fns[k]["Function"]), [*input_combo, gr.State(PORT)], output_combo)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  click_handle.then(on_report_generated, [file_upload, chatbot], [file_upload, chatbot])
 
 
 
143
  cancel_handles.append(click_handle)
144
- # 函数插件-下拉菜单与随变按钮的互动
145
- def on_dropdown_changed(k):
146
- variant = crazy_fns[k]["Color"] if "Color" in crazy_fns[k] else "secondary"
147
- return {switchy_bt: gr.update(value=k, variant=variant)}
148
- dropdown.select(on_dropdown_changed, [dropdown], [switchy_bt] )
149
- # 随变按钮的回调函数注册
150
- def route(k, *args, **kwargs):
151
- if k in [r"打开插件列表", r"请先从插件列表中选择"]: return
152
- yield from ArgsGeneralWrapper(crazy_fns[k]["Function"])(*args, **kwargs)
153
- click_handle = switchy_bt.click(route,[switchy_bt, *input_combo, gr.State(PORT)], output_combo)
154
- click_handle.then(on_report_generated, [file_upload, chatbot], [file_upload, chatbot])
155
- # def expand_file_area(file_upload, area_file_up):
156
- # if len(file_upload)>0: return {area_file_up: gr.update(open=True)}
157
- # click_handle.then(expand_file_area, [file_upload, area_file_up], [area_file_up])
158
- cancel_handles.append(click_handle)
159
- # 终止按钮的回调函数注册
160
- stopBtn.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
161
- stopBtn2.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
162
- # gradio的inbrowser触发不太稳定,回滚代码到原始的浏览器打开函数
163
- def auto_opentab_delay():
164
- import threading, webbrowser, time
165
- print(f"如果浏览器没有自动打开,请复制并转到以下URL:")
166
- print(f"\t(亮色主题): http://localhost:{PORT}")
167
- print(f"\t(暗色主题): http://localhost:{PORT}/?__dark-theme=true")
168
- def open():
169
- time.sleep(2) # 打开浏览器
170
- webbrowser.open_new_tab(f"http://localhost:{PORT}/?__dark-theme=true")
171
- threading.Thread(target=open, name="open-browser", daemon=True).start()
172
- threading.Thread(target=auto_update, name="self-upgrade", daemon=True).start()
173
-
174
- demo.launch(auth=(os.environ.get("USER"), os.environ.get("PASSWD")))
175
- #auto_opentab_delay()
176
- #demo.queue(concurrency_count=CONCURRENT_COUNT).launch(server_name="0.0.0.0", share=True, server_port=PORT, auth=AUTHENTICATION)
 
1
  import os; os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染
2
+
3
+ def main():
4
+ import gradio as gr
5
+ from request_llm.bridge_all import predict
6
+ from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated, get_conf, ArgsGeneralWrapper, DummyWith
7
+ # 建议您复制一个config_private.py放自己的秘密, 如API和代理网址, 避免不小心传github被别人看到
8
+ proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION, CHATBOT_HEIGHT, LAYOUT, API_KEY, AVAIL_LLM_MODELS = \
9
+ get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION', 'CHATBOT_HEIGHT', 'LAYOUT', 'API_KEY', 'AVAIL_LLM_MODELS')
10
+
11
+ # 如果WEB_PORT是-1, 则随机选取WEB端口
12
+ PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT
13
+ if not AUTHENTICATION: AUTHENTICATION = None
14
+
15
+ from check_proxy import get_current_version
16
+ initial_prompt = "Serve me as a writing and programming assistant."
17
+ title_html = f"<h1 align=\"center\">ChatGPT 学术优化 {get_current_version()}</h1>"
18
+ description = """代码开源和更新[地址🚀](https://github.com/binary-husky/chatgpt_academic),感谢热情的[开发者们❤️](https://github.com/binary-husky/chatgpt_academic/graphs/contributors)"""
19
+
20
+ # 问询记录, python 版本建议3.9+(越新越好)
21
+ import logging
22
+ os.makedirs("gpt_log", exist_ok=True)
23
+ try:logging.basicConfig(filename="gpt_log/chat_secrets.log", level=logging.INFO, encoding="utf-8")
24
+ except:logging.basicConfig(filename="gpt_log/chat_secrets.log", level=logging.INFO)
25
+ print("所有问询记录将自动保存在本地目录./gpt_log/chat_secrets.log, 请注意自我隐私保护哦!")
26
+
27
+ # 一些普通功能模块
28
+ from core_functional import get_core_functions
29
+ functional = get_core_functions()
30
+
31
+ # 高级函数插件
32
+ from crazy_functional import get_crazy_functions
33
+ crazy_fns = get_crazy_functions()
34
+
35
+ # 处理markdown文本格式的转变
36
+ gr.Chatbot.postprocess = format_io
37
+
38
+ # 做一些外观色彩上的调整
39
+ from theme import adjust_theme, advanced_css
40
+ set_theme = adjust_theme()
41
+
42
+ # 代理与自动更新
43
+ from check_proxy import check_proxy, auto_update, warm_up_modules
44
+ proxy_info = check_proxy(proxies)
45
+
46
+ gr_L1 = lambda: gr.Row().style()
47
+ gr_L2 = lambda scale: gr.Column(scale=scale)
48
+ if LAYOUT == "TOP-DOWN":
49
+ gr_L1 = lambda: DummyWith()
50
+ gr_L2 = lambda scale: gr.Row()
51
+ CHATBOT_HEIGHT /= 2
52
+
53
+ cancel_handles = []
54
+ with gr.Blocks(title="ChatGPT 学术优化", theme=set_theme, analytics_enabled=False, css=advanced_css) as demo:
55
+ gr.HTML(title_html)
56
+ cookies = gr.State({'api_key': API_KEY, 'llm_model': LLM_MODEL})
57
+ with gr_L1():
58
+ with gr_L2(scale=2):
59
+ chatbot = gr.Chatbot(label=f"当前模型:{LLM_MODEL}")
60
+ chatbot.style(height=CHATBOT_HEIGHT)
61
+ history = gr.State([])
62
+ with gr_L2(scale=1):
63
+ with gr.Accordion("输入区", open=True) as area_input_primary:
64
+ with gr.Row():
65
+ txt = gr.Textbox(show_label=False, placeholder="Input question here.").style(container=False)
66
+ with gr.Row():
67
+ submitBtn = gr.Button("提交", variant="primary")
68
+ with gr.Row():
69
+ resetBtn = gr.Button("重置", variant="secondary"); resetBtn.style(size="sm")
70
+ stopBtn = gr.Button("停止", variant="secondary"); stopBtn.style(size="sm")
71
+ clearBtn = gr.Button("清除", variant="secondary", visible=False); clearBtn.style(size="sm")
72
+ with gr.Row():
73
+ status = gr.Markdown(f"Tip: 按Enter提交, 按Shift+Enter换行。当前模型: {LLM_MODEL} \n {proxy_info}")
74
+ with gr.Accordion("基础功能区", open=True) as area_basic_fn:
75
+ with gr.Row():
76
+ for k in functional:
77
+ variant = functional[k]["Color"] if "Color" in functional[k] else "secondary"
78
+ functional[k]["Button"] = gr.Button(k, variant=variant)
79
+ with gr.Accordion("函数插件区", open=True) as area_crazy_fn:
80
+ with gr.Row():
81
+ gr.Markdown("注意:以下“红颜色”标识的函数插件需从输入区读取路径作为参数.")
82
+ with gr.Row():
83
+ for k in crazy_fns:
84
+ if not crazy_fns[k].get("AsButton", True): continue
85
+ variant = crazy_fns[k]["Color"] if "Color" in crazy_fns[k] else "secondary"
86
+ crazy_fns[k]["Button"] = gr.Button(k, variant=variant)
87
+ crazy_fns[k]["Button"].style(size="sm")
88
+ with gr.Row():
89
+ with gr.Accordion("更多函数插件", open=True):
90
+ dropdown_fn_list = [k for k in crazy_fns.keys() if not crazy_fns[k].get("AsButton", True)]
91
+ with gr.Row():
92
+ dropdown = gr.Dropdown(dropdown_fn_list, value=r"打开插件列表", label="").style(container=False)
93
+ with gr.Row():
94
+ plugin_advanced_arg = gr.Textbox(show_label=True, label="高级参数输入区", visible=False,
95
+ placeholder="这里是特殊函数插件的高级参数输入区").style(container=False)
96
+ with gr.Row():
97
+ switchy_bt = gr.Button(r"请先从插件列表中选择", variant="secondary")
98
+ with gr.Row():
99
+ with gr.Accordion("点击展开“文件上传区”。上传本地文件可供红色函数插件调用。", open=False) as area_file_up:
100
+ file_upload = gr.Files(label="任何文件, 但推荐上传压缩文件(zip, tar)", file_count="multiple")
101
+ with gr.Accordion("更换模型 & SysPrompt & 交互界面布局", open=(LAYOUT == "TOP-DOWN")):
102
+ system_prompt = gr.Textbox(show_label=True, placeholder=f"System Prompt", label="System prompt", value=initial_prompt)
103
+ top_p = gr.Slider(minimum=-0, maximum=1.0, value=1.0, step=0.01,interactive=True, label="Top-p (nucleus sampling)",)
104
+ temperature = gr.Slider(minimum=-0, maximum=2.0, value=1.0, step=0.01, interactive=True, label="Temperature",)
105
+ max_length_sl = gr.Slider(minimum=256, maximum=4096, value=512, step=1, interactive=True, label="Local LLM MaxLength",)
106
+ checkboxes = gr.CheckboxGroup(["基础功能区", "函数插件区", "底部输入区", "输入清除键", "插件参数区"], value=["基础功能区", "函数插件区"], label="显示/隐藏功能区")
107
+ md_dropdown = gr.Dropdown(AVAIL_LLM_MODELS, value=LLM_MODEL, label="更换LLM模型/请求源").style(container=False)
108
+
109
+ gr.Markdown(description)
110
+ with gr.Accordion("备选输入区", open=True, visible=False) as area_input_secondary:
111
+ with gr.Row():
112
+ txt2 = gr.Textbox(show_label=False, placeholder="Input question here.", label="输入区2").style(container=False)
113
+ with gr.Row():
114
+ submitBtn2 = gr.Button("提交", variant="primary")
115
+ with gr.Row():
116
+ resetBtn2 = gr.Button("重置", variant="secondary"); resetBtn2.style(size="sm")
117
+ stopBtn2 = gr.Button("停止", variant="secondary"); stopBtn2.style(size="sm")
118
+ clearBtn2 = gr.Button("清除", variant="secondary", visible=False); clearBtn2.style(size="sm")
119
+ # 功能区显示开关与功能区的互动
120
+ def fn_area_visibility(a):
121
+ ret = {}
122
+ ret.update({area_basic_fn: gr.update(visible=("基础功能区" in a))})
123
+ ret.update({area_crazy_fn: gr.update(visible=("函数插件区" in a))})
124
+ ret.update({area_input_primary: gr.update(visible=("底部输入区" not in a))})
125
+ ret.update({area_input_secondary: gr.update(visible=("底部输入区" in a))})
126
+ ret.update({clearBtn: gr.update(visible=("输入清除键" in a))})
127
+ ret.update({clearBtn2: gr.update(visible=("输入清除键" in a))})
128
+ ret.update({plugin_advanced_arg: gr.update(visible=("插件参数区" in a))})
129
+ if "底部输入区" in a: ret.update({txt: gr.update(value="")})
130
+ return ret
131
+ checkboxes.select(fn_area_visibility, [checkboxes], [area_basic_fn, area_crazy_fn, area_input_primary, area_input_secondary, txt, txt2, clearBtn, clearBtn2, plugin_advanced_arg] )
132
+ # 整理反复出现的控件句柄组合
133
+ input_combo = [cookies, max_length_sl, md_dropdown, txt, txt2, top_p, temperature, chatbot, history, system_prompt, plugin_advanced_arg]
134
+ output_combo = [cookies, chatbot, history, status]
135
+ predict_args = dict(fn=ArgsGeneralWrapper(predict), inputs=input_combo, outputs=output_combo)
136
+ # 提交按钮、重置按钮
137
+ cancel_handles.append(txt.submit(**predict_args))
138
+ cancel_handles.append(txt2.submit(**predict_args))
139
+ cancel_handles.append(submitBtn.click(**predict_args))
140
+ cancel_handles.append(submitBtn2.click(**predict_args))
141
+ resetBtn.click(lambda: ([], [], "已重置"), None, [chatbot, history, status])
142
+ resetBtn2.click(lambda: ([], [], "已重置"), None, [chatbot, history, status])
143
+ clearBtn.click(lambda: ("",""), None, [txt, txt2])
144
+ clearBtn2.click(lambda: ("",""), None, [txt, txt2])
145
+ # 基础功能区的回调函数注册
146
+ for k in functional:
147
+ click_handle = functional[k]["Button"].click(fn=ArgsGeneralWrapper(predict), inputs=[*input_combo, gr.State(True), gr.State(k)], outputs=output_combo)
148
+ cancel_handles.append(click_handle)
149
+ # 文件上传区,接收文件后与chatbot的互动
150
+ file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt, txt2, checkboxes], [chatbot, txt, txt2])
151
+ # 函数插件-固定按钮区
152
+ for k in crazy_fns:
153
+ if not crazy_fns[k].get("AsButton", True): continue
154
+ click_handle = crazy_fns[k]["Button"].click(ArgsGeneralWrapper(crazy_fns[k]["Function"]), [*input_combo, gr.State(PORT)], output_combo)
155
+ click_handle.then(on_report_generated, [file_upload, chatbot], [file_upload, chatbot])
156
+ cancel_handles.append(click_handle)
157
+ # 函数插件-下拉菜单与随变按钮的互动
158
+ def on_dropdown_changed(k):
159
+ variant = crazy_fns[k]["Color"] if "Color" in crazy_fns[k] else "secondary"
160
+ ret = {switchy_bt: gr.update(value=k, variant=variant)}
161
+ if crazy_fns[k].get("AdvancedArgs", False): # 是否唤起高级插件参数区
162
+ ret.update({plugin_advanced_arg: gr.update(visible=True, label=f"插件[{k}]的高级参数说明:" + crazy_fns[k].get("ArgsReminder", [f"没有提供高级参数功能说明"]))})
163
+ else:
164
+ ret.update({plugin_advanced_arg: gr.update(visible=False, label=f"插件[{k}]不需要高级参数。")})
165
+ return ret
166
+ dropdown.select(on_dropdown_changed, [dropdown], [switchy_bt, plugin_advanced_arg] )
167
+ def on_md_dropdown_changed(k):
168
+ return {chatbot: gr.update(label="当前模型:"+k)}
169
+ md_dropdown.select(on_md_dropdown_changed, [md_dropdown], [chatbot] )
170
+ # 随变按钮的回调函数注册
171
+ def route(k, *args, **kwargs):
172
+ if k in [r"打开插件列表", r"请先从插件列表中选择"]: return
173
+ yield from ArgsGeneralWrapper(crazy_fns[k]["Function"])(*args, **kwargs)
174
+ click_handle = switchy_bt.click(route,[switchy_bt, *input_combo, gr.State(PORT)], output_combo)
175
  click_handle.then(on_report_generated, [file_upload, chatbot], [file_upload, chatbot])
176
+ # def expand_file_area(file_upload, area_file_up):
177
+ # if len(file_upload)>0: return {area_file_up: gr.update(open=True)}
178
+ # click_handle.then(expand_file_area, [file_upload, area_file_up], [area_file_up])
179
  cancel_handles.append(click_handle)
180
+ # 终止按钮的回调函数注册
181
+ stopBtn.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
182
+ stopBtn2.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
183
+
184
+ # gradio的inbrowser触发不太稳定,回滚代码到原始的浏览器打开函数
185
+ def auto_opentab_delay():
186
+ import threading, webbrowser, time
187
+ print(f"如果浏览器没有自动打开,请复制并转到以下URL:")
188
+ print(f"\t(亮色主题): http://localhost:{PORT}")
189
+ print(f"\t(暗色主题): http://localhost:{PORT}/?__dark-theme=true")
190
+ def open():
191
+ time.sleep(2) # 打开浏览器
192
+ webbrowser.open_new_tab(f"http://localhost:{PORT}/?__dark-theme=true")
193
+ threading.Thread(target=open, name="open-browser", daemon=True).start()
194
+ threading.Thread(target=auto_update, name="self-upgrade", daemon=True).start()
195
+ threading.Thread(target=warm_up_modules, name="warm-up", daemon=True).start()
196
+
197
+ auto_opentab_delay()
198
+ demo.queue(concurrency_count=CONCURRENT_COUNT).launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png")
199
+
200
+ # 如果需要在二级路径下运行
201
+ # CUSTOM_PATH, = get_conf('CUSTOM_PATH')
202
+ # if CUSTOM_PATH != "/":
203
+ # from toolbox import run_gradio_in_subpath
204
+ # run_gradio_in_subpath(demo, auth=AUTHENTICATION, port=PORT, custom_path=CUSTOM_PATH)
205
+ # else:
206
+ # demo.launch(server_name="0.0.0.0", server_port=PORT, auth=AUTHENTICATION, favicon_path="docs/logo.png")
207
+
208
+ if __name__ == "__main__":
209
+ main()
 
 
 
request_llm/README.md CHANGED
@@ -1,35 +1,53 @@
1
- # 如何使用其他大语言模型(dev分支测试中)
 
 
 
 
 
2
 
3
- ## 1. 先运行text-generation
4
  ``` sh
5
- # 下载模型( text-generation 这么牛的项目,别忘了给人家star )
6
- git clone https://github.com/oobabooga/text-generation-webui.git
 
 
 
 
7
 
8
- # 安装text-generation的额外依赖
9
- pip install accelerate bitsandbytes flexgen gradio llamacpp markdown numpy peft requests rwkv safetensors sentencepiece tqdm datasets git+https://github.com/huggingface/transformers
10
 
11
- # 切换路径
12
- cd text-generation-webui
13
 
14
- # 下载模型
 
 
 
 
 
 
 
 
 
 
15
  python download-model.py facebook/galactica-1.3b
16
  # 其他可选如 facebook/opt-1.3b
 
17
  # facebook/galactica-6.7b
18
  # facebook/galactica-120b
19
  # facebook/pygmalion-1.3b 等
20
  # 详情见 https://github.com/oobabooga/text-generation-webui
21
 
22
- # 启动text-generation,注意把模型的斜杠改成下划线
23
- python server.py --cpu --listen --listen-port 7860 --model facebook_galactica-1.3b
24
  ```
25
 
26
- ## 2. 修改config.py
 
27
  ``` sh
28
- # LLM_MODEL格式较复杂 TGUI:[模型]@[ws地址]:[ws端口] , 端口要和上面给定的端口一致
29
- LLM_MODEL = "TGUI:galactica-1.3b@localhost:7860"
30
  ```
31
 
32
- ## 3. 运行!
33
  ``` sh
34
  cd chatgpt-academic
35
  python main.py
 
1
+ # 如何使用其他大语言模型
2
+
3
+ ## ChatGLM
4
+
5
+ - 安装依赖 `pip install -r request_llm/requirements_chatglm.txt`
6
+ - 修改配置,在config.py中将LLM_MODEL的值改为"chatglm"
7
 
 
8
  ``` sh
9
+ LLM_MODEL = "chatglm"
10
+ ```
11
+ - 运行!
12
+ ``` sh
13
+ `python main.py`
14
+ ```
15
 
 
 
16
 
17
+ ---
18
+ ## Text-Generation-UI (TGUI,调试中,暂不可用)
19
 
20
+ ### 1. 部署TGUI
21
+ ``` sh
22
+ # 1 下载模型
23
+ git clone https://github.com/oobabooga/text-generation-webui.git
24
+ # 2 这个仓库的最新代码有问题,回滚到几周之前
25
+ git reset --hard fcda3f87767e642d1c0411776e549e1d3894843d
26
+ # 3 切换路径
27
+ cd text-generation-webui
28
+ # 4 安装text-generation的额外依赖
29
+ pip install accelerate bitsandbytes flexgen gradio llamacpp markdown numpy peft requests rwkv safetensors sentencepiece tqdm datasets git+https://github.com/huggingface/transformers
30
+ # 5 下载模型
31
  python download-model.py facebook/galactica-1.3b
32
  # 其他可选如 facebook/opt-1.3b
33
+ # facebook/galactica-1.3b
34
  # facebook/galactica-6.7b
35
  # facebook/galactica-120b
36
  # facebook/pygmalion-1.3b 等
37
  # 详情见 https://github.com/oobabooga/text-generation-webui
38
 
39
+ # 6 启动text-generation
40
+ python server.py --cpu --listen --listen-port 7865 --model facebook_galactica-1.3b
41
  ```
42
 
43
+ ### 2. 修改config.py
44
+
45
  ``` sh
46
+ # LLM_MODEL格式: tgui:[模型]@[ws地址]:[ws端口] , 端口要和上面给定的端口一致
47
+ LLM_MODEL = "tgui:galactica-1.3b@localhost:7860"
48
  ```
49
 
50
+ ### 3. 运行!
51
  ``` sh
52
  cd chatgpt-academic
53
  python main.py
request_llm/bridge_all.py ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ """
3
+ 该文件中主要包含2个函数,是所有LLM的通用接口,它们会继续向下调用更底层的LLM模型,处理多模型并行等细节
4
+
5
+ 不具备多线程能力的函数:正常对话时使用,具备完备的交互功能,不可多线程
6
+ 1. predict(...)
7
+
8
+ 具备多线程调用能力的函数:在函数插件中被调用,灵活而简洁
9
+ 2. predict_no_ui_long_connection(...)
10
+ """
11
+ import tiktoken
12
+ from functools import lru_cache
13
+ from concurrent.futures import ThreadPoolExecutor
14
+ from toolbox import get_conf
15
+
16
+ from .bridge_chatgpt import predict_no_ui_long_connection as chatgpt_noui
17
+ from .bridge_chatgpt import predict as chatgpt_ui
18
+
19
+ from .bridge_chatglm import predict_no_ui_long_connection as chatglm_noui
20
+ from .bridge_chatglm import predict as chatglm_ui
21
+
22
+ # from .bridge_tgui import predict_no_ui_long_connection as tgui_noui
23
+ # from .bridge_tgui import predict as tgui_ui
24
+
25
+ colors = ['#FF00FF', '#00FFFF', '#FF0000', '#990099', '#009999', '#990044']
26
+
27
+ class LazyloadTiktoken(object):
28
+ def __init__(self, model):
29
+ self.model = model
30
+
31
+ @staticmethod
32
+ @lru_cache(maxsize=128)
33
+ def get_encoder(model):
34
+ print('正在加载tokenizer,如果是第一次运行,可能需要一点时间下载参数')
35
+ tmp = tiktoken.encoding_for_model(model)
36
+ print('加载tokenizer完毕')
37
+ return tmp
38
+
39
+ def encode(self, *args, **kwargs):
40
+ encoder = self.get_encoder(self.model)
41
+ return encoder.encode(*args, **kwargs)
42
+
43
+ def decode(self, *args, **kwargs):
44
+ encoder = self.get_encoder(self.model)
45
+ return encoder.decode(*args, **kwargs)
46
+
47
+ # Endpoint 重定向
48
+ API_URL_REDIRECT, = get_conf("API_URL_REDIRECT")
49
+ openai_endpoint = "https://api.openai.com/v1/chat/completions"
50
+ api2d_endpoint = "https://openai.api2d.net/v1/chat/completions"
51
+ # 兼容旧版的配置
52
+ try:
53
+ API_URL, = get_conf("API_URL")
54
+ if API_URL != "https://api.openai.com/v1/chat/completions":
55
+ openai_endpoint = API_URL
56
+ print("警告!API_URL配置选项将被弃用,请更换为API_URL_REDIRECT配置")
57
+ except:
58
+ pass
59
+ # 新版配置
60
+ if openai_endpoint in API_URL_REDIRECT: openai_endpoint = API_URL_REDIRECT[openai_endpoint]
61
+ if api2d_endpoint in API_URL_REDIRECT: api2d_endpoint = API_URL_REDIRECT[api2d_endpoint]
62
+
63
+
64
+ # 获取tokenizer
65
+ tokenizer_gpt35 = LazyloadTiktoken("gpt-3.5-turbo")
66
+ tokenizer_gpt4 = LazyloadTiktoken("gpt-4")
67
+ get_token_num_gpt35 = lambda txt: len(tokenizer_gpt35.encode(txt, disallowed_special=()))
68
+ get_token_num_gpt4 = lambda txt: len(tokenizer_gpt4.encode(txt, disallowed_special=()))
69
+
70
+
71
+ model_info = {
72
+ # openai
73
+ "gpt-3.5-turbo": {
74
+ "fn_with_ui": chatgpt_ui,
75
+ "fn_without_ui": chatgpt_noui,
76
+ "endpoint": openai_endpoint,
77
+ "max_token": 4096,
78
+ "tokenizer": tokenizer_gpt35,
79
+ "token_cnt": get_token_num_gpt35,
80
+ },
81
+
82
+ "gpt-4": {
83
+ "fn_with_ui": chatgpt_ui,
84
+ "fn_without_ui": chatgpt_noui,
85
+ "endpoint": openai_endpoint,
86
+ "max_token": 8192,
87
+ "tokenizer": tokenizer_gpt4,
88
+ "token_cnt": get_token_num_gpt4,
89
+ },
90
+
91
+ # api_2d
92
+ "api2d-gpt-3.5-turbo": {
93
+ "fn_with_ui": chatgpt_ui,
94
+ "fn_without_ui": chatgpt_noui,
95
+ "endpoint": api2d_endpoint,
96
+ "max_token": 4096,
97
+ "tokenizer": tokenizer_gpt35,
98
+ "token_cnt": get_token_num_gpt35,
99
+ },
100
+
101
+ "api2d-gpt-4": {
102
+ "fn_with_ui": chatgpt_ui,
103
+ "fn_without_ui": chatgpt_noui,
104
+ "endpoint": api2d_endpoint,
105
+ "max_token": 8192,
106
+ "tokenizer": tokenizer_gpt4,
107
+ "token_cnt": get_token_num_gpt4,
108
+ },
109
+
110
+ # chatglm
111
+ "chatglm": {
112
+ "fn_with_ui": chatglm_ui,
113
+ "fn_without_ui": chatglm_noui,
114
+ "endpoint": None,
115
+ "max_token": 1024,
116
+ "tokenizer": tokenizer_gpt35,
117
+ "token_cnt": get_token_num_gpt35,
118
+ },
119
+
120
+ }
121
+
122
+
123
+ def LLM_CATCH_EXCEPTION(f):
124
+ """
125
+ 装饰器函数,将错误显示出来
126
+ """
127
+ def decorated(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience):
128
+ try:
129
+ return f(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience)
130
+ except Exception as e:
131
+ from toolbox import get_conf
132
+ import traceback
133
+ proxies, = get_conf('proxies')
134
+ tb_str = '\n```\n' + traceback.format_exc() + '\n```\n'
135
+ observe_window[0] = tb_str
136
+ return tb_str
137
+ return decorated
138
+
139
+
140
+ def predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience=False):
141
+ """
142
+ 发送至LLM,等待回复,一次性完成,不显示中间过程。但内部用stream的方法避免中途网线被掐。
143
+ inputs:
144
+ 是本次问询的输入
145
+ sys_prompt:
146
+ 系统静默prompt
147
+ llm_kwargs:
148
+ LLM的内部调优参数
149
+ history:
150
+ 是之前的对话列表
151
+ observe_window = None:
152
+ 用于负责跨越线程传递已经输出的部分,大部分时候仅仅为了fancy的视觉效果,留空即可。observe_window[0]:观测窗。observe_window[1]:看门狗
153
+ """
154
+ import threading, time, copy
155
+
156
+ model = llm_kwargs['llm_model']
157
+ n_model = 1
158
+ if '&' not in model:
159
+ assert not model.startswith("tgui"), "TGUI不支持函数插件的实现"
160
+
161
+ # 如果只询问1个大语言模型:
162
+ method = model_info[model]["fn_without_ui"]
163
+ return method(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience)
164
+ else:
165
+ # 如果同时询问多个大语言模型:
166
+ executor = ThreadPoolExecutor(max_workers=4)
167
+ models = model.split('&')
168
+ n_model = len(models)
169
+
170
+ window_len = len(observe_window)
171
+ assert window_len==3
172
+ window_mutex = [["", time.time(), ""] for _ in range(n_model)] + [True]
173
+
174
+ futures = []
175
+ for i in range(n_model):
176
+ model = models[i]
177
+ method = model_info[model]["fn_without_ui"]
178
+ llm_kwargs_feedin = copy.deepcopy(llm_kwargs)
179
+ llm_kwargs_feedin['llm_model'] = model
180
+ future = executor.submit(LLM_CATCH_EXCEPTION(method), inputs, llm_kwargs_feedin, history, sys_prompt, window_mutex[i], console_slience)
181
+ futures.append(future)
182
+
183
+ def mutex_manager(window_mutex, observe_window):
184
+ while True:
185
+ time.sleep(0.5)
186
+ if not window_mutex[-1]: break
187
+ # 看门狗(watchdog)
188
+ for i in range(n_model):
189
+ window_mutex[i][1] = observe_window[1]
190
+ # 观察窗(window)
191
+ chat_string = []
192
+ for i in range(n_model):
193
+ chat_string.append( f"【{str(models[i])} 说】: <font color=\"{colors[i]}\"> {window_mutex[i][0]} </font>" )
194
+ res = '<br/><br/>\n\n---\n\n'.join(chat_string)
195
+ # # # # # # # # # # #
196
+ observe_window[0] = res
197
+
198
+ t_model = threading.Thread(target=mutex_manager, args=(window_mutex, observe_window), daemon=True)
199
+ t_model.start()
200
+
201
+ return_string_collect = []
202
+ while True:
203
+ worker_done = [h.done() for h in futures]
204
+ if all(worker_done):
205
+ executor.shutdown()
206
+ break
207
+ time.sleep(1)
208
+
209
+ for i, future in enumerate(futures): # wait and get
210
+ return_string_collect.append( f"【{str(models[i])} 说】: <font color=\"{colors[i]}\"> {future.result()} </font>" )
211
+
212
+ window_mutex[-1] = False # stop mutex thread
213
+ res = '<br/><br/>\n\n---\n\n'.join(return_string_collect)
214
+ return res
215
+
216
+
217
+ def predict(inputs, llm_kwargs, *args, **kwargs):
218
+ """
219
+ 发送至LLM,流式获取输出。
220
+ 用于基础的对话功能。
221
+ inputs 是本次问询的输入
222
+ top_p, temperature是LLM的内部调优参数
223
+ history 是之前的对话列表(注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误)
224
+ chatbot 为WebUI中显示的对话列表,修改它,然后yeild出去,可以直接修改对话界面内容
225
+ additional_fn代表点击的哪个按钮,按钮见functional.py
226
+ """
227
+
228
+ method = model_info[llm_kwargs['llm_model']]["fn_with_ui"]
229
+ yield from method(inputs, llm_kwargs, *args, **kwargs)
230
+
request_llm/bridge_chatglm.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from transformers import AutoModel, AutoTokenizer
3
+ import time
4
+ import importlib
5
+ from toolbox import update_ui, get_conf
6
+ from multiprocessing import Process, Pipe
7
+
8
+ load_message = "ChatGLM尚未加载,加载需要一段时间。注意,取决于`config.py`的配置,ChatGLM消耗大量的内存(CPU)或显存(GPU),也许会导致低配计算机卡死 ……"
9
+
10
+ #################################################################################
11
+ class GetGLMHandle(Process):
12
+ def __init__(self):
13
+ super().__init__(daemon=True)
14
+ self.parent, self.child = Pipe()
15
+ self.chatglm_model = None
16
+ self.chatglm_tokenizer = None
17
+ self.info = ""
18
+ self.success = True
19
+ self.check_dependency()
20
+ self.start()
21
+
22
+ def check_dependency(self):
23
+ try:
24
+ import sentencepiece
25
+ self.info = "依赖检测通过"
26
+ self.success = True
27
+ except:
28
+ self.info = "缺少ChatGLM的依赖,如果要使用ChatGLM,除了基础的pip依赖以外,您还需要运行`pip install -r request_llm/requirements_chatglm.txt`安装ChatGLM的依赖。"
29
+ self.success = False
30
+
31
+ def ready(self):
32
+ return self.chatglm_model is not None
33
+
34
+ def run(self):
35
+ # 第一次运行,加载参数
36
+ retry = 0
37
+ while True:
38
+ try:
39
+ if self.chatglm_model is None:
40
+ self.chatglm_tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True)
41
+ device, = get_conf('LOCAL_MODEL_DEVICE')
42
+ if device=='cpu':
43
+ self.chatglm_model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).float()
44
+ else:
45
+ self.chatglm_model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).half().cuda()
46
+ self.chatglm_model = self.chatglm_model.eval()
47
+ break
48
+ else:
49
+ break
50
+ except:
51
+ retry += 1
52
+ if retry > 3:
53
+ self.child.send('[Local Message] Call ChatGLM fail 不能正常加载ChatGLM的参数。')
54
+ raise RuntimeError("不能正常加载ChatGLM的参数!")
55
+
56
+ # 进入任务等待状态
57
+ while True:
58
+ kwargs = self.child.recv()
59
+ try:
60
+ for response, history in self.chatglm_model.stream_chat(self.chatglm_tokenizer, **kwargs):
61
+ self.child.send(response)
62
+ except:
63
+ self.child.send('[Local Message] Call ChatGLM fail.')
64
+ self.child.send('[Finish]')
65
+
66
+ def stream_chat(self, **kwargs):
67
+ self.parent.send(kwargs)
68
+ while True:
69
+ res = self.parent.recv()
70
+ if res != '[Finish]':
71
+ yield res
72
+ else:
73
+ break
74
+ return
75
+
76
+ global glm_handle
77
+ glm_handle = None
78
+ #################################################################################
79
+ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="", observe_window=None, console_slience=False):
80
+ """
81
+ 多线程方法
82
+ 函数的说明请见 request_llm/bridge_all.py
83
+ """
84
+ global glm_handle
85
+ if glm_handle is None:
86
+ glm_handle = GetGLMHandle()
87
+ observe_window[0] = load_message + "\n\n" + glm_handle.info
88
+ if not glm_handle.success:
89
+ error = glm_handle.info
90
+ glm_handle = None
91
+ raise RuntimeError(error)
92
+
93
+ # chatglm 没有 sys_prompt 接口,因此把prompt加入 history
94
+ history_feedin = []
95
+ history_feedin.append(["What can I do?", sys_prompt])
96
+ for i in range(len(history)//2):
97
+ history_feedin.append([history[2*i], history[2*i+1]] )
98
+
99
+ watch_dog_patience = 5 # 看门狗 (watchdog) 的耐心, 设置5秒即可
100
+ response = ""
101
+ for response in glm_handle.stream_chat(query=inputs, history=history_feedin, max_length=llm_kwargs['max_length'], top_p=llm_kwargs['top_p'], temperature=llm_kwargs['temperature']):
102
+ observe_window[0] = response
103
+ if len(observe_window) >= 2:
104
+ if (time.time()-observe_window[1]) > watch_dog_patience:
105
+ raise RuntimeError("程序终止。")
106
+ return response
107
+
108
+
109
+
110
+ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
111
+ """
112
+ 单线程方法
113
+ 函数的说明请见 request_llm/bridge_all.py
114
+ """
115
+ chatbot.append((inputs, ""))
116
+
117
+ global glm_handle
118
+ if glm_handle is None:
119
+ glm_handle = GetGLMHandle()
120
+ chatbot[-1] = (inputs, load_message + "\n\n" + glm_handle.info)
121
+ yield from update_ui(chatbot=chatbot, history=[])
122
+ if not glm_handle.success:
123
+ glm_handle = None
124
+ return
125
+
126
+ if additional_fn is not None:
127
+ import core_functional
128
+ importlib.reload(core_functional) # 热更新prompt
129
+ core_functional = core_functional.get_core_functions()
130
+ if "PreProcess" in core_functional[additional_fn]: inputs = core_functional[additional_fn]["PreProcess"](inputs) # 获取预处理函数(如果有的话)
131
+ inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
132
+
133
+ history_feedin = []
134
+ history_feedin.append(["What can I do?", system_prompt] )
135
+ for i in range(len(history)//2):
136
+ history_feedin.append([history[2*i], history[2*i+1]] )
137
+
138
+ for response in glm_handle.stream_chat(query=inputs, history=history_feedin, max_length=llm_kwargs['max_length'], top_p=llm_kwargs['top_p'], temperature=llm_kwargs['temperature']):
139
+ chatbot[-1] = (inputs, response)
140
+ yield from update_ui(chatbot=chatbot, history=history)
141
+
142
+ history.extend([inputs, response])
143
+ yield from update_ui(chatbot=chatbot, history=history)
request_llm/bridge_chatgpt.py CHANGED
@@ -21,9 +21,9 @@ import importlib
21
 
22
  # config_private.py放自己的秘密如API和代理网址
23
  # 读取时首先看是否存在私密的config_private配置文件(不受git管控),如果有,则覆盖原config文件
24
- from toolbox import get_conf
25
- proxies, API_URL, API_KEY, TIMEOUT_SECONDS, MAX_RETRY, LLM_MODEL = \
26
- get_conf('proxies', 'API_URL', 'API_KEY', 'TIMEOUT_SECONDS', 'MAX_RETRY', 'LLM_MODEL')
27
 
28
  timeout_bot_msg = '[Local Message] Request timeout. Network error. Please check proxy settings in config.py.' + \
29
  '网络错误,检查代理服务器是否可用,以及代理设置的格式是否正确,格式须是[协议]://[地址]:[端口],缺一不可。'
@@ -39,60 +39,30 @@ def get_full_error(chunk, stream_response):
39
  break
40
  return chunk
41
 
42
- def predict_no_ui(inputs, top_p, temperature, history=[], sys_prompt=""):
43
- """
44
- 发送至chatGPT,等待回复,一次性完成,不显示中间过程。
45
- predict函数的简化版。
46
- 用于payload比较大的情况,或者用于实现多线、带嵌套的复杂功能。
47
 
48
- inputs 是本次问询的输入
49
- top_p, temperature是chatGPT的内部调优参数
50
- history 是之前的对话列表
51
- (注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误,然后raise ConnectionAbortedError)
52
  """
53
- headers, payload = generate_payload(inputs, top_p, temperature, history, system_prompt=sys_prompt, stream=False)
54
-
55
- retry = 0
56
- while True:
57
- try:
58
- # make a POST request to the API endpoint, stream=False
59
- response = requests.post(API_URL, headers=headers, proxies=proxies,
60
- json=payload, stream=False, timeout=TIMEOUT_SECONDS*2); break
61
- except requests.exceptions.ReadTimeout as e:
62
- retry += 1
63
- traceback.print_exc()
64
- if retry > MAX_RETRY: raise TimeoutError
65
- if MAX_RETRY!=0: print(f'请求超时,正在重试 ({retry}/{MAX_RETRY}) ……')
66
-
67
- try:
68
- result = json.loads(response.text)["choices"][0]["message"]["content"]
69
- return result
70
- except Exception as e:
71
- if "choices" not in response.text: print(response.text)
72
- raise ConnectionAbortedError("Json解析不合常规,可能是文本过长" + response.text)
73
-
74
-
75
- def predict_no_ui_long_connection(inputs, top_p, temperature, history=[], sys_prompt="", observe_window=None):
76
- """
77
- 发送至chatGPT,等待回复,一次性完成,不显示中间过程。但内部用stream的方法避免中途网线被掐。
78
- inputs:
79
- 是本次问询的输入
80
- sys_prompt:
81
- 系统静默prompt
82
- top_p, temperature:
83
- chatGPT的内部调优参数
84
- history:
85
- 是之前的对话列表
86
- observe_window = None:
87
- 用于负责跨越线程传递已经输出的部分,大部分时候仅仅为了fancy的视觉效果,留空即可。observe_window[0]:观测窗。observe_window[1]:看门狗
88
  """
89
  watch_dog_patience = 5 # 看门狗的耐心, 设置5秒即可
90
- headers, payload = generate_payload(inputs, top_p, temperature, history, system_prompt=sys_prompt, stream=True)
91
  retry = 0
92
  while True:
93
  try:
94
  # make a POST request to the API endpoint, stream=False
95
- response = requests.post(API_URL, headers=headers, proxies=proxies,
 
 
96
  json=payload, stream=True, timeout=TIMEOUT_SECONDS); break
97
  except requests.exceptions.ReadTimeout as e:
98
  retry += 1
@@ -115,37 +85,47 @@ def predict_no_ui_long_connection(inputs, top_p, temperature, history=[], sys_pr
115
  raise ConnectionAbortedError("OpenAI拒绝了请求:" + error_msg)
116
  else:
117
  raise RuntimeError("OpenAI拒绝了请求:" + error_msg)
 
118
  json_data = json.loads(chunk.lstrip('data:'))['choices'][0]
119
  delta = json_data["delta"]
120
  if len(delta) == 0: break
121
  if "role" in delta: continue
122
  if "content" in delta:
123
  result += delta["content"]
124
- print(delta["content"], end='')
125
  if observe_window is not None:
126
  # 观测窗,把已经获取的数据显示出去
127
  if len(observe_window) >= 1: observe_window[0] += delta["content"]
128
  # 看门狗,如果超过期限没有喂狗,则终止
129
  if len(observe_window) >= 2:
130
  if (time.time()-observe_window[1]) > watch_dog_patience:
131
- raise RuntimeError("程序终止。")
132
  else: raise RuntimeError("意外Json结构:"+delta)
133
  if json_data['finish_reason'] == 'length':
134
  raise ConnectionAbortedError("正常结束,但显示Token不足,导致输出不完整,请削减单次输入的文本量。")
135
  return result
136
 
137
 
138
- def predict(inputs, top_p, temperature, chatbot=[], history=[], system_prompt='',
139
- stream = True, additional_fn=None):
140
  """
141
- 发送至chatGPT,流式获取输出。
142
- 用于基础的对话功能。
143
- inputs 是本次问询的输入
144
- top_p, temperature是chatGPT的内部调优参数
145
- history 是之前的对话列表(注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误)
146
- chatbot 为WebUI中显示的对话列表,修改它,然后yeild出去,可以直接修改对话界面内容
147
- additional_fn代表点击的哪个按钮,按钮见functional.py
148
  """
 
 
 
 
 
 
 
 
 
 
149
  if additional_fn is not None:
150
  import core_functional
151
  importlib.reload(core_functional) # 热更新prompt
@@ -153,26 +133,33 @@ def predict(inputs, top_p, temperature, chatbot=[], history=[], system_prompt=''
153
  if "PreProcess" in core_functional[additional_fn]: inputs = core_functional[additional_fn]["PreProcess"](inputs) # 获取预处理函数(如果有的话)
154
  inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
155
 
156
- if stream:
157
- raw_input = inputs
158
- logging.info(f'[raw_input] {raw_input}')
159
- chatbot.append((inputs, ""))
160
- yield chatbot, history, "等待响应"
161
 
162
- headers, payload = generate_payload(inputs, top_p, temperature, history, system_prompt, stream)
 
 
 
 
 
 
163
  history.append(inputs); history.append(" ")
164
 
165
  retry = 0
166
  while True:
167
  try:
168
  # make a POST request to the API endpoint, stream=True
169
- response = requests.post(API_URL, headers=headers, proxies=proxies,
 
 
170
  json=payload, stream=True, timeout=TIMEOUT_SECONDS);break
171
  except:
172
  retry += 1
173
  chatbot[-1] = ((chatbot[-1][0], timeout_bot_msg))
174
  retry_msg = f",正在重试 ({retry}/{MAX_RETRY}) ……" if MAX_RETRY > 0 else ""
175
- yield chatbot, history, "请求超时"+retry_msg
176
  if retry > MAX_RETRY: raise TimeoutError
177
 
178
  gpt_replying_buffer = ""
@@ -183,51 +170,65 @@ def predict(inputs, top_p, temperature, chatbot=[], history=[], system_prompt=''
183
  while True:
184
  chunk = next(stream_response)
185
  # print(chunk.decode()[6:])
186
- if is_head_of_the_stream:
187
  # 数据流的第一帧不携带content
188
  is_head_of_the_stream = False; continue
189
 
190
  if chunk:
191
  try:
192
- if len(json.loads(chunk.decode()[6:])['choices'][0]["delta"]) == 0:
 
 
193
  # 判定为数据流的结束,gpt_replying_buffer也写完了
194
  logging.info(f'[response] {gpt_replying_buffer}')
195
  break
196
  # 处理数据流的主体
197
- chunkjson = json.loads(chunk.decode()[6:])
198
  status_text = f"finish_reason: {chunkjson['choices'][0]['finish_reason']}"
199
  # 如果这里抛出异常,一般是文本过长,详情见get_full_error的输出
200
- gpt_replying_buffer = gpt_replying_buffer + json.loads(chunk.decode()[6:])['choices'][0]["delta"]["content"]
201
  history[-1] = gpt_replying_buffer
202
  chatbot[-1] = (history[-2], history[-1])
203
- yield chatbot, history, status_text
204
 
205
  except Exception as e:
206
  traceback.print_exc()
207
- yield chatbot, history, "Json解析不合常规"
208
  chunk = get_full_error(chunk, stream_response)
209
- error_msg = chunk.decode()
 
210
  if "reduce the length" in error_msg:
211
  chatbot[-1] = (chatbot[-1][0], "[Local Message] Reduce the length. 本次输入过长,或历史数据过长. 历史缓存数据现已释放,您可以请再次尝试.")
212
  history = [] # 清除历史
 
 
213
  elif "Incorrect API key" in error_msg:
214
  chatbot[-1] = (chatbot[-1][0], "[Local Message] Incorrect API key. OpenAI以提供了不正确的API_KEY为由,拒绝服务.")
215
  elif "exceeded your current quota" in error_msg:
216
  chatbot[-1] = (chatbot[-1][0], "[Local Message] You exceeded your current quota. OpenAI以账户额度不足为由,拒绝服务.")
 
 
 
 
217
  else:
218
  from toolbox import regular_txt_to_markdown
219
  tb_str = '```\n' + traceback.format_exc() + '```'
220
- chatbot[-1] = (chatbot[-1][0], f"[Local Message] 异常 \n\n{tb_str} \n\n{regular_txt_to_markdown(chunk.decode()[4:])}")
221
- yield chatbot, history, "Json异常" + error_msg
222
  return
223
 
224
- def generate_payload(inputs, top_p, temperature, history, system_prompt, stream):
225
  """
226
- 整合所有信息,选择LLM模型,生成http请求,为发送请求做准备
227
  """
 
 
 
 
 
228
  headers = {
229
  "Content-Type": "application/json",
230
- "Authorization": f"Bearer {API_KEY}"
231
  }
232
 
233
  conversation_cnt = len(history) // 2
@@ -255,17 +256,19 @@ def generate_payload(inputs, top_p, temperature, history, system_prompt, stream)
255
  messages.append(what_i_ask_now)
256
 
257
  payload = {
258
- "model": LLM_MODEL,
259
  "messages": messages,
260
- "temperature": temperature, # 1.0,
261
- "top_p": top_p, # 1.0,
262
  "n": 1,
263
  "stream": stream,
264
  "presence_penalty": 0,
265
  "frequency_penalty": 0,
266
  }
267
-
268
- print(f" {LLM_MODEL} : {conversation_cnt} : {inputs}")
 
 
269
  return headers,payload
270
 
271
 
 
21
 
22
  # config_private.py放自己的秘密如API和代理网址
23
  # 读取时首先看是否存在私密的config_private配置文件(不受git管控),如果有,则覆盖原config文件
24
+ from toolbox import get_conf, update_ui, is_any_api_key, select_api_key, what_keys
25
+ proxies, API_KEY, TIMEOUT_SECONDS, MAX_RETRY = \
26
+ get_conf('proxies', 'API_KEY', 'TIMEOUT_SECONDS', 'MAX_RETRY')
27
 
28
  timeout_bot_msg = '[Local Message] Request timeout. Network error. Please check proxy settings in config.py.' + \
29
  '网络错误,检查代理服务器是否可用,以及代理设置的格式是否正确,格式须是[协议]://[地址]:[端口],缺一不可。'
 
39
  break
40
  return chunk
41
 
 
 
 
 
 
42
 
43
+ def predict_no_ui_long_connection(inputs, llm_kwargs, history=[], sys_prompt="", observe_window=None, console_slience=False):
 
 
 
44
  """
45
+ 发送至chatGPT,等待回复,一次性完成,不显示中间过程。但内部用stream的方法避免中途网线被掐。
46
+ inputs:
47
+ 是本次问询的输入
48
+ sys_prompt:
49
+ 系统静默prompt
50
+ llm_kwargs:
51
+ chatGPT的内部调优参数
52
+ history:
53
+ 是之前的对话列表
54
+ observe_window = None:
55
+ 用于负责跨越线程传递已经输出的部分,大部分时候仅仅为了fancy的视觉效果,留空即可。observe_window[0]:观测窗。observe_window[1]:看门狗
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  """
57
  watch_dog_patience = 5 # 看门狗的耐心, 设置5秒即可
58
+ headers, payload = generate_payload(inputs, llm_kwargs, history, system_prompt=sys_prompt, stream=True)
59
  retry = 0
60
  while True:
61
  try:
62
  # make a POST request to the API endpoint, stream=False
63
+ from .bridge_all import model_info
64
+ endpoint = model_info[llm_kwargs['llm_model']]['endpoint']
65
+ response = requests.post(endpoint, headers=headers, proxies=proxies,
66
  json=payload, stream=True, timeout=TIMEOUT_SECONDS); break
67
  except requests.exceptions.ReadTimeout as e:
68
  retry += 1
 
85
  raise ConnectionAbortedError("OpenAI拒绝了请求:" + error_msg)
86
  else:
87
  raise RuntimeError("OpenAI拒绝了请求:" + error_msg)
88
+ if ('data: [DONE]' in chunk): break # api2d 正常完成
89
  json_data = json.loads(chunk.lstrip('data:'))['choices'][0]
90
  delta = json_data["delta"]
91
  if len(delta) == 0: break
92
  if "role" in delta: continue
93
  if "content" in delta:
94
  result += delta["content"]
95
+ if not console_slience: print(delta["content"], end='')
96
  if observe_window is not None:
97
  # 观测窗,把已经获取的数据显示出去
98
  if len(observe_window) >= 1: observe_window[0] += delta["content"]
99
  # 看门狗,如果超过期限没有喂狗,则终止
100
  if len(observe_window) >= 2:
101
  if (time.time()-observe_window[1]) > watch_dog_patience:
102
+ raise RuntimeError("用户取消了程序。")
103
  else: raise RuntimeError("意外Json结构:"+delta)
104
  if json_data['finish_reason'] == 'length':
105
  raise ConnectionAbortedError("正常结束,但显示Token不足,导致输出不完整,请削减单次输入的文本量。")
106
  return result
107
 
108
 
109
+ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
 
110
  """
111
+ 发送至chatGPT,流式获取输出。
112
+ 用于基础的对话功能。
113
+ inputs 是本次问询的输入
114
+ top_p, temperature是chatGPT的内部调优参数
115
+ history 是之前的对话列表(注意无论是inputs还是history,内容太长了都会触发token数量溢出的错误)
116
+ chatbot 为WebUI中显示的对话列表,修改它,然后yeild出去,可以直接修改对话界面内容
117
+ additional_fn代表点击的哪个按钮,按钮见functional.py
118
  """
119
+ if is_any_api_key(inputs):
120
+ chatbot._cookies['api_key'] = inputs
121
+ chatbot.append(("输入已识别为openai的api_key", what_keys(inputs)))
122
+ yield from update_ui(chatbot=chatbot, history=history, msg="api_key已导入") # 刷新界面
123
+ return
124
+ elif not is_any_api_key(chatbot._cookies['api_key']):
125
+ chatbot.append((inputs, "缺少api_key。\n\n1. 临时解决方案:直接在输入区键入api_key,然后回车提交。\n\n2. 长效解决方案:在config.py中配置。"))
126
+ yield from update_ui(chatbot=chatbot, history=history, msg="缺少api_key") # 刷新界面
127
+ return
128
+
129
  if additional_fn is not None:
130
  import core_functional
131
  importlib.reload(core_functional) # 热更新prompt
 
133
  if "PreProcess" in core_functional[additional_fn]: inputs = core_functional[additional_fn]["PreProcess"](inputs) # 获取预处理函数(如果有的话)
134
  inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
135
 
136
+ raw_input = inputs
137
+ logging.info(f'[raw_input] {raw_input}')
138
+ chatbot.append((inputs, ""))
139
+ yield from update_ui(chatbot=chatbot, history=history, msg="等待响应") # 刷新界面
 
140
 
141
+ try:
142
+ headers, payload = generate_payload(inputs, llm_kwargs, history, system_prompt, stream)
143
+ except RuntimeError as e:
144
+ chatbot[-1] = (inputs, f"您提供的api-key不满足要求,不包含任何可用于{llm_kwargs['llm_model']}的api-key。您可能选择了错误的模型或请求源。")
145
+ yield from update_ui(chatbot=chatbot, history=history, msg="api-key不满足要求") # 刷新界面
146
+ return
147
+
148
  history.append(inputs); history.append(" ")
149
 
150
  retry = 0
151
  while True:
152
  try:
153
  # make a POST request to the API endpoint, stream=True
154
+ from .bridge_all import model_info
155
+ endpoint = model_info[llm_kwargs['llm_model']]['endpoint']
156
+ response = requests.post(endpoint, headers=headers, proxies=proxies,
157
  json=payload, stream=True, timeout=TIMEOUT_SECONDS);break
158
  except:
159
  retry += 1
160
  chatbot[-1] = ((chatbot[-1][0], timeout_bot_msg))
161
  retry_msg = f",正在重试 ({retry}/{MAX_RETRY}) ……" if MAX_RETRY > 0 else ""
162
+ yield from update_ui(chatbot=chatbot, history=history, msg="请求超时"+retry_msg) # 刷新界面
163
  if retry > MAX_RETRY: raise TimeoutError
164
 
165
  gpt_replying_buffer = ""
 
170
  while True:
171
  chunk = next(stream_response)
172
  # print(chunk.decode()[6:])
173
+ if is_head_of_the_stream and (r'"object":"error"' not in chunk.decode()):
174
  # 数据流的第一帧不携带content
175
  is_head_of_the_stream = False; continue
176
 
177
  if chunk:
178
  try:
179
+ chunk_decoded = chunk.decode()
180
+ # 前者API2D的
181
+ if ('data: [DONE]' in chunk_decoded) or (len(json.loads(chunk_decoded[6:])['choices'][0]["delta"]) == 0):
182
  # 判定为数据流的结束,gpt_replying_buffer也写完了
183
  logging.info(f'[response] {gpt_replying_buffer}')
184
  break
185
  # 处理数据流的主体
186
+ chunkjson = json.loads(chunk_decoded[6:])
187
  status_text = f"finish_reason: {chunkjson['choices'][0]['finish_reason']}"
188
  # 如果这里抛出异常,一般是文本过长,详情见get_full_error的输出
189
+ gpt_replying_buffer = gpt_replying_buffer + json.loads(chunk_decoded[6:])['choices'][0]["delta"]["content"]
190
  history[-1] = gpt_replying_buffer
191
  chatbot[-1] = (history[-2], history[-1])
192
+ yield from update_ui(chatbot=chatbot, history=history, msg=status_text) # 刷新界面
193
 
194
  except Exception as e:
195
  traceback.print_exc()
196
+ yield from update_ui(chatbot=chatbot, history=history, msg="Json解析不合常规") # 刷新界面
197
  chunk = get_full_error(chunk, stream_response)
198
+ chunk_decoded = chunk.decode()
199
+ error_msg = chunk_decoded
200
  if "reduce the length" in error_msg:
201
  chatbot[-1] = (chatbot[-1][0], "[Local Message] Reduce the length. 本次输入过长,或历史数据过长. 历史缓存数据现已释放,您可以请再次尝试.")
202
  history = [] # 清除历史
203
+ elif "does not exist" in error_msg:
204
+ chatbot[-1] = (chatbot[-1][0], f"[Local Message] Model {llm_kwargs['llm_model']} does not exist. 模型不存在,或者您没有获得体验资格.")
205
  elif "Incorrect API key" in error_msg:
206
  chatbot[-1] = (chatbot[-1][0], "[Local Message] Incorrect API key. OpenAI以提供了不正确的API_KEY为由,拒绝服务.")
207
  elif "exceeded your current quota" in error_msg:
208
  chatbot[-1] = (chatbot[-1][0], "[Local Message] You exceeded your current quota. OpenAI以账户额度不足为由,拒绝服务.")
209
+ elif "bad forward key" in error_msg:
210
+ chatbot[-1] = (chatbot[-1][0], "[Local Message] Bad forward key. API2D账户额度不足.")
211
+ elif "Not enough point" in error_msg:
212
+ chatbot[-1] = (chatbot[-1][0], "[Local Message] Not enough point. API2D账户点数不足.")
213
  else:
214
  from toolbox import regular_txt_to_markdown
215
  tb_str = '```\n' + traceback.format_exc() + '```'
216
+ chatbot[-1] = (chatbot[-1][0], f"[Local Message] 异常 \n\n{tb_str} \n\n{regular_txt_to_markdown(chunk_decoded[4:])}")
217
+ yield from update_ui(chatbot=chatbot, history=history, msg="Json异常" + error_msg) # 刷新界面
218
  return
219
 
220
+ def generate_payload(inputs, llm_kwargs, history, system_prompt, stream):
221
  """
222
+ 整合所有信息,选择LLM模型,生成http请求,为发送请求做准备
223
  """
224
+ if not is_any_api_key(llm_kwargs['api_key']):
225
+ raise AssertionError("你提供了错误的API_KEY。\n\n1. 临时解决方案:直接在输入区键入api_key,然后回车提交。\n\n2. 长效解决方案:在config.py中配置。")
226
+
227
+ api_key = select_api_key(llm_kwargs['api_key'], llm_kwargs['llm_model'])
228
+
229
  headers = {
230
  "Content-Type": "application/json",
231
+ "Authorization": f"Bearer {api_key}"
232
  }
233
 
234
  conversation_cnt = len(history) // 2
 
256
  messages.append(what_i_ask_now)
257
 
258
  payload = {
259
+ "model": llm_kwargs['llm_model'].strip('api2d-'),
260
  "messages": messages,
261
+ "temperature": llm_kwargs['temperature'], # 1.0,
262
+ "top_p": llm_kwargs['top_p'], # 1.0,
263
  "n": 1,
264
  "stream": stream,
265
  "presence_penalty": 0,
266
  "frequency_penalty": 0,
267
  }
268
+ try:
269
+ print(f" {llm_kwargs['llm_model']} : {conversation_cnt} : {inputs[:100]} ..........")
270
+ except:
271
+ print('输入中可能存在乱码。')
272
  return headers,payload
273
 
274
 
request_llm/bridge_tgui.py CHANGED
@@ -12,24 +12,19 @@ import logging
12
  import time
13
  import threading
14
  import importlib
15
- from toolbox import get_conf
16
- LLM_MODEL, = get_conf('LLM_MODEL')
17
 
18
- # "TGUI:galactica-1.3b@localhost:7860"
19
- model_name, addr_port = LLM_MODEL.split('@')
20
- assert ':' in addr_port, "LLM_MODEL 格式不正确!" + LLM_MODEL
21
- addr, port = addr_port.split(':')
22
 
23
  def random_hash():
24
  letters = string.ascii_lowercase + string.digits
25
  return ''.join(random.choice(letters) for i in range(9))
26
 
27
- async def run(context, max_token=512):
28
  params = {
29
  'max_new_tokens': max_token,
30
  'do_sample': True,
31
- 'temperature': 0.5,
32
- 'top_p': 0.9,
33
  'typical_p': 1,
34
  'repetition_penalty': 1.05,
35
  'encoder_repetition_penalty': 1.0,
@@ -90,7 +85,7 @@ async def run(context, max_token=512):
90
 
91
 
92
 
93
- def predict_tgui(inputs, top_p, temperature, chatbot=[], history=[], system_prompt='', stream = True, additional_fn=None):
94
  """
95
  发送至chatGPT,流式获取输出。
96
  用于基础的对话功能。
@@ -108,18 +103,26 @@ def predict_tgui(inputs, top_p, temperature, chatbot=[], history=[], system_prom
108
  inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
109
 
110
  raw_input = "What I would like to say is the following: " + inputs
111
- logging.info(f'[raw_input] {raw_input}')
112
  history.extend([inputs, ""])
113
  chatbot.append([inputs, ""])
114
- yield chatbot, history, "等待响应"
115
 
116
- prompt = inputs
117
  tgui_say = ""
118
 
 
 
 
 
 
119
  mutable = ["", time.time()]
120
  def run_coorotine(mutable):
121
  async def get_result(mutable):
122
- async for response in run(prompt):
 
 
 
 
123
  print(response[len(mutable[0]):])
124
  mutable[0] = response
125
  if (time.time() - mutable[1]) > 3:
@@ -138,30 +141,31 @@ def predict_tgui(inputs, top_p, temperature, chatbot=[], history=[], system_prom
138
  tgui_say = mutable[0]
139
  history[-1] = tgui_say
140
  chatbot[-1] = (history[-2], history[-1])
141
- yield chatbot, history, "status_text"
142
 
143
- logging.info(f'[response] {tgui_say}')
144
 
145
 
146
 
147
- def predict_tgui_no_ui(inputs, top_p, temperature, history=[], sys_prompt=""):
148
  raw_input = "What I would like to say is the following: " + inputs
149
- prompt = inputs
150
  tgui_say = ""
151
- mutable = ["", time.time()]
152
- def run_coorotine(mutable):
153
- async def get_result(mutable):
154
- async for response in run(prompt, max_token=20):
155
- print(response[len(mutable[0]):])
156
- mutable[0] = response
157
- if (time.time() - mutable[1]) > 3:
 
 
 
 
 
 
158
  print('exit when no listener')
159
  break
160
- asyncio.run(get_result(mutable))
161
- thread_listen = threading.Thread(target=run_coorotine, args=(mutable,))
162
  thread_listen.start()
163
- while thread_listen.is_alive():
164
- time.sleep(1)
165
- mutable[1] = time.time()
166
- tgui_say = mutable[0]
167
- return tgui_say
 
12
  import time
13
  import threading
14
  import importlib
15
+ from toolbox import get_conf, update_ui
 
16
 
 
 
 
 
17
 
18
  def random_hash():
19
  letters = string.ascii_lowercase + string.digits
20
  return ''.join(random.choice(letters) for i in range(9))
21
 
22
+ async def run(context, max_token, temperature, top_p, addr, port):
23
  params = {
24
  'max_new_tokens': max_token,
25
  'do_sample': True,
26
+ 'temperature': temperature,
27
+ 'top_p': top_p,
28
  'typical_p': 1,
29
  'repetition_penalty': 1.05,
30
  'encoder_repetition_penalty': 1.0,
 
85
 
86
 
87
 
88
+ def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
89
  """
90
  发送至chatGPT,流式获取输出。
91
  用于基础的对话功能。
 
103
  inputs = core_functional[additional_fn]["Prefix"] + inputs + core_functional[additional_fn]["Suffix"]
104
 
105
  raw_input = "What I would like to say is the following: " + inputs
 
106
  history.extend([inputs, ""])
107
  chatbot.append([inputs, ""])
108
+ yield from update_ui(chatbot=chatbot, history=history, msg="等待响应") # 刷新界面
109
 
110
+ prompt = raw_input
111
  tgui_say = ""
112
 
113
+ model_name, addr_port = llm_kwargs['llm_model'].split('@')
114
+ assert ':' in addr_port, "LLM_MODEL 格式不正确!" + llm_kwargs['llm_model']
115
+ addr, port = addr_port.split(':')
116
+
117
+
118
  mutable = ["", time.time()]
119
  def run_coorotine(mutable):
120
  async def get_result(mutable):
121
+ # "tgui:galactica-1.3b@localhost:7860"
122
+
123
+ async for response in run(context=prompt, max_token=llm_kwargs['max_length'],
124
+ temperature=llm_kwargs['temperature'],
125
+ top_p=llm_kwargs['top_p'], addr=addr, port=port):
126
  print(response[len(mutable[0]):])
127
  mutable[0] = response
128
  if (time.time() - mutable[1]) > 3:
 
141
  tgui_say = mutable[0]
142
  history[-1] = tgui_say
143
  chatbot[-1] = (history[-2], history[-1])
144
+ yield from update_ui(chatbot=chatbot, history=history) # 刷新界面
145
 
 
146
 
147
 
148
 
149
+ def predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window, console_slience=False):
150
  raw_input = "What I would like to say is the following: " + inputs
151
+ prompt = raw_input
152
  tgui_say = ""
153
+ model_name, addr_port = llm_kwargs['llm_model'].split('@')
154
+ assert ':' in addr_port, "LLM_MODEL 格式不正确!" + llm_kwargs['llm_model']
155
+ addr, port = addr_port.split(':')
156
+
157
+
158
+ def run_coorotine(observe_window):
159
+ async def get_result(observe_window):
160
+ async for response in run(context=prompt, max_token=llm_kwargs['max_length'],
161
+ temperature=llm_kwargs['temperature'],
162
+ top_p=llm_kwargs['top_p'], addr=addr, port=port):
163
+ print(response[len(observe_window[0]):])
164
+ observe_window[0] = response
165
+ if (time.time() - observe_window[1]) > 5:
166
  print('exit when no listener')
167
  break
168
+ asyncio.run(get_result(observe_window))
169
+ thread_listen = threading.Thread(target=run_coorotine, args=(observe_window,))
170
  thread_listen.start()
171
+ return observe_window[0]
 
 
 
 
request_llm/requirements_chatglm.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ protobuf
2
+ transformers==4.27.1
3
+ cpm_kernels
4
+ torch>=1.10
5
+ mdtex2html
6
+ sentencepiece
requirements.txt CHANGED
@@ -1,13 +1,16 @@
1
- gradio>=3.23
 
2
  requests[socks]
3
  transformers
4
  python-markdown-math
5
  beautifulsoup4
6
  latex2mathml
 
7
  mdtex2html
8
- tiktoken
9
  Markdown
10
  pygments
11
  pymupdf
12
  openai
13
- numpy
 
 
1
+ gradio==3.25.0
2
+ tiktoken>=0.3.3
3
  requests[socks]
4
  transformers
5
  python-markdown-math
6
  beautifulsoup4
7
  latex2mathml
8
+ python-docx
9
  mdtex2html
10
+ colorama
11
  Markdown
12
  pygments
13
  pymupdf
14
  openai
15
+ numpy
16
+ arxiv
theme.py CHANGED
@@ -28,7 +28,7 @@ CODE_HIGHLIGHT, = get_conf('CODE_HIGHLIGHT')
28
 
29
  def adjust_theme():
30
  try:
31
- color_er = gr.themes.utils.colors.pink
32
  set_theme = gr.themes.Default(
33
  primary_hue=gr.themes.utils.colors.sky,
34
  neutral_hue=gr.themes.utils.colors.fuchsia,
@@ -154,10 +154,12 @@ advanced_css = """
154
  padding: 1em;
155
  margin: 1em 2em 1em 0.5em;
156
  }
 
157
  """
158
 
159
  if CODE_HIGHLIGHT:
160
  advanced_css += """
 
161
  .hll { background-color: #ffffcc }
162
  .c { color: #3D7B7B; font-style: italic } /* Comment */
163
  .err { border: 1px solid #FF0000 } /* Error */
 
28
 
29
  def adjust_theme():
30
  try:
31
+ color_er = gr.themes.utils.colors.fuchsia
32
  set_theme = gr.themes.Default(
33
  primary_hue=gr.themes.utils.colors.sky,
34
  neutral_hue=gr.themes.utils.colors.fuchsia,
 
154
  padding: 1em;
155
  margin: 1em 2em 1em 0.5em;
156
  }
157
+
158
  """
159
 
160
  if CODE_HIGHLIGHT:
161
  advanced_css += """
162
+
163
  .hll { background-color: #ffffcc }
164
  .c { color: #3D7B7B; font-style: italic } /* Comment */
165
  .err { border: 1px solid #FF0000 } /* Error */
toolbox.py CHANGED
@@ -1,28 +1,104 @@
1
  import markdown
2
- import mdtex2html
3
- import threading
4
  import importlib
5
  import traceback
6
- import importlib
7
  import inspect
8
  import re
9
  from latex2mathml.converter import convert as tex2mathml
10
  from functools import wraps, lru_cache
 
 
 
 
 
 
 
 
11
 
 
 
 
 
 
12
 
13
  def ArgsGeneralWrapper(f):
14
  """
15
- 装饰器函数,用于重组输入参数,改变输入参数的顺序与结构。
16
  """
17
- def decorated(txt, txt2, *args, **kwargs):
18
  txt_passon = txt
19
- if txt == "" and txt2 != "":
20
- txt_passon = txt2
21
- yield from f(txt_passon, *args, **kwargs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  return decorated
23
 
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  def get_reduce_token_percent(text):
 
 
 
26
  try:
27
  # text = "maximum context length is 4097 tokens. However, your messages resulted in 4870 tokens"
28
  pattern = r"(\d+)\s+tokens\b"
@@ -37,73 +113,10 @@ def get_reduce_token_percent(text):
37
  return 0.5, '不详'
38
 
39
 
40
- def predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[], sys_prompt='', long_connection=True):
41
- """
42
- 调用简单的predict_no_ui接口,但是依然保留了���许界面心跳功能,当对话太长时,会自动采用二分法截断
43
- i_say: 当前输入
44
- i_say_show_user: 显示到对话界面上的当前输入,例如,输入整个文件时,你绝对不想把文件的内容都糊到对话界面上
45
- chatbot: 对话界面句柄
46
- top_p, temperature: gpt参数
47
- history: gpt参数 对话历史
48
- sys_prompt: gpt参数 sys_prompt
49
- long_connection: 是否采用更稳定的连接方式(推荐)
50
- """
51
- import time
52
- from request_llm.bridge_chatgpt import predict_no_ui, predict_no_ui_long_connection
53
- from toolbox import get_conf
54
- TIMEOUT_SECONDS, MAX_RETRY = get_conf('TIMEOUT_SECONDS', 'MAX_RETRY')
55
- # 多线程的时候,需要一个mutable结构在不同线程之间传递信息
56
- # list就是最简单的mutable结构,我们第一个位置放gpt输出,第二个位置传递报错信息
57
- mutable = [None, '']
58
- # multi-threading worker
59
-
60
- def mt(i_say, history):
61
- while True:
62
- try:
63
- if long_connection:
64
- mutable[0] = predict_no_ui_long_connection(
65
- inputs=i_say, top_p=top_p, temperature=temperature, history=history, sys_prompt=sys_prompt)
66
- else:
67
- mutable[0] = predict_no_ui(
68
- inputs=i_say, top_p=top_p, temperature=temperature, history=history, sys_prompt=sys_prompt)
69
- break
70
- except ConnectionAbortedError as token_exceeded_error:
71
- # 尝试计算比例,尽可能多地保留文本
72
- p_ratio, n_exceed = get_reduce_token_percent(
73
- str(token_exceeded_error))
74
- if len(history) > 0:
75
- history = [his[int(len(his) * p_ratio):]
76
- for his in history if his is not None]
77
- else:
78
- i_say = i_say[: int(len(i_say) * p_ratio)]
79
- mutable[1] = f'警告,文本过长将进行截断,Token溢出数:{n_exceed},截断比例:{(1-p_ratio):.0%}。'
80
- except TimeoutError as e:
81
- mutable[0] = '[Local Message] 请求超时。'
82
- raise TimeoutError
83
- except Exception as e:
84
- mutable[0] = f'[Local Message] 异常:{str(e)}.'
85
- raise RuntimeError(f'[Local Message] 异常:{str(e)}.')
86
- # 创建新线程发出http请求
87
- thread_name = threading.Thread(target=mt, args=(i_say, history))
88
- thread_name.start()
89
- # 原来的线程则负责持续更新UI,实现一个超时倒计时,并等待新线程的任务完成
90
- cnt = 0
91
- while thread_name.is_alive():
92
- cnt += 1
93
- chatbot[-1] = (i_say_show_user,
94
- f"[Local Message] {mutable[1]}waiting gpt response {cnt}/{TIMEOUT_SECONDS*2*(MAX_RETRY+1)}"+''.join(['.']*(cnt % 4)))
95
- yield chatbot, history, '正常'
96
- time.sleep(1)
97
- # 把gpt的输出从mutable中取出来
98
- gpt_say = mutable[0]
99
- if gpt_say == '[Local Message] Failed with timeout.':
100
- raise TimeoutError
101
- return gpt_say
102
-
103
 
104
  def write_results_to_file(history, file_name=None):
105
  """
106
- 将对话记录history以Markdown格式写入文件中。如果没有指定文件名,则使用当前时间生成文件名。
107
  """
108
  import os
109
  import time
@@ -131,7 +144,7 @@ def write_results_to_file(history, file_name=None):
131
 
132
  def regular_txt_to_markdown(text):
133
  """
134
- 将普通文本转换为Markdown格式的文本。
135
  """
136
  text = text.replace('\n', '\n\n')
137
  text = text.replace('\n\n\n', '\n\n')
@@ -139,48 +152,11 @@ def regular_txt_to_markdown(text):
139
  return text
140
 
141
 
142
- def CatchException(f):
143
- """
144
- 装饰器函数,捕捉函数f中的异常并封装到一个生成器中返回,并显示到聊天当中。
145
- """
146
- @wraps(f)
147
- def decorated(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
148
- try:
149
- yield from f(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT)
150
- except Exception as e:
151
- from check_proxy import check_proxy
152
- from toolbox import get_conf
153
- proxies, = get_conf('proxies')
154
- tb_str = '```\n' + traceback.format_exc() + '```'
155
- if chatbot is None or len(chatbot) == 0:
156
- chatbot = [["插件调度异常", "异常原因"]]
157
- chatbot[-1] = (chatbot[-1][0],
158
- f"[Local Message] 实验性函数调用出错: \n\n{tb_str} \n\n当前代理可用性: \n\n{check_proxy(proxies)}")
159
- yield chatbot, history, f'异常 {e}'
160
- return decorated
161
-
162
-
163
- def HotReload(f):
164
- """
165
- HotReload的装饰器函数,用于实现Python函数插件的热更新。
166
- 函数热更新是指在不停止程序运行的情况下,更新函数代码,从而达到实时更新功能。
167
- 在装饰器内部,使用wraps(f)来保留函数的元信息,并定义了一个名为decorated的内部函数。
168
- 内部函数通过使用importlib模块的reload函数和inspect模块的getmodule函数来重新加载并获取函数模块,
169
- 然后通过getattr函数获取函数名,并在新模块中重新加载函数。
170
- 最后,使用yield from语句返回重新加载过的函数,并在被装饰的函数上执行。
171
- 最终,装饰器函数返回内部函数。这个内部函数可以将函数的原始定义更新为最新版本,并执行函数的新版本。
172
- """
173
- @wraps(f)
174
- def decorated(*args, **kwargs):
175
- fn_name = f.__name__
176
- f_hot_reload = getattr(importlib.reload(inspect.getmodule(f)), fn_name)
177
- yield from f_hot_reload(*args, **kwargs)
178
- return decorated
179
 
180
 
181
  def report_execption(chatbot, history, a, b):
182
  """
183
- 向chatbot中添加错误信息
184
  """
185
  chatbot.append((a, b))
186
  history.append(a)
@@ -189,7 +165,7 @@ def report_execption(chatbot, history, a, b):
189
 
190
  def text_divide_paragraph(text):
191
  """
192
- 将文本按照段落分隔符分割开,生成带有段落标签的HTML代码。
193
  """
194
  if '```' in text:
195
  # careful input
@@ -205,7 +181,7 @@ def text_divide_paragraph(text):
205
 
206
  def markdown_convertion(txt):
207
  """
208
- 将Markdown格式的文本转换为HTML格式。如果包含数学公式,则先将公式转换为HTML格式。
209
  """
210
  pre = '<div class="markdown-body">'
211
  suf = '</div>'
@@ -243,7 +219,7 @@ def markdown_convertion(txt):
243
  return content
244
  else:
245
  return tex2mathml_catch_exception(content)
246
-
247
  def markdown_bug_hunt(content):
248
  """
249
  解决一个mdx_math的bug(单$包裹begin命令时多余<script>)
@@ -251,7 +227,7 @@ def markdown_convertion(txt):
251
  content = content.replace('<script type="math/tex">\n<script type="math/tex; mode=display">', '<script type="math/tex; mode=display">')
252
  content = content.replace('</script>\n</script>', '</script>')
253
  return content
254
-
255
 
256
  if ('$' in txt) and ('```' not in txt): # 有$标识的公式符号,且没有代码段```的标识
257
  # convert everything to html format
@@ -272,7 +248,7 @@ def markdown_convertion(txt):
272
  def close_up_code_segment_during_stream(gpt_reply):
273
  """
274
  在gpt输出代码的中途(输出了前面的```,但还没输出完后面的```),补上后面的```
275
-
276
  Args:
277
  gpt_reply (str): GPT模型返回的回复字符串。
278
 
@@ -297,17 +273,15 @@ def close_up_code_segment_during_stream(gpt_reply):
297
 
298
  def format_io(self, y):
299
  """
300
- 将输入和输出解析为HTML格式。将y中最后一项的输入部分段落化,并将输出部分的Markdown和数学公式转换为HTML格式。
301
  """
302
  if y is None or y == []:
303
  return []
304
  i_ask, gpt_reply = y[-1]
305
  i_ask = text_divide_paragraph(i_ask) # 输入部分太自由,预处理一波
306
- gpt_reply = close_up_code_segment_during_stream(
307
- gpt_reply) # 当代码输出半截的时候,试着补上后个```
308
  y[-1] = (
309
- None if i_ask is None else markdown.markdown(
310
- i_ask, extensions=['fenced_code', 'tables']),
311
  None if gpt_reply is None else markdown_convertion(gpt_reply)
312
  )
313
  return y
@@ -315,7 +289,7 @@ def format_io(self, y):
315
 
316
  def find_free_port():
317
  """
318
- 返回当前系统中可用的未使用端口。
319
  """
320
  import socket
321
  from contextlib import closing
@@ -394,7 +368,7 @@ def find_recent_files(directory):
394
  return recent_files
395
 
396
 
397
- def on_file_uploaded(files, chatbot, txt):
398
  if len(files) == 0:
399
  return chatbot, txt
400
  import shutil
@@ -416,13 +390,18 @@ def on_file_uploaded(files, chatbot, txt):
416
  dest_dir=f'private_upload/{time_tag}/{file_origin_name}.extract')
417
  moved_files = [fp for fp in glob.glob(
418
  'private_upload/**/*', recursive=True)]
419
- txt = f'private_upload/{time_tag}'
 
 
 
 
 
420
  moved_files_str = '\t\n\n'.join(moved_files)
421
  chatbot.append(['我上传了文件,请查收',
422
  f'[Local Message] 收到以下文件: \n\n{moved_files_str}' +
423
  f'\n\n调用路径参数已自动修正到: \n\n{txt}' +
424
- f'\n\n现在您点击任意实验功能时,以上文件将被作为输入参数'+err_msg])
425
- return chatbot, txt
426
 
427
 
428
  def on_report_generated(files, chatbot):
@@ -434,27 +413,78 @@ def on_report_generated(files, chatbot):
434
  chatbot.append(['汇总报告如何远程获取?', '汇总报告已经添加到右侧“文件上传区”(可能处于折叠状态),请查收。'])
435
  return report_files, chatbot
436
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
 
438
  @lru_cache(maxsize=128)
439
  def read_single_conf_with_lru_cache(arg):
 
440
  try:
441
  r = getattr(importlib.import_module('config_private'), arg)
442
  except:
443
  r = getattr(importlib.import_module('config'), arg)
444
  # 在读取API_KEY时,检查一下是不是忘了改config
445
  if arg == 'API_KEY':
446
- # 正确的 API_KEY"sk-" + 48 位大小写字母数字的组合
447
- API_MATCH = re.match(r"sk-[a-zA-Z0-9]{48}$", r)
448
- if API_MATCH:
449
- print(f"[API_KEY] 您的 API_KEY 是: {r[:15]}*** API_KEY 导入成功")
450
  else:
451
- assert False, "正确的 API_KEY 是 'sk-' + '48 位大小写字母数字' 的组合,请在config文件中修改API密钥, 添加海外代理之后再运行。" + \
452
- "(如果您刚更新过代码,请确保旧版config_private文件中没有遗留任何新增键值)"
453
  if arg == 'proxies':
454
  if r is None:
455
- print('[PROXY] 网络代理状态:未配置。无代理状态下很可能无法访问。建议:检查USE_PROXY选项是否修改。')
456
  else:
457
- print('[PROXY] 网络代理状态:已配置。配置信息如下:', r)
458
  assert isinstance(r, dict), 'proxies格式错误,请注意proxies选项的格式,不要遗漏括号。'
459
  return r
460
 
@@ -481,7 +511,7 @@ class DummyWith():
481
  它的作用是……额……没用,即在代码结构不变得情况下取代其他的上下文管理器。
482
  上下文管理器是一种Python对象,用于与with语句一起使用,
483
  以确保一些资源在代码块执行期间得到正确的初始化和清理。
484
- 上下文管理器必须实现两个方法,分别为 __enter__()和 __exit__()。
485
  在上下文执行开始的情况下,__enter__()方法会在代码块被执行前被调用,
486
  而在上下文执行结束时,__exit__()方法则会被调用。
487
  """
@@ -490,3 +520,34 @@ class DummyWith():
490
 
491
  def __exit__(self, exc_type, exc_value, traceback):
492
  return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import markdown
 
 
2
  import importlib
3
  import traceback
 
4
  import inspect
5
  import re
6
  from latex2mathml.converter import convert as tex2mathml
7
  from functools import wraps, lru_cache
8
+ ############################### 插件输入输出接驳区 #######################################
9
+ class ChatBotWithCookies(list):
10
+ def __init__(self, cookie):
11
+ self._cookies = cookie
12
+
13
+ def write_list(self, list):
14
+ for t in list:
15
+ self.append(t)
16
 
17
+ def get_list(self):
18
+ return [t for t in self]
19
+
20
+ def get_cookies(self):
21
+ return self._cookies
22
 
23
  def ArgsGeneralWrapper(f):
24
  """
25
+ 装饰器函数,用于重组输入参数,改变输入参数的顺序与结构。
26
  """
27
+ def decorated(cookies, max_length, llm_model, txt, txt2, top_p, temperature, chatbot, history, system_prompt, plugin_advanced_arg, *args):
28
  txt_passon = txt
29
+ if txt == "" and txt2 != "": txt_passon = txt2
30
+ # 引入一个有cookie的chatbot
31
+ cookies.update({
32
+ 'top_p':top_p,
33
+ 'temperature':temperature,
34
+ })
35
+ llm_kwargs = {
36
+ 'api_key': cookies['api_key'],
37
+ 'llm_model': llm_model,
38
+ 'top_p':top_p,
39
+ 'max_length': max_length,
40
+ 'temperature':temperature,
41
+ }
42
+ plugin_kwargs = {
43
+ "advanced_arg": plugin_advanced_arg,
44
+ }
45
+ chatbot_with_cookie = ChatBotWithCookies(cookies)
46
+ chatbot_with_cookie.write_list(chatbot)
47
+ yield from f(txt_passon, llm_kwargs, plugin_kwargs, chatbot_with_cookie, history, system_prompt, *args)
48
+ return decorated
49
+
50
+ def update_ui(chatbot, history, msg='正常', **kwargs): # 刷新界面
51
+ """
52
+ 刷新用户界面
53
+ """
54
+ assert isinstance(chatbot, ChatBotWithCookies), "在传递chatbot的过程中不要将其丢弃。必要时,可用clear将其清空,然后用for+append循环重新赋值。"
55
+ yield chatbot.get_cookies(), chatbot, history, msg
56
+
57
+ def CatchException(f):
58
+ """
59
+ 装饰器函数,捕捉函数f中的异常并封装到一个生成器中返回,并显示到聊天当中。
60
+ """
61
+ @wraps(f)
62
+ def decorated(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
63
+ try:
64
+ yield from f(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT)
65
+ except Exception as e:
66
+ from check_proxy import check_proxy
67
+ from toolbox import get_conf
68
+ proxies, = get_conf('proxies')
69
+ tb_str = '```\n' + traceback.format_exc() + '```'
70
+ if chatbot is None or len(chatbot) == 0:
71
+ chatbot = [["插件调度异常", "异常原因"]]
72
+ chatbot[-1] = (chatbot[-1][0],
73
+ f"[Local Message] 实验性函数调用出错: \n\n{tb_str} \n\n当前代理可用性: \n\n{check_proxy(proxies)}")
74
+ yield from update_ui(chatbot=chatbot, history=history, msg=f'异常 {e}') # 刷新界面
75
  return decorated
76
 
77
 
78
+ def HotReload(f):
79
+ """
80
+ HotReload的装饰器函数,用于实现Python函数插件的热更新。
81
+ 函数热更新是指在不停止程序运行的情况下,更新函数代码,从而达到实时更新功能。
82
+ 在装饰器内部,使用wraps(f)来保留函数的元信息,并定义了一个名为decorated的内部函数。
83
+ 内部函数通过使用importlib模块的reload函数和inspect模块的getmodule函数来重新加载并获取函数模块,
84
+ 然后通过getattr函数获取函数名,并在新模块中重新加载函数。
85
+ 最后,使用yield from语句返回重新加载过的函数,并在被装饰的函数上执行。
86
+ 最终,装饰器函数返回内部函数。这个内部函数可以将函数的原始定义更新为最新版本,并执行函数的新版本。
87
+ """
88
+ @wraps(f)
89
+ def decorated(*args, **kwargs):
90
+ fn_name = f.__name__
91
+ f_hot_reload = getattr(importlib.reload(inspect.getmodule(f)), fn_name)
92
+ yield from f_hot_reload(*args, **kwargs)
93
+ return decorated
94
+
95
+
96
+ ####################################### 其他小工具 #####################################
97
+
98
  def get_reduce_token_percent(text):
99
+ """
100
+ * 此函数未来将被弃用
101
+ """
102
  try:
103
  # text = "maximum context length is 4097 tokens. However, your messages resulted in 4870 tokens"
104
  pattern = r"(\d+)\s+tokens\b"
 
113
  return 0.5, '不详'
114
 
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
  def write_results_to_file(history, file_name=None):
118
  """
119
+ 将对话记录history以Markdown格式写入文件中。如果没有指定文件名,则使用当前时间生成文件名。
120
  """
121
  import os
122
  import time
 
144
 
145
  def regular_txt_to_markdown(text):
146
  """
147
+ 将普通文本转换为Markdown格式的文本。
148
  """
149
  text = text.replace('\n', '\n\n')
150
  text = text.replace('\n\n\n', '\n\n')
 
152
  return text
153
 
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
 
157
  def report_execption(chatbot, history, a, b):
158
  """
159
+ 向chatbot中添加错误信息
160
  """
161
  chatbot.append((a, b))
162
  history.append(a)
 
165
 
166
  def text_divide_paragraph(text):
167
  """
168
+ 将文本按照段落分隔符分割开,生成带有段落标签的HTML代码。
169
  """
170
  if '```' in text:
171
  # careful input
 
181
 
182
  def markdown_convertion(txt):
183
  """
184
+ 将Markdown格式的文本转换为HTML格式。如果包含数学公式,则先将公式转换为HTML格式。
185
  """
186
  pre = '<div class="markdown-body">'
187
  suf = '</div>'
 
219
  return content
220
  else:
221
  return tex2mathml_catch_exception(content)
222
+
223
  def markdown_bug_hunt(content):
224
  """
225
  解决一个mdx_math的bug(单$包裹begin命令时多余<script>)
 
227
  content = content.replace('<script type="math/tex">\n<script type="math/tex; mode=display">', '<script type="math/tex; mode=display">')
228
  content = content.replace('</script>\n</script>', '</script>')
229
  return content
230
+
231
 
232
  if ('$' in txt) and ('```' not in txt): # 有$标识的公式符号,且没有代码段```的标识
233
  # convert everything to html format
 
248
  def close_up_code_segment_during_stream(gpt_reply):
249
  """
250
  在gpt输出代码的中途(输出了前面的```,但还没输出完后面的```),补上后面的```
251
+
252
  Args:
253
  gpt_reply (str): GPT模型返回的回复字符串。
254
 
 
273
 
274
  def format_io(self, y):
275
  """
276
+ 将输入和输出解析为HTML格式。将y中最后一项的输入部分段落化,并将输出部分的Markdown和数学公式转换为HTML格式。
277
  """
278
  if y is None or y == []:
279
  return []
280
  i_ask, gpt_reply = y[-1]
281
  i_ask = text_divide_paragraph(i_ask) # 输入部分太自由,预处理一波
282
+ gpt_reply = close_up_code_segment_during_stream(gpt_reply) # 当代码输出半截的时候,试着补上后个```
 
283
  y[-1] = (
284
+ None if i_ask is None else markdown.markdown(i_ask, extensions=['fenced_code', 'tables']),
 
285
  None if gpt_reply is None else markdown_convertion(gpt_reply)
286
  )
287
  return y
 
289
 
290
  def find_free_port():
291
  """
292
+ 返回当前系统中可用的未使用端口。
293
  """
294
  import socket
295
  from contextlib import closing
 
368
  return recent_files
369
 
370
 
371
+ def on_file_uploaded(files, chatbot, txt, txt2, checkboxes):
372
  if len(files) == 0:
373
  return chatbot, txt
374
  import shutil
 
390
  dest_dir=f'private_upload/{time_tag}/{file_origin_name}.extract')
391
  moved_files = [fp for fp in glob.glob(
392
  'private_upload/**/*', recursive=True)]
393
+ if "底部输入区" in checkboxes:
394
+ txt = ""
395
+ txt2 = f'private_upload/{time_tag}'
396
+ else:
397
+ txt = f'private_upload/{time_tag}'
398
+ txt2 = ""
399
  moved_files_str = '\t\n\n'.join(moved_files)
400
  chatbot.append(['我上传了文件,请查收',
401
  f'[Local Message] 收到以下文件: \n\n{moved_files_str}' +
402
  f'\n\n调用路径参数已自动修正到: \n\n{txt}' +
403
+ f'\n\n现在您点击任意“红颜色”标识的函数插件时,以上文件将被作为输入参数'+err_msg])
404
+ return chatbot, txt, txt2
405
 
406
 
407
  def on_report_generated(files, chatbot):
 
413
  chatbot.append(['汇总报告如何远程获取?', '汇总报告已经添加到右侧“文件上传区”(可能处于折叠状态),请查收。'])
414
  return report_files, chatbot
415
 
416
+ def is_openai_api_key(key):
417
+ API_MATCH = re.match(r"sk-[a-zA-Z0-9]{48}$", key)
418
+ return bool(API_MATCH)
419
+
420
+ def is_api2d_key(key):
421
+ if key.startswith('fk') and len(key) == 41:
422
+ return True
423
+ else:
424
+ return False
425
+
426
+ def is_any_api_key(key):
427
+ if ',' in key:
428
+ keys = key.split(',')
429
+ for k in keys:
430
+ if is_any_api_key(k): return True
431
+ return False
432
+ else:
433
+ return is_openai_api_key(key) or is_api2d_key(key)
434
+
435
+ def what_keys(keys):
436
+ avail_key_list = {'OpenAI Key':0, "API2D Key":0}
437
+ key_list = keys.split(',')
438
+
439
+ for k in key_list:
440
+ if is_openai_api_key(k):
441
+ avail_key_list['OpenAI Key'] += 1
442
+
443
+ for k in key_list:
444
+ if is_api2d_key(k):
445
+ avail_key_list['API2D Key'] += 1
446
+
447
+ return f"检测到: OpenAI Key {avail_key_list['OpenAI Key']} 个,API2D Key {avail_key_list['API2D Key']} 个"
448
+
449
+ def select_api_key(keys, llm_model):
450
+ import random
451
+ avail_key_list = []
452
+ key_list = keys.split(',')
453
+
454
+ if llm_model.startswith('gpt-'):
455
+ for k in key_list:
456
+ if is_openai_api_key(k): avail_key_list.append(k)
457
+
458
+ if llm_model.startswith('api2d-'):
459
+ for k in key_list:
460
+ if is_api2d_key(k): avail_key_list.append(k)
461
+
462
+ if len(avail_key_list) == 0:
463
+ raise RuntimeError(f"您提供的api-key不满足要求,不包含任何可用于{llm_model}的api-key。您可能选择了错误的模型或请求源。")
464
+
465
+ api_key = random.choice(avail_key_list) # 随机负载均衡
466
+ return api_key
467
 
468
  @lru_cache(maxsize=128)
469
  def read_single_conf_with_lru_cache(arg):
470
+ from colorful import print亮红, print亮绿, print亮蓝
471
  try:
472
  r = getattr(importlib.import_module('config_private'), arg)
473
  except:
474
  r = getattr(importlib.import_module('config'), arg)
475
  # 在读取API_KEY时,检查一下是不是忘了改config
476
  if arg == 'API_KEY':
477
+ print亮蓝(f"[API_KEY] 本项目现已支持OpenAI和API2D的api-key。也支持同时填写多个api-key,如API_KEY=\"openai-key1,openai-key2,api2d-key3\"")
478
+ print亮蓝(f"[API_KEY] 您既可以在config.py中修改api-key(s),也可以在问题输入区输入临时的api-key(s),然后回车键提交后即可生效。")
479
+ if is_any_api_key(r):
480
+ print亮绿(f"[API_KEY] 您的 API_KEY 是: {r[:15]}*** API_KEY 导入成功")
481
  else:
482
+ print亮红( "[API_KEY] 正确的 API_KEY 是'sk'开头的51位密钥(OpenAI),或者 'fk'开头的41位密钥,请在config文件中修改API密钥之后再运行。")
 
483
  if arg == 'proxies':
484
  if r is None:
485
+ print亮红('[PROXY] 网络代理状态:未配置。无代理状态下很可能无法访问OpenAI家族的模型。建议:检查USE_PROXY选项是否修改。')
486
  else:
487
+ print亮绿('[PROXY] 网络代理状态:已配置。配置信息如下:', r)
488
  assert isinstance(r, dict), 'proxies格式错误,请注意proxies选项的格式,不要遗漏括号。'
489
  return r
490
 
 
511
  它的作用是……额……没用,即在代码结构不变得情况下取代其他的上下文管理器。
512
  上下文管理器是一种Python对象,用于与with语句一起使用,
513
  以确保一些资源在代码块执行期间得到正确的初始化和清理。
514
+ 上下文管理器必须实现两个方法,分别为 __enter__()和 __exit__()。
515
  在上下文执行开始的情况下,__enter__()方法会在代码块被执行前被调用,
516
  而在上下文执行结束时,__exit__()方法则会被调用。
517
  """
 
520
 
521
  def __exit__(self, exc_type, exc_value, traceback):
522
  return
523
+
524
+ def run_gradio_in_subpath(demo, auth, port, custom_path):
525
+ def is_path_legal(path: str)->bool:
526
+ '''
527
+ check path for sub url
528
+ path: path to check
529
+ return value: do sub url wrap
530
+ '''
531
+ if path == "/": return True
532
+ if len(path) == 0:
533
+ print("ilegal custom path: {}\npath must not be empty\ndeploy on root url".format(path))
534
+ return False
535
+ if path[0] == '/':
536
+ if path[1] != '/':
537
+ print("deploy on sub-path {}".format(path))
538
+ return True
539
+ return False
540
+ print("ilegal custom path: {}\npath should begin with \'/\'\ndeploy on root url".format(path))
541
+ return False
542
+
543
+ if not is_path_legal(custom_path): raise RuntimeError('Ilegal custom path')
544
+ import uvicorn
545
+ import gradio as gr
546
+ from fastapi import FastAPI
547
+ app = FastAPI()
548
+ if custom_path != "/":
549
+ @app.get("/")
550
+ def read_main():
551
+ return {"message": f"Gradio is running at: {custom_path}"}
552
+ app = gr.mount_gradio_app(app, demo, path=custom_path)
553
+ uvicorn.run(app, host="0.0.0.0", port=port) # , auth=auth
version CHANGED
@@ -1,5 +1,5 @@
1
  {
2
- "version": 2.5,
3
  "show_feature": true,
4
- "new_feature": "新增一键更新程序<->高亮代码<->高亮公式<->新增垂直布局选项"
5
  }
 
1
  {
2
+ "version": 3.2,
3
  "show_feature": true,
4
+ "new_feature": "保存对话功能 <-> 解读任意语言代码+同时询问任意的LLM组合 <-> 添加联网(Google)回答问题插件 <-> 修复ChatGLM上下文BUG <-> 添加支持清华ChatGLM和GPT-4 <-> 改进架构,支持与多个LLM模型同时对话 <-> 添加支持API2D(国内,可支持gpt4)"
5
  }