AI对话新增多轮对话能力

This commit is contained in:
SiYuan 2024-04-12 15:36:55 +08:00
parent 4fed8cea46
commit c7cf15acf6
20 changed files with 4790 additions and 2042 deletions

View File

@ -1,6 +1,6 @@
import os import os
version = '2.0.0' version = '2.0.5'
contact = '701805520' contact = '701805520'
github = 'https://github.com/LC044/WeChatMsg' github = 'https://github.com/LC044/WeChatMsg'
website = 'https://memotrace.cn/' website = 'https://memotrace.cn/'
@ -33,5 +33,3 @@ os.makedirs(OUTPUT_DIR, exist_ok=True)
# 全局参数 # 全局参数
SEND_LOG_FLAG = True # 是否发送错误日志 SEND_LOG_FLAG = True # 是否发送错误日志
SERVER_API_URL = 'http://api.lc044.love' # api接口 SERVER_API_URL = 'http://api.lc044.love' # api接口
# SERVER_API_URL = 'https://api.memotrace.cn/'
# SERVER_API_URL = 'http://127.0.0.1:8000' # api接口

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 73 KiB

File diff suppressed because it is too large Load Diff

View File

@ -39,6 +39,7 @@ class Icon:
Arrow_left_Icon = QIcon(':/icons/icons/arrow-left.svg') Arrow_left_Icon = QIcon(':/icons/icons/arrow-left.svg')
Arrow_right_Icon = QIcon(':/icons/icons/arrow-right.svg') Arrow_right_Icon = QIcon(':/icons/icons/arrow-right.svg')
Update_Icon = QIcon(':/icons/icons/update.svg') Update_Icon = QIcon(':/icons/icons/update.svg')
Clear_Icon = QIcon(':/icons/icons/clear.svg')
# Man_Icon_pixmap = QPixmap(Man_Icon_path) # Man_Icon_pixmap = QPixmap(Man_Icon_path)
# Woman_Icon_pixmap = QPixmap(Woman_Icon_path) # Woman_Icon_pixmap = QPixmap(Woman_Icon_path)
# Logo_Icon = QIcon(':/icons/icons/logo.png') # Logo_Icon = QIcon(':/icons/icons/logo.png')

View File

