AI对话新增多轮对话能力
@ -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接口
|
|
||||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 73 KiB |
@ -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')
|
||||||
|
@ -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()}')
|
||||||
|
@ -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", "发送"))
|
||||||
|
@ -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)
|
||||||
|
Before Width: | Height: | Size: 178 KiB |
Before Width: | Height: | Size: 137 KiB |
Before Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 41 KiB |
@ -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>
|
||||||
|
|
||||||
|