Author SHA1 Message Date
qingxu fu 57a668bf30 自译解报告 2023-03-30 18:21:17 +08:00
qingxu fu 700d14be10 Merge branch 'hot-reload-test' of https://github.com/binary-husky/chatgpt_academic into hot-reload-test 2023-03-30 18:05:03 +08:00
qingxu fu 3fe96956ce 新增热更新功能 2023-03-30 18:04:20 +08:00
qingxu fu c358c95630 新增热更新功能 2023-03-30 18:01:06 +08:00
binary-husky 1c3ce18eff Update README.md 2023-03-30 14:48:46 +08:00
binary-husky a689960e31 Update README.md 2023-03-30 14:48:20 +08:00
binary-husky 07eca9fe55 Update README.md 2023-03-30 14:47:19 +08:00
binary-husky 00f29f2120 Update README.md 2023-03-30 14:08:24 +08:00
binary-husky 10ea3daaa5 Update README.md 2023-03-30 13:24:30 +08:00
binary-husky eb95eec122 Merge pull request #124 from Freddd13/master
feat: 添加wsl2使用windows proxy的方法
2023-03-30 12:56:13 +08:00
qingxu fu e03634f9e2 查找语法错误之前先清除换行符 2023-03-30 12:52:28 +08:00
qingxu fu 77d4628877 语法错误查找prompt更新 2023-03-30 12:16:18 +08:00
qingxu fu 8c3d37bbce up 2023-03-30 11:51:55 +08:00
qingxu fu 28f6801870 标准化代码格式 2023-03-30 11:50:11 +08:00
qingxu fu 6d7fb20b5a 修改配置的读取方式 2023-03-30 11:05:38 +08:00
Freddd13 9dc0d3273b update: 修改readme 2023-03-30 02:00:15 +08:00
Freddd13 13e976774f Merge remote-tracking branch 'upstream/master' 2023-03-30 01:58:39 +08:00
Freddd13 35d3346a1c feat: 支持wsl2使用windows proxy 2023-03-30 01:47:39 +08:00
Your Name eaec1c3728 Merge branch 'master' of github.com:binary-husky/chatgpt_academic 2023-03-30 00:15:37 +08:00
Your Name 0140b0cda8 change UI layout 2023-03-30 00:15:31 +08:00
binary-husky f98fe5b9ab Update README.md 2023-03-30 00:09:58 +08:00
binary-husky 0063f8dd82 Update README.md 2023-03-29 23:53:33 +08:00
binary-husky 23b8c47c54 Update README.md 2023-03-29 23:50:20 +08:00
binary-husky 5353a32345 Update README.md 2023-03-29 23:48:58 +08:00
binary-husky d569d2f9c1 Update README.md 2023-03-29 23:44:37 +08:00
binary-husky 67e6070d80 Update README.md 2023-03-29 23:44:01 +08:00
binary-husky 01873f7811 Merge pull request #108 from sjiang95/condainstall
readme: update
2023-03-29 23:22:44 +08:00
Your Name c2318bc197 Merge branch 'dev' 2023-03-29 23:15:29 +08:00
binary-husky 86dc4ca3af Merge pull request #102 from ValeriaWong/master
feat(读文章写摘要):支持pdf文件批量阅读及总结 #101
2023-03-29 23:14:12 +08:00
Your Name 4a2f73d007 change UI layout 2023-03-29 23:04:37 +08:00
Your Name 9c643e6d8c change ui layout 2023-03-29 23:00:16 +08:00
Your Name 34323c9d36 Merge https://github.com/ValeriaWong/chatgpt_academic into ValeriaWong-master 2023-03-29 21:49:56 +08:00
Your Name 48cc2349e3 add pip package check 2023-03-29 21:47:56 +08:00
Your Name 7d57967519 Merge branch 'master' of https://github.com/ValeriaWong/chatgpt_academic 2023-03-29 21:44:59 +08:00
Shengjiang Quan 68ffa54c84 readme: update
Re-format a part of the markdown content
and add conda instruction for installation.