@ -1,3 +1,4 @@
import json
import sys import sys
import time import time
import traceback import traceback
@ -8,6 +9,7 @@ from PyQt5.QtCore import QThread, pyqtSignal, QSize, Qt
from PyQt5.QtGui import QPixmap from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout, QApplication, QTextBrowser, QMessageBox from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout, QApplication, QTextBrowser, QMessageBox
from app import config
from app.config import SERVER_API_URL from app.config import SERVER_API_URL
from app.log import logger from app.log import logger
from app.ui.Icon import Icon from app.ui.Icon import Icon
@ -63,6 +65,8 @@ class AIChat(QWidget, Ui_Form):
self.show_chats() self.show_chats()
self.pushButton.clicked.connect(self.send_msg) self.pushButton.clicked.connect(self.send_msg)
self.toolButton.clicked.connect(self.tool) self.toolButton.clicked.connect(self.tool)
self.btn_clear.clicked.connect(self.clear_dialog)
self.btn_clear.setIcon(Icon.Clear_Icon)
def init_ui(self): def init_ui(self):
self.textEdit.installEventFilter(self) self.textEdit.installEventFilter(self)
@ -94,6 +98,16 @@ class AIChat(QWidget, Ui_Form):
self.show_chat_thread.start() self.show_chat_thread.start()
self.scrollArea.verticalScrollBar().setValue(self.scrollArea.verticalScrollBar().maximum()) self.scrollArea.verticalScrollBar().setValue(self.scrollArea.verticalScrollBar().maximum())
def clear_dialog(self):
self.show_chat_thread.history = []
while self.verticalLayout_message.count():
item = self.verticalLayout_message.takeAt(0)
widget = item.widget()
if widget is not None:
widget.deleteLater()
else:
del item
def show_chats(self): def show_chats(self):
# return # return
self.show_chat_thread = AIChatThread() self.show_chat_thread = AIChatThread()
@ -134,13 +148,16 @@ class AIChatThread(QThread):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.msg = '' self.msg = ''
self.history = []
def run(self) -> None: def run(self) -> None:
url = urljoin(SERVER_API_URL, 'chat') url = urljoin(SERVER_API_URL, 'chat')
data = { data = {
'username': Me().wxid, 'username': Me().wxid,
'token': Me().token, 'token': Me().token,
'version': config.version,
'messages': [ 'messages': [
*self.history,
{ {
'role': 'user', 'role': 'user',
"content": self.msg "content": self.msg
@ -156,17 +173,36 @@ class AIChatThread(QThread):
# time.sleep(0.05) # time.sleep(0.05)
# return # return
resp = requests.post(url, json=data, stream=True) resp = requests.post(url, json=data, stream=True)
message = {
'role': 'user',
'content': self.msg
}
resp_message = {
'role': 'assistant',
'content': ''
}
if resp.status_code == 200: if resp.status_code == 200:
for line in resp.iter_lines(): for line in resp.iter_lines():
if line: if line:
trunk = line.decode('utf-8') trunk = line.decode('utf-8')
try:
data = json.loads(trunk.strip('data: '))
answer = data.get('answer')
print(answer)
if isinstance(answer, str):
resp_message['content'] += answer
self.msgSignal.emit(answer)
except:
print(trunk) print(trunk)
resp_message['content'] += trunk
self.msgSignal.emit(trunk) self.msgSignal.emit(trunk)
else: else:
print(resp.text) print(resp.text)
error = resp.json().get('error') error = resp.json().get('error')
logger.error(f'ai请求错误:{error}') logger.error(f'ai请求错误:{error}')
self.msgSignal.emit(error) self.msgSignal.emit(error)
self.history.append(message)
self.history.append(resp_message)
except Exception as e: except Exception as e:
error = str(e) error = str(e)
logger.error(f'ai请求错误:{error}{traceback.format_exc()}') logger.error(f'ai请求错误:{error}{traceback.format_exc()}')

View File

@ -32,6 +32,9 @@ class Ui_Form(object):
self.horizontalLayout_2.addWidget(self.label_reamrk) self.horizontalLayout_2.addWidget(self.label_reamrk)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem) self.horizontalLayout_2.addItem(spacerItem)
self.btn_clear = QtWidgets.QPushButton(self.frame)
self.btn_clear.setObjectName("btn_clear")
self.horizontalLayout_2.addWidget(self.btn_clear)
self.toolButton = QtWidgets.QToolButton(self.frame) self.toolButton = QtWidgets.QToolButton(self.frame)
self.toolButton.setObjectName("toolButton") self.toolButton.setObjectName("toolButton")
self.horizontalLayout_2.addWidget(self.toolButton) self.horizontalLayout_2.addWidget(self.toolButton)
@ -41,7 +44,7 @@ class Ui_Form(object):
self.scrollArea.setWidgetResizable(True) self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea") self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget() self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 795, 555)) self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 799, 564))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents) self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
self.verticalLayout_3.setObjectName("verticalLayout_3") self.verticalLayout_3.setObjectName("verticalLayout_3")
@ -66,5 +69,6 @@ class Ui_Form(object):
_translate = QtCore.QCoreApplication.translate _translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form")) Form.setWindowTitle(_translate("Form", "Form"))
self.label_reamrk.setText(_translate("Form", "EmoAi")) self.label_reamrk.setText(_translate("Form", "EmoAi"))
self.btn_clear.setText(_translate("Form", "清除对话"))
self.toolButton.setText(_translate("Form", "...")) self.toolButton.setText(_translate("Form", "..."))
self.pushButton.setText(_translate("Form", "发送")) self.pushButton.setText(_translate("Form", "发送"))

View File

@ -336,12 +336,11 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow, QCursorGif):
self.startBusy() self.startBusy()
self.action_update.triggered.connect(self.update) self.action_update.triggered.connect(self.update)
self.action_help_faq.triggered.connect( self.action_help_faq.triggered.connect(
lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/7"))) lambda: QDesktopServices.openUrl(QUrl("https://memotrace.cn/doc/posts/error/")))
self.about_view = AboutDialog(main_window=self, parent=self) self.about_view = AboutDialog(main_window=self, parent=self)
self.update_thread = UpdateThread(check_time=True) self.update_thread = UpdateThread(check_time=True)
self.update_thread.updateSignal.connect(self.show_update) self.update_thread.updateSignal.connect(self.show_update)
self.update_thread.start() self.update_thread.start()
# self.statusbar.set
def setCurrentIndex(self, row): def setCurrentIndex(self, row):
self.stackedWidget.setCurrentIndex(row) self.stackedWidget.setCurrentIndex(row)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

View File

@ -117,8 +117,6 @@
## PC端使用过程中部分问题解决可参考 ## PC端使用过程中部分问题解决可参考
<details>
#### 🤔如果您在pc端使用的时候出现问题可以先参考以下方面如果仍未解决可以在群里交流~ #### 🤔如果您在pc端使用的时候出现问题可以先参考以下方面如果仍未解决可以在群里交流~
* 不支持Win7 * 不支持Win7
@ -131,9 +129,7 @@
* 换电脑 * 换电脑
如果您在运行可执行程序的时候出现闪退的现象,请右击软件使用管理员权限运行。 如果您在运行可执行程序的时候出现闪退的现象,请右击软件使用管理员权限运行。
[查看详细教程](https://blog.lc044.love/post/5) [查看详细教程](https://memotrace.cn/doc/)
</details>
# 🏆致谢 # 🏆致谢
@ -216,7 +212,7 @@
后续更新将会在公众号同步发布 后续更新将会在公众号同步发布
<div> <div>
<img src="https://blog.lc044.love/static/img/3fd32f1732a2c8f53a7eb923472b8f19.clipboard-2023-12-18.webp"> <img src="https://blog.lc044.love/static/img/b8df8c594a4cabaa0a62025767a3cfd9.weixin.webp">
<img src="./doc/images/qq2.jpg" height="200"> <img src="./doc/images/qq2.jpg" height="200">
</div> </div>