新功能

This commit is contained in:
yuruo 2024-04-12 14:46:07 +08:00
parent 5bdfe7dbd5
commit 3c9e818e65
12 changed files with 98 additions and 92 deletions

4
.gitignore vendored
View File

@ -7,7 +7,11 @@ dist/
.venv
config.yaml
build/
cache
**.lock
# Ignore Python cache files
**/__pycache__/
/session
main.spec

View File

@ -33,19 +33,21 @@ class WorkerAgent:
def get_iter(question):
llm = LLM_Util().llm()
tools = ToolsUtil.get_tools()
instructions = ""
example = """例子如下案例1```Thought: 我需要使用工具吗? 需要\nAction: 桌面路径\nAction Input: 无\nObservation: c:/path/develop```\n
案例2```Thought: 我需要使用工具吗? 需要\nAction: 打开应用\nAction Input: xxx\nObservation: 打开成功```\n
案例3```Thought: 我需要使用工具吗? 不需要\nFinal Answer: 您的桌面上有以下文件```\n
"""
prompt = PromptTemplate(
template="{instructions}\n\nTOOLS:\n------\n\n你可以使用以下工具:\n\n{tools}\n\n使用工具时,请使用以下格式:\n\n"
template="TOOLS:\n------\n\n你可以使用以下工具:\n\n{tools}\n\n使用工具时,请使用以下格式:\n\n"
"```\n'Thought: 我需要使用工具吗? 需要\nAction: {tool_names}'\n"
"'Action Input: Action的输入'\n'Observation: 运行Action的结果'\n```"
"\n\n当输出内容时,或者不需要使用工具,必须使用以下格式: "
"\n\n```\nThought: 我需要使用工具吗? 不需要\nFinal Answer: [你的回复]\n```\n\n开始!\n\n"
"\n\n```\nThought: 我需要使用工具吗? 不需要\nFinal Answer: [你的回复]\n```\n\n{example}\n\n"
"Previous conversation history:\n{chat_history}\n\nNew input: {input}\n{agent_scratchpad}",
input_variables=['agent_scratchpad', 'input', 'tool_names', 'tools'],
partial_variables={'chat_history': '', 'instructions': ""}
)
base_prompt = hub.pull("langchain-ai/react-agent-template")
# prompt = base_prompt.partial(instructions=instructions)
prompt = prompt.partial(example=example)
agent = create_react_agent(llm=llm, tools=tools, prompt=prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
return agent_executor.iter({"input": question})

View File

@ -5,6 +5,7 @@ from PyQt6.QtWidgets import QLabel, QTextEdit, QListWidgetItem, QSpacerItem, QSi
from agent.woker_agent import WorkerAgent
from pages.bse_page import BasePage
from pages.func_list_page import FuncListPage
from utils.config import Config
from utils.qt_util import QtUtil
@ -62,7 +63,6 @@ class ChatPage(BasePage):
chat_input.setGeometry(QtCore.QRect(40, 580, 601, 51))
chat_input.setStyleSheet("border-radius: 30px")
chat_input.setObjectName("chat_input")
self.ui.action_widget.hide()
self.new_conversation(
"<b>你好,欢迎来到智子 🎉</b>\n\n智子是一个让普通人成为超级个体的Agent开发平台只要你有想法都可以用智子快速、低门槛搭建专属于你的 Agent",
"system"
@ -72,10 +72,24 @@ class ChatPage(BasePage):
# 设置 QListWidget 的选择模式为 NoSelection
self.ui.chat_list.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
# 设置 QListWidget 的焦点策略为 NoFocus
self.ui.chat_list.setFocusPolicy(Qt.FocusPolicy.NoFocus)
# 垂直滚动条滑动时才显示,否则隐藏
self.ui.chat_list.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
# 隐藏水平滚动条
self.ui.chat_list.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
# self.ui.select_action.clicked.connect(self.select_action_clicked)
setting_action = self.ui.setting_action
setting_action.triggered.connect(self.open_setting_page)
# 添加按钮点击事件,打开添加对话框
self.ui.add_action.clicked.connect(self.open_add_dialog)
def open_add_dialog(self):
self.func_list_page = FuncListPage(parent=self.ui)
# self.func_list_page.setParent(self.ui)
self.func_list_page.show()
self.ui.hide()
def open_setting_page(self):
self.setting_page = QtUtil.load_ui("setting_page.ui")
@ -97,13 +111,6 @@ class ChatPage(BasePage):
def cancel_btn(self):
self.setting_page.close()
def hide_action(self, event):
action_widget = self.ui.action_widget
if not QRect(action_widget.mapToGlobal(QPoint(0, 0)), action_widget.size()).contains(event.globalPos()):
action_widget.hide()
def select_action_clicked(self):
self.ui.action_widget.show()
def new_conversation(self, text, role):
text = text.replace("\n", "<br>")

View File

@ -40,58 +40,18 @@
<string notr="true">border-radius: 30px</string>
</property>
</widget>
<widget class="QWidget" name="action_widget" native="true">
<widget class="QPushButton" name="add_action">
<property name="geometry">
<rect>
<x>40</x>
<y>340</y>
<width>201</width>
<height>201</height>
<y>550</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background: rgb(255, 255, 255)</string>
<property name="text">
<string>注入魔力</string>
</property>
<widget class="QPushButton" name="pushButton_3">
<property name="geometry">
<rect>
<x>120</x>
<y>0</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>新增插件</string>
</property>
</widget>
<widget class="QListWidget" name="listWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>30</y>
<width>201</width>
<height>171</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background: transparent;
border: none;</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>101</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>已选用 0/0 个插件</string>
</property>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">

View File

@ -124,8 +124,8 @@ class ActionList(QListWidget):
mime_data.setData(self.MY_MIME_TYPE, byte_array)
# 设置拖拽缩略图
drag = QDrag(self)
icon = self.style().standardIcon(QStyle.StandardPixmap.SP_TitleBarNormalButton)
drag.setMimeData(mime_data)
icon = self.style().standardIcon(QStyle.StandardPixmap.SP_TitleBarNormalButton)
pixmap = icon.pixmap(10, 10)
drag.setPixmap(pixmap)
# 拖拽结束

View File

@ -1,10 +1,13 @@
import typing
from PyQt6 import QtCore
from PyQt6.QtCore import QSize, Qt
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QGraphicsOpacityEffect, QToolButton
from PyQt6.QtWidgets import QGraphicsOpacityEffect, QToolButton, QMainWindow, QWidget
from pages.bse_page import BasePage
from pages.edit_page import EditPage, GlobalUtil
from utils.qt_util import QtUtil
from PyQt6.uic import loadUiType
class AddFuncButton(QToolButton):
def __init__(self, func_status, func_list_pos_row, func_list_pos_column, func_list_page):
@ -48,17 +51,33 @@ class AddFuncButton(QToolButton):
self.opacity_effect.setOpacity(0)
class FuncListPage(BasePage):
interface_ui = QtUtil.load_ui_type("func_list_page.ui")
class FuncListPage(QMainWindow, interface_ui):
def __init__(self, parent):
self.parent_ui = parent
super().__init__()
self.setupUi(self)
self.setup_up()
# 关闭事件
def closeEvent(self, event):
self.parent_ui.show()
def setup_up(self):
self.ui = QtUtil.load_ui("func_list_page.ui")
# self.ui = QtUtil.load_ui("func_list_page.ui")
# 四行三列,辅满通用应用列表布局
for i in range(3): # 3行
for j in range(4): # 4列
add_button = AddFuncButton("通用", i, j, self.ui)
self.ui.general_layout.addWidget(add_button, i, j)
add_button = AddFuncButton("通用", i, j, self)
self.general_layout.addWidget(add_button, i, j)
# 四行四列,辅满专属应用列表布局
for i in range(3): # 4行
for j in range(4): # 4列
add_button = AddFuncButton("专属", i, j, self.ui)
self.ui.special_layout.addWidget(add_button, i, j)
add_button = AddFuncButton("专属", i, j, self)
self.special_layout.addWidget(add_button, i, j)

View File

@ -1,7 +1,5 @@
import os
from langchain_core.tools import BaseTool
from langchain.tools import BaseTool
class FindDesktopPath(BaseTool):
name = "桌面路径"
@ -9,6 +7,6 @@ class FindDesktopPath(BaseTool):
# args_schema = None
def _run(self, *tool_args, **tool_kwargs):
def _run(self):
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
return desktop_path
return desktop_path

View File

@ -1,7 +1,6 @@
import os
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field
from langchain.tools import BaseTool
class ListAllFileInput(BaseModel):

View File

@ -1,7 +1,5 @@
import os
from langchain_core.tools import BaseTool
from langchain.tools import BaseTool
from tools.FindDesktopPath import FindDesktopPath
from tools.ListAllFile import ListAllFile
@ -10,7 +8,8 @@ class ListDesktopFiles(BaseTool):
name = "桌面的所有文件"
description = "返回桌面的所有文件"
def _run(self, *tool_args, **tool_kwargs):
def _run(self, *args):
print(args)
desk_top_path = FindDesktopPath().invoke(input={})
all_files = ListAllFile().invoke(input={"path": desk_top_path})
return all_files

View File

@ -1,16 +1,18 @@
import subprocess
from langchain.tools import BaseTool, ToolException # Updated import statement
from langchain.tools import BaseTool # Added ToolException impor
from pydantic import BaseModel, Field
from langchain_core.tools import ToolException
class OpenApplicationInput(BaseModel):
path: str = Field(description="应用路径", title="应用路径")
class OpenApplicationAction(BaseTool):
name = "打开应用"
description = "打开指定目录的应用"
args_schema = OpenApplicationInput
def _run(self, path):
subprocess.Popen(path)
try:
subprocess.Popen(path)
except Exception as e:
raise ToolException(f"请好好检查一下路径,是不是有不合理的字符,比如`\nObservation: `、`非路径内容`") # Using ToolException here

7
tools/base_tool.py Normal file
View File

@ -0,0 +1,7 @@
from langchain_core.tools import BaseTool
class BaseTool(BaseTool):
def run(self, **kwargs):
pass
def _run(self, **kwargs):
return self.run(**kwargs)

View File

@ -2,20 +2,29 @@ import os
import sys
from PyQt6 import uic
from PyQt6.uic import loadUiType
class QtUtil:
@staticmethod
def load_ui(*path):
# 项目根目录
# project_root_path = os.path.abspath(os.path.dirname(__file__))
@classmethod
def get_root_path(cls):
project_root_path = os.path.dirname(os.path.realpath(sys.argv[0]))
path = os.path.join(project_root_path, "pages", *path)
return project_root_path
@classmethod
def load_ui(cls, *path):
# 项目根目录
path = os.path.join(cls.get_root_path(), "pages", *path)
return uic.loadUi(path)
@staticmethod
def get_icon(*path):
project_root_path = os.path.dirname(os.path.realpath(sys.argv[0]))
# project_root_path = os.path.abspath(os.path.dirname(__file__))
path = os.path.join(project_root_path, "source", *path)
@classmethod
def load_ui_type(cls, *path):
path = os.path.join(cls.get_root_path(), "pages", *path)
interface_ui, _ = loadUiType(path)
return interface_ui
@classmethod
def get_icon(cls, *path):
path = os.path.join(cls.get_root_path(), "source", *path)
return path