app.py 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. import datetime
  2. import importlib
  3. import json
  4. import os
  5. import random
  6. import shutil
  7. import sys
  8. from pathlib import Path
  9. import gradio as gr
  10. import jsonlines
  11. import config_browserqwen
  12. sys.path.insert(
  13. 0,
  14. str(Path(__file__).absolute().parent.parent)) # NOQA
  15. from qwen_agent.tools.tools import tools_list, call_plugin # NOQA
  16. from qwen_agent.utils.util import get_last_one_line_context, save_text_to_file, count_tokens, get_html_content, format_answer # NOQA
  17. from qwen_agent.actions import ContinueWriting, Simple, WriteFromZero, ReAct # NOQA
  18. from qwen_agent.memory import Memory # NOQA
  19. from qwen_agent.actions.func_call import func_call # NOQA
  20. prompt_lan = sys.argv[1]
  21. llm_name = sys.argv[2]
  22. max_ref_token = int(sys.argv[3])
  23. workstation_port = int(sys.argv[4])
  24. model_server = sys.argv[5]
  25. api_key = sys.argv[6]
  26. server_host = sys.argv[7]
  27. print(sys.argv)
  28. if model_server.startswith('http'):
  29. source = 'local'
  30. elif model_server.startswith('dashscope'):
  31. source = 'dashscope'
  32. if llm_name.startswith('gpt'):
  33. module = 'qwen_agent.llm.gpt'
  34. llm = importlib.import_module(module).GPT(llm_name)
  35. elif llm_name.startswith('Qwen') or llm_name.startswith('qwen'):
  36. module = 'qwen_agent.llm.qwen'
  37. llm = importlib.import_module(module).Qwen(llm_name, model_server=model_server, api_key=api_key)
  38. else:
  39. raise NotImplementedError
  40. mem = Memory(config_browserqwen.similarity_search, config_browserqwen.similarity_search_type)
  41. app_global_para = {
  42. 'time': [str(datetime.date.today()), str(datetime.date.today())],
  43. 'cache_file': os.path.join(config_browserqwen.cache_root, config_browserqwen.browser_cache_file),
  44. 'use_ci_flag': False,
  45. 'use_bidding_flag': True,
  46. 'messages': [],
  47. 'last_turn_msg_id': [],
  48. 'is_first_upload': True
  49. }
  50. with open(Path(__file__).resolve().parent / 'css/main.css', 'r') as f:
  51. css = f.read()
  52. with open(Path(__file__).resolve().parent / 'js/main.js', 'r') as f:
  53. js = f.read()
  54. def add_text(history, text):
  55. history = history + [(text, None)]
  56. app_global_para['last_turn_msg_id'] = []
  57. return history, gr.update(value='', interactive=False)
  58. def rm_text(history):
  59. if not history:
  60. gr.Warning('No input content!')
  61. elif not history[-1][1]:
  62. return history, gr.update(value='', interactive=False)
  63. else:
  64. history = history[:-1] + [(history[-1][0], None)]
  65. return history, gr.update(value='', interactive=False)
  66. def chat_clear():
  67. app_global_para['messages'] = []
  68. return None, None, None
  69. def chat_clear_last():
  70. # print(app_global_para['last_turn_msg_id'][::-1])
  71. # print(app_global_para['messages'])
  72. for index in app_global_para['last_turn_msg_id'][::-1]:
  73. del app_global_para['messages'][index]
  74. app_global_para['last_turn_msg_id'] = []
  75. def add_file(file):
  76. output_filepath = config_browserqwen.code_interpreter_ws
  77. fn = os.path.basename(file.name)
  78. new_path = os.path.join(output_filepath, fn)
  79. if os.path.exists(new_path):
  80. os.remove(new_path)
  81. shutil.move(file.name, output_filepath)
  82. path_show = '<p></p><p>File</p>' # NOQA
  83. app_global_para['is_first_upload'] = True
  84. return path_show, new_path
  85. def check_file():
  86. if not app_global_para['use_ci_flag']:
  87. gr.Warning('Select the Code Interpreter to analyze the file!')
  88. def read_records(file, times=None):
  89. lines = []
  90. if times:
  91. for line in jsonlines.open(file):
  92. if times[0] <= line['time'] <= times[1]:
  93. lines.append(line)
  94. return lines
  95. def update_rec_list(flag):
  96. rec_list = []
  97. if not os.path.exists(app_global_para['cache_file']):
  98. return 'No browsing records'
  99. lines = []
  100. for line in jsonlines.open(app_global_para['cache_file']):
  101. if (app_global_para['time'][0] <= line['time'] <= app_global_para['time'][1]) and line['checked']:
  102. if flag == 'load' and line['topic']:
  103. rec_list.append(line['topic'])
  104. else:
  105. agent = Simple(llm=llm, stream=False)
  106. page_number = len(line['raw'])
  107. index = random.randint(0, page_number-1)
  108. if prompt_lan == 'CN':
  109. topicprompt = '请提出一个有新意的吸引人的话题'
  110. elif prompt_lan == 'EN':
  111. topicprompt = 'Please propose a new and attractive topic'
  112. rec = agent.run(line['raw'][index]['page_content'], topicprompt, prompt_lan=prompt_lan)
  113. assert isinstance(rec, str)
  114. rec_list.append(rec)
  115. line['topic'] = rec
  116. lines.append(line)
  117. if lines:
  118. # update cache file
  119. with jsonlines.open(app_global_para['cache_file'], mode='w') as writer:
  120. for new_line in lines:
  121. writer.write(new_line)
  122. res = '<ol>{rec}</ol>'
  123. rec = ''
  124. for x in rec_list:
  125. rec += '<li>{rec_topic}</li>'.format(rec_topic=x)
  126. res = res.format(rec=rec)
  127. return res
  128. def update_app_global_para(date1, date2):
  129. app_global_para['time'][0] = date1
  130. app_global_para['time'][1] = date2
  131. app_global_para['use_ci_flag'] = False
  132. app_global_para['use_bidding_flag'] = True
  133. def update_browser_list():
  134. if not os.path.exists(app_global_para['cache_file']):
  135. return 'No browsing records'
  136. lines = read_records(app_global_para['cache_file'], times=app_global_para['time'])
  137. br_list = [[line['url'], line['extract'], line['checked']] for line in lines]
  138. print('browser_list: ', len(br_list))
  139. res = '<ol>{bl}</ol>'
  140. bl = ''
  141. for i, x in enumerate(br_list):
  142. ck = '<input type="checkbox" class="custom-checkbox" id="ck-'+x[0]+'" '
  143. if x[2]:
  144. ck += 'checked>'
  145. else:
  146. ck += '>'
  147. bl += '<li>{checkbox}{title}<a href="{url}"> [url]</a></li>'.format(checkbox=ck, url=x[0], title=x[1])
  148. res = res.format(bl=bl)
  149. return res
  150. def update_all(date1, date2):
  151. update_app_global_para(date1, date2)
  152. return update_browser_list(), update_rec_list('update')
  153. def layout_to_right(text):
  154. return text, text
  155. def download_text(text):
  156. now = datetime.datetime.now()
  157. current_time = now.strftime('%Y-%m-%d_%H-%M-%S')
  158. filename = f'file_{current_time}.md'
  159. rsp = save_text_to_file(os.path.join(config_browserqwen.download_root, filename), text)
  160. if rsp == 'SUCCESS':
  161. raise gr.Info('Saved')
  162. else:
  163. raise gr.Error("Can't Save: ", rsp)
  164. def count_token(text):
  165. return count_tokens(text)
  166. def change_use_ci_flag():
  167. if app_global_para['use_ci_flag']:
  168. app_global_para['use_ci_flag'] = False
  169. else:
  170. app_global_para['use_ci_flag'] = True
  171. def change_use_bidding_flag():
  172. if app_global_para['use_bidding_flag']:
  173. app_global_para['use_bidding_flag'] = False
  174. else:
  175. app_global_para['use_bidding_flag'] = True
  176. def add_url_manu(url, date):
  177. text = get_html_content(url)
  178. msg = {'content': text, 'query': '', 'url': url, 'task': 'cache', 'type': 'html'}
  179. from main import cache_data # NOQA
  180. cache_data(msg, app_global_para['cache_file'])
  181. def bot(history, upload_file):
  182. if not history:
  183. yield history
  184. else:
  185. history[-1][1] = ''
  186. if app_global_para['use_ci_flag']: # use code interpreter
  187. prompt_upload_file = ''
  188. if upload_file and app_global_para['is_first_upload']:
  189. workspace_dir = config_browserqwen.code_interpreter_ws
  190. file_relpath = os.path.relpath(path=upload_file, start=workspace_dir)
  191. if prompt_lan == 'EN':
  192. prompt_upload_file = f'[Upload file {file_relpath}]'
  193. elif prompt_lan == 'CN':
  194. prompt_upload_file = f'上传了[文件]({file_relpath})到当前目录,'
  195. app_global_para['is_first_upload'] = False
  196. history[-1][0] = prompt_upload_file+history[-1][0]
  197. if source == 'local': # using func call interface
  198. message = {
  199. 'role': 'user', 'content': history[-1][0]
  200. }
  201. app_global_para['last_turn_msg_id'].append(len(app_global_para['messages']))
  202. app_global_para['messages'].append(message)
  203. while True:
  204. print(app_global_para['messages'])
  205. functions = [x for x in tools_list if x['name_for_model'] == 'code_interpreter']
  206. rsp = llm.qwen_chat_func(app_global_para['messages'], functions)
  207. if rsp['function_call']:
  208. history[-1][1] += rsp['content'].strip() + '\n'
  209. yield history
  210. history[-1][1] += 'Action: '+rsp['function_call']['name'].strip() + '\n'
  211. yield history
  212. history[-1][1] += 'Action Input:\n'+rsp['function_call']['arguments'] + '\n'
  213. yield history
  214. bot_msg = {
  215. 'role': 'assistant',
  216. 'content': rsp['content'],
  217. 'function_call': {
  218. 'name': rsp['function_call']['name'],
  219. 'arguments': rsp['function_call']['arguments'],
  220. }
  221. }
  222. app_global_para['last_turn_msg_id'].append(len(app_global_para['messages']))
  223. app_global_para['messages'].append(bot_msg)
  224. obs = call_plugin(rsp['function_call']['name'], rsp['function_call']['arguments'])
  225. func_msg = {
  226. 'role': 'function',
  227. 'name': rsp['function_call']['name'],
  228. 'content': obs,
  229. }
  230. history[-1][1] += ('Observation: ' + obs + '\n')
  231. yield history
  232. app_global_para['last_turn_msg_id'].append(len(app_global_para['messages']))
  233. app_global_para['messages'].append(func_msg)
  234. else:
  235. bot_msg = {
  236. 'role': 'assistant',
  237. 'content': rsp['content'],
  238. }
  239. history[-1][1] += rsp['content']
  240. yield history
  241. app_global_para['last_turn_msg_id'].append(len(app_global_para['messages']))
  242. app_global_para['messages'].append(bot_msg)
  243. break
  244. elif source == 'dashscope': # using dashscope interface:
  245. print(app_global_para['messages'])
  246. functions = [x for x in tools_list if x['name_for_model'] == 'code_interpreter']
  247. agent = ReAct(llm=llm, list_of_plugin_info=functions)
  248. response = agent.run(history[-1][0], messages=app_global_para['messages'])
  249. if 'Action' not in response:
  250. response = response.split('Final Answer:')[-1]
  251. history[-1][1] = response
  252. yield history
  253. message = {
  254. 'role': 'user', 'content': history[-1][0]
  255. }
  256. app_global_para['last_turn_msg_id'].append(len(app_global_para['messages']))
  257. app_global_para['messages'].append(message)
  258. rsp_message = {
  259. 'role': 'assistant', 'content': history[-1][1]
  260. }
  261. app_global_para['last_turn_msg_id'].append(len(app_global_para['messages']))
  262. app_global_para['messages'].append(rsp_message)
  263. elif app_global_para['use_bidding_flag']:
  264. sp_query = history[-1][0]
  265. print('history_message:', app_global_para['messages'])
  266. # if config_browserqwen.ifbunit_flag in sp_query: # router to code interpreter
  267. # if True:
  268. from qwen_agent.planning.plan_dispatcher import PlanDispatcher
  269. import copy
  270. # from qwen_agent.messages.base import UserResponseStream
  271. # sp_query = sp_query.split(config_browserqwen.ifbunit_flag)[-1]
  272. agent = PlanDispatcher(llm=llm, stream=False, enable_critic=True)
  273. response = agent.run(sp_query, messages=app_global_para['messages'])
  274. details_info = copy.deepcopy(history)
  275. thought = ''
  276. summary = ''
  277. for res in response:
  278. # yield f'######## {res.type}: {res.content}\n'
  279. if res.type == 'thought':
  280. thought += res.content
  281. elif res.type == 'summary':
  282. summary += res.content
  283. details_info[-1][1] += f"{res.type.upper()}: {res.content}\n"
  284. yield details_info
  285. if thought:
  286. history[-1][1] += f'Final Thought: {thought}\n'
  287. if summary:
  288. history[-1][1] += f'Final Summary: {summary}\n'
  289. # yield history
  290. print(f'Fineshed Query:{sp_query}')
  291. message = {
  292. 'role': 'user', 'content': history[-1][0]
  293. }
  294. app_global_para['last_turn_msg_id'].append(len(app_global_para['messages']))
  295. app_global_para['messages'].append(message)
  296. message = {
  297. 'role': 'assistant', 'content': history[-1][1]
  298. }
  299. app_global_para['last_turn_msg_id'].append(len(app_global_para['messages']))
  300. app_global_para['messages'].append(message)
  301. else:
  302. lines = []
  303. if not os.path.exists(app_global_para['cache_file']):
  304. _ref = ''
  305. else:
  306. for line in jsonlines.open(app_global_para['cache_file']):
  307. if (app_global_para['time'][0] <= line['time'] <= app_global_para['time'][1]) and line['checked']:
  308. lines.append(line)
  309. if lines:
  310. _ref_list = mem.get(history[-1][0], lines, llm=llm, stream=True, max_token=max_ref_token)
  311. _ref = '\n'.join(json.dumps(x, ensure_ascii=False) for x in _ref_list)
  312. else:
  313. _ref = ''
  314. gr.Warning('No reference materials selected, Qwen will answer directly')
  315. agent = Simple(llm=llm, stream=True)
  316. response = agent.run(_ref, history)
  317. for chunk in response:
  318. history[-1][1] += chunk
  319. yield history
  320. # append message
  321. message = {
  322. 'role': 'user', 'content': history[-1][0]
  323. }
  324. app_global_para['last_turn_msg_id'].append(len(app_global_para['messages']))
  325. app_global_para['messages'].append(message)
  326. message = {
  327. 'role': 'assistant', 'content': history[-1][1]
  328. }
  329. app_global_para['last_turn_msg_id'].append(len(app_global_para['messages']))
  330. app_global_para['messages'].append(message)
  331. def generate(context):
  332. print("context", context)
  333. sp_query = get_last_one_line_context(context)
  334. res = ''
  335. # if config_browserqwen.ifbunit_flag in sp_query: # router to code interpreter
  336. from qwen_agent.planning.plan_dispatcher import PlanDispatcher
  337. sp_query = sp_query.split(config_browserqwen.ifbunit_flag)[-1]
  338. agent = PlanDispatcher(llm=llm, stream=False)
  339. response = agent.run(sp_query, messages=[])
  340. for chunk in response:
  341. res += chunk.content
  342. yield res
  343. # if config_browserqwen.code_flag in sp_query: # router to code interpreter
  344. # sp_query = sp_query.split(config_browserqwen.code_flag)[-1]
  345. # sp_query += ', 必须使用code_interpreter工具'
  346. # functions = [x for x in tools_list if x['name_for_model'] == 'code_interpreter']
  347. # if source == 'local': # using func call interface
  348. # response = func_call(sp_query, functions, llm)
  349. # for chunk in response:
  350. # res += chunk
  351. # yield res
  352. # elif source == 'dashscope': # using dashscope interface
  353. # agent = ReAct(llm=llm, list_of_plugin_info=functions)
  354. # response = agent.run(sp_query, messages=[])
  355. # yield response
  356. # elif config_browserqwen.plugin_flag in sp_query: # router to plugin
  357. # sp_query = sp_query.split(config_browserqwen.plugin_flag)[-1]
  358. # functions = tools_list
  359. # if source == 'local': # using func call interface
  360. # response = func_call(sp_query, functions, llm)
  361. # for chunk in response:
  362. # res += chunk
  363. # yield res
  364. # elif source == 'dashscope': # using dashscope interface
  365. # agent = ReAct(llm=llm, list_of_plugin_info=functions)
  366. # response = agent.run(sp_query, messages=[])
  367. # yield response
  368. # else: # router to continue writing
  369. # lines = []
  370. # for line in jsonlines.open(app_global_para['cache_file']):
  371. # if (app_global_para['time'][0] <= line['time'] <= app_global_para['time'][1]) and line['checked']:
  372. # lines.append(line)
  373. # if lines:
  374. # if config_browserqwen.similarity_search:
  375. # res += '\n========================= \n'
  376. # yield res
  377. # res += '> Search for relevant information: \n'
  378. # yield res
  379. # sp_query_no_title = sp_query
  380. # if config_browserqwen.title_flag in sp_query: # /title
  381. # sp_query_no_title = sp_query.split(config_browserqwen.title_flag)[-1]
  382. # _ref_list = mem.get(sp_query_no_title, lines, llm=llm, stream=True, max_token=max_ref_token)
  383. # _ref = '\n'.join(json.dumps(x, ensure_ascii=False) for x in _ref_list)
  384. # res += _ref
  385. # yield res
  386. # res += '\n'
  387. # else:
  388. # _ref = ''
  389. # gr.Warning('No reference materials selected, Qwen will answer directly')
  390. # if config_browserqwen.title_flag in sp_query: # /title
  391. # sp_query = sp_query.split(config_browserqwen.title_flag)[-1]
  392. # agent = WriteFromZero(llm=llm, stream=True, auto_agent=config_browserqwen.auto_agent)
  393. # else:
  394. # res += '\n========================= \n'
  395. # res += '> Writing Text: \n'
  396. # yield res
  397. # agent = ContinueWriting(llm=llm, stream=True)
  398. # response = agent.run(_ref, context, prompt_lan=prompt_lan)
  399. # if config_browserqwen.code_flag in sp_query: # router to code interpreter
  400. # sp_query = sp_query.split(config_browserqwen.code_flag)[-1]
  401. # sp_query += ', 必须使用code_interpreter工具'
  402. # functions = [x for x in tools_list if x['name_for_model'] == 'code_interpreter']
  403. # if source == 'local': # using func call interface
  404. # response = func_call(sp_query, functions, llm)
  405. # for chunk in response:
  406. # res += chunk
  407. # yield res
  408. # elif source == 'dashscope': # using dashscope interface
  409. # agent = ReAct(llm=llm, list_of_plugin_info=functions, source=source)
  410. # response = agent.run(sp_query, messages=[])
  411. # yield response
  412. # elif config_browserqwen.plugin_flag in sp_query: # router to plugin
  413. # sp_query = sp_query.split(config_browserqwen.plugin_flag)[-1]
  414. # functions = tools_list
  415. # if source == 'local': # using func call interface
  416. # response = func_call(sp_query, functions, llm)
  417. # for chunk in response:
  418. # res += chunk
  419. # yield res
  420. # elif source == 'dashscope': # using dashscope interface
  421. # agent = ReAct(llm=llm, list_of_plugin_info=functions, source=source)
  422. # response = agent.run(sp_query, messages=[])
  423. # yield response
  424. # else: # router to continue writing
  425. # lines = []
  426. # for line in jsonlines.open(app_global_para['cache_file']):
  427. # if (app_global_para['time'][0] <= line['time'] <= app_global_para['time'][1]) and line['checked']:
  428. # lines.append(line)
  429. # if lines:
  430. # if config_browserqwen.similarity_search:
  431. # res += '\n========================= \n'
  432. # yield res
  433. # res += '> Search for relevant information: \n'
  434. # yield res
  435. # sp_query_no_title = sp_query
  436. # if config_browserqwen.title_flag in sp_query: # /title
  437. # sp_query_no_title = sp_query.split(config_browserqwen.title_flag)[-1]
  438. # _ref_list = mem.get(sp_query_no_title, lines, llm=llm, stream=True, max_token=max_ref_token)
  439. # _ref = '\n'.join(json.dumps(x, ensure_ascii=False) for x in _ref_list)
  440. # res += _ref
  441. # yield res
  442. # res += '\n'
  443. # else:
  444. # _ref = ''
  445. # gr.Warning('No reference materials selected, Qwen will answer directly')
  446. def format_generate(edit, context):
  447. res = edit
  448. yield res
  449. if '> Writing Text: ' in context:
  450. text = context.split('> Writing Text: ')[-1].strip()
  451. res += '\n'
  452. res += text
  453. yield res
  454. elif 'Final Answer' in context:
  455. response = format_answer(context)
  456. res += '\n'
  457. res += response
  458. yield res
  459. else:
  460. res += context
  461. yield res
  462. # generate('/ifbunit 浙江万维今年的中标情况')
  463. with gr.Blocks(css=css, theme='soft') as demo:
  464. title = gr.Markdown('Qwen Agent: BrowserQwen', elem_classes='title')
  465. desc = gr.Markdown(
  466. 'This is the editing workstation of BrowserQwen, where Qwen has collected the browsing history. Qwen can assist you in completing your creative work!',
  467. elem_classes='desc')
  468. with gr.Row():
  469. with gr.Column():
  470. rec = gr.Markdown('Browsing History', elem_classes='rec')
  471. with gr.Row():
  472. with gr.Column(scale=0.3, min_width=0):
  473. date1 = gr.Dropdown([str(datetime.date.today()-datetime.timedelta(days=i)) for i in range(
  474. config_browserqwen.max_days)], value=str(datetime.date.today()), label='Start Date') # NOQA
  475. date2 = gr.Dropdown([str(datetime.date.today()-datetime.timedelta(days=i)) for i in range(
  476. config_browserqwen.max_days)], value=str(datetime.date.today()), label='End Date') # NOQA
  477. with gr.Column(scale=0.7, min_width=0):
  478. browser_list = gr.HTML(value='', label='browser_list', elem_classes=['div_tmp', 'add_scrollbar'])
  479. with gr.Tab('Editor', elem_id='default-tab'):
  480. with gr.Row():
  481. with gr.Column():
  482. with gr.Row():
  483. edit_area = gr.Textbox(
  484. value='',
  485. elem_classes=['textbox_default', 'add_scrollbar'],
  486. lines=30,
  487. label='Input',
  488. show_copy_button=True)
  489. # token_count = gr.HTML(value='<span>0</span>',
  490. # elem_classes=[
  491. # 'token-counter',
  492. # 'default-token-counter'
  493. # ])
  494. with gr.Row():
  495. ctn_bt = gr.Button('Continue', variant='primary')
  496. stop_bt = gr.Button('Stop')
  497. clr_bt = gr.Button('Clear')
  498. dld_bt = gr.Button('Download')
  499. # with gr.Row():
  500. # layout_bt = gr.Button('👉', variant='primary')
  501. with gr.Column():
  502. cmd_area = gr.Textbox(lines=10, max_lines=10, label="Qwen's Inner Thought", elem_id='cmd')
  503. with gr.Tab('Markdown'):
  504. # md_out_bt = gr.Button('Render')
  505. md_out_area = gr.Markdown(elem_classes=[
  506. 'md_tmp',
  507. 'add_scrollbar'
  508. ])
  509. with gr.Tab('HTML'):
  510. html_out_area = gr.HTML()
  511. with gr.Tab('Raw'):
  512. text_out_area = gr.Textbox(lines=20,
  513. label='',
  514. elem_classes=[
  515. 'textbox_default_output',
  516. 'add_scrollbar'
  517. ],
  518. show_copy_button=True)
  519. # br_input_bt.click(add_url_manu, br_input, None).then(update_browser_list, None, browser_list).then(lambda: None, None, None, _js=f'() => {{{js}}}')
  520. # .then(update_rec_list, gr.Textbox('update', visible=False), rec_list)
  521. # clk_ctn_bt = ctn_bt.click(qwen_ctn, edit_area, edit_area)
  522. clk_ctn_bt = ctn_bt.click(generate, edit_area, cmd_area)
  523. clk_ctn_bt.then(format_generate, [edit_area, cmd_area], edit_area)
  524. edit_area_change = edit_area.change(layout_to_right, edit_area, [text_out_area, md_out_area])
  525. # edit_area_change.then(count_token, edit_area, token_count)
  526. stop_bt.click(lambda: None, cancels=[clk_ctn_bt], queue=False)
  527. clr_bt.click(lambda: [None, None, None], None, [edit_area, cmd_area, md_out_area], queue=False)
  528. dld_bt.click(download_text, edit_area, None)
  529. # layout_bt.click(layout_to_right,
  530. # edit_area, [text_out_area, md_out_area],
  531. # queue=False)
  532. gr.Markdown('''
  533. ### Usage Tips:
  534. - Browsing History:
  535. - Start Date/End Date: Selecting the browsed materials for the desired time period, including the start and end dates
  536. - The browsed materials list: supporting the selection or removal of specific browsing content
  537. - Editor: In the editing area, you can directly input content or special instructions, and then click the ```Continue``` button to have Qwen assist in completing the editing work:
  538. - After inputting the content, directly click the ```Continue``` button: Qwen will begin to continue writing based on the browsing information
  539. - Using special instructions:
  540. - /title + content: Qwen enables the built-in planning process and writes a complete manuscript
  541. - /code + content: Qwen enables the code interpreter plugin, writes and runs Python code, and generates replies
  542. - /plug + content: Qwen enables plugin and select appropriate plugin to generate reply
  543. - Chat: Interactive area. Qwen generates replies based on given reference materials. Selecting Code Interpreter will enable the code interpreter plugin
  544. ''')
  545. with gr.Tab('Chat', elem_id='chat-tab'):
  546. with gr.Column():
  547. chatbot = gr.Chatbot([],
  548. elem_id='chatbot',
  549. height=680,
  550. show_copy_button=True,
  551. avatar_images=(None, (os.path.join(
  552. Path(__file__).resolve().parent, 'img/logo.png'))))
  553. with gr.Row():
  554. with gr.Column(scale=1, min_width=0):
  555. file_btn = gr.UploadButton('Upload', file_types=['file']) # NOQA
  556. with gr.Column(scale=3, min_width=0):
  557. plug_bt = gr.Checkbox(label='Code Interpreter')
  558. with gr.Column(scale=3, min_width=0):
  559. bidding_bt = gr.Checkbox(label='Bidding Analysis', value=True)
  560. with gr.Column(scale=1, min_width=0):
  561. show_path_md = gr.HTML('')
  562. # with gr.Column(scale=0.03, min_width=0):
  563. # show_path_bt = gr.Button('✖️', visible=False) # NOQA
  564. with gr.Column(scale=13):
  565. chat_txt = gr.Textbox(show_label=False, placeholder='Chat with Qwen...', container=False) # NOQA
  566. # with gr.Column(scale=0.05, min_width=0):
  567. # chat_smt_bt = gr.Button('⏎') # NOQA
  568. with gr.Column(scale=1, min_width=0):
  569. chat_clr_bt = gr.Button('Clear') # NOQA
  570. with gr.Column(scale=1, min_width=0):
  571. chat_stop_bt = gr.Button('Stop') # NOQA
  572. with gr.Column(scale=1, min_width=0):
  573. chat_re_bt = gr.Button('Again') # NOQA
  574. hidden_file_path = gr.Textbox(visible=False)
  575. txt_msg = chat_txt.submit(add_text, [chatbot, chat_txt], [chatbot, chat_txt], queue=False).then(bot, [chatbot, hidden_file_path], chatbot)
  576. txt_msg.then(lambda: gr.update(interactive=True), None, [chat_txt], queue=False)
  577. # txt_msg_bt = chat_smt_bt.click(add_text, [chatbot, chat_txt], [chatbot, chat_txt], queue=False).then(bot, chatbot, chatbot)
  578. # txt_msg_bt.then(lambda: gr.update(interactive=True), None, [chat_txt], queue=False)
  579. # (None, None, None, cancels=[txt_msg], queue=False).then
  580. re_txt_msg = chat_re_bt.click(rm_text, [chatbot], [chatbot, chat_txt], queue=False).then(chat_clear_last, None, None).then(bot, [chatbot, hidden_file_path], chatbot)
  581. re_txt_msg.then(lambda: gr.update(interactive=True), None, [chat_txt], queue=False)
  582. file_msg = file_btn.upload(add_file, [file_btn], [show_path_md, hidden_file_path], queue=False).then(check_file, None, None)
  583. chat_clr_bt.click(chat_clear, None, [chatbot, hidden_file_path, show_path_md], queue=False)
  584. # re_bt.click(re_bot, chatbot, chatbot)
  585. chat_stop_bt.click(chat_clear_last, None, None, cancels=[txt_msg, re_txt_msg], queue=False)
  586. # show_path_bt.click(lambda x:[None, gr.update(visible=False)], hidden_file_path, [show_path_md,show_path_bt])
  587. plug_bt.change(change_use_ci_flag)
  588. bidding_bt.change(change_use_bidding_flag)
  589. # img_cloud = gr.Image(height='50px')
  590. # update_bt.click(update_rec_list, gr.Textbox('update', visible=False), rec_list, queue=False)
  591. # date.change(update_all, date, [img_cloud, browser_list, rec_list], queue=False)
  592. date1.change(update_app_global_para, [date1, date2], None).then(update_browser_list, None, browser_list).then(lambda: None, None, None, _js=f'() => {{{js}}}').then(chat_clear, None, [chatbot, hidden_file_path, show_path_md])
  593. date2.change(update_app_global_para, [date1, date2], None).then(update_browser_list, None, browser_list).then(lambda: None, None, None, _js=f'() => {{{js}}}').then(chat_clear, None, [chatbot, hidden_file_path, show_path_md])
  594. # demo.load(update_all, date, [img_cloud, browser_list, rec_list])
  595. demo.load(update_app_global_para, [date1, date2], None).then(update_browser_list, None, browser_list).then(lambda: None, None, None, _js=f'() => {{{js}}}').then(chat_clear, None, [chatbot, hidden_file_path, show_path_md])
  596. # .then(update_rec_list, gr.Textbox('load', visible=False), rec_list, queue=False)
  597. demo.queue().launch(server_name=server_host, server_port=workstation_port)