Commit
•
e84694a
1
Parent(s):
54f9595
Upload 22 files
Browse files- README.md +2 -2
- app.py +2 -1
- assets/Kelpy-Codos.js +76 -0
- assets/custom.js +1 -0
- assets/favicon.ico +0 -0
- custom.css +14 -36
- overwrites.py +19 -2
- presets.py +1 -1
- run_Linux.sh +25 -0
- run_Windows.bat +5 -0
- run_macOS.command +25 -0
- utils.py +3 -0
README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
---
|
2 |
title: ChuanhuChatGPT
|
3 |
-
emoji:
|
4 |
colorFrom: blue
|
5 |
colorTo: red
|
6 |
sdk: gradio
|
7 |
-
sdk_version: 3.
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
license: gpl-3.0
|
|
|
1 |
---
|
2 |
title: ChuanhuChatGPT
|
3 |
+
emoji: 🐠
|
4 |
colorFrom: blue
|
5 |
colorTo: red
|
6 |
sdk: gradio
|
7 |
+
sdk_version: 3.23.0
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
license: gpl-3.0
|
app.py
CHANGED
@@ -434,6 +434,7 @@ logging.info(
|
|
434 |
demo.title = "川虎ChatGPT 🚀"
|
435 |
|
436 |
if __name__ == "__main__":
|
|
|
437 |
# if running in Docker
|
438 |
if dockerflag:
|
439 |
if authflag:
|
@@ -448,7 +449,7 @@ if __name__ == "__main__":
|
|
448 |
if authflag:
|
449 |
demo.queue().launch(share=False, auth=(username, password), favicon_path="./assets/favicon.png", inbrowser=True)
|
450 |
else:
|
451 |
-
demo.queue().launch(share=False, favicon_path="./assets/favicon.
|
452 |
# demo.queue().launch(server_name="0.0.0.0", server_port=7860, share=False) # 可自定义端口
|
453 |
# demo.queue().launch(server_name="0.0.0.0", server_port=7860,auth=("在这里填写用户名", "在这里填写密码")) # 可设置用户名与密码
|
454 |
# demo.queue().launch(auth=("在这里填写用户名", "在这里填写密码")) # 适合Nginx反向代理
|
|
|
434 |
demo.title = "川虎ChatGPT 🚀"
|
435 |
|
436 |
if __name__ == "__main__":
|
437 |
+
reload_javascript()
|
438 |
# if running in Docker
|
439 |
if dockerflag:
|
440 |
if authflag:
|
|
|
449 |
if authflag:
|
450 |
demo.queue().launch(share=False, auth=(username, password), favicon_path="./assets/favicon.png", inbrowser=True)
|
451 |
else:
|
452 |
+
demo.queue().launch(share=False, favicon_path="./assets/favicon.ico", inbrowser=True) # 改为 share=True 可以创建公开分享链接
|
453 |
# demo.queue().launch(server_name="0.0.0.0", server_port=7860, share=False) # 可自定义端口
|
454 |
# demo.queue().launch(server_name="0.0.0.0", server_port=7860,auth=("在这里填写用户名", "在这里填写密码")) # 可设置用户名与密码
|
455 |
# demo.queue().launch(auth=("在这里填写用户名", "在这里填写密码")) # 适合Nginx反向代理
|
assets/Kelpy-Codos.js
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// ==UserScript==
|
2 |
+
// @name Kelpy Codos
|
3 |
+
// @namespace https://github.com/Keldos-Li/Kelpy-Codos
|
4 |
+
// @version 1.0.5
|
5 |
+
// @author Keldos; https://keldos.me/
|
6 |
+
// @description Add copy button to PRE tags before CODE tag, for Chuanhu ChatGPT especially.
|
7 |
+
// Based on Chuanhu ChatGPT version: ac04408 (2023-3-22)
|
8 |
+
// @license GPL-3.0
|
9 |
+
// @grant none
|
10 |
+
// ==/UserScript==
|
11 |
+
|
12 |
+
(function () {
|
13 |
+
'use strict';
|
14 |
+
|
15 |
+
function addCopyButton(pre) {
|
16 |
+
var code = pre.querySelector('code');
|
17 |
+
if (!code) {
|
18 |
+
return; // 如果没有找到 <code> 元素,则不添加按钮
|
19 |
+
}
|
20 |
+
var firstChild = code.firstChild;
|
21 |
+
if (!firstChild) {
|
22 |
+
return; // 如果 <code> 元素没有子节点,则不添加按钮
|
23 |
+
}
|
24 |
+
var button = document.createElement('button');
|
25 |
+
button.textContent = '\uD83D\uDCCE'; // 使用 📎 符号作为“复制”按钮的文本
|
26 |
+
button.style.position = 'relative';
|
27 |
+
button.style.float = 'right';
|
28 |
+
button.style.fontSize = '1em'; // 可选:调整按钮大小
|
29 |
+
button.style.background = 'none'; // 可选:去掉背景颜色
|
30 |
+
button.style.border = 'none'; // 可选:去掉边框
|
31 |
+
button.style.cursor = 'pointer'; // 可选:显示指针样式
|
32 |
+
button.addEventListener('click', function () {
|
33 |
+
var range = document.createRange();
|
34 |
+
range.selectNodeContents(code);
|
35 |
+
range.setStartBefore(firstChild); // 将范围设置为第一个子节点之前
|
36 |
+
var selection = window.getSelection();
|
37 |
+
selection.removeAllRanges();
|
38 |
+
selection.addRange(range);
|
39 |
+
|
40 |
+
try {
|
41 |
+
var success = document.execCommand('copy');
|
42 |
+
if (success) {
|
43 |
+
button.textContent = '\u2714';
|
44 |
+
setTimeout(function () {
|
45 |
+
button.textContent = '\uD83D\uDCCE'; // 恢复按钮为“复制”
|
46 |
+
}, 2000);
|
47 |
+
} else {
|
48 |
+
button.textContent = '\u2716';
|
49 |
+
}
|
50 |
+
} catch (e) {
|
51 |
+
console.error(e);
|
52 |
+
button.textContent = '\u2716';
|
53 |
+
}
|
54 |
+
|
55 |
+
selection.removeAllRanges();
|
56 |
+
});
|
57 |
+
code.insertBefore(button, firstChild); // 将按钮插入到第一个子元素之前
|
58 |
+
}
|
59 |
+
|
60 |
+
function handleNewElements(mutationsList, observer) {
|
61 |
+
for (var mutation of mutationsList) {
|
62 |
+
if (mutation.type === 'childList') {
|
63 |
+
for (var node of mutation.addedNodes) {
|
64 |
+
if (node.nodeName === 'PRE') {
|
65 |
+
addCopyButton(node);
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
var observer = new MutationObserver(handleNewElements);
|
73 |
+
observer.observe(document.documentElement, { childList: true, subtree: true });
|
74 |
+
|
75 |
+
document.querySelectorAll('pre').forEach(addCopyButton);
|
76 |
+
})();
|
assets/custom.js
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
// custom javascript here
|
assets/favicon.ico
ADDED
|
custom.css
CHANGED
@@ -19,45 +19,21 @@
|
|
19 |
#chuanhu_chatbot, #status_display {
|
20 |
transition: all 0.6s;
|
21 |
}
|
22 |
-
|
23 |
-
ol, ul {
|
24 |
-
|
25 |
-
padding-left: 0;
|
26 |
-
}
|
27 |
-
|
28 |
-
ol li, ul:not(.options) li {
|
29 |
-
padding-left: 1.5em;
|
30 |
-
text-indent: -1.5em;
|
31 |
}
|
32 |
|
33 |
/* 亮色 */
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
background-color: #95EC69 !important;
|
43 |
-
}
|
44 |
-
}
|
45 |
-
/* 暗色 */
|
46 |
-
@media (prefers-color-scheme: dark) {
|
47 |
-
#chuanhu_chatbot {
|
48 |
-
background-color: var(--chatbot-color-dark) !important;
|
49 |
-
}
|
50 |
-
[data-testid = "bot"] {
|
51 |
-
background-color: #2C2C2C !important;
|
52 |
-
}
|
53 |
-
[data-testid = "user"] {
|
54 |
-
background-color: #26B561 !important;
|
55 |
-
}
|
56 |
-
body {
|
57 |
-
background-color: var(--neutral-950) !important;
|
58 |
-
}
|
59 |
}
|
60 |
-
|
61 |
/* 对话气泡 */
|
62 |
[class *= "message"] {
|
63 |
border-radius: var(--radius-xl) !important;
|
@@ -65,6 +41,8 @@ ol li, ul:not(.options) li {
|
|
65 |
padding: var(--spacing-xl) !important;
|
66 |
font-size: var(--text-md) !important;
|
67 |
line-height: var(--line-md) !important;
|
|
|
|
|
68 |
}
|
69 |
[data-testid = "bot"] {
|
70 |
max-width: 85%;
|
@@ -107,7 +85,7 @@ pre code {
|
|
107 |
white-space: pre;
|
108 |
background-color: hsla(0, 0%, 0%, 80%)!important;
|
109 |
border-radius: 10px;
|
110 |
-
padding:
|
111 |
margin: 1.2em 2em 1.2em 0.5em;
|
112 |
color: #FFF;
|
113 |
box-shadow: 6px 6px 16px hsla(0, 0%, 0%, 0.2);
|
|
|
19 |
#chuanhu_chatbot, #status_display {
|
20 |
transition: all 0.6s;
|
21 |
}
|
22 |
+
/* list */
|
23 |
+
ol:not(.options), ul:not(.options) {
|
24 |
+
padding-inline-start: 2em !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
|
27 |
/* 亮色 */
|
28 |
+
#chuanhu_chatbot {
|
29 |
+
background-color: var(--chatbot-color-light) !important;
|
30 |
+
}
|
31 |
+
[data-testid = "bot"] {
|
32 |
+
background-color: #FFFFFF !important;
|
33 |
+
}
|
34 |
+
[data-testid = "user"] {
|
35 |
+
background-color: #95EC69 !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
}
|
|
|
37 |
/* 对话气泡 */
|
38 |
[class *= "message"] {
|
39 |
border-radius: var(--radius-xl) !important;
|
|
|
41 |
padding: var(--spacing-xl) !important;
|
42 |
font-size: var(--text-md) !important;
|
43 |
line-height: var(--line-md) !important;
|
44 |
+
min-height: calc(var(--text-md)*var(--line-md) + 2*var(--spacing-xl));
|
45 |
+
min-width: calc(var(--text-md)*var(--line-md) + 2*var(--spacing-xl));
|
46 |
}
|
47 |
[data-testid = "bot"] {
|
48 |
max-width: 85%;
|
|
|
85 |
white-space: pre;
|
86 |
background-color: hsla(0, 0%, 0%, 80%)!important;
|
87 |
border-radius: 10px;
|
88 |
+
padding: 1.4em 1.2em 0em 1.4em;
|
89 |
margin: 1.2em 2em 1.2em 0.5em;
|
90 |
color: #FFF;
|
91 |
box-shadow: 6px 6px 16px hsla(0, 0%, 0%, 0.2);
|
overwrites.py
CHANGED
@@ -32,7 +32,24 @@ def postprocess(
|
|
32 |
return []
|
33 |
tag_regex = re.compile(r"^<\w+>[^<]+</\w+>")
|
34 |
if tag_regex.search(y[-1][1]):
|
35 |
-
y[-1] = (y[-1][0]
|
36 |
else:
|
37 |
-
y[-1] = (y[-1][0]
|
38 |
return y
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
return []
|
33 |
tag_regex = re.compile(r"^<\w+>[^<]+</\w+>")
|
34 |
if tag_regex.search(y[-1][1]):
|
35 |
+
y[-1] = (convert_user(y[-1][0]), y[-1][1])
|
36 |
else:
|
37 |
+
y[-1] = (convert_user(y[-1][0]), convert_mdtext(y[-1][1]))
|
38 |
return y
|
39 |
+
|
40 |
+
with open("./assets/custom.js", "r", encoding="utf-8") as f, open("./assets/Kelpy-Codos.js", "r", encoding="utf-8") as f2:
|
41 |
+
customJS = f.read()
|
42 |
+
kelpyCodos = f2.read()
|
43 |
+
|
44 |
+
def reload_javascript():
|
45 |
+
print("Reloading javascript...")
|
46 |
+
js = f'<script>{customJS}</script><script>{kelpyCodos}</script>'
|
47 |
+
def template_response(*args, **kwargs):
|
48 |
+
res = GradioTemplateResponseOriginal(*args, **kwargs)
|
49 |
+
res.body = res.body.replace(b'</html>', f'{js}</html>'.encode("utf8"))
|
50 |
+
res.init_headers()
|
51 |
+
return res
|
52 |
+
|
53 |
+
gr.routes.templates.TemplateResponse = template_response
|
54 |
+
|
55 |
+
GradioTemplateResponseOriginal = gr.routes.templates.TemplateResponse
|
presets.py
CHANGED
@@ -16,7 +16,7 @@ ssl_error_prompt = "SSL错误,无法获取对话。" # SSL 错误
|
|
16 |
no_apikey_msg = "API key长度不是51位,请检查是否输入正确。" # API key 长度不足 51 位
|
17 |
|
18 |
max_token_streaming = 3500 # 流式对话时的最大 token 数
|
19 |
-
timeout_streaming =
|
20 |
max_token_all = 3500 # 非流式对话时的最大 token 数
|
21 |
timeout_all = 200 # 非流式对话时的超时时间
|
22 |
enable_streaming_option = True # 是否启用选择选择是否实时显示回答的勾选框
|
|
|
16 |
no_apikey_msg = "API key长度不是51位,请检查是否输入正确。" # API key 长度不足 51 位
|
17 |
|
18 |
max_token_streaming = 3500 # 流式对话时的最大 token 数
|
19 |
+
timeout_streaming = 5 # 流式对话时的超时时间
|
20 |
max_token_all = 3500 # 非流式对话时的最大 token 数
|
21 |
timeout_all = 200 # 非流式对话时的超时时间
|
22 |
enable_streaming_option = True # 是否启用选择选择是否实时显示回答的勾选框
|
run_Linux.sh
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
# 获取脚本所在目录
|
4 |
+
script_dir=$(dirname "$0")
|
5 |
+
|
6 |
+
# 将工作目录更改为脚本所在目录
|
7 |
+
cd "$script_dir"
|
8 |
+
|
9 |
+
# 检查Git仓库是否有更新
|
10 |
+
git remote update
|
11 |
+
pwd
|
12 |
+
|
13 |
+
if ! git status -uno | grep 'up to date' > /dev/null; then
|
14 |
+
# 如果有更新,关闭当前运行的服务器
|
15 |
+
pkill -f ChuanhuChatbot.py
|
16 |
+
|
17 |
+
# 拉取最新更改
|
18 |
+
git pull
|
19 |
+
|
20 |
+
# 安装依赖
|
21 |
+
pip3 install -r requirements.txt
|
22 |
+
|
23 |
+
# 重新启动服务器
|
24 |
+
nohup python3 ChuanhuChatbot.py &
|
25 |
+
fi
|
run_Windows.bat
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@echo off
|
2 |
+
echo Opening ChuanhuChatGPT...
|
3 |
+
|
4 |
+
REM Open powershell via bat
|
5 |
+
start powershell.exe -NoExit -Command "python ./ChuanhuChatbot.py"
|
run_macOS.command
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
# 获取脚本所在目录
|
4 |
+
script_dir=$(dirname "$0")
|
5 |
+
|
6 |
+
# 将工作目录更改为脚本所在目录
|
7 |
+
cd "$script_dir"
|
8 |
+
|
9 |
+
# 检查Git仓库是否有更新
|
10 |
+
git remote update
|
11 |
+
pwd
|
12 |
+
|
13 |
+
if ! git status -uno | grep 'up to date' > /dev/null; then
|
14 |
+
# 如果有更新,关闭当前运行的服务器
|
15 |
+
pkill -f ChuanhuChatbot.py
|
16 |
+
|
17 |
+
# 拉取最新更改
|
18 |
+
git pull
|
19 |
+
|
20 |
+
# 安装依赖
|
21 |
+
pip3 install -r requirements.txt
|
22 |
+
|
23 |
+
# 重新启动服务器
|
24 |
+
nohup python3 ChuanhuChatbot.py &
|
25 |
+
fi
|
utils.py
CHANGED
@@ -107,6 +107,9 @@ def convert_mdtext(md_text):
|
|
107 |
result = "".join(result)
|
108 |
return result
|
109 |
|
|
|
|
|
|
|
110 |
|
111 |
def detect_language(code):
|
112 |
if code.startswith("\n"):
|
|
|
107 |
result = "".join(result)
|
108 |
return result
|
109 |
|
110 |
+
def convert_user(userinput):
|
111 |
+
userinput = userinput.replace("\n", "<br>")
|
112 |
+
return f"<pre>{userinput}</pre>"
|
113 |
|
114 |
def detect_language(code):
|
115 |
if code.startswith("\n"):
|