Spaces:
Running
Running
vlffζι£ι£
commited on
Commit
β’
b53a832
1
Parent(s):
68743ec
add data from backblaze
Browse files- .gitignore +1 -1
- Dockerfile +1 -1
- qwen_server/__init__.py β __init__.py +0 -0
- qwen_server/assistant_server.py β assistant_server.py +29 -92
- browser_qwen/background.js +3 -4
- browser_qwen/manifest.json +4 -1
- browser_qwen/src/md5.js +1 -0
- browser_qwen/src/popup.html +1 -0
- browser_qwen/src/popup.js +33 -31
- {qwen_server/css β css}/main.css +0 -0
- qwen_server/database_server.py β database_server.py +22 -93
- {qwen_server/img β img}/logo.png +0 -0
- {qwen_server/js β js}/main.js +0 -0
- qwen_agent/llm/__init__.py +0 -10
- qwen_agent/llm/qwen_oai.py +3 -4
- qwen_server/add_qwen_libs.py +0 -5
- qwen_server/server_config.json +0 -1
- qwen_server/server_config_ε―ζ¬.json +0 -1
- requirements.txt +1 -1
- run_server.py +0 -146
- qwen_server/schema.py β schema.py +0 -20
- qwen_server/utils.py β utils.py +108 -47
- qwen_server/workstation_server.py β workstation_server.py +56 -53
.gitignore
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
env
|
2 |
*.pyc
|
3 |
__pycache__
|
4 |
-
|
5 |
.idea
|
6 |
.vscode
|
7 |
.DS_Store
|
|
|
1 |
env
|
2 |
*.pyc
|
3 |
__pycache__
|
4 |
+
.env
|
5 |
.idea
|
6 |
.vscode
|
7 |
.DS_Store
|
Dockerfile
CHANGED
@@ -12,4 +12,4 @@ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
|
12 |
COPY . .
|
13 |
RUN mkdir -p .cache/huggingface/models--Qwen--Qwen-1_8B-Chat && mkdir -p ./.cache/huggingface/models--Qwen--Qwen-1_8B-Chat
|
14 |
RUN chmod 777 -R ./* && chmod 777 -R ./.cache/*
|
15 |
-
CMD ["python", "
|
|
|
12 |
COPY . .
|
13 |
RUN mkdir -p .cache/huggingface/models--Qwen--Qwen-1_8B-Chat && mkdir -p ./.cache/huggingface/models--Qwen--Qwen-1_8B-Chat
|
14 |
RUN chmod 777 -R ./* && chmod 777 -R ./.cache/*
|
15 |
+
CMD ["python", "database_server.py"]
|
qwen_server/__init__.py β __init__.py
RENAMED
File without changes
|
qwen_server/assistant_server.py β assistant_server.py
RENAMED
@@ -1,37 +1,19 @@
|
|
1 |
import json
|
2 |
import os
|
3 |
from pathlib import Path
|
4 |
-
|
5 |
-
import add_qwen_libs # NOQA
|
6 |
import gradio as gr
|
7 |
import jsonlines
|
8 |
-
from schema import GlobalConfig
|
9 |
-
|
10 |
from qwen_agent.actions import RetrievalQA
|
11 |
-
from qwen_agent.llm import
|
12 |
-
from qwen_agent.log import logger
|
13 |
from qwen_agent.memory import Memory
|
|
|
14 |
|
15 |
-
|
16 |
-
with open(Path(__file__).resolve().parent / 'server_config.json', 'r') as f:
|
17 |
-
server_config = json.load(f)
|
18 |
-
server_config = GlobalConfig(**server_config)
|
19 |
-
|
20 |
-
llm = get_chat_model(model=server_config.server.llm,
|
21 |
-
api_key=server_config.server.api_key,
|
22 |
-
model_server=server_config.server.model_server)
|
23 |
-
|
24 |
mem = Memory(llm=llm, stream=False)
|
25 |
|
26 |
-
|
27 |
-
cache_file_popup_url = os.path.join(server_config.path.cache_root, 'popup_url.jsonl')
|
28 |
-
access_token_file = os.path.join(server_config.path.cache_root, 'access_token.jsonl')
|
29 |
-
|
30 |
-
PAGE_URL = {}
|
31 |
-
|
32 |
-
with open(Path(__file__).resolve().parent / 'css/main.css', 'r') as f:
|
33 |
css = f.read()
|
34 |
-
with open(
|
35 |
js = f.read()
|
36 |
|
37 |
|
@@ -55,52 +37,31 @@ def add_file(history, file):
|
|
55 |
return history
|
56 |
|
57 |
|
58 |
-
def set_page_url(access_token):
|
59 |
-
lines = {access_token: []}
|
60 |
-
assert os.path.exists(cache_file_popup_url)
|
61 |
-
for line in jsonlines.open(cache_file_popup_url):
|
62 |
-
_access_token = line['access_token']
|
63 |
-
if _access_token not in lines:
|
64 |
-
lines[_access_token] = []
|
65 |
-
lines[_access_token].append(line)
|
66 |
-
if access_token not in PAGE_URL:
|
67 |
-
PAGE_URL[access_token] = []
|
68 |
-
PAGE_URL[access_token].append(lines[access_token][-1]['url'])
|
69 |
-
logger.info('The current access page is: ' + PAGE_URL[access_token][-1])
|
70 |
-
|
71 |
-
|
72 |
def initialize(request: gr.Request):
|
73 |
-
|
|
|
|
|
74 |
is_valid = False
|
75 |
if access_token:
|
76 |
-
|
|
|
77 |
is_valid = True
|
78 |
-
else:
|
79 |
-
for line in jsonlines.open(access_token_file):
|
80 |
-
if line['access_token'] == access_token:
|
81 |
-
is_valid = True
|
82 |
-
break
|
83 |
if not is_valid:
|
84 |
gr.Info("The token is not valid, Please reset!")
|
85 |
return
|
86 |
-
|
87 |
-
return access_token
|
88 |
|
89 |
|
90 |
-
def bot(history, access_token):
|
91 |
-
set_page_url(access_token)
|
92 |
if not history:
|
93 |
yield history
|
94 |
else:
|
95 |
now_page = None
|
96 |
_ref = ''
|
97 |
-
if not
|
98 |
gr.Info("Please add this page to LLMBB's Reading List first!")
|
99 |
else:
|
100 |
-
|
101 |
-
if line["access_token"] == access_token and line['url'] == PAGE_URL[access_token][-1]:
|
102 |
-
now_page = line
|
103 |
-
|
104 |
if not now_page:
|
105 |
gr.Info(
|
106 |
"This page has not yet been added to the LLMBB's reading list!"
|
@@ -110,7 +71,7 @@ def bot(history, access_token):
|
|
110 |
else:
|
111 |
_ref_list = mem.get(
|
112 |
history[-1][0], [now_page],
|
113 |
-
max_token=
|
114 |
if _ref_list:
|
115 |
_ref = '\n'.join(
|
116 |
json.dumps(x, ensure_ascii=False) for x in _ref_list)
|
@@ -130,25 +91,15 @@ def bot(history, access_token):
|
|
130 |
# save history
|
131 |
if now_page:
|
132 |
now_page['session'] = history
|
133 |
-
|
134 |
-
for line in jsonlines.open(cache_file):
|
135 |
-
if line["access_token"] == access_token and line['url'] != PAGE_URL[access_token][-1]:
|
136 |
-
lines.append(line)
|
137 |
-
|
138 |
-
lines.append(now_page)
|
139 |
-
with jsonlines.open(cache_file, mode='w') as writer:
|
140 |
-
for new_line in lines:
|
141 |
-
writer.write(new_line)
|
142 |
|
143 |
|
144 |
-
def load_history_session(history, access_token):
|
145 |
now_page = None
|
146 |
-
if not
|
147 |
gr.Info("Please add this page to LLMBB's Reading List first!")
|
148 |
return []
|
149 |
-
|
150 |
-
if line["access_token"] == access_token and line['url'] == PAGE_URL[access_token][-1]:
|
151 |
-
now_page = line
|
152 |
if not now_page:
|
153 |
gr.Info("Please add this page to LLMBB's Reading List first!")
|
154 |
return []
|
@@ -158,35 +109,21 @@ def load_history_session(history, access_token):
|
|
158 |
return now_page['session']
|
159 |
|
160 |
|
161 |
-
def clear_session(access_token):
|
162 |
-
if not
|
163 |
return None
|
164 |
-
now_page =
|
165 |
-
lines = []
|
166 |
-
for line in jsonlines.open(cache_file):
|
167 |
-
if line["access_token"] == access_token and line['url'] == PAGE_URL[access_token][-1]:
|
168 |
-
now_page = line
|
169 |
-
else:
|
170 |
-
lines.append(line)
|
171 |
if not now_page:
|
172 |
return None
|
173 |
now_page['session'] = []
|
174 |
-
|
175 |
-
with jsonlines.open(cache_file, mode='w') as writer:
|
176 |
-
for new_line in lines:
|
177 |
-
writer.write(new_line)
|
178 |
-
|
179 |
return None
|
180 |
|
181 |
|
182 |
with gr.Blocks(css=css, theme='soft') as demo:
|
183 |
access_token = gr.State("")
|
184 |
-
|
185 |
-
|
186 |
-
height=480,
|
187 |
-
avatar_images=(None, (os.path.join(
|
188 |
-
Path(__file__).resolve().parent,
|
189 |
-
'img/logo.png'))))
|
190 |
with gr.Row():
|
191 |
with gr.Column(scale=7):
|
192 |
txt = gr.Textbox(show_label=False,
|
@@ -202,7 +139,7 @@ with gr.Blocks(css=css, theme='soft') as demo:
|
|
202 |
re_bt = gr.Button('π', elem_classes='bt_small_font')
|
203 |
|
204 |
txt_msg = txt.submit(add_text, [chatbot, txt], [chatbot, txt],
|
205 |
-
queue=False).then(bot, [chatbot, access_token], chatbot)
|
206 |
txt_msg.then(lambda: gr.update(interactive=True), None, [txt], queue=False)
|
207 |
|
208 |
# txt_msg_bt = smt_bt.click(add_text, [chatbot, txt], [chatbot, txt],
|
@@ -211,16 +148,16 @@ with gr.Blocks(css=css, theme='soft') as demo:
|
|
211 |
# None, [txt],
|
212 |
# queue=False)
|
213 |
|
214 |
-
clr_bt.click(clear_session, [access_token], chatbot, queue=False)
|
215 |
re_txt_msg = re_bt.click(rm_text, [chatbot], [chatbot, txt],
|
216 |
-
queue=False).then(bot, [chatbot, access_token], chatbot)
|
217 |
re_txt_msg.then(lambda: gr.update(interactive=True),
|
218 |
None, [txt],
|
219 |
queue=False)
|
220 |
|
221 |
stop_bt.click(None, None, None, cancels=[txt_msg, re_txt_msg], queue=False)
|
222 |
|
223 |
-
demo.load(initialize, [], [access_token]).then(load_history_session, [chatbot, access_token], chatbot)
|
224 |
demo.queue()
|
225 |
|
226 |
# demo.queue().launch(server_name=server_config.server.server_host, server_port=server_config.server.app_in_browser_port)
|
|
|
1 |
import json
|
2 |
import os
|
3 |
from pathlib import Path
|
|
|
|
|
4 |
import gradio as gr
|
5 |
import jsonlines
|
|
|
|
|
6 |
from qwen_agent.actions import RetrievalQA
|
7 |
+
from qwen_agent.llm import QwenChatAsOAI
|
|
|
8 |
from qwen_agent.memory import Memory
|
9 |
+
from utils import service, cache_file, max_ref_token
|
10 |
|
11 |
+
llm = QwenChatAsOAI(model="gpt-3.5-turbo")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
mem = Memory(llm=llm, stream=False)
|
13 |
|
14 |
+
with open('css/main.css', 'r') as f:
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
css = f.read()
|
16 |
+
with open('js/main.js', 'r') as f:
|
17 |
js = f.read()
|
18 |
|
19 |
|
|
|
37 |
return history
|
38 |
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
def initialize(request: gr.Request):
|
41 |
+
# print(request.kwargs)
|
42 |
+
access_token = request.query_params["access_token"]
|
43 |
+
url = request.query_params["url"]
|
44 |
is_valid = False
|
45 |
if access_token:
|
46 |
+
account_info = json.loads(service.get(access_token, "info.json", False))
|
47 |
+
if account_info and account_info["enabled"]:
|
48 |
is_valid = True
|
|
|
|
|
|
|
|
|
|
|
49 |
if not is_valid:
|
50 |
gr.Info("The token is not valid, Please reset!")
|
51 |
return
|
52 |
+
return access_token, url
|
|
|
53 |
|
54 |
|
55 |
+
def bot(history, access_token, page_url):
|
|
|
56 |
if not history:
|
57 |
yield history
|
58 |
else:
|
59 |
now_page = None
|
60 |
_ref = ''
|
61 |
+
if not service.exists(access_token, page_url):
|
62 |
gr.Info("Please add this page to LLMBB's Reading List first!")
|
63 |
else:
|
64 |
+
now_page = json.loads(service.get(access_token, page_url))
|
|
|
|
|
|
|
65 |
if not now_page:
|
66 |
gr.Info(
|
67 |
"This page has not yet been added to the LLMBB's reading list!"
|
|
|
71 |
else:
|
72 |
_ref_list = mem.get(
|
73 |
history[-1][0], [now_page],
|
74 |
+
max_token=max_ref_token)
|
75 |
if _ref_list:
|
76 |
_ref = '\n'.join(
|
77 |
json.dumps(x, ensure_ascii=False) for x in _ref_list)
|
|
|
91 |
# save history
|
92 |
if now_page:
|
93 |
now_page['session'] = history
|
94 |
+
service.upsert(access_token, page_url, json.dumps(now_page, ensure_ascii=False))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
|
96 |
|
97 |
+
def load_history_session(history, access_token, page_url):
|
98 |
now_page = None
|
99 |
+
if not service.exists(access_token, page_url):
|
100 |
gr.Info("Please add this page to LLMBB's Reading List first!")
|
101 |
return []
|
102 |
+
now_page = json.loads(service.get(access_token, page_url))
|
|
|
|
|
103 |
if not now_page:
|
104 |
gr.Info("Please add this page to LLMBB's Reading List first!")
|
105 |
return []
|
|
|
109 |
return now_page['session']
|
110 |
|
111 |
|
112 |
+
def clear_session(access_token, page_url):
|
113 |
+
if not service.exists(access_token, page_url):
|
114 |
return None
|
115 |
+
now_page = json.loads(service.get(access_token, page_url))
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
if not now_page:
|
117 |
return None
|
118 |
now_page['session'] = []
|
119 |
+
service.upsert(access_token, page_url, json.dumps(now_page, ensure_ascii=False))
|
|
|
|
|
|
|
|
|
120 |
return None
|
121 |
|
122 |
|
123 |
with gr.Blocks(css=css, theme='soft') as demo:
|
124 |
access_token = gr.State("")
|
125 |
+
page_url = gr.State("")
|
126 |
+
chatbot = gr.Chatbot([], elem_id='chatbot', height=480, avatar_images=(None, 'img/logo.png'))
|
|
|
|
|
|
|
|
|
127 |
with gr.Row():
|
128 |
with gr.Column(scale=7):
|
129 |
txt = gr.Textbox(show_label=False,
|
|
|
139 |
re_bt = gr.Button('π', elem_classes='bt_small_font')
|
140 |
|
141 |
txt_msg = txt.submit(add_text, [chatbot, txt], [chatbot, txt],
|
142 |
+
queue=False).then(bot, [chatbot, access_token, page_url], chatbot)
|
143 |
txt_msg.then(lambda: gr.update(interactive=True), None, [txt], queue=False)
|
144 |
|
145 |
# txt_msg_bt = smt_bt.click(add_text, [chatbot, txt], [chatbot, txt],
|
|
|
148 |
# None, [txt],
|
149 |
# queue=False)
|
150 |
|
151 |
+
clr_bt.click(clear_session, [access_token, page_url], chatbot, queue=False)
|
152 |
re_txt_msg = re_bt.click(rm_text, [chatbot], [chatbot, txt],
|
153 |
+
queue=False).then(bot, [chatbot, access_token, page_url], chatbot)
|
154 |
re_txt_msg.then(lambda: gr.update(interactive=True),
|
155 |
None, [txt],
|
156 |
queue=False)
|
157 |
|
158 |
stop_bt.click(None, None, None, cancels=[txt_msg, re_txt_msg], queue=False)
|
159 |
|
160 |
+
demo.load(initialize, [], [access_token, page_url]).then(load_history_session, [chatbot, access_token, page_url], chatbot)
|
161 |
demo.queue()
|
162 |
|
163 |
# demo.queue().launch(server_name=server_config.server.server_host, server_port=server_config.server.app_in_browser_port)
|
browser_qwen/background.js
CHANGED
@@ -1,11 +1,10 @@
|
|
1 |
-
var database_url;
|
2 |
-
|
3 |
function send_data(msg){
|
4 |
chrome.storage.local.get(['access_token'], function(result) {
|
5 |
console.log(result)
|
6 |
if (result.access_token) {
|
7 |
console.log('access_token currently is ' + result.access_token);
|
8 |
-
database_url = "https://llmbb-llmbb-agent.hf.space/endpoint";
|
9 |
fetch(database_url, {
|
10 |
method: "POST",
|
11 |
headers: {
|
@@ -15,7 +14,7 @@ function send_data(msg){
|
|
15 |
body: JSON.stringify(msg),
|
16 |
})
|
17 |
.then((response) => {
|
18 |
-
|
19 |
})
|
20 |
.then((data) => {
|
21 |
console.log(msg["task"])
|
|
|
1 |
+
//var database_url="http://127.0.0.1:7860/endpoint";
|
2 |
+
var database_url= "https://llmbb-llmbb-agent.hf.space/endpoint";
|
3 |
function send_data(msg){
|
4 |
chrome.storage.local.get(['access_token'], function(result) {
|
5 |
console.log(result)
|
6 |
if (result.access_token) {
|
7 |
console.log('access_token currently is ' + result.access_token);
|
|
|
8 |
fetch(database_url, {
|
9 |
method: "POST",
|
10 |
headers: {
|
|
|
14 |
body: JSON.stringify(msg),
|
15 |
})
|
16 |
.then((response) => {
|
17 |
+
return response.json();
|
18 |
})
|
19 |
.then((data) => {
|
20 |
console.log(msg["task"])
|
browser_qwen/manifest.json
CHANGED
@@ -32,7 +32,10 @@
|
|
32 |
},
|
33 |
"content_scripts": [
|
34 |
{
|
35 |
-
"js": [
|
|
|
|
|
|
|
36 |
"matches": [
|
37 |
"https://www.jianshu.com/p/*",
|
38 |
"https://*/*",
|
|
|
32 |
},
|
33 |
"content_scripts": [
|
34 |
{
|
35 |
+
"js": [
|
36 |
+
"src/content.js",
|
37 |
+
"src/md5.js"
|
38 |
+
],
|
39 |
"matches": [
|
40 |
"https://www.jianshu.com/p/*",
|
41 |
"https://*/*",
|
browser_qwen/src/md5.js
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
!function(n){"use strict";function d(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function f(n,t,r,e,o,u){return d((u=d(d(t,n),d(e,u)))<<o|u>>>32-o,r)}function l(n,t,r,e,o,u,c){return f(t&r|~t&e,n,t,o,u,c)}function g(n,t,r,e,o,u,c){return f(t&e|r&~e,n,t,o,u,c)}function v(n,t,r,e,o,u,c){return f(t^r^e,n,t,o,u,c)}function m(n,t,r,e,o,u,c){return f(r^(t|~e),n,t,o,u,c)}function c(n,t){var r,e,o,u;n[t>>5]|=128<<t%32,n[14+(t+64>>>9<<4)]=t;for(var c=1732584193,f=-271733879,i=-1732584194,a=271733878,h=0;h<n.length;h+=16)c=l(r=c,e=f,o=i,u=a,n[h],7,-680876936),a=l(a,c,f,i,n[h+1],12,-389564586),i=l(i,a,c,f,n[h+2],17,606105819),f=l(f,i,a,c,n[h+3],22,-1044525330),c=l(c,f,i,a,n[h+4],7,-176418897),a=l(a,c,f,i,n[h+5],12,1200080426),i=l(i,a,c,f,n[h+6],17,-1473231341),f=l(f,i,a,c,n[h+7],22,-45705983),c=l(c,f,i,a,n[h+8],7,1770035416),a=l(a,c,f,i,n[h+9],12,-1958414417),i=l(i,a,c,f,n[h+10],17,-42063),f=l(f,i,a,c,n[h+11],22,-1990404162),c=l(c,f,i,a,n[h+12],7,1804603682),a=l(a,c,f,i,n[h+13],12,-40341101),i=l(i,a,c,f,n[h+14],17,-1502002290),c=g(c,f=l(f,i,a,c,n[h+15],22,1236535329),i,a,n[h+1],5,-165796510),a=g(a,c,f,i,n[h+6],9,-1069501632),i=g(i,a,c,f,n[h+11],14,643717713),f=g(f,i,a,c,n[h],20,-373897302),c=g(c,f,i,a,n[h+5],5,-701558691),a=g(a,c,f,i,n[h+10],9,38016083),i=g(i,a,c,f,n[h+15],14,-660478335),f=g(f,i,a,c,n[h+4],20,-405537848),c=g(c,f,i,a,n[h+9],5,568446438),a=g(a,c,f,i,n[h+14],9,-1019803690),i=g(i,a,c,f,n[h+3],14,-187363961),f=g(f,i,a,c,n[h+8],20,1163531501),c=g(c,f,i,a,n[h+13],5,-1444681467),a=g(a,c,f,i,n[h+2],9,-51403784),i=g(i,a,c,f,n[h+7],14,1735328473),c=v(c,f=g(f,i,a,c,n[h+12],20,-1926607734),i,a,n[h+5],4,-378558),a=v(a,c,f,i,n[h+8],11,-2022574463),i=v(i,a,c,f,n[h+11],16,1839030562),f=v(f,i,a,c,n[h+14],23,-35309556),c=v(c,f,i,a,n[h+1],4,-1530992060),a=v(a,c,f,i,n[h+4],11,1272893353),i=v(i,a,c,f,n[h+7],16,-155497632),f=v(f,i,a,c,n[h+10],23,-1094730640),c=v(c,f,i,a,n[h+13],4,681279174),a=v(a,c,f,i,n[h],11,-358537222),i=v(i,a,c,f,n[h+3],16,-722521979),f=v(f,i,a,c,n[h+6],23,76029189),c=v(c,f,i,a,n[h+9],4,-640364487),a=v(a,c,f,i,n[h+12],11,-421815835),i=v(i,a,c,f,n[h+15],16,530742520),c=m(c,f=v(f,i,a,c,n[h+2],23,-995338651),i,a,n[h],6,-198630844),a=m(a,c,f,i,n[h+7],10,1126891415),i=m(i,a,c,f,n[h+14],15,-1416354905),f=m(f,i,a,c,n[h+5],21,-57434055),c=m(c,f,i,a,n[h+12],6,1700485571),a=m(a,c,f,i,n[h+3],10,-1894986606),i=m(i,a,c,f,n[h+10],15,-1051523),f=m(f,i,a,c,n[h+1],21,-2054922799),c=m(c,f,i,a,n[h+8],6,1873313359),a=m(a,c,f,i,n[h+15],10,-30611744),i=m(i,a,c,f,n[h+6],15,-1560198380),f=m(f,i,a,c,n[h+13],21,1309151649),c=m(c,f,i,a,n[h+4],6,-145523070),a=m(a,c,f,i,n[h+11],10,-1120210379),i=m(i,a,c,f,n[h+2],15,718787259),f=m(f,i,a,c,n[h+9],21,-343485551),c=d(c,r),f=d(f,e),i=d(i,o),a=d(a,u);return[c,f,i,a]}function i(n){for(var t="",r=32*n.length,e=0;e<r;e+=8)t+=String.fromCharCode(n[e>>5]>>>e%32&255);return t}function a(n){var t=[];for(t[(n.length>>2)-1]=void 0,e=0;e<t.length;e+=1)t[e]=0;for(var r=8*n.length,e=0;e<r;e+=8)t[e>>5]|=(255&n.charCodeAt(e/8))<<e%32;return t}function e(n){for(var t,r="0123456789abcdef",e="",o=0;o<n.length;o+=1)t=n.charCodeAt(o),e+=r.charAt(t>>>4&15)+r.charAt(15&t);return e}function r(n){return unescape(encodeURIComponent(n))}function o(n){return i(c(a(n=r(n)),8*n.length))}function u(n,t){return function(n,t){var r,e=a(n),o=[],u=[];for(o[15]=u[15]=void 0,16<e.length&&(e=c(e,8*n.length)),r=0;r<16;r+=1)o[r]=909522486^e[r],u[r]=1549556828^e[r];return t=c(o.concat(a(t)),512+8*t.length),i(c(u.concat(t),640))}(r(n),r(t))}function t(n,t,r){return t?r?u(t,n):e(u(t,n)):r?o(n):e(o(n))}"function"==typeof define&&define.amd?define(function(){return t}):"object"==typeof module&&module.exports?module.exports=t:n.md5=t}(this);
|
browser_qwen/src/popup.html
CHANGED
@@ -117,5 +117,6 @@
|
|
117 |
<button id="set_access_token" class="upload_btn">Change</button>
|
118 |
|
119 |
<script src="popup.js"></script>
|
|
|
120 |
</body>
|
121 |
</html>
|
|
|
117 |
<button id="set_access_token" class="upload_btn">Change</button>
|
118 |
|
119 |
<script src="popup.js"></script>
|
120 |
+
<script src="md5.js"></script>
|
121 |
</body>
|
122 |
</html>
|
browser_qwen/src/popup.js
CHANGED
@@ -1,45 +1,47 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
4 |
-
// if (msg.flag == 'from_content'){
|
5 |
-
// console.log(msg.rsp);
|
6 |
-
// var sessionContainer = document.getElementById('session');
|
7 |
-
// sessionContainer.innerText = msg.rsp;
|
8 |
-
// sendResponse({ msg: 'Get!' });
|
9 |
-
// }
|
10 |
-
if (msg.flag === 'from_llm'){
|
11 |
-
// var sessionContainer = document.getElementById('session');
|
12 |
-
// // sessionContainer.innerHTML = msg.rsp;
|
13 |
-
// sessionContainer.innerText = msg.rsp;
|
14 |
-
sendResponse({ message: 'Get Response!' });
|
15 |
-
}
|
16 |
-
});
|
17 |
-
|
18 |
-
|
19 |
document.addEventListener('DOMContentLoaded', function() {
|
20 |
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
|
21 |
-
|
22 |
-
|
23 |
-
chrome.runtime.sendMessage({ data: currentUrl , close: true , flag: 'open_popup_and_send_url_from_popup'});
|
24 |
-
|
25 |
-
});
|
26 |
-
setTimeout(function() {
|
27 |
-
console.log('This message will be logged after 0.5 second');
|
28 |
-
var popup_url='';
|
29 |
chrome.storage.local.get(['access_token'], function(result) {
|
30 |
if (result.access_token) {
|
31 |
console.log('access_token currently is ' + result.access_token);
|
32 |
-
popup_url = "https://llmbb-llmbb-agent.hf.space/?access_token="+result.access_token;
|
33 |
var iframe = document.createElement('iframe');
|
34 |
-
iframe.src =
|
35 |
iframe.height = '570px';
|
36 |
-
|
37 |
-
|
38 |
var iframe_area = document.getElementById('iframe_area')
|
39 |
iframe_area.appendChild(iframe);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
});
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
})
|
44 |
|
45 |
document.getElementById('set_access_token').addEventListener('click', function() {
|
|
|
1 |
+
//var assistant_url="http://127.0.0.1:7860/assistant/";
|
2 |
+
var assistant_url="https://llmbb-llmbb-agent.hf.space/assistant";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
document.addEventListener('DOMContentLoaded', function() {
|
4 |
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
|
5 |
+
var currentUrl = tabs[0].url;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
chrome.storage.local.get(['access_token'], function(result) {
|
7 |
if (result.access_token) {
|
8 |
console.log('access_token currently is ' + result.access_token);
|
|
|
9 |
var iframe = document.createElement('iframe');
|
10 |
+
iframe.src = assistant_url + "?access_token="+result.access_token+"&url=" + currentUrl;
|
11 |
iframe.height = '570px';
|
12 |
+
// iframe.sandbox = 'allow-same-origin allow-scripts';
|
13 |
+
// iframe.allow = "geolocation *;";
|
14 |
var iframe_area = document.getElementById('iframe_area')
|
15 |
iframe_area.appendChild(iframe);
|
16 |
+
}else{
|
17 |
+
chrome.notifications.create("access_token", {
|
18 |
+
type: 'basic',
|
19 |
+
iconUrl: 'img/popup.png',
|
20 |
+
title: 'access token',
|
21 |
+
message: 'access token is not validοΌ'
|
22 |
+
});
|
23 |
}
|
24 |
});
|
25 |
+
// chrome.runtime.sendMessage({ data: currentUrl , close: true , flag: 'open_popup_and_send_url_from_popup'});
|
26 |
+
|
27 |
+
});
|
28 |
+
// setTimeout(function() {
|
29 |
+
// console.log('This message will be logged after 0.5 second');
|
30 |
+
// var popup_url='';
|
31 |
+
// chrome.storage.local.get(['access_token'], function(result) {
|
32 |
+
// if (result.access_token) {
|
33 |
+
// console.log('access_token currently is ' + result.access_token);
|
34 |
+
// popup_url = "https://llmbb-llmbb-agent.hf.space/?access_token="+result.access_token;
|
35 |
+
// var iframe = document.createElement('iframe');
|
36 |
+
// iframe.src = popup_url;
|
37 |
+
// iframe.height = '570px';
|
38 |
+
// // iframe.sandbox = 'allow-same-origin allow-scripts';
|
39 |
+
// // iframe.allow = "geolocation *;";
|
40 |
+
// var iframe_area = document.getElementById('iframe_area')
|
41 |
+
// iframe_area.appendChild(iframe);
|
42 |
+
// }
|
43 |
+
// });
|
44 |
+
// }, 500);
|
45 |
})
|
46 |
|
47 |
document.getElementById('set_access_token').addEventListener('click', function() {
|
{qwen_server/css β css}/main.css
RENAMED
File without changes
|
qwen_server/database_server.py β database_server.py
RENAMED
@@ -1,38 +1,19 @@
|
|
1 |
-
import json
|
2 |
import multiprocessing
|
|
|
3 |
import os
|
4 |
-
from pathlib import Path
|
5 |
-
|
6 |
-
import add_qwen_libs # NOQA
|
7 |
-
import jsonlines
|
8 |
import uvicorn
|
9 |
from fastapi import FastAPI, Request, HTTPException, Response
|
10 |
from fastapi.middleware.cors import CORSMiddleware
|
11 |
from fastapi.responses import JSONResponse
|
12 |
from fastapi.staticfiles import StaticFiles
|
13 |
-
|
14 |
-
from qwen_agent.log import logger
|
15 |
-
from qwen_agent.utils.utils import get_local_ip
|
16 |
-
from qwen_server.schema import GlobalConfig
|
17 |
-
from qwen_server.utils import extract_and_cache_document
|
18 |
from starlette.middleware.sessions import SessionMiddleware
|
19 |
|
20 |
-
#
|
21 |
-
|
22 |
-
server_config = json.load(f)
|
23 |
-
server_config = GlobalConfig(**server_config)
|
24 |
|
25 |
app = FastAPI()
|
26 |
|
27 |
-
logger.info(get_local_ip())
|
28 |
-
origins = [
|
29 |
-
'http://127.0.0.1:' + str(server_config.server.workstation_port),
|
30 |
-
'http://localhost:' + str(server_config.server.workstation_port),
|
31 |
-
'http://0.0.0.0:' + str(server_config.server.workstation_port),
|
32 |
-
'http://' + get_local_ip() + ':' +
|
33 |
-
str(server_config.server.workstation_port),
|
34 |
-
]
|
35 |
-
access_token_file = os.path.join(server_config.path.cache_root, 'access_token.jsonl')
|
36 |
app.add_middleware(
|
37 |
CORSMiddleware,
|
38 |
# allow_origins=origins,
|
@@ -41,42 +22,7 @@ app.add_middleware(
|
|
41 |
allow_headers=['*'],
|
42 |
)
|
43 |
|
44 |
-
app.mount('/static',
|
45 |
-
StaticFiles(directory=server_config.path.code_interpreter_ws),
|
46 |
-
name='static')
|
47 |
-
|
48 |
-
|
49 |
-
def update_pop_url(data, cache_file_popup_url, access_token):
|
50 |
-
new_line = {'url': data['url'], "access_token": access_token}
|
51 |
-
lines = []
|
52 |
-
for line in jsonlines.open(cache_file_popup_url):
|
53 |
-
if line['access_token'] == access_token and line['url'] != data['url']:
|
54 |
-
lines.append(line)
|
55 |
-
lines.append(new_line)
|
56 |
-
with jsonlines.open(cache_file_popup_url, mode='w') as writer:
|
57 |
-
for new_line in lines:
|
58 |
-
writer.write(new_line)
|
59 |
-
response = 'Update URL'
|
60 |
-
return response
|
61 |
-
|
62 |
-
|
63 |
-
def change_checkbox_state(text, cache_file, access_token):
|
64 |
-
if not os.path.exists(cache_file):
|
65 |
-
return {'result': 'no file'}
|
66 |
-
lines = []
|
67 |
-
for line in jsonlines.open(cache_file):
|
68 |
-
if line['access_token'] == access_token and line['url'] == text[3:]:
|
69 |
-
if line['checked']:
|
70 |
-
line['checked'] = False
|
71 |
-
else:
|
72 |
-
line['checked'] = True
|
73 |
-
lines.append(line)
|
74 |
-
|
75 |
-
with jsonlines.open(cache_file, mode='w') as writer:
|
76 |
-
for new_line in lines:
|
77 |
-
writer.write(new_line)
|
78 |
-
|
79 |
-
return {'result': 'changed'}
|
80 |
|
81 |
|
82 |
@app.middleware("http")
|
@@ -85,19 +31,16 @@ async def access_token_auth(request: Request, call_next):
|
|
85 |
access_token: str = request.headers.get("Authorization") or request.query_params.get("access_token") or request.session.get("access_token")
|
86 |
is_valid = False
|
87 |
if access_token:
|
88 |
-
|
|
|
89 |
is_valid = True
|
90 |
-
else:
|
91 |
-
for line in jsonlines.open(access_token_file):
|
92 |
-
if line['access_token'] == access_token:
|
93 |
-
is_valid = True
|
94 |
-
break
|
95 |
if not is_valid:
|
96 |
return Response(status_code=401, content="the token is not valid")
|
97 |
request.session.setdefault("access_token", access_token)
|
98 |
return await call_next(request)
|
99 |
|
100 |
|
|
|
101 |
@app.get('/healthz')
|
102 |
async def healthz(request: Request):
|
103 |
return JSONResponse({"healthz": True})
|
@@ -106,29 +49,22 @@ async def healthz(request: Request):
|
|
106 |
@app.post('/token/add')
|
107 |
async def add_token(request: Request):
|
108 |
access_token: str = request.headers.get("Authorization") or request.query_params.get("access_token") or request.session.get("access_token")
|
109 |
-
|
|
|
110 |
return Response(status_code=401, content="the token is not valid")
|
111 |
data = await request.json()
|
112 |
-
|
113 |
-
for line in jsonlines.open(access_token_file):
|
114 |
-
lines.append(line)
|
115 |
-
lines.append(data)
|
116 |
-
with jsonlines.open(access_token_file, mode='w') as writer:
|
117 |
-
for new_line in lines:
|
118 |
-
writer.write(new_line)
|
119 |
return JSONResponse({"success": True})
|
120 |
|
121 |
|
122 |
@app.get('/cachedata/{file_name}')
|
123 |
async def cache_data(request: Request, file_name: str):
|
124 |
access_token: str = request.headers.get("Authorization") or request.query_params.get("access_token") or request.session.get("access_token")
|
125 |
-
|
|
|
126 |
return Response(status_code=401, content="the token is not valid")
|
127 |
-
|
128 |
-
|
129 |
-
for line in jsonlines.open(cache_file):
|
130 |
-
lines.append(line)
|
131 |
-
return JSONResponse(lines)
|
132 |
|
133 |
|
134 |
@app.post('/endpoint')
|
@@ -136,15 +72,10 @@ async def web_listening(request: Request):
|
|
136 |
data = await request.json()
|
137 |
msg_type = data['task']
|
138 |
access_token = request.session.get("access_token")
|
139 |
-
cache_file_popup_url = os.path.join(server_config.path.cache_root, 'popup_url.jsonl')
|
140 |
-
cache_file = os.path.join(server_config.path.cache_root, 'browse.jsonl')
|
141 |
-
|
142 |
if msg_type == 'change_checkbox':
|
143 |
rsp = change_checkbox_state(data['ckid'], cache_file, access_token)
|
144 |
elif msg_type == 'cache':
|
145 |
-
cache_obj = multiprocessing.Process(
|
146 |
-
target=extract_and_cache_document,
|
147 |
-
args=(data, cache_file, server_config.path.cache_root, access_token))
|
148 |
cache_obj.start()
|
149 |
# rsp = cache_data(data, cache_file)
|
150 |
rsp = 'caching'
|
@@ -158,14 +89,12 @@ async def web_listening(request: Request):
|
|
158 |
|
159 |
|
160 |
import gradio as gr
|
161 |
-
|
162 |
-
from
|
163 |
|
164 |
-
|
165 |
-
app = gr.mount_gradio_app(app,
|
166 |
app.add_middleware(SessionMiddleware, secret_key=os.getenv("SECRET_KEY"), max_age=25200)
|
|
|
167 |
if __name__ == '__main__':
|
168 |
-
uvicorn.run(app='database_server:app',
|
169 |
-
host=server_config.server.server_host,
|
170 |
-
port=server_config.server.fast_api_port,
|
171 |
-
reload=False, workers=1)
|
|
|
|
|
1 |
import multiprocessing
|
2 |
+
import json
|
3 |
import os
|
|
|
|
|
|
|
|
|
4 |
import uvicorn
|
5 |
from fastapi import FastAPI, Request, HTTPException, Response
|
6 |
from fastapi.middleware.cors import CORSMiddleware
|
7 |
from fastapi.responses import JSONResponse
|
8 |
from fastapi.staticfiles import StaticFiles
|
9 |
+
from utils import extract_and_cache_document, service, cache_file_popup_url, cache_root, cache_file, code_interpreter_ws, update_pop_url, change_checkbox_state
|
|
|
|
|
|
|
|
|
10 |
from starlette.middleware.sessions import SessionMiddleware
|
11 |
|
12 |
+
# os.environ["TRANSFORMERS_CACHE"] = ".cache/huggingface/"
|
13 |
+
|
|
|
|
|
14 |
|
15 |
app = FastAPI()
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
app.add_middleware(
|
18 |
CORSMiddleware,
|
19 |
# allow_origins=origins,
|
|
|
22 |
allow_headers=['*'],
|
23 |
)
|
24 |
|
25 |
+
app.mount('/static', StaticFiles(directory=code_interpreter_ws), name='static')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
|
28 |
@app.middleware("http")
|
|
|
31 |
access_token: str = request.headers.get("Authorization") or request.query_params.get("access_token") or request.session.get("access_token")
|
32 |
is_valid = False
|
33 |
if access_token:
|
34 |
+
account_info = json.loads(service.get(access_token, "info.json", False))
|
35 |
+
if account_info and account_info["enabled"]:
|
36 |
is_valid = True
|
|
|
|
|
|
|
|
|
|
|
37 |
if not is_valid:
|
38 |
return Response(status_code=401, content="the token is not valid")
|
39 |
request.session.setdefault("access_token", access_token)
|
40 |
return await call_next(request)
|
41 |
|
42 |
|
43 |
+
@app.get('/')
|
44 |
@app.get('/healthz')
|
45 |
async def healthz(request: Request):
|
46 |
return JSONResponse({"healthz": True})
|
|
|
49 |
@app.post('/token/add')
|
50 |
async def add_token(request: Request):
|
51 |
access_token: str = request.headers.get("Authorization") or request.query_params.get("access_token") or request.session.get("access_token")
|
52 |
+
account_info = json.loads(service.get(access_token, "info.json", False))
|
53 |
+
if account_info and account_info["enabled"] and account_info["role"] == 'admin':
|
54 |
return Response(status_code=401, content="the token is not valid")
|
55 |
data = await request.json()
|
56 |
+
service.upsert(access_token, "info.json", json.dumps(data, ensure_ascii=False), False)
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
return JSONResponse({"success": True})
|
58 |
|
59 |
|
60 |
@app.get('/cachedata/{file_name}')
|
61 |
async def cache_data(request: Request, file_name: str):
|
62 |
access_token: str = request.headers.get("Authorization") or request.query_params.get("access_token") or request.session.get("access_token")
|
63 |
+
account_info = json.loads(service.get(access_token, "info.json", False))
|
64 |
+
if account_info and account_info["enabled"] and account_info["role"] == 'admin':
|
65 |
return Response(status_code=401, content="the token is not valid")
|
66 |
+
content = json.loads(service.get(access_token, file_name))
|
67 |
+
return JSONResponse(content)
|
|
|
|
|
|
|
68 |
|
69 |
|
70 |
@app.post('/endpoint')
|
|
|
72 |
data = await request.json()
|
73 |
msg_type = data['task']
|
74 |
access_token = request.session.get("access_token")
|
|
|
|
|
|
|
75 |
if msg_type == 'change_checkbox':
|
76 |
rsp = change_checkbox_state(data['ckid'], cache_file, access_token)
|
77 |
elif msg_type == 'cache':
|
78 |
+
cache_obj = multiprocessing.Process( target=extract_and_cache_document, args=(data, cache_root, access_token))
|
|
|
|
|
79 |
cache_obj.start()
|
80 |
# rsp = cache_data(data, cache_file)
|
81 |
rsp = 'caching'
|
|
|
89 |
|
90 |
|
91 |
import gradio as gr
|
92 |
+
from assistant_server import demo as assistant_app
|
93 |
+
from workstation_server import demo as workstation_app
|
94 |
|
95 |
+
app = gr.mount_gradio_app(app, assistant_app, path="/assistant")
|
96 |
+
app = gr.mount_gradio_app(app, workstation_app, path="/workstation")
|
97 |
app.add_middleware(SessionMiddleware, secret_key=os.getenv("SECRET_KEY"), max_age=25200)
|
98 |
+
|
99 |
if __name__ == '__main__':
|
100 |
+
uvicorn.run(app='database_server:app', host='0.0.0.0', port=7860, reload=False, workers=1)
|
|
|
|
|
|
{qwen_server/img β img}/logo.png
RENAMED
File without changes
|
{qwen_server/js β js}/main.js
RENAMED
File without changes
|
qwen_agent/llm/__init__.py
CHANGED
@@ -2,13 +2,3 @@ from .base import BaseChatModel
|
|
2 |
from .qwen_dashscope import QwenChatAtDS
|
3 |
from .qwen_oai import QwenChatAsOAI
|
4 |
|
5 |
-
|
6 |
-
def get_chat_model(model: str, api_key: str,
|
7 |
-
model_server: str) -> BaseChatModel:
|
8 |
-
if model_server.strip().lower() == 'dashscope':
|
9 |
-
llm = QwenChatAtDS(model=model, api_key=api_key)
|
10 |
-
else:
|
11 |
-
llm = QwenChatAsOAI(model=model,
|
12 |
-
api_key=api_key,
|
13 |
-
model_server=model_server)
|
14 |
-
return llm
|
|
|
2 |
from .qwen_dashscope import QwenChatAtDS
|
3 |
from .qwen_oai import QwenChatAsOAI
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
qwen_agent/llm/qwen_oai.py
CHANGED
@@ -7,11 +7,10 @@ from typing import Dict, List, Literal, Optional, Union
|
|
7 |
|
8 |
class QwenChatAsOAI(BaseChatModel):
|
9 |
|
10 |
-
def __init__(self, model: str
|
11 |
super().__init__()
|
12 |
-
|
13 |
-
|
14 |
-
openai.api_key = api_key.strip() or os.getenv('OPENAI_API_KEY', 'EMPTY')
|
15 |
self.model = os.getenv('OPENAI_MODEL_NAME', model)
|
16 |
|
17 |
def _chat_stream(
|
|
|
7 |
|
8 |
class QwenChatAsOAI(BaseChatModel):
|
9 |
|
10 |
+
def __init__(self, model: str):
|
11 |
super().__init__()
|
12 |
+
openai.api_base = os.getenv('OPENAI_API_BASE')
|
13 |
+
openai.api_key = os.getenv('OPENAI_API_KEY', 'EMPTY')
|
|
|
14 |
self.model = os.getenv('OPENAI_MODEL_NAME', model)
|
15 |
|
16 |
def _chat_stream(
|
qwen_server/add_qwen_libs.py
DELETED
@@ -1,5 +0,0 @@
|
|
1 |
-
import sys
|
2 |
-
from pathlib import Path
|
3 |
-
|
4 |
-
# A temporary solution. We should use `python setup.py develop` in the future.
|
5 |
-
sys.path.insert(0, str(Path(__file__).absolute().parent.parent))
|
|
|
|
|
|
|
|
|
|
|
|
qwen_server/server_config.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
{"path": {"work_space_root": "workspace/", "cache_root": "workspace/browser_cache/", "download_root": "workspace/download/", "code_interpreter_ws": "workspace/ci_workspace/"}, "server": {"server_host": "0.0.0.0", "fast_api_port": 7860, "app_in_browser_port": 7863, "workstation_port": 7864, "model_server": "http://127.0.0.1:7905/v1", "api_key": "", "llm": "Qwen/Qwen-1_8B-Chat", "max_ref_token": 4000, "max_days": 7}}
|
|
|
|
qwen_server/server_config_ε―ζ¬.json
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
{"path": {"work_space_root": "workspace/", "cache_root": "workspace/browser_cache/", "download_root": "workspace/download/", "code_interpreter_ws": "workspace/ci_workspace/"}, "server": {"server_host": "127.0.0.1", "fast_api_port": 7866, "app_in_browser_port": 7863, "workstation_port": 7864, "model_server": "dashscope", "api_key": "", "llm": "qwen-plus", "max_ref_token": 4000, "max_days": 7}}
|
|
|
|
requirements.txt
CHANGED
@@ -36,4 +36,4 @@ transformers_stream_generator
|
|
36 |
einops
|
37 |
accelerate
|
38 |
itsdangerous
|
39 |
-
b2sdk
|
|
|
36 |
einops
|
37 |
accelerate
|
38 |
itsdangerous
|
39 |
+
b2sdk
|
run_server.py
DELETED
@@ -1,146 +0,0 @@
|
|
1 |
-
import argparse
|
2 |
-
import json
|
3 |
-
import os
|
4 |
-
import signal
|
5 |
-
import stat
|
6 |
-
import subprocess
|
7 |
-
import sys
|
8 |
-
from pathlib import Path
|
9 |
-
|
10 |
-
from qwen_agent.log import logger
|
11 |
-
from qwen_agent.utils.utils import get_local_ip
|
12 |
-
from qwen_server.schema import GlobalConfig
|
13 |
-
# os.environ["TRANSFORMERS_CACHE"] = ".cache/huggingface/"
|
14 |
-
os.environ["HF_HOME"] = ".cache/huggingface/"
|
15 |
-
os.environ["MPLCONFIGDIR"] = ".cache/huggingface/"
|
16 |
-
|
17 |
-
def parse_args():
|
18 |
-
parser = argparse.ArgumentParser()
|
19 |
-
parser.add_argument('-m', '--model_server', type=str, default='dashscope')
|
20 |
-
parser.add_argument('-k', '--api_key', type=str, default='')
|
21 |
-
parser.add_argument(
|
22 |
-
'-l',
|
23 |
-
'--llm',
|
24 |
-
type=str,
|
25 |
-
default='qwen-plus',
|
26 |
-
help='DashScope: qwen-plus, qwen-turbo, qwen-14b-chat, qwen-7b-chat.',
|
27 |
-
)
|
28 |
-
parser.add_argument('-s',
|
29 |
-
'--server_host',
|
30 |
-
type=str,
|
31 |
-
default='127.0.0.1',
|
32 |
-
choices=['127.0.0.1', '0.0.0.0'])
|
33 |
-
parser.add_argument(
|
34 |
-
'-t',
|
35 |
-
'--max_ref_token',
|
36 |
-
type=int,
|
37 |
-
default=4000,
|
38 |
-
help='the max token number of reference material',
|
39 |
-
)
|
40 |
-
parser.add_argument(
|
41 |
-
'-w',
|
42 |
-
'--workstation_port',
|
43 |
-
type=int,
|
44 |
-
default=7864,
|
45 |
-
help='the port of editing workstation',
|
46 |
-
)
|
47 |
-
args = parser.parse_args()
|
48 |
-
# args.model_server = args.model_server.replace('0.0.0.0', '127.0.0.1')
|
49 |
-
return args
|
50 |
-
|
51 |
-
|
52 |
-
def _fix_secure_write_for_code_interpreter(code_interpreter_ws):
|
53 |
-
if 'linux' in sys.platform.lower():
|
54 |
-
fname = os.path.join(code_interpreter_ws, 'test_file_permission.txt')
|
55 |
-
if os.path.exists(fname):
|
56 |
-
os.remove(fname)
|
57 |
-
with os.fdopen(
|
58 |
-
os.open(fname, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 0o0600),
|
59 |
-
'w') as f:
|
60 |
-
f.write('test')
|
61 |
-
file_mode = stat.S_IMODE(os.stat(fname).st_mode) & 0o6677
|
62 |
-
if file_mode != 0o0600:
|
63 |
-
os.environ['JUPYTER_ALLOW_INSECURE_WRITES'] = '1'
|
64 |
-
|
65 |
-
|
66 |
-
def update_config(server_config, args, server_config_path):
|
67 |
-
server_config.server.model_server = args.model_server
|
68 |
-
server_config.server.api_key = args.api_key
|
69 |
-
server_config.server.llm = args.llm
|
70 |
-
server_config.server.server_host = args.server_host
|
71 |
-
server_config.server.max_ref_token = args.max_ref_token
|
72 |
-
server_config.server.workstation_port = args.workstation_port
|
73 |
-
|
74 |
-
with open(server_config_path, 'w') as f:
|
75 |
-
try:
|
76 |
-
cfg = server_config.model_dump_json()
|
77 |
-
except AttributeError: # for pydantic v1
|
78 |
-
cfg = server_config.json()
|
79 |
-
json.dump(json.loads(cfg), f, ensure_ascii=False)
|
80 |
-
return server_config
|
81 |
-
|
82 |
-
|
83 |
-
def main():
|
84 |
-
args = parse_args()
|
85 |
-
server_config_path = Path(
|
86 |
-
__file__).resolve().parent / 'qwen_server/server_config.json'
|
87 |
-
with open(server_config_path, 'r') as f:
|
88 |
-
server_config = json.load(f)
|
89 |
-
server_config = GlobalConfig(**server_config)
|
90 |
-
server_config = update_config(server_config, args, server_config_path)
|
91 |
-
|
92 |
-
logger.info(server_config)
|
93 |
-
|
94 |
-
os.makedirs(server_config.path.work_space_root, exist_ok=True)
|
95 |
-
os.makedirs(server_config.path.cache_root, exist_ok=True)
|
96 |
-
os.makedirs(server_config.path.download_root, exist_ok=True)
|
97 |
-
|
98 |
-
os.makedirs(server_config.path.code_interpreter_ws, exist_ok=True)
|
99 |
-
code_interpreter_work_dir = str(
|
100 |
-
Path(__file__).resolve().parent /
|
101 |
-
server_config.path.code_interpreter_ws)
|
102 |
-
os.environ['M6_CODE_INTERPRETER_WORK_DIR'] = code_interpreter_work_dir
|
103 |
-
|
104 |
-
if args.server_host == '0.0.0.0':
|
105 |
-
static_url = get_local_ip()
|
106 |
-
else:
|
107 |
-
static_url = args.server_host
|
108 |
-
static_url = f'http://{static_url}:{server_config.server.fast_api_port}/static'
|
109 |
-
os.environ['M6_CODE_INTERPRETER_STATIC_URL'] = static_url
|
110 |
-
|
111 |
-
_fix_secure_write_for_code_interpreter(
|
112 |
-
server_config.path.code_interpreter_ws)
|
113 |
-
|
114 |
-
servers = {
|
115 |
-
'database':
|
116 |
-
subprocess.Popen([
|
117 |
-
sys.executable,
|
118 |
-
os.path.join(os.getcwd(), 'qwen_server/database_server.py')
|
119 |
-
]),
|
120 |
-
# 'workstation':
|
121 |
-
# subprocess.Popen([
|
122 |
-
# sys.executable,
|
123 |
-
# os.path.join(os.getcwd(), 'qwen_server/workstation_server.py')
|
124 |
-
# ]),
|
125 |
-
# 'assistant':
|
126 |
-
# subprocess.Popen([
|
127 |
-
# sys.executable,
|
128 |
-
# os.path.join(os.getcwd(), 'qwen_server/assistant_server.py')
|
129 |
-
# ]),
|
130 |
-
}
|
131 |
-
|
132 |
-
def signal_handler(_sig, _frame):
|
133 |
-
for v in servers.values():
|
134 |
-
v.terminate()
|
135 |
-
for k in list(servers.keys()):
|
136 |
-
del servers[k]
|
137 |
-
|
138 |
-
signal.signal(signal.SIGINT, signal_handler)
|
139 |
-
signal.signal(signal.SIGTERM, signal_handler)
|
140 |
-
|
141 |
-
for p in list(servers.values()):
|
142 |
-
p.wait()
|
143 |
-
|
144 |
-
|
145 |
-
if __name__ == '__main__':
|
146 |
-
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
qwen_server/schema.py β schema.py
RENAMED
@@ -31,23 +31,3 @@ class PathConfig(BaseModel):
|
|
31 |
cache_root: str
|
32 |
download_root: str
|
33 |
code_interpreter_ws: str
|
34 |
-
|
35 |
-
|
36 |
-
class ServerConfig(BaseModel):
|
37 |
-
server_host: str
|
38 |
-
fast_api_port: int
|
39 |
-
app_in_browser_port: int
|
40 |
-
workstation_port: int
|
41 |
-
model_server: str
|
42 |
-
api_key: str
|
43 |
-
llm: str
|
44 |
-
max_ref_token: int
|
45 |
-
max_days: int
|
46 |
-
|
47 |
-
class Config:
|
48 |
-
protected_namespaces = ()
|
49 |
-
|
50 |
-
|
51 |
-
class GlobalConfig(BaseModel):
|
52 |
-
path: PathConfig
|
53 |
-
server: ServerConfig
|
|
|
31 |
cache_root: str
|
32 |
download_root: str
|
33 |
code_interpreter_ws: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
qwen_server/utils.py β utils.py
RENAMED
@@ -1,22 +1,54 @@
|
|
1 |
-
import datetime
|
2 |
import os
|
3 |
import re
|
|
|
|
|
4 |
from urllib.parse import unquote, urlparse
|
5 |
-
|
6 |
-
import add_qwen_libs # NOQA
|
7 |
import jsonlines
|
8 |
-
|
9 |
from qwen_agent.log import logger
|
10 |
from qwen_agent.utils.doc_parser import parse_doc, parse_html_bs
|
11 |
from qwen_agent.utils.utils import print_traceback, save_text_to_file
|
12 |
-
from
|
13 |
from b2sdk.v2 import B2Api
|
14 |
from b2sdk.v2 import InMemoryAccountInfo
|
15 |
import hashlib
|
16 |
-
|
17 |
from io import BytesIO
|
18 |
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
class B2Manager():
|
21 |
def __init__(self):
|
22 |
info = InMemoryAccountInfo()
|
@@ -28,37 +60,75 @@ class B2Manager():
|
|
28 |
self.b2_api = b2_api
|
29 |
self.file_name = None
|
30 |
|
31 |
-
def gen_file_name(self, access_token, url):
|
32 |
url_md5 = hashlib.md5(b'%s' % url.encode(encoding='UTF-8')).hexdigest()
|
33 |
-
|
34 |
|
35 |
-
def get(self):
|
36 |
in_memory_file = BytesIO()
|
37 |
-
self.b2_bucket.download_file_by_name(self.
|
38 |
# export_file = self.b2_bucket.download_file_by_name(self.file_name)
|
39 |
# export_file.save(in_memory_file)
|
40 |
in_memory_file.seek(0)
|
41 |
-
return in_memory_file.read()
|
42 |
|
43 |
-
def upsert(self,
|
44 |
-
|
45 |
-
|
46 |
-
self.b2_bucket.upload_bytes(file_data.read(), self.file_name, file_infos=None)
|
47 |
|
48 |
-
def delete(self):
|
49 |
-
file_version_info = self.b2_bucket.get_file_info_by_name(self.
|
50 |
self.b2_bucket.hide_file(file_version_info.file_name)
|
51 |
# for version in self.b2_bucket.list_file_versions(self.file_name):
|
52 |
# self.b2_bucket.delete_file_version(version.id_, version.file_name)
|
53 |
|
54 |
def list_files(self, access_token):
|
55 |
files = []
|
56 |
-
for file_version_info, folder_name in self.b2_bucket.ls(folder_to_list="access_token/"
|
57 |
# The upload timestamp is in milliseconds, so we divide by 1000 to convert it to seconds
|
58 |
-
upload_timestamp = datetime.fromtimestamp(file_version_info.upload_timestamp / 1000.0)
|
59 |
files.append(f"File Name: {file_version_info.file_name}, \nUpload timestamp: {upload_timestamp}, \nMetadata: {file_version_info.file_info}")
|
60 |
return files
|
61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
def is_local_path(path):
|
64 |
if path.startswith('https://') or path.startswith('http://'):
|
@@ -92,11 +162,10 @@ def sanitize_chrome_file_path(file_path: str) -> str:
|
|
92 |
return file_path
|
93 |
|
94 |
|
95 |
-
def extract_and_cache_document(data,
|
96 |
logger.info('Starting cache pages...')
|
97 |
if data['url'].split('.')[-1].lower() in ['pdf', 'docx', 'pptx']:
|
98 |
date1 = datetime.datetime.now()
|
99 |
-
|
100 |
# generate one processing record
|
101 |
new_record = Record(url=data['url'],
|
102 |
time='',
|
@@ -106,12 +175,10 @@ def extract_and_cache_document(data, cache_file, cache_root, access_token):
|
|
106 |
access_token=access_token,
|
107 |
topic='',
|
108 |
checked=False,
|
109 |
-
session=[])
|
110 |
-
|
111 |
-
writer.write(new_record)
|
112 |
|
113 |
-
if data['url'].startswith('https://') or data['url'].startswith(
|
114 |
-
'http://'):
|
115 |
pdf_path = data['url']
|
116 |
else:
|
117 |
parsed_url = urlparse(data['url'])
|
@@ -123,14 +190,7 @@ def extract_and_cache_document(data, cache_file, cache_root, access_token):
|
|
123 |
except Exception:
|
124 |
print_traceback()
|
125 |
# del the processing record
|
126 |
-
|
127 |
-
if os.path.exists(cache_file):
|
128 |
-
for line in jsonlines.open(cache_file):
|
129 |
-
if line['access_token'] == access_token and line['url'] != data['url']:
|
130 |
-
lines.append(line)
|
131 |
-
with jsonlines.open(cache_file, mode='w') as writer:
|
132 |
-
for new_line in lines:
|
133 |
-
writer.write(new_line)
|
134 |
return 'failed'
|
135 |
|
136 |
date2 = datetime.datetime.now()
|
@@ -147,9 +207,8 @@ def extract_and_cache_document(data, cache_file, cache_root, access_token):
|
|
147 |
access_token=access_token,
|
148 |
topic='',
|
149 |
checked=False,
|
150 |
-
session=[])
|
151 |
-
|
152 |
-
writer.write(new_record)
|
153 |
|
154 |
try:
|
155 |
tmp_html_file = os.path.join(cache_root, 'tmp.html')
|
@@ -174,15 +233,17 @@ def extract_and_cache_document(data, cache_file, cache_root, access_token):
|
|
174 |
topic='',
|
175 |
checked=True,
|
176 |
session=[])
|
177 |
-
|
178 |
-
if os.path.exists(cache_file):
|
179 |
-
for line in jsonlines.open(cache_file):
|
180 |
-
if line['access_token'] == access_token and line['url'] != data['url']:
|
181 |
-
lines.append(line)
|
182 |
-
lines.append(new_record.to_dict()) # cache
|
183 |
-
with jsonlines.open(cache_file, mode='w') as writer:
|
184 |
-
for new_line in lines:
|
185 |
-
writer.write(new_line)
|
186 |
-
|
187 |
response = 'Cached'
|
188 |
return response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import os
|
2 |
import re
|
3 |
+
import stat
|
4 |
+
import sys
|
5 |
from urllib.parse import unquote, urlparse
|
|
|
|
|
6 |
import jsonlines
|
|
|
7 |
from qwen_agent.log import logger
|
8 |
from qwen_agent.utils.doc_parser import parse_doc, parse_html_bs
|
9 |
from qwen_agent.utils.utils import print_traceback, save_text_to_file
|
10 |
+
from schema import Record
|
11 |
from b2sdk.v2 import B2Api
|
12 |
from b2sdk.v2 import InMemoryAccountInfo
|
13 |
import hashlib
|
14 |
+
import datetime
|
15 |
from io import BytesIO
|
16 |
|
17 |
|
18 |
+
def _fix_secure_write_for_code_interpreter(code_interpreter_ws):
|
19 |
+
if 'linux' in sys.platform.lower():
|
20 |
+
fname = os.path.join(code_interpreter_ws, 'test_file_permission.txt')
|
21 |
+
if os.path.exists(fname):
|
22 |
+
os.remove(fname)
|
23 |
+
with os.fdopen(
|
24 |
+
os.open(fname, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 0o0600),
|
25 |
+
'w') as f:
|
26 |
+
f.write('test')
|
27 |
+
file_mode = stat.S_IMODE(os.stat(fname).st_mode) & 0o6677
|
28 |
+
if file_mode != 0o0600:
|
29 |
+
os.environ['JUPYTER_ALLOW_INSECURE_WRITES'] = '1'
|
30 |
+
|
31 |
+
|
32 |
+
work_space_root = "./workspace"
|
33 |
+
cache_root = f"{work_space_root}/browser_cache/"
|
34 |
+
download_root = f"{work_space_root}/download/"
|
35 |
+
code_interpreter_ws = f"{work_space_root}/ci_workspace/"
|
36 |
+
cache_file_popup_url = os.path.join(cache_root, 'popup_url.jsonl')
|
37 |
+
cache_file = os.path.join(cache_root, 'browse.jsonl')
|
38 |
+
max_ref_token = 4000
|
39 |
+
max_days = 7
|
40 |
+
os.makedirs(work_space_root, exist_ok=True)
|
41 |
+
os.makedirs(cache_root, exist_ok=True)
|
42 |
+
os.makedirs(download_root, exist_ok=True)
|
43 |
+
os.makedirs(code_interpreter_ws, exist_ok=True)
|
44 |
+
code_interpreter_work_dir = code_interpreter_ws
|
45 |
+
os.environ['M6_CODE_INTERPRETER_WORK_DIR'] = code_interpreter_work_dir
|
46 |
+
os.environ['M6_CODE_INTERPRETER_STATIC_URL'] = f'{os.getenv("DOMAIN")}/static'
|
47 |
+
os.environ["HF_HOME"] = ".cache/huggingface/"
|
48 |
+
os.environ["MPLCONFIGDIR"] = ".cache/huggingface/"
|
49 |
+
_fix_secure_write_for_code_interpreter(code_interpreter_ws)
|
50 |
+
|
51 |
+
|
52 |
class B2Manager():
|
53 |
def __init__(self):
|
54 |
info = InMemoryAccountInfo()
|
|
|
60 |
self.b2_api = b2_api
|
61 |
self.file_name = None
|
62 |
|
63 |
+
def gen_file_name(self, access_token, url, need_md5):
|
64 |
url_md5 = hashlib.md5(b'%s' % url.encode(encoding='UTF-8')).hexdigest()
|
65 |
+
return f"{access_token}/{url_md5}" if need_md5 else f"{access_token}/{url}"
|
66 |
|
67 |
+
def get(self, access_token, url, need_md5=True):
|
68 |
in_memory_file = BytesIO()
|
69 |
+
self.b2_bucket.download_file_by_name(self.gen_file_name(access_token, url, need_md5)).save(in_memory_file)
|
70 |
# export_file = self.b2_bucket.download_file_by_name(self.file_name)
|
71 |
# export_file.save(in_memory_file)
|
72 |
in_memory_file.seek(0)
|
73 |
+
return str(in_memory_file.read(), "utf-8")
|
74 |
|
75 |
+
def upsert(self, access_token, url, content, need_md5=True):
|
76 |
+
self.b2_bucket.upload_bytes(content.encode('utf-8'), self.gen_file_name(access_token, url, need_md5), file_infos=None)
|
77 |
+
# self.b2_bucket.upload()
|
|
|
78 |
|
79 |
+
def delete(self, access_token, url, need_md5=True):
|
80 |
+
file_version_info = self.b2_bucket.get_file_info_by_name(self.gen_file_name(access_token, url, need_md5))
|
81 |
self.b2_bucket.hide_file(file_version_info.file_name)
|
82 |
# for version in self.b2_bucket.list_file_versions(self.file_name):
|
83 |
# self.b2_bucket.delete_file_version(version.id_, version.file_name)
|
84 |
|
85 |
def list_files(self, access_token):
|
86 |
files = []
|
87 |
+
for file_version_info, folder_name in self.b2_bucket.ls(folder_to_list=f"{access_token}/"):
|
88 |
# The upload timestamp is in milliseconds, so we divide by 1000 to convert it to seconds
|
89 |
+
upload_timestamp = datetime.datetime.fromtimestamp(file_version_info.upload_timestamp / 1000.0)
|
90 |
files.append(f"File Name: {file_version_info.file_name}, \nUpload timestamp: {upload_timestamp}, \nMetadata: {file_version_info.file_info}")
|
91 |
return files
|
92 |
|
93 |
+
def exists(self, access_token, url=None, need_md5=True):
|
94 |
+
try:
|
95 |
+
self.b2_bucket.get_file_info_by_name(self.gen_file_name(access_token, url, need_md5))
|
96 |
+
return True
|
97 |
+
except:
|
98 |
+
return False
|
99 |
+
|
100 |
+
def update_pop_url(data, cache_file_popup_url, access_token):
|
101 |
+
new_line = {'url': data['url'], "access_token": access_token}
|
102 |
+
lines = []
|
103 |
+
for line in jsonlines.open(cache_file_popup_url):
|
104 |
+
if line['access_token'] == access_token and line['url'] != data['url']:
|
105 |
+
lines.append(line)
|
106 |
+
lines.append(new_line)
|
107 |
+
with jsonlines.open(cache_file_popup_url, mode='w') as writer:
|
108 |
+
for new_line in lines:
|
109 |
+
writer.write(new_line)
|
110 |
+
response = 'Update URL'
|
111 |
+
return response
|
112 |
+
|
113 |
+
|
114 |
+
def change_checkbox_state(text, cache_file, access_token):
|
115 |
+
if not os.path.exists(cache_file):
|
116 |
+
return {'result': 'no file'}
|
117 |
+
lines = []
|
118 |
+
for line in jsonlines.open(cache_file):
|
119 |
+
if line['access_token'] == access_token and line['url'] == text[3:]:
|
120 |
+
if line['checked']:
|
121 |
+
line['checked'] = False
|
122 |
+
else:
|
123 |
+
line['checked'] = True
|
124 |
+
lines.append(line)
|
125 |
+
|
126 |
+
with jsonlines.open(cache_file, mode='w') as writer:
|
127 |
+
for new_line in lines:
|
128 |
+
writer.write(new_line)
|
129 |
+
|
130 |
+
return {'result': 'changed'}
|
131 |
+
|
132 |
|
133 |
def is_local_path(path):
|
134 |
if path.startswith('https://') or path.startswith('http://'):
|
|
|
162 |
return file_path
|
163 |
|
164 |
|
165 |
+
def extract_and_cache_document(data, cache_root, access_token):
|
166 |
logger.info('Starting cache pages...')
|
167 |
if data['url'].split('.')[-1].lower() in ['pdf', 'docx', 'pptx']:
|
168 |
date1 = datetime.datetime.now()
|
|
|
169 |
# generate one processing record
|
170 |
new_record = Record(url=data['url'],
|
171 |
time='',
|
|
|
175 |
access_token=access_token,
|
176 |
topic='',
|
177 |
checked=False,
|
178 |
+
session=[])
|
179 |
+
service.upsert(access_token, data['url'], new_record.model_dump_json())
|
|
|
180 |
|
181 |
+
if data['url'].startswith('https://') or data['url'].startswith( 'http://'):
|
|
|
182 |
pdf_path = data['url']
|
183 |
else:
|
184 |
parsed_url = urlparse(data['url'])
|
|
|
190 |
except Exception:
|
191 |
print_traceback()
|
192 |
# del the processing record
|
193 |
+
service.delete(access_token, data['url'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
return 'failed'
|
195 |
|
196 |
date2 = datetime.datetime.now()
|
|
|
207 |
access_token=access_token,
|
208 |
topic='',
|
209 |
checked=False,
|
210 |
+
session=[])
|
211 |
+
service.upsert(access_token, data['url'], new_record.model_dump_json())
|
|
|
212 |
|
213 |
try:
|
214 |
tmp_html_file = os.path.join(cache_root, 'tmp.html')
|
|
|
233 |
topic='',
|
234 |
checked=True,
|
235 |
session=[])
|
236 |
+
service.upsert(access_token, data['url'], new_record.model_dump_json())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
response = 'Cached'
|
238 |
return response
|
239 |
+
|
240 |
+
|
241 |
+
service = B2Manager()
|
242 |
+
|
243 |
+
|
244 |
+
if __name__ == '__main__':
|
245 |
+
# print(service.gen_file_name("test", "settings.xml"))
|
246 |
+
# print(service.get("test", "settings.xml"))
|
247 |
+
# print(service.upsert("test", "settings.xml", b"1111"))
|
248 |
+
print(service.list_files("test"))
|
249 |
+
print(service.exists("test", "https://tree-iad1-0003.secure.backblaze.com/b2_browse_files2.htm1"))
|
qwen_server/workstation_server.py β workstation_server.py
RENAMED
@@ -3,38 +3,26 @@ import json
|
|
3 |
import os
|
4 |
import shutil
|
5 |
from pathlib import Path
|
6 |
-
|
7 |
-
import add_qwen_libs # NOQA
|
8 |
import gradio as gr
|
9 |
import jsonlines
|
10 |
-
|
11 |
-
from qwen_agent.actions import (ContinueWriting, ReAct, RetrievalQA,
|
12 |
-
WriteFromScratch)
|
13 |
from qwen_agent.actions.function_calling import FunctionCalling
|
14 |
-
from qwen_agent.llm import
|
15 |
from qwen_agent.log import logger
|
16 |
from qwen_agent.memory import Memory
|
17 |
from qwen_agent.tools import call_plugin, list_of_all_functions
|
18 |
from qwen_agent.utils.utils import (format_answer, get_last_one_line_context,
|
19 |
has_chinese_chars, save_text_to_file)
|
20 |
-
from
|
21 |
-
from qwen_server.utils import extract_and_cache_document
|
22 |
|
23 |
-
|
24 |
-
with open(Path(__file__).resolve().parent / 'server_config.json', 'r') as f:
|
25 |
-
server_config = json.load(f)
|
26 |
-
server_config = GlobalConfig(**server_config)
|
27 |
-
|
28 |
-
llm = get_chat_model(model=server_config.server.llm,
|
29 |
-
api_key=server_config.server.api_key,
|
30 |
-
model_server=server_config.server.model_server)
|
31 |
|
32 |
mem = Memory(llm=llm, stream=False)
|
33 |
|
34 |
app_global_para = {
|
35 |
'time': [str(datetime.date.today()),
|
36 |
str(datetime.date.today())],
|
37 |
-
'cache_file': os.path.join(
|
38 |
'messages': [],
|
39 |
'last_turn_msg_id': [],
|
40 |
'is_first_upload': True,
|
@@ -46,9 +34,9 @@ CODE_FLAG = '/code'
|
|
46 |
PLUGIN_FLAG = '/plug'
|
47 |
TITLE_FLAG = '/title'
|
48 |
|
49 |
-
with open(
|
50 |
css = f.read()
|
51 |
-
with open(
|
52 |
js = f.read()
|
53 |
|
54 |
|
@@ -84,8 +72,8 @@ def chat_clear_last():
|
|
84 |
app_global_para['last_turn_msg_id'] = []
|
85 |
|
86 |
|
87 |
-
def add_file(file, chosen_plug):
|
88 |
-
output_filepath =
|
89 |
fn = os.path.basename(file.name)
|
90 |
fn_type = fn.split('.')[-1].lower()
|
91 |
logger.info('file type: ' + fn_type)
|
@@ -112,7 +100,7 @@ def add_file(file, chosen_plug):
|
|
112 |
}
|
113 |
extract_and_cache_document(
|
114 |
data, app_global_para['cache_file'],
|
115 |
-
|
116 |
|
117 |
return new_path
|
118 |
|
@@ -134,7 +122,7 @@ def update_app_global_para(date1, date2):
|
|
134 |
def refresh_date():
|
135 |
option = [
|
136 |
str(datetime.date.today() - datetime.timedelta(days=i))
|
137 |
-
for i in range(
|
138 |
]
|
139 |
return (gr.update(choices=option, value=str(datetime.date.today())),
|
140 |
gr.update(choices=option, value=str(datetime.date.today())))
|
@@ -172,7 +160,7 @@ def download_text(text):
|
|
172 |
now = datetime.datetime.now()
|
173 |
current_time = now.strftime('%Y-%m-%d_%H-%M-%S')
|
174 |
filename = f'file_{current_time}.md'
|
175 |
-
save_path = os.path.join(
|
176 |
rsp = save_text_to_file(save_path, text)
|
177 |
if rsp == 'SUCCESS':
|
178 |
gr.Info(f'Saved to {save_path}')
|
@@ -215,7 +203,7 @@ def bot(history, upload_file, chosen_plug):
|
|
215 |
if chosen_plug == CI_OPTION: # use code interpreter
|
216 |
prompt_upload_file = ''
|
217 |
if upload_file and app_global_para['is_first_upload']:
|
218 |
-
workspace_dir =
|
219 |
file_relpath = os.path.relpath(path=upload_file,
|
220 |
start=workspace_dir)
|
221 |
if has_chinese_chars(history[-1][0]):
|
@@ -240,8 +228,8 @@ def bot(history, upload_file, chosen_plug):
|
|
240 |
history[-1][1] += rsp['content'].strip() + '\n'
|
241 |
yield history
|
242 |
history[-1][1] += (
|
243 |
-
|
244 |
-
|
245 |
yield history
|
246 |
history[-1][1] += ('Action Input:\n' +
|
247 |
rsp['function_call']['arguments'] +
|
@@ -316,13 +304,13 @@ def bot(history, upload_file, chosen_plug):
|
|
316 |
else:
|
317 |
for line in jsonlines.open(app_global_para['cache_file']):
|
318 |
if (app_global_para['time'][0] <= line['time'] <=
|
319 |
-
|
320 |
lines.append(line)
|
321 |
if lines:
|
322 |
_ref_list = mem.get(
|
323 |
history[-1][0],
|
324 |
lines,
|
325 |
-
max_token=
|
326 |
_ref = '\n'.join(
|
327 |
json.dumps(x, ensure_ascii=False) for x in _ref_list)
|
328 |
else:
|
@@ -397,7 +385,7 @@ def generate(context):
|
|
397 |
if os.path.exists(app_global_para['cache_file']):
|
398 |
for line in jsonlines.open(app_global_para['cache_file']):
|
399 |
if (app_global_para['time'][0] <= line['time'] <=
|
400 |
-
|
401 |
lines.append(line)
|
402 |
if lines:
|
403 |
res += '\n========================= \n'
|
@@ -411,7 +399,7 @@ def generate(context):
|
|
411 |
|
412 |
_ref_list = mem.get(sp_query_no_title,
|
413 |
lines,
|
414 |
-
max_token=
|
415 |
_ref = '\n'.join(
|
416 |
json.dumps(x, ensure_ascii=False) for x in _ref_list)
|
417 |
res += _ref
|
@@ -456,7 +444,22 @@ def format_generate(edit, context):
|
|
456 |
yield res
|
457 |
|
458 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
459 |
with gr.Blocks(css=css, theme='soft') as demo:
|
|
|
460 |
title = gr.Markdown('Qwen Agent: BrowserQwen', elem_classes='title')
|
461 |
desc = gr.Markdown(
|
462 |
'This is the editing workstation of BrowserQwen, where Qwen has collected the browsing history. Qwen can assist you in completing your creative work!',
|
@@ -472,7 +475,7 @@ with gr.Blocks(css=css, theme='soft') as demo:
|
|
472 |
[
|
473 |
str(datetime.date.today() -
|
474 |
datetime.timedelta(days=i))
|
475 |
-
for i in range(
|
476 |
],
|
477 |
value=str(datetime.date.today()),
|
478 |
label='Start Date',
|
@@ -481,7 +484,7 @@ with gr.Blocks(css=css, theme='soft') as demo:
|
|
481 |
[
|
482 |
str(datetime.date.today() -
|
483 |
datetime.timedelta(days=i))
|
484 |
-
for i in range(
|
485 |
],
|
486 |
value=str(datetime.date.today()),
|
487 |
label='End Date',
|
@@ -631,12 +634,12 @@ with gr.Blocks(css=css, theme='soft') as demo:
|
|
631 |
re_txt_msg = (chat_re_bt.click(
|
632 |
rm_text, [chatbot], [chatbot, chat_txt],
|
633 |
queue=False).then(chat_clear_last, None, None).then(
|
634 |
-
|
635 |
re_txt_msg.then(lambda: gr.update(interactive=True),
|
636 |
None, [chat_txt],
|
637 |
queue=False)
|
638 |
|
639 |
-
file_msg = file_btn.upload(add_file, [file_btn, plug_bt],
|
640 |
[hidden_file_path],
|
641 |
queue=False)
|
642 |
file_msg.then(update_browser_list, None,
|
@@ -691,7 +694,7 @@ with gr.Blocks(css=css, theme='soft') as demo:
|
|
691 |
txt_msg = chat_txt.submit(pure_add_text, [pure_chatbot, chat_txt],
|
692 |
[pure_chatbot, chat_txt],
|
693 |
queue=False).then(
|
694 |
-
|
695 |
txt_msg.then(lambda: gr.update(interactive=True),
|
696 |
None, [chat_txt],
|
697 |
queue=False)
|
@@ -699,8 +702,8 @@ with gr.Blocks(css=css, theme='soft') as demo:
|
|
699 |
re_txt_msg = chat_re_bt.click(rm_text, [pure_chatbot],
|
700 |
[pure_chatbot, chat_txt],
|
701 |
queue=False).then(
|
702 |
-
|
703 |
-
|
704 |
re_txt_msg.then(lambda: gr.update(interactive=True),
|
705 |
None, [chat_txt],
|
706 |
queue=False)
|
@@ -719,26 +722,26 @@ with gr.Blocks(css=css, theme='soft') as demo:
|
|
719 |
None,
|
720 |
None,
|
721 |
_js=f'() => {{{js}}}').then(
|
722 |
-
|
723 |
-
|
724 |
date2.change(update_app_global_para, [date1, date2],
|
725 |
None).then(update_browser_list, None,
|
726 |
browser_list).then(lambda: None,
|
727 |
None,
|
728 |
None,
|
729 |
_js=f'() => {{{js}}}').then(
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
demo.load(
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
demo.queue()
|
743 |
|
744 |
-
# demo.queue().launch(server_name=
|
|
|
3 |
import os
|
4 |
import shutil
|
5 |
from pathlib import Path
|
|
|
|
|
6 |
import gradio as gr
|
7 |
import jsonlines
|
8 |
+
from qwen_agent.actions import (ContinueWriting, ReAct, RetrievalQA, WriteFromScratch)
|
|
|
|
|
9 |
from qwen_agent.actions.function_calling import FunctionCalling
|
10 |
+
from qwen_agent.llm import QwenChatAsOAI
|
11 |
from qwen_agent.log import logger
|
12 |
from qwen_agent.memory import Memory
|
13 |
from qwen_agent.tools import call_plugin, list_of_all_functions
|
14 |
from qwen_agent.utils.utils import (format_answer, get_last_one_line_context,
|
15 |
has_chinese_chars, save_text_to_file)
|
16 |
+
from utils import service, extract_and_cache_document, code_interpreter_ws, cache_root, max_ref_token, max_days, download_root
|
|
|
17 |
|
18 |
+
llm = QwenChatAsOAI(model="gpt-3.5-turbo")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
mem = Memory(llm=llm, stream=False)
|
21 |
|
22 |
app_global_para = {
|
23 |
'time': [str(datetime.date.today()),
|
24 |
str(datetime.date.today())],
|
25 |
+
'cache_file': os.path.join(cache_root, 'browse.jsonl'),
|
26 |
'messages': [],
|
27 |
'last_turn_msg_id': [],
|
28 |
'is_first_upload': True,
|
|
|
34 |
PLUGIN_FLAG = '/plug'
|
35 |
TITLE_FLAG = '/title'
|
36 |
|
37 |
+
with open('css/main.css', 'r') as f:
|
38 |
css = f.read()
|
39 |
+
with open('js/main.js', 'r') as f:
|
40 |
js = f.read()
|
41 |
|
42 |
|
|
|
72 |
app_global_para['last_turn_msg_id'] = []
|
73 |
|
74 |
|
75 |
+
def add_file(file, chosen_plug, access_token):
|
76 |
+
output_filepath = code_interpreter_ws
|
77 |
fn = os.path.basename(file.name)
|
78 |
fn_type = fn.split('.')[-1].lower()
|
79 |
logger.info('file type: ' + fn_type)
|
|
|
100 |
}
|
101 |
extract_and_cache_document(
|
102 |
data, app_global_para['cache_file'],
|
103 |
+
cache_root, access_token) # waiting for analyse file
|
104 |
|
105 |
return new_path
|
106 |
|
|
|
122 |
def refresh_date():
|
123 |
option = [
|
124 |
str(datetime.date.today() - datetime.timedelta(days=i))
|
125 |
+
for i in range(max_days)
|
126 |
]
|
127 |
return (gr.update(choices=option, value=str(datetime.date.today())),
|
128 |
gr.update(choices=option, value=str(datetime.date.today())))
|
|
|
160 |
now = datetime.datetime.now()
|
161 |
current_time = now.strftime('%Y-%m-%d_%H-%M-%S')
|
162 |
filename = f'file_{current_time}.md'
|
163 |
+
save_path = os.path.join(download_root, filename)
|
164 |
rsp = save_text_to_file(save_path, text)
|
165 |
if rsp == 'SUCCESS':
|
166 |
gr.Info(f'Saved to {save_path}')
|
|
|
203 |
if chosen_plug == CI_OPTION: # use code interpreter
|
204 |
prompt_upload_file = ''
|
205 |
if upload_file and app_global_para['is_first_upload']:
|
206 |
+
workspace_dir = code_interpreter_ws
|
207 |
file_relpath = os.path.relpath(path=upload_file,
|
208 |
start=workspace_dir)
|
209 |
if has_chinese_chars(history[-1][0]):
|
|
|
228 |
history[-1][1] += rsp['content'].strip() + '\n'
|
229 |
yield history
|
230 |
history[-1][1] += (
|
231 |
+
'Action: ' + rsp['function_call']['name'].strip() +
|
232 |
+
'\n')
|
233 |
yield history
|
234 |
history[-1][1] += ('Action Input:\n' +
|
235 |
rsp['function_call']['arguments'] +
|
|
|
304 |
else:
|
305 |
for line in jsonlines.open(app_global_para['cache_file']):
|
306 |
if (app_global_para['time'][0] <= line['time'] <=
|
307 |
+
app_global_para['time'][1]) and line['checked']:
|
308 |
lines.append(line)
|
309 |
if lines:
|
310 |
_ref_list = mem.get(
|
311 |
history[-1][0],
|
312 |
lines,
|
313 |
+
max_token=max_ref_token)
|
314 |
_ref = '\n'.join(
|
315 |
json.dumps(x, ensure_ascii=False) for x in _ref_list)
|
316 |
else:
|
|
|
385 |
if os.path.exists(app_global_para['cache_file']):
|
386 |
for line in jsonlines.open(app_global_para['cache_file']):
|
387 |
if (app_global_para['time'][0] <= line['time'] <=
|
388 |
+
app_global_para['time'][1]) and line['checked']:
|
389 |
lines.append(line)
|
390 |
if lines:
|
391 |
res += '\n========================= \n'
|
|
|
399 |
|
400 |
_ref_list = mem.get(sp_query_no_title,
|
401 |
lines,
|
402 |
+
max_token=max_ref_token)
|
403 |
_ref = '\n'.join(
|
404 |
json.dumps(x, ensure_ascii=False) for x in _ref_list)
|
405 |
res += _ref
|
|
|
444 |
yield res
|
445 |
|
446 |
|
447 |
+
def initialize(request: gr.Request, date1, date2):
|
448 |
+
access_token = request.query_params["access_token"] or request.session["access_token"]
|
449 |
+
is_valid = False
|
450 |
+
if access_token:
|
451 |
+
account_info = json.loads(service.get(access_token, "info.json", False))
|
452 |
+
if account_info and account_info["enabled"]:
|
453 |
+
is_valid = True
|
454 |
+
if not is_valid:
|
455 |
+
gr.Info("The token is not valid, Please reset!")
|
456 |
+
return
|
457 |
+
update_app_global_para(date1, date2)
|
458 |
+
return access_token
|
459 |
+
|
460 |
+
|
461 |
with gr.Blocks(css=css, theme='soft') as demo:
|
462 |
+
access_token = gr.State("")
|
463 |
title = gr.Markdown('Qwen Agent: BrowserQwen', elem_classes='title')
|
464 |
desc = gr.Markdown(
|
465 |
'This is the editing workstation of BrowserQwen, where Qwen has collected the browsing history. Qwen can assist you in completing your creative work!',
|
|
|
475 |
[
|
476 |
str(datetime.date.today() -
|
477 |
datetime.timedelta(days=i))
|
478 |
+
for i in range(max_days)
|
479 |
],
|
480 |
value=str(datetime.date.today()),
|
481 |
label='Start Date',
|
|
|
484 |
[
|
485 |
str(datetime.date.today() -
|
486 |
datetime.timedelta(days=i))
|
487 |
+
for i in range(max_days)
|
488 |
],
|
489 |
value=str(datetime.date.today()),
|
490 |
label='End Date',
|
|
|
634 |
re_txt_msg = (chat_re_bt.click(
|
635 |
rm_text, [chatbot], [chatbot, chat_txt],
|
636 |
queue=False).then(chat_clear_last, None, None).then(
|
637 |
+
bot, [chatbot, hidden_file_path, plug_bt], chatbot))
|
638 |
re_txt_msg.then(lambda: gr.update(interactive=True),
|
639 |
None, [chat_txt],
|
640 |
queue=False)
|
641 |
|
642 |
+
file_msg = file_btn.upload(add_file, [file_btn, plug_bt, access_token],
|
643 |
[hidden_file_path],
|
644 |
queue=False)
|
645 |
file_msg.then(update_browser_list, None,
|
|
|
694 |
txt_msg = chat_txt.submit(pure_add_text, [pure_chatbot, chat_txt],
|
695 |
[pure_chatbot, chat_txt],
|
696 |
queue=False).then(
|
697 |
+
pure_bot, pure_chatbot, pure_chatbot)
|
698 |
txt_msg.then(lambda: gr.update(interactive=True),
|
699 |
None, [chat_txt],
|
700 |
queue=False)
|
|
|
702 |
re_txt_msg = chat_re_bt.click(rm_text, [pure_chatbot],
|
703 |
[pure_chatbot, chat_txt],
|
704 |
queue=False).then(
|
705 |
+
pure_bot, pure_chatbot,
|
706 |
+
pure_chatbot)
|
707 |
re_txt_msg.then(lambda: gr.update(interactive=True),
|
708 |
None, [chat_txt],
|
709 |
queue=False)
|
|
|
722 |
None,
|
723 |
None,
|
724 |
_js=f'() => {{{js}}}').then(
|
725 |
+
chat_clear, None,
|
726 |
+
[chatbot, hidden_file_path])
|
727 |
date2.change(update_app_global_para, [date1, date2],
|
728 |
None).then(update_browser_list, None,
|
729 |
browser_list).then(lambda: None,
|
730 |
None,
|
731 |
None,
|
732 |
_js=f'() => {{{js}}}').then(
|
733 |
+
chat_clear, None,
|
734 |
+
[chatbot, hidden_file_path])
|
735 |
+
|
736 |
+
demo.load(initialize, [date1, date2],
|
737 |
+
[access_token]).then(refresh_date, None, [date1, date2]).then(
|
738 |
+
update_browser_list, None,
|
739 |
+
browser_list).then(lambda: None,
|
740 |
+
None,
|
741 |
+
None,
|
742 |
+
_js=f'() => {{{js}}}').then(
|
743 |
+
chat_clear, None,
|
744 |
+
[chatbot, hidden_file_path])
|
745 |
demo.queue()
|
746 |
|
747 |
+
# demo.queue().launch(server_name=server_host, server_port=workstation_port)
|