Signed-off-by: Shengjiang Quan <[email protected]>
2023-03-29 22:36:15 +09:00
ValeriaWong 02ddcdf731 Merge branch 'master' of https://github.com/ValeriaWong/chatgpt_academic 2023-03-29 21:05:25 +08:00
ValeriaWong 14ea206a5a Merge branch 'binary-husky:master' into master 2023-03-29 20:57:07 +08:00
ValeriaWong 814c93bb75 feat(读文章写摘要):支持pdf文件批量阅读及总结 #101 2023-03-29 20:55:13 +08:00
binary-husky fb953148b9 Update main.py 2023-03-29 20:47:34 +08:00
Your Name 2bcd34360a bug quick fix 2023-03-29 20:41:07 +08:00
binary-husky b3211362f9 Merge pull request #82 from Okabe-Rintarou-0/master
支持暂停按钮 #53
2023-03-29 20:38:06 +08:00
Your Name be1bf6cb77 提交后不清空输入栏,添加停止键 2023-03-29 20:36:58 +08:00
Your Name 5f771d8acf Merge branch 'master' of https://github.com/Okabe-Rintarou-0/chatgpt_academic into Okabe-Rintarou-0-master 2023-03-29 20:26:13 +08:00
Your Name 095579c323 Merge branch 'master' of https://github.com/Okabe-Rintarou-0/chatgpt_academic into Okabe-Rintarou-0-master 2023-03-29 20:07:38 +08:00
Your Name f9308300f3 handle ip location lookup error 2023-03-29 19:37:39 +08:00
binary-husky 6ca28fbff2 Merge pull request #87 from Okabe-Rintarou-0/fix-markdown-display
正确显示多行输入的 markdown #84
2023-03-29 19:32:19 +08:00
binary-husky 11f619f76f Merge pull request #96 from eltociear/patch-1
fix typo in predict.py
2023-03-29 18:47:51 +08:00
Your Name 39d0176673 新增代理配置说明 2023-03-29 18:07:33 +08:00
Ikko Eltociear Ashimine 043bd59ffc fix typo in predict.py
refleshing -> refreshing
2023-03-29 18:57:37 +09:00
ValeriaWong 2ac602e0aa feat(读文章写摘要):支持pdf文件批量阅读及总结 2023-03-29 17:57:17 +08:00
Your Name 50ee37f23c error message change 2023-03-29 16:50:37 +08:00
Your Name f0d9098df5 dev 2023-03-29 16:47:15 +08:00
okabe 2401cf2136 fix: markdown display bug #84 2023-03-29 15:29:40 +08:00
okabe dd3c4f988c feat: support stop generate button (#53) 2023-03-29 14:53:53 +08:00
Your Name 22e7dc617b fix directory return bug 2023-03-29 14:28:57 +08:00
Your Name a3c937c202 update comments 2023-03-29 14:16:59 +08:00
505030475 1b01d0fd8a 修复变量名 2023-03-29 13:58:30 +08:00
505030475 0b018bf871 Merge remote-tracking branch 'origin/test-3-29' 2023-03-29 13:44:57 +08:00
505030475 88d41ab4ca config comments 2023-03-29 13:43:07 +08:00
binary-husky 6ebadeb2a6 Update README.md 2023-03-29 13:38:43 +08:00
binary-husky 515045a8d1 Merge pull request #57 from GaiZhenbiao/master
Adding a bunch of nice-to-have features
2023-03-29 13:37:58 +08:00
Tuchuanhuhuhu 39ad492a65 增加“重置”按钮,提交之后自动清空输入框 2023-03-28 23:33:19 +08:00
Tuchuanhuhuhu dd8ec0d511 temprature的取值范围为[0, 2] 2023-03-28 23:20:54 +08:00
Tuchuanhuhuhu 43d59d936f 增加并行处理与权限控制 2023-03-28 23:17:12 +08:00
Chuan Hu 46eba1f399 Improve the way to open webbrowser 2023-03-28 22:47:30 +08:00
12 changed files with 387 additions and 131 deletions
+85 -29
View File
@@ -1,3 +1,5 @@
# ChatGPT 学术优化 # ChatGPT 学术优化
**如果喜欢这个项目,请给它一个Star;如果你发明了更好用的学术快捷键,欢迎发issue或者pull requests** **如果喜欢这个项目,请给它一个Star;如果你发明了更好用的学术快捷键,欢迎发issue或者pull requests**
@@ -6,15 +8,24 @@ If you like this project, please give it a Star. If you've come up with more use
``` ```
代码中参考了很多其他优秀项目中的设计,主要包括: 代码中参考了很多其他优秀项目中的设计,主要包括:
# 借鉴项目1:借鉴了mdtex2html中公式处理的方法
https://github.com/polarwinkel/mdtex2html
# 借鉴项目2:借鉴了ChuanhuChatGPT中读取OpenAI json的方法、记录历史问询记录的方法以及gradio queue的使用技巧 # 借鉴项目1:借鉴了ChuanhuChatGPT中读取OpenAI json的方法、记录历史问询记录的方法以及gradio queue的使用技巧
https://github.com/GaiZhenbiao/ChuanhuChatGPT https://github.com/GaiZhenbiao/ChuanhuChatGPT
# 借鉴项目2:借鉴了mdtex2html中公式处理的方法
https://github.com/polarwinkel/mdtex2html
项目使用OpenAI的gpt-3.5-turbo模型,期待gpt-4早点放宽门槛😂 项目使用OpenAI的gpt-3.5-turbo模型,期待gpt-4早点放宽门槛😂
``` ```
> **Note**
>
> 1.请注意只有“红颜色”标识的函数插件(按钮)才支持读取文件。目前暂不能完善地支持pdf格式文献的翻译解读,尚不支持word格式文件的读取。
>
> 2.本项目中每个文件的功能都在`project_self_analysis.md`详细说明。随着版本的迭代,您也可以随时自行点击相关函数插件,调用GPT重新生成项目的自译解报告。
>
> 3.如果您不太习惯部分中文命名的函数,您可以随时点击相关函数插件,调用GPT一键生成纯英文的项目源代码。
<div align="center"> <div align="center">
功能 | 描述 功能 | 描述
@@ -33,12 +44,13 @@ chat分析报告生成 | [实验性功能] 运行后自动生成总结汇报
公式显示 | 可以同时显示公式的tex形式和渲染形式 公式显示 | 可以同时显示公式的tex形式和渲染形式
图片显示 | 可以在markdown中显示图片 图片显示 | 可以在markdown中显示图片
支持GPT输出的markdown表格 | 可以输出支持GPT的markdown表格 支持GPT输出的markdown表格 | 可以输出支持GPT的markdown表格
…… | ……
</div> </div>
- 新界面 - 新界面
<div align="center"> <div align="center">
<img src="https://user-images.githubusercontent.com/96192199/227851398-fab5a158-aaf6-4151-95ac-a8172ce611c7.png" width="700" > <img src="https://user-images.githubusercontent.com/96192199/228600410-7d44e34f-63f1-4046-acb8-045cb05da8bb.png" width="700" >
</div> </div>
@@ -70,33 +82,61 @@ chat分析报告生成 | [实验性功能] 运行后自动生成总结汇报
<img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="700" > <img src="https://user-images.githubusercontent.com/96192199/226935232-6b6a73ce-8900-4aee-93f9-733c7e6fef53.png" width="700" >
</div> </div>
## 直接运行 (Windows or Linux or MacOS) ## 直接运行 (Windows, Linux or MacOS)
``` sh 下载项目
# 下载项目
```sh
git clone https://github.com/binary-husky/chatgpt_academic.git git clone https://github.com/binary-husky/chatgpt_academic.git
cd chatgpt_academic cd chatgpt_academic
# 在config.py中,配置 海外Proxy 和 OpenAI API KEY
- 1.如果你在国内,需要设置海外代理才能够使用 OpenAI API,你可以通过 config.py 文件来进行设置。
- 2.配置 OpenAI API KEY。你需要在 OpenAI 官网上注册并获取 API KEY。一旦你拿到了 API KEY,在 config.py 文件里配置好即可。
# 安装依赖
python -m pip install -r requirements.txt
# 运行
python main.py
# 测试实验性功能
## 测试C++项目头文件分析
input区域 输入 ./crazy_functions/test_project/cpp/libJPG 然后点击 "[实验] 解析整个C++项目(input输入项目根路径)"
## 测试给Latex项目写摘要
input区域 输入 ./crazy_functions/test_project/latex/attention 然后点击 "[实验] 读tex论文写摘要(input输入项目根路径)"
## 测试Python项目分析
input区域 输入 ./crazy_functions/test_project/python/dqn 然后点击 "[实验] 解析整个py项目(input输入项目根路径)"
## 测试自我代码解读
点击 "[实验] 请解析并解构此项目本身"
## 测试实验功能模板函数(要求gpt回答几个数的平方是什么),您可以根据此函数为模板,实现更复杂的功能
点击 "[实验] 实验功能函数模板"
``` ```
我们建议将`config.py`复制为`config_private.py`并将后者用作个性化配置文件以避免`config.py`中的变更影响你的使用或不小心将包含你的OpenAI API KEY的`config.py`提交至本项目。
```sh
cp config.py config_private.py
```
`config_private.py`中,配置 海外Proxy 和 OpenAI API KEY
```
1. 如果你在国内,需要设置海外代理才能够使用 OpenAI API,你可以通过 config.py 文件来进行设置。
2. 配置 OpenAI API KEY。你需要在 OpenAI 官网上注册并获取 API KEY。一旦你拿到了 API KEY,在 config.py 文件里配置好即可。
```
安装依赖
```sh
python -m pip install -r requirements.txt
```
或者,如果你希望使用`conda`
```sh
conda create -n gptac 'gradio>=3.23' requests
conda activate gptac
python3 -m pip install mdtex2html
```
运行
```sh
python main.py
```
测试实验性功能
```
- 测试C++项目头文件分析
input区域 输入 `./crazy_functions/test_project/cpp/libJPG` 然后点击 "[实验] 解析整个C++项目(input输入项目根路径)"
- 测试给Latex项目写摘要
input区域 输入 `./crazy_functions/test_project/latex/attention` 然后点击 "[实验] 读tex论文写摘要(input输入项目根路径)"
- 测试Python项目分析
input区域 输入 `./crazy_functions/test_project/python/dqn` 然后点击 "[实验] 解析整个py项目(input输入项目根路径)"
- 测试自我代码解读
点击 "[实验] 请解析并解构此项目本身"
- 测试实验功能模板函数(要求gpt回答历史上的今天发生了什么),您可以根据此函数为模板,实现更复杂的功能
点击 "[实验] 实验功能函数模板"
```
与代理网络有关的issue(网络超时、代理不起作用)汇总到 https://github.com/binary-husky/chatgpt_academic/issues/1
## 使用docker (Linux) ## 使用docker (Linux)
@@ -114,7 +154,7 @@ docker run --rm -it --net=host gpt-academic
# 测试实验性功能 # 测试实验性功能
## 测试自我代码解读 ## 测试自我代码解读
点击 "[实验] 请解析并解构此项目本身" 点击 "[实验] 请解析并解构此项目本身"
## 测试实验功能模板函数(要求gpt回答几个数的平方是什么),您可以根据此函数为模板,实现更复杂的功能 ## 测试实验功能模板函数(要求gpt回答历史上的今天发生了什么),您可以根据此函数为模板,实现更复杂的功能
点击 "[实验] 实验功能函数模板" 点击 "[实验] 实验功能函数模板"
##(请注意在docker中运行时,需要额外注意程序的文件访问权限问题) ##(请注意在docker中运行时,需要额外注意程序的文件访问权限问题)
## 测试C++项目头文件分析 ## 测试C++项目头文件分析
@@ -126,6 +166,21 @@ input区域 输入 ./crazy_functions/test_project/python/dqn 然后点击 "[
``` ```
## 使用WSL2Windows Subsystem for Linux 子系统)
选择这种方式默认您已经具备一定基本知识,因此不再赘述多余步骤。如果不是这样,您可以从[这里](https://learn.microsoft.com/zh-cn/windows/wsl/about)或GPT处获取更多关于子系统的信息。
WSL2可以配置使用Windows侧的代理上网,前置步骤可以参考[这里](https://www.cnblogs.com/tuilk/p/16287472.html)
由于Windows相对WSL2的IP会发生变化,我们需要每次启动前先获取这个IP来保证顺利访问,将config.py中设置proxies的部分更改为如下代码:
```python
import subprocess
cmd_get_ip = 'grep -oP "(\d+\.)+(\d+)" /etc/resolv.conf'
ip_proxy = subprocess.run(
cmd_get_ip, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, shell=True
).stdout.strip() # 获取windows的IP
proxies = { "http": ip_proxy + ":51837", "https": ip_proxy + ":51837", } # 请自行修改
```
在启动main.py后,可以在windows浏览器中访问服务。至此测试、使用与上面其他方法无异。
## 自定义新的便捷按钮(学术快捷键自定义) ## 自定义新的便捷按钮(学术快捷键自定义)
打开functional.py,添加条目如下,然后重启程序即可。(如果按钮已经添加成功并可见,那么前缀、后缀都支持热修改,无需重启程序即可生效。) 打开functional.py,添加条目如下,然后重启程序即可。(如果按钮已经添加成功并可见,那么前缀、后缀都支持热修改,无需重启程序即可生效。)
@@ -165,11 +220,12 @@ python check_proxy.py
## 兼容性测试 ## 兼容性测试
### 图片显示: ### 图片显示:
<div align="center"> <div align="center">
<img src="https://user-images.githubusercontent.com/96192199/226906087-b5f1c127-2060-4db9-af05-487643b21ed9.png" height="200" > <img src="https://user-images.githubusercontent.com/96192199/228737599-bf0a9d9c-1808-4f43-ae15-dfcc7af0f295.png" width="800" >
<img src="https://user-images.githubusercontent.com/96192199/226906703-7226495d-6a1f-4a53-9728-ce6778cbdd19.png" height="200" >
</div> </div>
### 如果一个程序能够读懂并剖析自己: ### 如果一个程序能够读懂并剖析自己:
<div align="center"> <div align="center">
+10 -5
View File
@@ -6,8 +6,11 @@ def check_proxy(proxies):
response = requests.get("https://ipapi.co/json/", proxies=proxies, timeout=4) response = requests.get("https://ipapi.co/json/", proxies=proxies, timeout=4)
data = response.json() data = response.json()
print(f'查询代理的地理位置,返回的结果是{data}') print(f'查询代理的地理位置,返回的结果是{data}')
country = data['country_name'] if 'country_name' in data:
result = f"代理配置 {proxies_https}, 代理所在地:{country}" country = data['country_name']
result = f"代理配置 {proxies_https}, 代理所在地:{country}"
elif 'error' in data:
result = f"代理配置 {proxies_https}, 代理所在地:未知,IP查询频率受限"
print(result) print(result)
return result return result
except: except:
@@ -17,6 +20,8 @@ def check_proxy(proxies):
if __name__ == '__main__': if __name__ == '__main__':
try: from config_private import proxies # 放自己的秘密如API和代理网址 os.path.exists('config_private.py') import os; os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染
except: from config import proxies from toolbox import get_conf
check_proxy(proxies) proxies, = get_conf('proxies')
check_proxy(proxies)
+14 -5
View File
@@ -5,15 +5,22 @@ API_URL = "https://api.openai.com/v1/chat/completions"
# 改为True应用代理 # 改为True应用代理
USE_PROXY = False USE_PROXY = False
if USE_PROXY: if USE_PROXY:
# 填写格式是 [协议]:// [地址] :[端口]
# 例如 "socks5h://localhost:11284"
# [协议] 常见协议无非socks5h/http,例如 v2*** 和 s** 的默认本地协议是socks5hcl**h 的默认本地协议是http
# [地址] 懂的都懂,不懂就填localhost或者127.0.0.1肯定错不了(localhost意思是代理软件安装在本机上)
# [端口] 在代理软件的设置里,不同的代理软件界面不一样,但端口号都应该在最显眼的位置上
# 代理网络的地址,打开你的科学上网软件查看代理的协议(socks5/http)、地址(localhost)和端口(11284) # 代理网络的地址,打开你的科学上网软件查看代理的协议(socks5/http)、地址(localhost)和端口(11284)
proxies = { "http": "socks5h://localhost:11284", "https": "socks5h://localhost:11284", } proxies = { "http": "socks5h://localhost:11284", "https": "socks5h://localhost:11284", }
print('网络代理状态:运行。') print('网络代理状态:运行。')
else: else:
proxies = None proxies = None
print('网络代理状态:未配置。无代理状态下很可能无法访问。') print('网络代理状态:未配置。无代理状态下很可能无法访问。')
# 发送请求到OpenAI后,等待多久判定为超时 # 发送请求到OpenAI后,等待多久判定为超时
TIMEOUT_SECONDS = 20 TIMEOUT_SECONDS = 25
# 网页的端口, -1代表随机端口 # 网页的端口, -1代表随机端口
WEB_PORT = -1 WEB_PORT = -1
@@ -24,6 +31,8 @@ MAX_RETRY = 2
# 选择的OpenAI模型是(gpt4现在只对申请成功的人开放) # 选择的OpenAI模型是(gpt4现在只对申请成功的人开放)
LLM_MODEL = "gpt-3.5-turbo" LLM_MODEL = "gpt-3.5-turbo"
# 检查一下是不是忘了改config # 设置并行使用的线程数
if API_KEY == "sk-此处填API秘钥": CONCURRENT_COUNT = 100
assert False, "请在config文件中修改API密钥, 添加海外代理之后再运行"
# 设置用户名和密码
AUTHENTICATION = [] # [("username", "password"), ("username2", "password2"), ...]
@@ -71,5 +71,5 @@ def 全项目切换英文(txt, top_p, temperature, chatbot, history, sys_prompt,
# 备份一个文件 # 备份一个文件
res = write_results_to_file(history) res = write_results_to_file(history)
chatbot.append(("给爷一份任务执行报告", res)) chatbot.append(("生成一份任务执行报告", res))
yield chatbot, history, '正常' yield chatbot, history, '正常'
+99
View File
@@ -0,0 +1,99 @@
from predict import predict_no_ui
from toolbox import CatchException, report_execption, write_results_to_file, predict_no_ui_but_counting_down
fast_debug = False
def 解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt):
import time, glob, os, fitz
print('begin analysis on:', file_manifest)
for index, fp in enumerate(file_manifest):
with fitz.open(fp) as doc:
file_content = ""
for page in doc:
file_content += page.get_text()
print(file_content)
prefix = "接下来请你逐文件分析下面的论文文件,概括其内容" if index==0 else ""
i_say = prefix + f'请对下面的文章片段用中文做一个概述,文件名是{os.path.relpath(fp, project_folder)},文章内容是 ```{file_content}```'
i_say_show_user = prefix + f'[{index}/{len(file_manifest)}] 请对下面的文章片段做一个概述: {os.path.abspath(fp)}'
chatbot.append((i_say_show_user, "[Local Message] waiting gpt response."))
print('[1] yield chatbot, history')
yield chatbot, history, '正常'
if not fast_debug:
msg = '正常'
# ** gpt request **
gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temperature, history=[]) # 带超时倒计时
print('[2] end gpt req')
chatbot[-1] = (i_say_show_user, gpt_say)
history.append(i_say_show_user); history.append(gpt_say)
print('[3] yield chatbot, history')
yield chatbot, history, msg
print('[4] next')
if not fast_debug: time.sleep(2)
all_file = ', '.join([os.path.relpath(fp, project_folder) for index, fp in enumerate(file_manifest)])
i_say = f'根据以上你自己的分析,对全文进行概括,用学术性语言写一段中文摘要,然后再写一段英文摘要(包括{all_file})。'
chatbot.append((i_say, "[Local Message] waiting gpt response."))
yield chatbot, history, '正常'
if not fast_debug:
msg = '正常'
# ** gpt request **
gpt_say = yield from predict_no_ui_but_counting_down(i_say, i_say, chatbot, top_p, temperature, history=history) # 带超时倒计时
chatbot[-1] = (i_say, gpt_say)
history.append(i_say); history.append(gpt_say)
yield chatbot, history, msg
res = write_results_to_file(history)
chatbot.append(("完成了吗?", res))
yield chatbot, history, msg
@CatchException
def 批量总结PDF文档(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
import glob, os
# 基本信息:功能、贡献者
chatbot.append([
"函数插件功能?",
"批量总结PDF文档。函数插件贡献者: ValeriaWong"])
yield chatbot, history, '正常'
# 尝试导入依赖,如果缺少依赖,则给出安装建议
try:
import fitz
except:
report_execption(chatbot, history,
a = f"解析项目: {txt}",
b = f"导入软件依赖失败。使用该模块需要额外依赖,安装方法```pip install --upgrade pymupdf```。")
yield chatbot, history, '正常'
return
# 清空历史,以免输入溢出
history = []
# 检测输入参数,如没有给定输入参数,直接退出
if os.path.exists(txt):
project_folder = txt
else:
if txt == "": txt = '空空如也的输入栏'
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到本地项目或无权访问: {txt}")
yield chatbot, history, '正常'
return
# 搜索需要处理的文件清单
file_manifest = [f for f in glob.glob(f'{project_folder}/**/*.pdf', recursive=True)] # + \
# [f for f in glob.glob(f'{project_folder}/**/*.tex', recursive=True)] + \
# [f for f in glob.glob(f'{project_folder}/**/*.cpp', recursive=True)] + \
# [f for f in glob.glob(f'{project_folder}/**/*.c', recursive=True)]
# 如果没找到任何文件
if len(file_manifest) == 0:
report_execption(chatbot, history, a = f"解析项目: {txt}", b = f"找不到任何.tex或.pdf文件: {txt}")
yield chatbot, history, '正常'
return
# 开始正式执行任务
yield from 解析PDF(file_manifest, project_folder, top_p, temperature, chatbot, history, systemPromptTxt)
+4 -1
View File
@@ -5,10 +5,13 @@ import datetime
@CatchException @CatchException
def 高阶功能模板函数(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT): def 高阶功能模板函数(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT):
history = [] # 清空历史,以免输入溢出 history = [] # 清空历史,以免输入溢出
chatbot.append(("这是什么功能?", "[Local Message] 请注意,您正在调用一个函数模板,该函数面向希望实现更多有趣功能的开发者,它可以作为创建新功能函数的模板。为了做到简单易读,该函数只有25行代码,不会实时反馈文字流或心跳,请耐心等待程序输出完成。另外您若希望分享新的功能模组,请不吝PR!"))
yield chatbot, history, '正常' # 由于请求gpt需要一段时间,我们先及时地做一次状态显示
for i in range(5): for i in range(5):
currentMonth = (datetime.date.today() + datetime.timedelta(days=i)).month currentMonth = (datetime.date.today() + datetime.timedelta(days=i)).month
currentDay = (datetime.date.today() + datetime.timedelta(days=i)).day currentDay = (datetime.date.today() + datetime.timedelta(days=i)).day
i_say = f'历史中哪些事件发生在{currentMonth}{currentDay}日?列举两条并发送相关图片。发送图片时,请使用Markdown,将Unsplash API中的PUT_YOUR_QUERY_HERE替换成描述改事件的个最重要的单词。' i_say = f'历史中哪些事件发生在{currentMonth}{currentDay}日?列举两条并发送相关图片。发送图片时,请使用Markdown,将Unsplash API中的PUT_YOUR_QUERY_HERE替换成描述改事件的个最重要的单词。'
chatbot.append((i_say, "[Local Message] waiting gpt response.")) chatbot.append((i_say, "[Local Message] waiting gpt response."))
yield chatbot, history, '正常' # 由于请求gpt需要一段时间,我们先及时地做一次状态显示 yield chatbot, history, '正常' # 由于请求gpt需要一段时间,我们先及时地做一次状态显示
+32 -33
View File
@@ -2,54 +2,53 @@
# 'secondary' 颜色对应 theme.py 中的 neutral_hue # 'secondary' 颜色对应 theme.py 中的 neutral_hue
# 'stop' 颜色对应 theme.py 中的 color_er # 'stop' 颜色对应 theme.py 中的 color_er
# 默认按钮颜色是 secondary # 默认按钮颜色是 secondary
from toolbox import clear_line_break
def get_functionals(): def get_functionals():
return { return {
"英语学术润色": { "英语学术润色": {
"Prefix": "Below is a paragraph from an academic paper. Polish the writing to meet the academic style, \ # 前言
improve the spelling, grammar, clarity, concision and overall readability. When neccessary, rewrite the whole sentence. \ "Prefix": r"Below is a paragraph from an academic paper. Polish the writing to meet the academic style, " +
Furthermore, list all modification and explain the reasons to do so in markdown table.\n\n", # 前言 r"improve the spelling, grammar, clarity, concision and overall readability. When neccessary, rewrite the whole sentence. " +
"Suffix": "", # 后语 r"Furthermore, list all modification and explain the reasons to do so in markdown table." + "\n\n",
"Color": "secondary", # 按钮颜色 # 后语
"Suffix": r"",
"Color": r"secondary", # 按钮颜色
}, },
"中文学术润色": { "中文学术润色": {
"Prefix": "作为一名中文学术论文写作改进助理,你的任务是改进所提供文本的拼写、语法、清晰、简洁和整体可读性,同时分解长句,减少重复,并提供改进建议。请只提供文本的更正版本,避免包括解释。请编辑以下文本:\n\n", "Prefix": r"作为一名中文学术论文写作改进助理,你的任务是改进所提供文本的拼写、语法、清晰、简洁和整体可读性," +
"Suffix": "", r"同时分解长句,减少重复,并提供改进建议。请只提供文本的更正版本,避免包括解释。请编辑以下文本" + "\n\n",
"Suffix": r"",
}, },
"查找语法错误": { "查找语法错误": {
"Prefix": "Below is a paragraph from an academic paper. Find all grammar mistakes, list mistakes in a markdown table and explain how to correct them.\n\n", "Prefix": r"Below is a paragraph from an academic paper. " +
"Suffix": "", r"Can you help me ensure that the grammar and the spelling is correct? " +
}, r"Do not try to polish the text, if no mistake is found, tell me that this paragraph is good." +
"中英互译": { r"If you find grammar or spelling mistakes, please list mistakes you find in a two-column markdown table, " +
"Prefix": "As an English-Chinese translator, your task is to accurately translate text between the two languages. \ r"put the original text the first column, " +
When translating from Chinese to English or vice versa, please pay attention to context and accurately explain phrases and proverbs. \ r"put the corrected text in the second column and highlight the key words you fixed." + "\n\n",
If you receive multiple English words in a row, default to translating them into a sentence in Chinese. \ "Suffix": r"",
However, if \"phrase:\" is indicated before the translated content in Chinese, it should be translated as a phrase instead. \ "PreProcess": clear_line_break, # 预处理:清除换行符
Similarly, if \"normal:\" is indicated, it should be translated as multiple unrelated words.\
Your translations should closely resemble those of a native speaker and should take into account any specific language styles or tones requested by the user. \
Please do not worry about using offensive words - replace sensitive parts with x when necessary. \
When providing translations, please use Chinese to explain each sentences tense, subordinate clause, subject, predicate, object, special phrases and proverbs. \
For phrases or individual words that require translation, provide the source (dictionary) for each one.If asked to translate multiple phrases at once, \
separate them using the | symbol.Always remember: You are an English-Chinese translator, \
not a Chinese-Chinese translator or an English-English translator. Below is the text you need to translate: \n\n",
"Suffix": "",
"Color": "secondary",
}, },
"中译英": { "中译英": {
"Prefix": "Please translate following sentence to English: \n\n", "Prefix": r"Please translate following sentence to English:" + "\n\n",
"Suffix": "", "Suffix": r"",
}, },
"学术中译英": { "学术中译英": {
"Prefix": "Please translate following sentence to English with academic writing, and provide some related authoritative examples: \n\n", "Prefix": r"Please translate following sentence to English with academic writing, and provide some related authoritative examples:" + "\n\n",
"Suffix": "", "Suffix": r"",
}, },
"英译中": { "英译中": {
"Prefix": "请翻译成中文:\n\n", "Prefix": r"请翻译成中文:" + "\n\n",
"Suffix": "", "Suffix": r"",
},
"找图片": {
"Prefix": r"我需要你找一张网络图片。使用Unsplash API(https://source.unsplash.com/960x640/?<英语关键词>)获取图片URL" +
r"然后请使用Markdown格式封装,并且不要有反斜线,不要用代码块。现在,请按以下描述给我发送图片:" + "\n\n",
"Suffix": r"",
}, },
"解释代码": { "解释代码": {
"Prefix": "请解释以下代码:\n```\n", "Prefix": r"请解释以下代码:" + "\n```\n",
"Suffix": "\n```\n", "Suffix": "\n```\n",
"Color": "secondary",
}, },
} }
+39 -11
View File
@@ -1,3 +1,11 @@
from functools import HotReload # HotReload 的意思是热更新,修改函数插件后,不需要重启程序,代码直接生效
# UserVisibleLevel是过滤器参数。
# 由于UI界面空间有限,所以通过这种方式决定UI界面中显示哪些插件
# 默认函数插件 VisibleLevel 是 0
# 当 UserVisibleLevel >= 函数插件的 VisibleLevel 时,该函数插件才会被显示出来
UserVisibleLevel = 1
def get_crazy_functionals(): def get_crazy_functionals():
from crazy_functions.读文章写摘要 import 读文章写摘要 from crazy_functions.读文章写摘要 import 读文章写摘要
@@ -9,37 +17,57 @@ def get_crazy_functionals():
from crazy_functions.高级功能函数模板 import 高阶功能模板函数 from crazy_functions.高级功能函数模板 import 高阶功能模板函数
from crazy_functions.代码重写为全英文_多线程 import 全项目切换英文 from crazy_functions.代码重写为全英文_多线程 import 全项目切换英文
return { function_plugins = {
"[实验] 请解析并解构此项目本身": { "请解析并解构此项目本身": {
# HotReload 的意思是热更新,修改函数插件后,不需要重启程序,代码直接生效
"Function": 解析项目本身 "Function": 解析项目本身
}, },
"[实验] 解析整个py项目(配合input输入框)": { "解析整个py项目": {
"Color": "stop", # 按钮颜色 "Color": "stop", # 按钮颜色
"Function": 解析一个Python项目 "Function": 解析一个Python项目
}, },
"[实验] 解析整个C++项目头文件(配合input输入框)": { "解析整个C++项目头文件": {
"Color": "stop", # 按钮颜色 "Color": "stop", # 按钮颜色
"Function": 解析一个C项目的头文件 "Function": 解析一个C项目的头文件
}, },
"[实验] 解析整个C++项目(配合input输入框)": { "解析整个C++项目": {
"Color": "stop", # 按钮颜色 "Color": "stop", # 按钮颜色
"Function": 解析一个C项目 "Function": 解析一个C项目
}, },
"[实验] 读tex论文写摘要(配合input输入框)": { "读tex论文写摘要": {
"Color": "stop", # 按钮颜色 "Color": "stop", # 按钮颜色
"Function": 读文章写摘要 "Function": 读文章写摘要
}, },
"[实验] 批量生成函数注释(配合input输入框)": { "批量生成函数注释": {
"Color": "stop", # 按钮颜色 "Color": "stop", # 按钮颜色
"Function": 批量生成函数注释 "Function": 批量生成函数注释
}, },
"[实验] 把本项目源代码切换成全英文(多线程demo": { "[多线程demo] 把本项目源代码切换成全英文": {
"Function": 全项目切换英文 # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
"Function": HotReload(全项目切换英文)
}, },
"[实验] 历史上的今天(高阶功能模板函数demo)": { "[函数插件模板demo] 历史上的今天": {
"Function": 高阶功能模板函数 # HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
"Function": HotReload(高阶功能模板函数)
}, },
} }
# VisibleLevel=1 经过测试,但功能未达到理想状态
if UserVisibleLevel >= 1:
from crazy_functions.批量总结PDF文档 import 批量总结PDF文档
function_plugins.update({
"[仅供开发调试] 批量总结PDF文档": {
"Color": "stop",
# HotReload 的意思是热更新,修改函数插件代码后,不需要重启程序,代码直接生效
"Function": HotReload(批量总结PDF文档)
},
})
# VisibleLevel=2 尚未充分测试的函数插件,放在这里
if UserVisibleLevel >= 2:
function_plugins.update({
})
return function_plugins
+39 -26
View File
@@ -1,14 +1,16 @@
import os; os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染 import os; os.environ['no_proxy'] = '*' # 避免代理网络产生意外污染
import gradio as gr import gradio as gr
from predict import predict from predict import predict
from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated from toolbox import format_io, find_free_port, on_file_uploaded, on_report_generated, get_conf
# 建议您复制一个config_private.py放自己的秘密, 如API和代理网址, 避免不小心传github被别人看到 # 建议您复制一个config_private.py放自己的秘密, 如API和代理网址, 避免不小心传github被别人看到
try: from config_private import proxies, WEB_PORT, LLM_MODEL proxies, WEB_PORT, LLM_MODEL, CONCURRENT_COUNT, AUTHENTICATION = \
except: from config import proxies, WEB_PORT, LLM_MODEL get_conf('proxies', 'WEB_PORT', 'LLM_MODEL', 'CONCURRENT_COUNT', 'AUTHENTICATION')
# 如果WEB_PORT是-1, 则随机选取WEB端口 # 如果WEB_PORT是-1, 则随机选取WEB端口
PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT PORT = find_free_port() if WEB_PORT <= 0 else WEB_PORT
AUTHENTICATION = None if AUTHENTICATION == [] else AUTHENTICATION
initial_prompt = "Serve me as a writing and programming assistant." initial_prompt = "Serve me as a writing and programming assistant."
title_html = """<h1 align="center">ChatGPT 学术优化</h1>""" title_html = """<h1 align="center">ChatGPT 学术优化</h1>"""
@@ -16,7 +18,7 @@ title_html = """<h1 align="center">ChatGPT 学术优化</h1>"""
# 问询记录, python 版本建议3.9+(越新越好) # 问询记录, python 版本建议3.9+(越新越好)
import logging import logging
os.makedirs('gpt_log', exist_ok=True) os.makedirs('gpt_log', exist_ok=True)
try:logging.basicConfig(filename='gpt_log/chat_secrets.log', level=logging.INFO, encoding='utf-8') try:logging.basicConfig(filename='gpt_log/chat_secrets.log', level=logging.INFO, encoding='utf-8')
except:logging.basicConfig(filename='gpt_log/chat_secrets.log', level=logging.INFO) except:logging.basicConfig(filename='gpt_log/chat_secrets.log', level=logging.INFO)
print('所有问询记录将自动保存在本地目录./gpt_log/chat_secrets.log, 请注意自我隐私保护哦!') print('所有问询记录将自动保存在本地目录./gpt_log/chat_secrets.log, 请注意自我隐私保护哦!')
@@ -35,66 +37,77 @@ gr.Chatbot.postprocess = format_io
from theme import adjust_theme from theme import adjust_theme
set_theme = adjust_theme() set_theme = adjust_theme()
cancel_handles = []
with gr.Blocks(theme=set_theme, analytics_enabled=False) as demo: with gr.Blocks(theme=set_theme, analytics_enabled=False) as demo:
gr.HTML(title_html) gr.HTML(title_html)
with gr.Row(): with gr.Row():
with gr.Column(scale=2): with gr.Column(scale=2):
chatbot = gr.Chatbot() chatbot = gr.Chatbot()
chatbot.style(height=1000) chatbot.style(height=1150)
chatbot.style() chatbot.style()
history = gr.State([]) history = gr.State([])
with gr.Column(scale=1): with gr.Column(scale=1):
with gr.Row(): with gr.Row():
with gr.Column(scale=12): txt = gr.Textbox(show_label=False, placeholder="Input question here.").style(container=False)
txt = gr.Textbox(show_label=False, placeholder="Input question here.").style(container=False) with gr.Row():
with gr.Column(scale=1): submitBtn = gr.Button("提交", variant="primary")
submitBtn = gr.Button("提交", variant="primary") with gr.Row():
resetBtn = gr.Button("重置", variant="secondary"); resetBtn.style(size="sm")
stopBtn = gr.Button("停止", variant="secondary"); stopBtn.style(size="sm")
with gr.Row(): with gr.Row():
from check_proxy import check_proxy from check_proxy import check_proxy
statusDisplay = gr.Markdown(f"Tip: 按Enter提交, 按Shift+Enter换行. \nNetwork: {check_proxy(proxies)}\nModel: {LLM_MODEL}") statusDisplay = gr.Markdown(f"Tip: 按Enter提交, 按Shift+Enter换行。当前模型: {LLM_MODEL} \n {check_proxy(proxies)}")
with gr.Row(): with gr.Row():
for k in functional: for k in functional:
variant = functional[k]["Color"] if "Color" in functional[k] else "secondary" variant = functional[k]["Color"] if "Color" in functional[k] else "secondary"
functional[k]["Button"] = gr.Button(k, variant=variant) functional[k]["Button"] = gr.Button(k, variant=variant)
with gr.Row(): with gr.Row():
gr.Markdown("以下部分实验性功能需从input读取路径.") gr.Markdown("注意:以下“红颜色”标识的函数插件需从input读取路径作为参数.")
with gr.Row(): with gr.Row():
for k in crazy_functional: for k in crazy_functional:
variant = crazy_functional[k]["Color"] if "Color" in crazy_functional[k] else "secondary" variant = crazy_functional[k]["Color"] if "Color" in crazy_functional[k] else "secondary"
crazy_functional[k]["Button"] = gr.Button(k, variant=variant) crazy_functional[k]["Button"] = gr.Button(k, variant=variant)
with gr.Row(): with gr.Row():
gr.Markdown("上传本地文件供上面的实验性功能调用.") gr.Markdown("上传本地文件供上面的函数插件调用.")
with gr.Row(): with gr.Row():
file_upload = gr.Files(label='任何文件,但推荐上传压缩文件(zip, tar)', file_count="multiple") file_upload = gr.Files(label='任何文件, 但推荐上传压缩文件(zip, tar)', file_count="multiple")
system_prompt = gr.Textbox(show_label=True, placeholder=f"System Prompt", label="System prompt", value=initial_prompt).style(container=True) system_prompt = gr.Textbox(show_label=True, placeholder=f"System Prompt", label="System prompt", value=initial_prompt).style(container=True)
with gr.Accordion("arguments", open=False): with gr.Accordion("arguments", open=False):
top_p = gr.Slider(minimum=-0, maximum=1.0, value=1.0, step=0.01,interactive=True, label="Top-p (nucleus sampling)",) top_p = gr.Slider(minimum=-0, maximum=1.0, value=1.0, step=0.01,interactive=True, label="Top-p (nucleus sampling)",)
temperature = gr.Slider(minimum=-0, maximum=5.0, value=1.0, step=0.01, interactive=True, label="Temperature",) temperature = gr.Slider(minimum=-0, maximum=2.0, value=1.0, step=0.01, interactive=True, label="Temperature",)
txt.submit(predict, [txt, top_p, temperature, chatbot, history, system_prompt], [chatbot, history, statusDisplay]) predict_args = dict(fn=predict, inputs=[txt, top_p, temperature, chatbot, history, system_prompt], outputs=[chatbot, history, statusDisplay], show_progress=True)
submitBtn.click(predict, [txt, top_p, temperature, chatbot, history, system_prompt], [chatbot, history, statusDisplay], show_progress=True) empty_txt_args = dict(fn=lambda: "", inputs=[], outputs=[txt]) # 用于在提交后清空输入栏
cancel_handles.append(txt.submit(**predict_args))
# txt.submit(**empty_txt_args) 在提交后清空输入栏
cancel_handles.append(submitBtn.click(**predict_args))
# submitBtn.click(**empty_txt_args) 在提交后清空输入栏
resetBtn.click(lambda: ([], [], "已重置"), None, [chatbot, history, statusDisplay])
for k in functional: for k in functional:
functional[k]["Button"].click(predict, click_handle = functional[k]["Button"].click(predict,
[txt, top_p, temperature, chatbot, history, system_prompt, gr.State(True), gr.State(k)], [chatbot, history, statusDisplay], show_progress=True) [txt, top_p, temperature, chatbot, history, system_prompt, gr.State(True), gr.State(k)], [chatbot, history, statusDisplay], show_progress=True)
cancel_handles.append(click_handle)
file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt], [chatbot, txt]) file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt], [chatbot, txt])
for k in crazy_functional: for k in crazy_functional:
click_handle = crazy_functional[k]["Button"].click(crazy_functional[k]["Function"], click_handle = crazy_functional[k]["Button"].click(crazy_functional[k]["Function"],
[txt, top_p, temperature, chatbot, history, system_prompt, gr.State(PORT)], [chatbot, history, statusDisplay] [txt, top_p, temperature, chatbot, history, system_prompt, gr.State(PORT)], [chatbot, history, statusDisplay]
) )
try: click_handle.then(on_report_generated, [file_upload, chatbot], [file_upload, chatbot]) try: click_handle.then(on_report_generated, [file_upload, chatbot], [file_upload, chatbot])
except: pass except: pass
cancel_handles.append(click_handle)
stopBtn.click(fn=None, inputs=None, outputs=None, cancels=cancel_handles)
# 延迟函数, 做一些准备工作, 最后尝试打开浏览器 # gradio的inbrowser触发不太稳定,回滚代码到原始的浏览器打开函数
def auto_opentab_delay(): def auto_opentab_delay():
import threading, webbrowser, time import threading, webbrowser, time
print(f"URL http://localhost:{PORT}") print(f"URL http://localhost:{PORT}")
def open_webbrowser(): time.sleep(2) def open():
webbrowser.open_new_tab(f'http://localhost:{PORT}') time.sleep(2)
t = threading.Thread(target=open_webbrowser) webbrowser.open_new_tab(f'http://localhost:{PORT}')
t = threading.Thread(target=open)
t.daemon = True; t.start() t.daemon = True; t.start()
auto_opentab_delay() auto_opentab_delay()
demo.title = "ChatGPT 学术优化" demo.title = "ChatGPT 学术优化"
demo.queue().launch(server_name="0.0.0.0", share=True, server_port=PORT) demo.queue(concurrency_count=CONCURRENT_COUNT).launch(server_name="0.0.0.0", share=True, server_port=PORT, auth=AUTHENTICATION)
# -> 代码控制在100行以内
+19 -5
View File
@@ -1,5 +1,16 @@
# 借鉴了 https://github.com/GaiZhenbiao/ChuanhuChatGPT 项目 # 借鉴了 https://github.com/GaiZhenbiao/ChuanhuChatGPT 项目
"""
该文件中主要包含三个函数
不具备多线程能力的函数
1. predict: 正常对话时使用具备完备的交互功能不可多线程
具备多线程调用能力的函数
2. predict_no_ui高级实验性功能模块调用不会实时显示在界面上参数简单可以多线程并行方便实现复杂的功能逻辑
3. predict_no_ui_long_connection在实验过程中发现调用predict_no_ui处理长文档时和openai的连接容易断掉这个函数用stream的方式解决这个问题同样支持多线程
"""
import json import json
import gradio as gr import gradio as gr
import logging import logging
@@ -9,10 +20,12 @@ import importlib
# config_private.py放自己的秘密如API和代理网址 # config_private.py放自己的秘密如API和代理网址
# 读取时首先看是否存在私密的config_private配置文件(不受git管控),如果有,则覆盖原config文件 # 读取时首先看是否存在私密的config_private配置文件(不受git管控),如果有,则覆盖原config文件
try: from config_private import proxies, API_URL, API_KEY, TIMEOUT_SECONDS, MAX_RETRY, LLM_MODEL from toolbox import get_conf
except: from config import proxies, API_URL, API_KEY, TIMEOUT_SECONDS, MAX_RETRY, LLM_MODEL proxies, API_URL, API_KEY, TIMEOUT_SECONDS, MAX_RETRY, LLM_MODEL = \
get_conf('proxies', 'API_URL', 'API_KEY', 'TIMEOUT_SECONDS', 'MAX_RETRY', 'LLM_MODEL')
timeout_bot_msg = '[local] Request timeout, network error. please check proxy settings in config.py.' timeout_bot_msg = '[Local Message] Request timeout. Network error. Please check proxy settings in config.py.' + \
'网络错误,检查代理服务器是否可用,以及代理设置的格式是否正确,格式须是[协议]://[地址]:[端口],缺一不可。'
def get_full_error(chunk, stream_response): def get_full_error(chunk, stream_response):
""" """
@@ -106,8 +119,9 @@ def predict(inputs, top_p, temperature, chatbot=[], history=[], system_prompt=''
""" """
if additional_fn is not None: if additional_fn is not None:
import functional import functional
importlib.reload(functional) importlib.reload(functional) # 热更新prompt
functional = functional.get_functionals() functional = functional.get_functionals()
if "PreProcess" in functional[additional_fn]: inputs = functional[additional_fn]["PreProcess"](inputs) # 获取预处理函数(如果有的话)
inputs = functional[additional_fn]["Prefix"] + inputs + functional[additional_fn]["Suffix"] inputs = functional[additional_fn]["Prefix"] + inputs + functional[additional_fn]["Suffix"]
if stream: if stream:
@@ -165,7 +179,7 @@ def predict(inputs, top_p, temperature, chatbot=[], history=[], system_prompt=''
chunk = get_full_error(chunk, stream_response) chunk = get_full_error(chunk, stream_response)
error_msg = chunk.decode() error_msg = chunk.decode()
if "reduce the length" in error_msg: if "reduce the length" in error_msg:
chatbot[-1] = (chatbot[-1][0], "[Local Message] Input (or history) is too long, please reduce input or clear history by refleshing this page.") chatbot[-1] = (chatbot[-1][0], "[Local Message] Input (or history) is too long, please reduce input or clear history by refreshing this page.")
history = [] history = []
elif "Incorrect API key" in error_msg: elif "Incorrect API key" in error_msg:
chatbot[-1] = (chatbot[-1][0], "[Local Message] Incorrect API key provided.") chatbot[-1] = (chatbot[-1][0], "[Local Message] Incorrect API key provided.")
+2 -2
View File
@@ -1,5 +1,5 @@
# chatgpt-academic项目分析报告 # chatgpt-academic项目自译解报告
(Author补充:以下分析均由本项目调用ChatGPT一键生成,如果有不准确的地方全怪GPT) (Author补充:以下分析均由本项目调用ChatGPT一键生成,如果有不准确的地方全怪GPT😄
## [0/10] 程序摘要: check_proxy.py ## [0/10] 程序摘要: check_proxy.py
+43 -13
View File
@@ -1,4 +1,4 @@
import markdown, mdtex2html, threading import markdown, mdtex2html, threading, importlib, traceback, importlib, inspect
from show_math import convert as convert_math from show_math import convert as convert_math
from functools import wraps from functools import wraps
@@ -7,14 +7,14 @@ def predict_no_ui_but_counting_down(i_say, i_say_show_user, chatbot, top_p, temp
调用简单的predict_no_ui接口但是依然保留了些许界面心跳功能当对话太长时会自动采用二分法截断 调用简单的predict_no_ui接口但是依然保留了些许界面心跳功能当对话太长时会自动采用二分法截断
""" """
import time import time
try: from config_private import TIMEOUT_SECONDS, MAX_RETRY
except: from config import TIMEOUT_SECONDS, MAX_RETRY
from predict import predict_no_ui from predict import predict_no_ui
from toolbox import get_conf
TIMEOUT_SECONDS, MAX_RETRY = get_conf('TIMEOUT_SECONDS', 'MAX_RETRY')
# 多线程的时候,需要一个mutable结构在不同线程之间传递信息 # 多线程的时候,需要一个mutable结构在不同线程之间传递信息
# list就是最简单的mutable结构,我们第一个位置放gpt输出,第二个位置传递报错信息 # list就是最简单的mutable结构,我们第一个位置放gpt输出,第二个位置传递报错信息
mutable = [None, ''] mutable = [None, '']
# multi-threading worker # multi-threading worker
def mt(i_say, history): def mt(i_say, history):
while True: while True:
try: try:
mutable[0] = predict_no_ui(inputs=i_say, top_p=top_p, temperature=temperature, history=history, sys_prompt=sys_prompt) mutable[0] = predict_no_ui(inputs=i_say, top_p=top_p, temperature=temperature, history=history, sys_prompt=sys_prompt)
@@ -80,15 +80,25 @@ def CatchException(f):
try: try:
yield from f(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT) yield from f(txt, top_p, temperature, chatbot, history, systemPromptTxt, WEB_PORT)
except Exception as e: except Exception as e:
import traceback
from check_proxy import check_proxy from check_proxy import check_proxy
try: from config_private import proxies from toolbox import get_conf
except: from config import proxies proxies, = get_conf('proxies')
tb_str = regular_txt_to_markdown(traceback.format_exc()) tb_str = regular_txt_to_markdown(traceback.format_exc())
chatbot[-1] = (chatbot[-1][0], f"[Local Message] 实验性函数调用出错: \n\n {tb_str} \n\n 当前代理可用性: \n\n {check_proxy(proxies)}") chatbot[-1] = (chatbot[-1][0], f"[Local Message] 实验性函数调用出错: \n\n {tb_str} \n\n 当前代理可用性: \n\n {check_proxy(proxies)}")
yield chatbot, history, f'异常 {e}' yield chatbot, history, f'异常 {e}'
return decorated return decorated
def HotReload(f):
"""
装饰器函数实现函数插件热更新
"""
@wraps(f)
def decorated(*args, **kwargs):
fn_name = f.__name__
f_hot_reload = getattr(importlib.reload(inspect.getmodule(f)), fn_name)
yield from f_hot_reload(*args, **kwargs)
return decorated
def report_execption(chatbot, history, a, b): def report_execption(chatbot, history, a, b):
""" """
向chatbot中添加错误信息 向chatbot中添加错误信息
@@ -107,8 +117,8 @@ def text_divide_paragraph(text):
# wtf input # wtf input
lines = text.split("\n") lines = text.split("\n")
for i, line in enumerate(lines): for i, line in enumerate(lines):
if i!=0: lines[i] = "<p>"+lines[i].replace(" ", "&nbsp;")+"</p>" lines[i] = lines[i].replace(" ", "&nbsp;")
text = "".join(lines) text = "</br>".join(lines)
return text return text
def markdown_convertion(txt): def markdown_convertion(txt):
@@ -126,7 +136,7 @@ def format_io(self, y):
""" """
将输入和输出解析为HTML格式将y中最后一项的输入部分段落化并将输出部分的Markdown和数学公式转换为HTML格式 将输入和输出解析为HTML格式将y中最后一项的输入部分段落化并将输出部分的Markdown和数学公式转换为HTML格式
""" """
if y is None: return [] if y is None or y == []: return []
i_ask, gpt_reply = y[-1] i_ask, gpt_reply = y[-1]
i_ask = text_divide_paragraph(i_ask) # 输入部分太自由,预处理一波 i_ask = text_divide_paragraph(i_ask) # 输入部分太自由,预处理一波
y[-1] = ( y[-1] = (
@@ -146,7 +156,7 @@ def find_free_port():
s.bind(('', 0)) s.bind(('', 0))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
return s.getsockname()[1] return s.getsockname()[1]
def extract_archive(file_path, dest_dir): def extract_archive(file_path, dest_dir):
import zipfile import zipfile
@@ -167,7 +177,7 @@ def extract_archive(file_path, dest_dir):
print("Successfully extracted tar archive to {}".format(dest_dir)) print("Successfully extracted tar archive to {}".format(dest_dir))
else: else:
return return
def find_recent_files(directory): def find_recent_files(directory):
""" """
me: find files that is created with in one minutes under a directory with python, write a function me: find files that is created with in one minutes under a directory with python, write a function
@@ -184,6 +194,7 @@ def find_recent_files(directory):
if file_path.endswith('.log'): continue if file_path.endswith('.log'): continue
created_time = os.path.getctime(file_path) created_time = os.path.getctime(file_path)
if created_time >= one_minute_ago: if created_time >= one_minute_ago:
if os.path.isdir(file_path): continue
recent_files.append(file_path) recent_files.append(file_path)
return recent_files return recent_files
@@ -206,7 +217,7 @@ def on_file_uploaded(files, chatbot, txt):
txt = f'private_upload/{time_tag}' txt = f'private_upload/{time_tag}'
moved_files_str = '\t\n\n'.join(moved_files) moved_files_str = '\t\n\n'.join(moved_files)
chatbot.append(['我上传了文件,请查收', chatbot.append(['我上传了文件,请查收',
f'[Local Message] 收到以下文件: \n\n{moved_files_str}\n\n调用路径参数已自动修正到: \n\n{txt}\n\n现在您可以直接选择任意实现性功能']) f'[Local Message] 收到以下文件: \n\n{moved_files_str}\n\n调用路径参数已自动修正到: \n\n{txt}\n\n现在您点击任意实验功能时,以上文件将被作为输入参数'])
return chatbot, txt return chatbot, txt
@@ -217,3 +228,22 @@ def on_report_generated(files, chatbot):
# files.extend(report_files) # files.extend(report_files)
chatbot.append(['汇总报告如何远程获取?', '汇总报告已经添加到右侧文件上传区,请查收。']) chatbot.append(['汇总报告如何远程获取?', '汇总报告已经添加到右侧文件上传区,请查收。'])
return report_files, chatbot return report_files, chatbot
def get_conf(*args):
# 建议您复制一个config_private.py放自己的秘密, 如API和代理网址, 避免不小心传github被别人看到
res = []
for arg in args:
try: r = getattr(importlib.import_module('config_private'), arg)
except: r = getattr(importlib.import_module('config'), arg)
res.append(r)
# 在读取API_KEY时,检查一下是不是忘了改config
if arg=='API_KEY' and len(r) != 51:
assert False, "正确的API_KEY密钥是51位,请在config文件中修改API密钥, 添加海外代理之后再运行。" + \
"(如果您刚更新过代码,请确保旧版config_private文件中没有遗留任何新增键值)"
return res
def clear_line_break(txt):
txt = txt.replace('\n', ' ')
txt = txt.replace(' ', ' ')
txt = txt.replace(' ', ' ')
return txt