From 3d8e10adec23f1977e8ecfa14dcae69e5bb43177 Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 10:13:45 +0800 Subject: [PATCH 01/14] =?UTF-8?q?fix=EF=BC=9A=E5=A2=9E=E5=8A=A0=E9=A2=84?= =?UTF-8?q?=E7=BD=AE=E5=B7=A5=E5=85=B7=E9=9C=80=E8=A6=81=E7=9A=84=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/pyproject.toml b/src/backend/pyproject.toml index a0928df76..bb8d7d857 100644 --- a/src/backend/pyproject.toml +++ b/src/backend/pyproject.toml @@ -83,6 +83,8 @@ psycopg-binary = "^3.1.9" emoji = "^2.10.1" platformdirs = ">=2.5" scipy = "*" +arxiv = "2.1.0" +matplotlib = "3.8.4" [tool.poetry.dev-dependencies] black = "^23.1.0" From da93b75920dfc28b8167c83560a78a5afd5ab4d1 Mon Sep 17 00:00:00 2001 From: jingwangyaun Date: Tue, 9 Apr 2024 14:49:43 +0800 Subject: [PATCH 02/14] current time prompt change --- .../bisheng_langchain/gpts/tools/get_current_time/tool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bisheng-langchain/bisheng_langchain/gpts/tools/get_current_time/tool.py b/src/bisheng-langchain/bisheng_langchain/gpts/tools/get_current_time/tool.py index 9d6ab27a5..f23215666 100644 --- a/src/bisheng-langchain/bisheng_langchain/gpts/tools/get_current_time/tool.py +++ b/src/bisheng-langchain/bisheng_langchain/gpts/tools/get_current_time/tool.py @@ -15,7 +15,7 @@ class GetCurTimeInput(BaseModel): @tool(args_schema=GetCurTimeInput) def get_current_time(timezone='Asia/Shanghai'): """ - Get the current UTC time and the time in the major time zones, which can be used for calculations related to time, date, and other scenarios. + 获取当前UTC时间以及主要时区的时间,可用于时间、日期等场景相关的计算。当问题涉及到时间,调用此工具来查询和时间有关的内容。 """ tz = pytz.timezone(timezone) current_time = datetime.now(tz) From cd12745fb967730845920bd7e8f62f0baadf514d Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 16:15:45 +0800 Subject: [PATCH 03/14] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E6=94=B9=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E8=B0=83=E7=94=A8=E7=9A=84=E5=9B=9E=E8=B0=83=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/bisheng/api/v1/callback.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/backend/bisheng/api/v1/callback.py b/src/backend/bisheng/api/v1/callback.py index b5caf2b66..0e958081e 100644 --- a/src/backend/bisheng/api/v1/callback.py +++ b/src/backend/bisheng/api/v1/callback.py @@ -1,4 +1,5 @@ import asyncio +import json from typing import Any, Dict, List, Union from bisheng.api.v1.schemas import ChatResponse @@ -371,7 +372,7 @@ async def on_tool_start(self, serialized: Dict[str, Any], input_str: str, **kwar message={'tool_key': tool_name, 'serialized': serialized, 'input_str': input_str}, flow_id=self.flow_id, chat_id=self.chat_id, - sender=kwargs.get('run_id').hex) + extra=json.dumps({'run_id': kwargs.get('run_id').hex})) await self.websocket.send_json(resp.dict()) ChatMessageDao.insert_one(ChatMessageModel( @@ -383,7 +384,7 @@ async def on_tool_start(self, serialized: Dict[str, Any], input_str: str, **kwar flow_id=self.flow_id, chat_id=self.chat_id, user_id=self.user_id, - sender=kwargs.get('run_id').hex + extra=json.dumps({'run_id': kwargs.get('run_id').hex}) )) async def on_tool_end(self, output: str, **kwargs: Any) -> Any: @@ -404,7 +405,7 @@ async def on_tool_end(self, output: str, **kwargs: Any) -> Any: message={'tool_key': tool_name, 'output': output}, flow_id=self.flow_id, chat_id=self.chat_id, - sender=kwargs.get('run_id').hex) + extra=json.dumps({'run_id': kwargs.get('run_id').hex})) await self.websocket.send_json(resp.dict()) ChatMessageDao.insert_one(ChatMessageModel( @@ -416,7 +417,7 @@ async def on_tool_end(self, output: str, **kwargs: Any) -> Any: flow_id=self.flow_id, chat_id=self.chat_id, user_id=self.user_id, - sender=kwargs.get('run_id').hex + extra=json.dumps({'run_id': kwargs.get('run_id').hex}) )) resp_start = ChatResponse(type='start', From 61d27d876046157205c4964836c77b7ef40659c0 Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 17:52:05 +0800 Subject: [PATCH 04/14] =?UTF-8?q?fix=EF=BC=9A=E5=8A=A9=E6=89=8B=E6=8E=88?= =?UTF-8?q?=E6=9D=83=E6=97=B6=E9=9C=80=E8=A6=81UUID=E5=92=8Cstr=E7=9A=84?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/bisheng/api/v1/user.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/bisheng/api/v1/user.py b/src/backend/bisheng/api/v1/user.py index f6d156b16..96b5927d2 100644 --- a/src/backend/bisheng/api/v1/user.py +++ b/src/backend/bisheng/api/v1/user.py @@ -373,10 +373,10 @@ async def access_refresh(*, data: RoleRefresh, Authorize: AuthJWT = Depends()): session.commit() # 添加新的权限 with session_getter() as session: - for id in access_id: - if access_type == AccessType.FLOW.value: - id = UUID(id).hex - role_access = RoleAccess(role_id=role_id, third_id=str(id), type=access_type) + for third_id in access_id: + if access_type in [AccessType.FLOW.value, AccessType.ASSISTANT_READ.value]: + third_id = UUID(third_id).hex + role_access = RoleAccess(role_id=role_id, third_id=str(third_id), type=access_type) session.add(role_access) session.commit() return resp_200() From f9496b86356ca99a708f8f33205d31fce3dd2adf Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 19:29:42 +0800 Subject: [PATCH 05/14] =?UTF-8?q?fix=EF=BC=9A=E8=8E=B7=E5=8F=96=E5=8A=A9?= =?UTF-8?q?=E6=89=8B=E6=8E=88=E6=9D=83=E5=88=97=E8=A1=A8=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B0=86id=E8=BD=AC=E4=B8=BAuuid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/bisheng/api/v1/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/bisheng/api/v1/user.py b/src/backend/bisheng/api/v1/user.py index 96b5927d2..c5b985c6e 100644 --- a/src/backend/bisheng/api/v1/user.py +++ b/src/backend/bisheng/api/v1/user.py @@ -399,7 +399,7 @@ async def access_list(*, role_id: int, type: Optional[int] = None, Authorize: Au total_count = session.scalar(count_sql) # uuid 和str的转化 for access in db_role_access: - if access.type == AccessType.FLOW.value: + if access.type in [AccessType.FLOW.value, AccessType.ASSISTANT_READ.value]: access.third_id = UUID(access.third_id) return resp_200({ From ff3891aa5a282209353a98b5c571c6d1c79d4a25 Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 19:39:26 +0800 Subject: [PATCH 06/14] =?UTF-8?q?fix=EF=BC=9A=E6=8A=80=E8=83=BD=E7=9A=84?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95=EF=BC=8C=E5=B0=86dict?= =?UTF-8?q?=E8=BD=AC=E4=B8=BAjson?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/bisheng/chat/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/bisheng/chat/manager.py b/src/backend/bisheng/chat/manager.py index bf14c4a25..c39a975c1 100644 --- a/src/backend/bisheng/chat/manager.py +++ b/src/backend/bisheng/chat/manager.py @@ -45,7 +45,7 @@ def add_message( if chat_id and (message.message or message.intermediate_steps or message.files) and message.type != 'stream': msg = message.copy() - msg.message = str(msg.message) if isinstance(msg.message, dict) else msg.message + msg.message = json.dumps(msg.message) if isinstance(msg.message, dict) else msg.message files = json.dumps(msg.files) if msg.files else '' msg.__dict__.pop('files') db_message = ChatMessage(files=files, **msg.__dict__) From 2c09c5548f8580dd4f8589d3fa284a4cce5bddff Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 21:27:42 +0800 Subject: [PATCH 07/14] =?UTF-8?q?fix=EF=BC=9Atool=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E5=BC=80=E5=A7=8B=E5=92=8C=E7=BB=93=E6=9D=9F=E6=97=A0=E9=9C=80?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E5=92=8C=E5=BC=80=E5=90=AFprocessing?= =?UTF-8?q?=E7=9A=84start=E5=92=8Cend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/bisheng/api/v1/callback.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/backend/bisheng/api/v1/callback.py b/src/backend/bisheng/api/v1/callback.py index 0e958081e..50e14f557 100644 --- a/src/backend/bisheng/api/v1/callback.py +++ b/src/backend/bisheng/api/v1/callback.py @@ -358,12 +358,6 @@ def parse_tool_category(tool_name) -> (str, str): async def on_tool_start(self, serialized: Dict[str, Any], input_str: str, **kwargs: Any) -> Any: """Run when tool starts running.""" logger.debug(f'on_tool_start serialized={serialized} input_str={input_str} kwargs={kwargs}') - resp_end = ChatResponse(type='end', - category='processing', - intermediate_steps='', - flow_id=self.flow_id, - chat_id=self.chat_id) - await self.websocket.send_json(resp_end.dict()) tool_name, tool_category = self.parse_tool_category(serialized['name']) resp = ChatResponse(type='start', @@ -419,10 +413,3 @@ async def on_tool_end(self, output: str, **kwargs: Any) -> Any: user_id=self.user_id, extra=json.dumps({'run_id': kwargs.get('run_id').hex}) )) - - resp_start = ChatResponse(type='start', - category='processing', - intermediate_steps='', - flow_id=self.flow_id, - chat_id=self.chat_id) - await self.websocket.send_json(resp_start.dict()) From bd4ee4cc2a24862accf6bdd67db7a02252e06b0b Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 21:41:20 +0800 Subject: [PATCH 08/14] =?UTF-8?q?fix=EF=BC=9Aanswer=E7=9A=84=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E4=BF=A1=E6=81=AF=E5=8C=85=E5=90=AB=E5=9C=A8process?= =?UTF-8?q?=E7=9A=84=E5=BC=80=E5=A7=8B=E5=92=8C=E7=BB=93=E6=9D=9F=E4=B9=8B?= =?UTF-8?q?=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/bisheng/chat/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/bisheng/chat/client.py b/src/backend/bisheng/chat/client.py index 0eec0d44a..1ac06e7db 100644 --- a/src/backend/bisheng/chat/client.py +++ b/src/backend/bisheng/chat/client.py @@ -191,8 +191,8 @@ async def handle_gpts_message(self, message: Dict[any, any]): res = await self.add_message('bot', answer, 'answer') - await self.send_response('processing', 'end', '') await self.send_response('answer', 'start', '') await self.send_response('answer', 'end', answer, message_id=res.id if res else None) + await self.send_response('processing', 'end', '') await self.send_response('processing', 'close', '') From bbbf1666a10e6d67490848c5a485addb19a1cfd2 Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 21:49:39 +0800 Subject: [PATCH 09/14] =?UTF-8?q?fix=EF=BC=9A=E5=8E=BB=E6=8E=89answer?= =?UTF-8?q?=E7=9A=84=E5=9B=9E=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/bisheng/chat/client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/bisheng/chat/client.py b/src/backend/bisheng/chat/client.py index 1ac06e7db..0349b9b22 100644 --- a/src/backend/bisheng/chat/client.py +++ b/src/backend/bisheng/chat/client.py @@ -191,8 +191,8 @@ async def handle_gpts_message(self, message: Dict[any, any]): res = await self.add_message('bot', answer, 'answer') - await self.send_response('answer', 'start', '') - await self.send_response('answer', 'end', answer, message_id=res.id if res else None) + # await self.send_response('answer', 'start', '') + # await self.send_response('answer', 'end', answer, message_id=res.id if res else None) - await self.send_response('processing', 'end', '') + await self.send_response('processing', 'end', answer, message_id=res.id if res else None) await self.send_response('processing', 'close', '') From 306e6b237d15525dc85c47bacd2a6d3ed3c745e2 Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 22:08:23 +0800 Subject: [PATCH 10/14] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E6=94=B9=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E7=9A=84=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/bisheng/api/v1/callback.py | 22 ++++++++++++++++++++++ src/backend/bisheng/chat/client.py | 6 ++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/backend/bisheng/api/v1/callback.py b/src/backend/bisheng/api/v1/callback.py index 50e14f557..5141eb45f 100644 --- a/src/backend/bisheng/api/v1/callback.py +++ b/src/backend/bisheng/api/v1/callback.py @@ -355,6 +355,28 @@ def parse_tool_category(tool_name) -> (str, str): tool_name = tool_name.replace('knowledge_', '') return tool_name, tool_category + async def on_chat_model_start(self, serialized: Dict[str, Any], + messages: List[List[BaseMessage]], **kwargs: Any) -> Any: + # """Run when retriever end running.""" + # content = messages[0][0] if isinstance(messages[0][0], str) else messages[0][0].get('content') + # stream = ChatResponse(message=f'{content}', type='stream') + # await self.websocket.send_json(stream.dict()) + logger.debug(f'on_chat_model_start serialized={serialized} messages={messages} kwargs={kwargs}') + resp = ChatResponse(type='start', + category='processing', + flow_id=self.flow_id, + chat_id=self.chat_id) + await self.websocket.send_json(resp.dict()) + + async def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any: + """Run when LLM ends running.""" + logger.debug(f'llm_end response={response}') + resp = ChatResponse(type='start', + category='processing', + flow_id=self.flow_id, + chat_id=self.chat_id) + await self.websocket.send_json(resp.dict()) + async def on_tool_start(self, serialized: Dict[str, Any], input_str: str, **kwargs: Any) -> Any: """Run when tool starts running.""" logger.debug(f'on_tool_start serialized={serialized} input_str={input_str} kwargs={kwargs}') diff --git a/src/backend/bisheng/chat/client.py b/src/backend/bisheng/chat/client.py index 0349b9b22..9463fc007 100644 --- a/src/backend/bisheng/chat/client.py +++ b/src/backend/bisheng/chat/client.py @@ -174,7 +174,6 @@ async def handle_gpts_message(self, message: Dict[any, any]): await self.init_gpts_agent() await self.send_response('processing', 'begin', '') - await self.send_response('processing', 'start', '') # 将用户问题写入到数据库 await self.add_message('human', json.dumps(inputs, ensure_ascii=False), 'question') @@ -191,8 +190,7 @@ async def handle_gpts_message(self, message: Dict[any, any]): res = await self.add_message('bot', answer, 'answer') - # await self.send_response('answer', 'start', '') - # await self.send_response('answer', 'end', answer, message_id=res.id if res else None) + await self.send_response('answer', 'start', '') + await self.send_response('answer', 'end', answer, message_id=res.id if res else None) - await self.send_response('processing', 'end', answer, message_id=res.id if res else None) await self.send_response('processing', 'close', '') From c31f763c00cdcec457151a4b81fcbff299fa406e Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 22:10:45 +0800 Subject: [PATCH 11/14] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E6=94=B9=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/bisheng/api/v1/callback.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/bisheng/api/v1/callback.py b/src/backend/bisheng/api/v1/callback.py index 5141eb45f..8c3f8040d 100644 --- a/src/backend/bisheng/api/v1/callback.py +++ b/src/backend/bisheng/api/v1/callback.py @@ -371,7 +371,7 @@ async def on_chat_model_start(self, serialized: Dict[str, Any], async def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any: """Run when LLM ends running.""" logger.debug(f'llm_end response={response}') - resp = ChatResponse(type='start', + resp = ChatResponse(type='end', category='processing', flow_id=self.flow_id, chat_id=self.chat_id) From 7a6861e94e10fb57eabed09dba96e19e741b1ed5 Mon Sep 17 00:00:00 2001 From: GuoQing Zhang Date: Tue, 9 Apr 2024 22:34:46 +0800 Subject: [PATCH 12/14] =?UTF-8?q?feat=EF=BC=9A=E4=BF=AE=E6=94=B9docker-com?= =?UTF-8?q?pose=E4=B8=ADrt=E7=9A=84=E5=90=AF=E5=8A=A8=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E6=94=B9redis=E7=9A=84=E5=81=A5=E5=BA=B7?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-compose-model.yml | 3 +++ docker/docker-compose.yml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docker/docker-compose-model.yml b/docker/docker-compose-model.yml index 9a7604846..69bde2235 100644 --- a/docker/docker-compose-model.yml +++ b/docker/docker-compose-model.yml @@ -16,7 +16,10 @@ services: device_ids: ['0,1'] # 指定想映射给rt服务使用的宿主机上的GPU ID号,如想映射多个卡,可写为['0','1','2'] environment: TZ: Asia/Shanghai + # 不使用闭源模型的话,用下面的启动命令 command: ["./bin/rtserver", "f"] + # 使用闭源模型的话,用下面的启动命令,地址替换为授权地址 + # command: ["bash", "bin/entrypoint.sh", "--serveraddr="] volumes: - ${DOCKER_VOLUME_DIRECTORY:-.}/data/llm:/opt/bisheng-rt/models/model_repository # 冒号前为宿主机上放置模型目录的路径,请根据实际环境修改;冒号后为映射到容器内的路径,请勿修改 healthcheck: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index c900b37da..65a8d6d9e 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -32,7 +32,7 @@ services: - ${DOCKER_VOLUME_DIRECTORY:-.}/redis/redis.conf:/etc/redis.conf command: redis-server /etc/redis.conf healthcheck: - test: ["CMD-SHELL", "redis-cli ping | grep PONG"] + test: ["CMD-SHELL", "redis-cli ping | grep -e 'PONG\|NOAUTH'"] interval: 10s timeout: 5s retries: 3 From a1cbfadfbedbf58ae2df1db890c2331550345bde Mon Sep 17 00:00:00 2001 From: dolphin <78075021@qq.com> Date: Tue, 9 Apr 2024 23:06:46 +0800 Subject: [PATCH 13/14] fix: markdown style --- src/frontend/public/locales/zh/bs.json | 2 +- src/frontend/src/App.tsx | 10 +- .../bs-comp/cardComponent/index.tsx | 16 +- .../bs-comp/chatComponent/ChatInput.tsx | 10 + .../bs-comp/chatComponent/MessageBs.tsx | 17 +- .../bs-comp/chatComponent/MessagePanne.tsx | 6 +- .../bs-comp/chatComponent/MessageSystem.tsx | 21 +- .../bs-comp/chatComponent/messageStore.ts | 82 ++- .../bs-comp/sheets/SkillChatSheet.tsx | 5 +- .../components/bs-comp/sheets/SkillSheet.tsx | 2 +- .../bs-comp/sheets/SkillTempSheet.tsx | 2 +- .../components/bs-comp/sheets/ToolsSheet.tsx | 15 +- .../components/bs-icons/assistant/icon.svg | 5 + .../components/bs-icons/assistant/index.tsx | 9 + .../src/components/bs-icons/tool/icon.svg | 14 + .../src/components/bs-icons/tool/index.tsx | 9 + .../bs-ui/pagination/autoPagination.tsx | 55 +- .../src/components/bs-ui/sheet/index.tsx | 1 + src/frontend/src/controllers/API/user.ts | 2 +- src/frontend/src/index.tsx | 2 + .../ChatAppPage/components/ChatPanne.tsx | 18 +- .../ChatAppPage/components/ChatReportForm.tsx | 19 +- src/frontend/src/pages/ChatAppPage/index.tsx | 2 +- .../components/editAssistant/Header.tsx | 3 +- .../components/editAssistant/Setting.tsx | 10 +- .../components/editAssistant/TestChat.tsx | 3 +- .../src/pages/SkillPage/editAssistant.tsx | 20 +- .../src/pages/SkillPage/tabAssistant.tsx | 6 +- .../src/pages/SkillPage/tabSkills.tsx | 2 +- .../pages/SystemPage/components/EditRole.tsx | 4 +- .../src/pages/SystemPage/components/Roles.tsx | 2 +- src/frontend/src/style/markdown.css | 572 ++++++++++++++++++ 32 files changed, 833 insertions(+), 113 deletions(-) create mode 100644 src/frontend/src/components/bs-icons/assistant/icon.svg create mode 100644 src/frontend/src/components/bs-icons/assistant/index.tsx create mode 100644 src/frontend/src/components/bs-icons/tool/icon.svg create mode 100644 src/frontend/src/components/bs-icons/tool/index.tsx create mode 100644 src/frontend/src/style/markdown.css diff --git a/src/frontend/public/locales/zh/bs.json b/src/frontend/public/locales/zh/bs.json index 8db845427..53eb59dfb 100644 --- a/src/frontend/public/locales/zh/bs.json +++ b/src/frontend/public/locales/zh/bs.json @@ -62,7 +62,7 @@ "skills": { "manageTemplate": "管理技能模板", "createNew": "新建技能", - "manageProjects": "这里管理您的个人项目,对技能上下线、编辑等等", + "manageProjects": "在此页面管理您的技能,对技能上下线、编辑等等", "skillSearch": "搜索您需要的技能", "confirmDeleteSkill": "确认删除该技能?", "backToSkillList": "返回技能列表", diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 9138ff2e6..c3574abc4 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -1,21 +1,21 @@ -import uniqueId from "lodash-es/uniqueId"; import cloneDeep from "lodash-es/cloneDeep"; +import uniqueId from "lodash-es/uniqueId"; import { useContext, useEffect, useState } from "react"; -import { RouterProvider, useSearchParams } from "react-router-dom"; +import { RouterProvider } from "react-router-dom"; import "reactflow/dist/style.css"; import "./App.css"; +import i18next from "i18next"; +import { useTranslation } from "react-i18next"; import ErrorAlert from "./alerts/error"; import NoticeAlert from "./alerts/notice"; import SuccessAlert from "./alerts/success"; +import { Toaster } from "./components/bs-ui/toast"; import { alertContext } from "./contexts/alertContext"; import { locationContext } from "./contexts/locationContext"; import { userContext } from "./contexts/userContext"; import { LoginPage } from "./pages/login"; import router from "./routes"; -import { useTranslation } from "react-i18next"; -import i18next from "i18next"; -import { Toaster } from "./components/bs-ui/toast"; export default function App() { let { setCurrent, setShowSideBar, setIsStackedOpen } = useContext(locationContext); diff --git a/src/frontend/src/components/bs-comp/cardComponent/index.tsx b/src/frontend/src/components/bs-comp/cardComponent/index.tsx index 99b139c6d..17a6282da 100644 --- a/src/frontend/src/components/bs-comp/cardComponent/index.tsx +++ b/src/frontend/src/components/bs-comp/cardComponent/index.tsx @@ -1,4 +1,7 @@ +import { AssistantIcon } from "@/components/bs-icons/assistant"; +import { cname } from "@/components/bs-ui/utils"; import { useState } from "react"; +import { AddToIcon } from "../../bs-icons/addTo"; import { DelIcon } from "../../bs-icons/del"; import { GoIcon } from "../../bs-icons/go"; import { PlusIcon } from "../../bs-icons/plus"; @@ -7,8 +10,6 @@ import { SkillIcon } from "../../bs-icons/skill"; import { UserIcon } from "../../bs-icons/user"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "../../bs-ui/card"; import { Switch } from "../../ui/switch"; -import { AddToIcon } from "../../bs-icons/addTo"; -import { cname } from "@/components/bs-ui/utils"; interface IProps { data: T, @@ -22,6 +23,7 @@ interface IProps { user?: string, isAdmin?: boolean, footer?: React.ReactNode, + icon?: any, onClick?: () => void, onAddTemp?: (data: T) => void, onCheckedChange?: (b: boolean, data: T) => Promise @@ -59,11 +61,11 @@ export function TitleIconBg({ id, className = '', children = }) { return
{children}
} - export default function CardComponent({ id = '', data, type, + icon: Icon = SkillIcon, edit = false, user, title, @@ -121,7 +123,9 @@ export default function CardComponent({
- + + +

{title}

{/* */} @@ -140,7 +144,9 @@ export default function CardComponent({ return
- + + {type === 'skill' ? : } + {edit && e.stopPropagation()}>}
{title} diff --git a/src/frontend/src/components/bs-comp/chatComponent/ChatInput.tsx b/src/frontend/src/components/bs-comp/chatComponent/ChatInput.tsx index 6e1b86c3c..f3b9186ee 100644 --- a/src/frontend/src/components/bs-comp/chatComponent/ChatInput.tsx +++ b/src/frontend/src/components/bs-comp/chatComponent/ChatInput.tsx @@ -64,6 +64,8 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on }, []) const handleSendClick = async () => { + // 解除锁定状态下 form 按钮开放的状态 + setShowWhenLocked(false) // 关闭引导词 setShowGuideQuestion(false) // 收起表单 @@ -83,6 +85,12 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on const chatid = chatId await createWebSocket(chatid) sendWsMsg(wsMsg) + + // 滚动聊天到底 + const messageDom = document.getElementById('message-panne') + if (messageDom) { + messageDom.scrollTop = messageDom.scrollHeight; + } } const sendWsMsg = async (msg) => { @@ -239,6 +247,7 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on > } + {/* form */}
{ form &&
}
+ {/* send */}
{ }, onSource }: { data: ChatMessageType, onUnlike?: any, onSource?: any }) { const avatarColor = colorList[ (data.sender?.split('').reduce((num, s) => num + s.charCodeAt(), 0) || 0) % colorList.length ] @@ -39,7 +38,7 @@ export default function MessageBs({ data, onUnlike, onSource }: { data: ChatMess remarkPlugins={[remarkGfm, remarkMath]} rehypePlugins={[rehypeMathjax]} linkTarget="_blank" - className="markdown prose inline-block break-all dark:prose-invert max-w-full text-sm text-[#111]" + className="bs-mkdown inline-block break-all max-w-full text-sm text-[#111]" components={{ code: ({ node, inline, className, children, ...props }) => { if (children.length) { @@ -102,7 +101,7 @@ export default function MessageBs({ data, onUnlike, onSource }: { data: ChatMess end={data.end} source={data.source} className="pl-8" - onSource={() => onSource({ + onSource={() => onSource?.({ chatId, messageId: data.id, message: data.message || data.thought, diff --git a/src/frontend/src/components/bs-comp/chatComponent/MessagePanne.tsx b/src/frontend/src/components/bs-comp/chatComponent/MessagePanne.tsx index 50ece9966..74ee139f6 100644 --- a/src/frontend/src/components/bs-comp/chatComponent/MessagePanne.tsx +++ b/src/frontend/src/components/bs-comp/chatComponent/MessagePanne.tsx @@ -56,8 +56,10 @@ export default function MessagePanne({ useName, guideWord, loadMore }) { return () => messagesRef.current?.removeEventListener('scroll', handleScroll) }, [messagesRef.current, messages, chatId]); - return
- {guideWord && } + return
+ {guideWord && } { messages.map(msg => { // 工厂 diff --git a/src/frontend/src/components/bs-comp/chatComponent/MessageSystem.tsx b/src/frontend/src/components/bs-comp/chatComponent/MessageSystem.tsx index e3c1107c4..f57a0626f 100644 --- a/src/frontend/src/components/bs-comp/chatComponent/MessageSystem.tsx +++ b/src/frontend/src/components/bs-comp/chatComponent/MessageSystem.tsx @@ -1,14 +1,30 @@ +import { useToast } from "@/components/bs-ui/toast/use-toast" +import { copyText } from "@/utils" +import { CopyIcon } from "@radix-ui/react-icons" import { useMemo } from "react" +import { useTranslation } from "react-i18next" import ReactMarkdown from "react-markdown" export default function MessageSystem({ data }) { + const { message } = useToast() + const { t } = useTranslation() + + const handleCopy = (dom) => { + copyText(dom) + + message({ + variant: 'success', + title: '提示', + description: t('chat.copyTip') + }) + } // 日志markdown const logMkdown = useMemo( () => ( data.thought && {data.thought.toString()} @@ -19,8 +35,9 @@ export default function MessageSystem({ data }) { const border = { system: 'border-slate-500', question: 'border-amber-500', processing: 'border-cyan-600', answer: 'border-lime-600', report: 'border-slate-500', guide: 'border-none' } return
-
+
{logMkdown} + {data.category === 'report' && handleCopy(e.target.parentNode)}>}
}; diff --git a/src/frontend/src/components/bs-comp/chatComponent/messageStore.ts b/src/frontend/src/components/bs-comp/chatComponent/messageStore.ts index ebd1f3c07..bfde64e94 100644 --- a/src/frontend/src/components/bs-comp/chatComponent/messageStore.ts +++ b/src/frontend/src/components/bs-comp/chatComponent/messageStore.ts @@ -34,6 +34,7 @@ type Actions = { startNewRound: () => void; insetSeparator: (text: string) => void; insetSystemMsg: (text: string) => void; + insetBsMsg: (text: string) => void; setShowGuideQuestion: (text: boolean) => void; } @@ -42,11 +43,17 @@ const handleHistoryMsg = (data: any[]): ChatMessageType[] => { return data.map(item => { // let count = 0 let { message, files, is_bot, intermediate_steps, ...other } = item + const correctedJsonString = (str: string) => str + // .replace(/\\([\s\S])|(`)/g, '\\\\$1$2') // 转义反斜线和反引号 + .replace(/\n/g, '\\n') // 转义换行符 + .replace(/\r/g, '\\r') // 转义回车符 + .replace(/\t/g, '\\t') // 转义制表符 + .replace(/'/g, '"'); // 将单引号替换为双引号 try { - message = message && message[0] === '{' ? JSON.parse(message.replace(/'/g, '"')) : message || '' + message = message && message[0] === '{' ? JSON.parse(correctedJsonString(message)) : message || '' } catch (e) { // 未考虑的情况暂不处理 - console.error('e :>> ', e); + console.error('消息 to JSON error :>> ', e); } return { ...other, @@ -61,6 +68,7 @@ const handleHistoryMsg = (data: any[]): ChatMessageType[] => { }) } +const runLogsTypes = ['tool', 'flow', 'knowledge'] export const useMessageStore = create((set, get) => ({ running: false, chatId: '', @@ -75,8 +83,10 @@ export const useMessageStore = create((set, get) => ({ set({ messages: msgs.reverse() }) }, async loadMoreHistoryMsg(flowid) { + if (get().running) return // 会话进行中禁止加载more历史 const chatId = get().chatId const prevMsgs = get().messages + if (!prevMsgs[0]?.id) return const res = await getChatHistory(flowid, chatId, 10, prevMsgs[0]?.id || 0) const msgs = handleHistoryMsg(res) set({ messages: [...msgs.reverse(), ...prevMsgs] }) @@ -101,56 +111,69 @@ export const useMessageStore = create((set, get) => ({ }] })) }, + // start createWsMsg(data) { console.log('change createWsMsg'); set((state) => { let newChat = cloneDeep(state.messages); newChat.push({ isSend: false, - message: ['tool', 'flow', 'knowledge'].includes(data.category) ? data.message : '', + message: runLogsTypes.includes(data.category) ? data.message : '', chatKey: '', thought: data.intermediate_steps || '', category: data.category || '', files: [], end: false, - user_name: '' + user_name: '', + extra: data.extra }) return { messages: newChat } }) }, + // stream end updateCurrentMessage(wsdata) { console.log('change updateCurrentMessage'); const messages = get().messages - const currentMessage = messages[messages.length - 1]; - + const isRunLog = runLogsTypes.includes(wsdata.category); + // run log类型存在嵌套情况,使用 extra 匹配 currentMessage; 否则取最近 + const currentMessageIndex = isRunLog ? + messages.findLastIndex((msg) => msg.extra === wsdata.extra) + : messages.findLastIndex((msg) => !runLogsTypes.includes(msg.category)) + const currentMessage = messages[currentMessageIndex] + const newCurrentMessage = { ...currentMessage, ...wsdata, id: wsdata.messageId, - message: ['tool', 'flow', 'knowledge'].includes(wsdata.category) ? wsdata.message : currentMessage.message + wsdata.message, + message: isRunLog ? wsdata.message : currentMessage.message + wsdata.message, thought: currentMessage.thought + (wsdata.thought ? `${wsdata.thought}\n` : ''), files: wsdata.files || null, category: wsdata.category || '', source: wsdata.source } - messages[messages.length - 1] = newCurrentMessage - // start - end 之间没有内容删除load - if (newCurrentMessage.end && !(newCurrentMessage.files.length || newCurrentMessage.thought || newCurrentMessage.message)) { - messages.pop() - } - // 无 messageid 删除 - // if (newCurrentMessage.end && !newCurrentMessage.id) { - // messages.pop() - // } - // 删除重复消息 - const prevMessage = messages[messages.length - 2]; - if (prevMessage && prevMessage.message === newCurrentMessage.message) { - const removedMsg = messages.pop() - // 使用最后一条的信息作为准确信息 - Object.keys(prevMessage).forEach((key) => { - prevMessage[key] = removedMsg[key] - }) + messages[currentMessageIndex] = newCurrentMessage + // 会话特殊处理,兼容后端的缺陷 + if (!isRunLog) { + // start - end 之间没有内容删除load + if (newCurrentMessage.end && !(newCurrentMessage.files.length || newCurrentMessage.thought || newCurrentMessage.message)) { + messages.pop() + } + // 无 messageid 删除 + // if (newCurrentMessage.end && !newCurrentMessage.id) { + // messages.pop() + // } + // 删除重复消息 + const prevMessage = messages[currentMessageIndex - 1]; + if (prevMessage + && prevMessage.message === newCurrentMessage.message + && prevMessage.thought === newCurrentMessage.thought) { + const removedMsg = messages.pop() + // 使用最后一条的信息作为准确信息 + Object.keys(prevMessage).forEach((key) => { + prevMessage[key] = removedMsg[key] + }) + } } set((state) => ({ messages: [...messages] })) }, @@ -180,6 +203,17 @@ export const useMessageStore = create((set, get) => ({ thought: text, }] })) + }, + insetBsMsg(text) { + set((state) => ({ + messages: [...state.messages, { + ...bsMsgItem, + id: 0, + category: 'guide', + thought: '', + message: text + }] + })) } })) diff --git a/src/frontend/src/components/bs-comp/sheets/SkillChatSheet.tsx b/src/frontend/src/components/bs-comp/sheets/SkillChatSheet.tsx index 66a2050d0..aa39a9b40 100644 --- a/src/frontend/src/components/bs-comp/sheets/SkillChatSheet.tsx +++ b/src/frontend/src/components/bs-comp/sheets/SkillChatSheet.tsx @@ -6,6 +6,8 @@ import { useNavigate } from "react-router-dom"; import { SearchInput } from "../../bs-ui/input"; import { Sheet, SheetContent, SheetDescription, SheetTitle, SheetTrigger } from "../../bs-ui/sheet"; import CardComponent from "../cardComponent"; +import { SkillIcon } from "@/components/bs-icons/skill"; +import { AssistantIcon } from "@/components/bs-icons/assistant"; export default function SkillChatSheet({ children, onSelect }) { const [open, setOpen] = useState(false) @@ -32,7 +34,7 @@ export default function SkillChatSheet({ children, onSelect }) { {children} -
+
e.stopPropagation()}>
对话选择 选择一个您想使用的线上技能或助手 @@ -47,6 +49,7 @@ export default function SkillChatSheet({ children, onSelect }) { title={flow.name} description={flow.desc} type="sheet" + icon={flow.flow_type === 'flow' ? SkillIcon : AssistantIcon} footer={ {flow.flow_type === 'flow' ? '技能' : '助手'} diff --git a/src/frontend/src/components/bs-comp/sheets/SkillSheet.tsx b/src/frontend/src/components/bs-comp/sheets/SkillSheet.tsx index 41d57b905..07a0db630 100644 --- a/src/frontend/src/components/bs-comp/sheets/SkillSheet.tsx +++ b/src/frontend/src/components/bs-comp/sheets/SkillSheet.tsx @@ -31,7 +31,7 @@ export default function SkillSheet({ select, children, onSelect }) { {children} -
+
e.stopPropagation()}>
添加技能 diff --git a/src/frontend/src/components/bs-comp/sheets/SkillTempSheet.tsx b/src/frontend/src/components/bs-comp/sheets/SkillTempSheet.tsx index 018d6adc5..b422bb960 100644 --- a/src/frontend/src/components/bs-comp/sheets/SkillTempSheet.tsx +++ b/src/frontend/src/components/bs-comp/sheets/SkillTempSheet.tsx @@ -29,7 +29,7 @@ export default function SkillTempSheet({ children, onSelect }) { {children} -
+
e.stopPropagation()}>
技能模板 您可以从这里挑选一个模板开始,或者自定义高级模板 diff --git a/src/frontend/src/components/bs-comp/sheets/ToolsSheet.tsx b/src/frontend/src/components/bs-comp/sheets/ToolsSheet.tsx index c695f3ab9..f4a7ff1da 100644 --- a/src/frontend/src/components/bs-comp/sheets/ToolsSheet.tsx +++ b/src/frontend/src/components/bs-comp/sheets/ToolsSheet.tsx @@ -5,6 +5,7 @@ import { Sheet, SheetContent, SheetTitle, SheetTrigger } from "@/components/bs-u import { getAssistantToolsApi } from "@/controllers/API/assistant"; import { useEffect, useMemo, useRef, useState } from "react"; import { TitleIconBg } from "../cardComponent"; +import { ToolIcon } from "@/components/bs-icons/tool"; export default function ToolsSheet({ select, onSelect, children }) { @@ -27,7 +28,7 @@ export default function ToolsSheet({ select, onSelect, children }) { {children} -
+
e.stopPropagation()}>
添加工具 setKeyword(e.target.value)} /> @@ -38,8 +39,8 @@ export default function ToolsSheet({ select, onSelect, children }) { options.length ? options.map(el => ( -
- +
+

{el.name}

{el.desc}

@@ -52,16 +53,16 @@ export default function ToolsSheet({ select, onSelect, children }) {

{api.name}

{api.desc}

-

参数: + {/*

参数: { api.params.map(param => ( {param.name} )) } -

+

*/} {select.some(_ => _.id === el.id) ? - - : + + : }
))} diff --git a/src/frontend/src/components/bs-icons/assistant/icon.svg b/src/frontend/src/components/bs-icons/assistant/icon.svg new file mode 100644 index 000000000..4b2d455f3 --- /dev/null +++ b/src/frontend/src/components/bs-icons/assistant/icon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/src/components/bs-icons/assistant/index.tsx b/src/frontend/src/components/bs-icons/assistant/index.tsx new file mode 100644 index 000000000..063ce9e7c --- /dev/null +++ b/src/frontend/src/components/bs-icons/assistant/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import { ReactComponent as Assistant } from "./icon.svg"; + +export const AssistantIcon = forwardRef< + SVGSVGElement & { className: any }, + React.PropsWithChildren<{ className?: string }> +>((props, ref) => { + return ; +}); diff --git a/src/frontend/src/components/bs-icons/tool/icon.svg b/src/frontend/src/components/bs-icons/tool/icon.svg new file mode 100644 index 000000000..7d65e8706 --- /dev/null +++ b/src/frontend/src/components/bs-icons/tool/icon.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/frontend/src/components/bs-icons/tool/index.tsx b/src/frontend/src/components/bs-icons/tool/index.tsx new file mode 100644 index 000000000..b39e8102c --- /dev/null +++ b/src/frontend/src/components/bs-icons/tool/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import { ReactComponent as Tool } from "./icon.svg"; + +export const ToolIcon = forwardRef< + SVGSVGElement & { className: any }, + React.PropsWithChildren<{ className?: string }> +>((props, ref) => { + return ; +}); diff --git a/src/frontend/src/components/bs-ui/pagination/autoPagination.tsx b/src/frontend/src/components/bs-ui/pagination/autoPagination.tsx index 4f2096a70..5d7a804d6 100644 --- a/src/frontend/src/components/bs-ui/pagination/autoPagination.tsx +++ b/src/frontend/src/components/bs-ui/pagination/autoPagination.tsx @@ -1,4 +1,5 @@ -import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious } from './index'; +import { DoubleArrowLeftIcon, DoubleArrowRightIcon } from '@radix-ui/react-icons'; +import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious } from './index'; interface IProps { /** 当前页码 */ @@ -28,6 +29,16 @@ const AutoPagination = ({ page, pageSize, total, maxVisiblePages = 5, className, // If total pages are more than maxVisiblePages, show at most maxVisiblePages pages const startPage = Math.max(1, page - Math.floor(maxVisiblePages / 2)); const endPage = Math.min(totalPages, startPage + maxVisiblePages - 1); + // page 0 + if (page !== 1) { + items.push( + + handlePageChange(1)} > + + + + ); + } // Previous Button items.push( @@ -53,14 +64,14 @@ const AutoPagination = ({ page, pageSize, total, maxVisiblePages = 5, className, } } else { - if (startPage > 1) { - // Display ellipsis if there are pages before the startPage - items.push( - - - - ); - } + // if (startPage > 1) { + // // Display ellipsis if there are pages before the startPage + // items.push( + // + // + // + // ); + // } for (let i = startPage; i <= endPage; i++) { items.push( @@ -74,14 +85,14 @@ const AutoPagination = ({ page, pageSize, total, maxVisiblePages = 5, className, ); } - if (endPage < totalPages) { - // Display ellipsis if there are pages after the endPage - items.push( - - - - ); - } + // if (endPage < totalPages) { + // // Display ellipsis if there are pages after the endPage + // items.push( + // + // + // + // ); + // } } // Next Button @@ -92,6 +103,16 @@ const AutoPagination = ({ page, pageSize, total, maxVisiblePages = 5, className, onClick={() => handlePageChange(page + 1)} /> ); + // page last + if (page !== totalPages) { + items.push( + + handlePageChange(totalPages)} > + + + + ); + } return items; }; diff --git a/src/frontend/src/components/bs-ui/sheet/index.tsx b/src/frontend/src/components/bs-ui/sheet/index.tsx index a1e6cd791..a957c3b46 100644 --- a/src/frontend/src/components/bs-ui/sheet/index.tsx +++ b/src/frontend/src/components/bs-ui/sheet/index.tsx @@ -23,6 +23,7 @@ const SheetOverlay = React.forwardRef< "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className )} + onClick={e => e.stopPropagation()} {...props} ref={ref} /> diff --git a/src/frontend/src/controllers/API/user.ts b/src/frontend/src/controllers/API/user.ts index 58c3bde78..dac715432 100644 --- a/src/frontend/src/controllers/API/user.ts +++ b/src/frontend/src/controllers/API/user.ts @@ -84,7 +84,7 @@ enum ACCESS_TYPE { USE_LIB = 1, USE_SKILL, MANAGE_LIB, - ASSISTANT + ASSISTANT = 5 } export async function updateRolePermissionsApi(data: { role_id: number, access_id: number[], type: ACCESS_TYPE }) { return await axios.post(`/api/v1/role_access/refresh`, data); diff --git a/src/frontend/src/index.tsx b/src/frontend/src/index.tsx index 6a7a525a0..876e27b87 100644 --- a/src/frontend/src/index.tsx +++ b/src/frontend/src/index.tsx @@ -9,6 +9,8 @@ import "./style/index.css"; import "./style/applies.css"; // @ts-ignore import "./style/classes.css"; +// @ts-ignore +import "./style/markdown.css"; const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement diff --git a/src/frontend/src/pages/ChatAppPage/components/ChatPanne.tsx b/src/frontend/src/pages/ChatAppPage/components/ChatPanne.tsx index f8506db18..dc0466269 100644 --- a/src/frontend/src/pages/ChatAppPage/components/ChatPanne.tsx +++ b/src/frontend/src/pages/ChatAppPage/components/ChatPanne.tsx @@ -2,10 +2,11 @@ import { TitleIconBg } from "@/components/bs-comp/cardComponent"; import ChatComponent from "@/components/bs-comp/chatComponent"; import { useMessageStore } from "@/components/bs-comp/chatComponent/messageStore"; +import { AssistantIcon } from "@/components/bs-icons/assistant"; import { NewApplicationIcon } from "@/components/bs-icons/newApplication"; import { useToast } from "@/components/bs-ui/toast/use-toast"; import { locationContext } from "@/contexts/locationContext"; -import { getAssistantDetailApi } from "@/controllers/API/assistant"; +import { useAssistantStore } from "@/store/assistantStore"; import { useContext, useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { TabsContext } from "../../../contexts/tabsContext"; @@ -21,7 +22,8 @@ export default function ChatPanne({ customWsHost = '', data }) { const [flow, setFlow] = useState(null) const [assistant, setAssistant] = useState(null) - console.log('data :>> ', flow); + const { assistantState, loadAssistantState } = useAssistantStore() + // console.log('data :>> ', flow); const build = useBuild() const { messages, loadHistoryMsg, loadMoreHistoryMsg, changeChatId, destory } = useMessageStore() @@ -35,7 +37,7 @@ export default function ChatPanne({ customWsHost = '', data }) { changeChatId(chatId) // ws } else { setFlow(null) - const _assistant = await getAssistantDetailApi(id) + const _assistant = await loadAssistantState(id) loadHistoryMsg(_assistant.id, chatId) setAssistant(_assistant) changeChatId(chatId) // ws @@ -158,12 +160,12 @@ export default function ChatPanne({ customWsHost = '', data }) {
- return
+ return
{/* 技能会话 */} { flow &&
{/* {flow && } */} -
+
{flow.name}
@@ -183,13 +185,13 @@ export default function ChatPanne({ customWsHost = '', data }) { assistant &&
{/* {flow && } */}
- + {assistant.name}
item)} + guideWord={assistantState.guide_word} wsUrl={wsUrl} onBeforSend={getWsParamData} loadMore={() => loadMoreHistoryMsg(assistant.id)} diff --git a/src/frontend/src/pages/ChatAppPage/components/ChatReportForm.tsx b/src/frontend/src/pages/ChatAppPage/components/ChatReportForm.tsx index 1256aeffc..0824ad8c8 100644 --- a/src/frontend/src/pages/ChatAppPage/components/ChatReportForm.tsx +++ b/src/frontend/src/pages/ChatAppPage/components/ChatReportForm.tsx @@ -1,6 +1,6 @@ +import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/bs-ui/select"; import { useContext, useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; -import Dropdown from "../../../components/dropdownComponent"; import InputComponent from "../../../components/inputComponent"; import InputFileComponent from "../../../components/inputFileComponent"; import { Button } from "../../../components/ui/button"; @@ -68,11 +68,18 @@ export default function ChatReportForm({ flow, onStart }) { onChange={(val) => handleChange(i, val)} /> : item.type === VariableType.Select ? - e.value)} - onSelect={(val) => handleChange(i, val)} - value={item.value} - > : + : item.type === VariableType.File ? handleSelectChat(chat)}>

- + {chat.flow_name}

{chat.flow_description} diff --git a/src/frontend/src/pages/SkillPage/components/editAssistant/Header.tsx b/src/frontend/src/pages/SkillPage/components/editAssistant/Header.tsx index 47b31b549..097d75df5 100644 --- a/src/frontend/src/pages/SkillPage/components/editAssistant/Header.tsx +++ b/src/frontend/src/pages/SkillPage/components/editAssistant/Header.tsx @@ -1,4 +1,5 @@ import { TitleIconBg } from "@/components/bs-comp/cardComponent"; +import { AssistantIcon } from "@/components/bs-icons/assistant"; import { Button } from "@/components/bs-ui/button"; import { Dialog, DialogTrigger } from "@/components/bs-ui/dialog"; import { useAssistantStore } from "@/store/assistantStore"; @@ -30,7 +31,7 @@ export default function Header({ onSave, onLine }) { return
- + {assistantState.name} {/* edit dialog */} diff --git a/src/frontend/src/pages/SkillPage/components/editAssistant/Setting.tsx b/src/frontend/src/pages/SkillPage/components/editAssistant/Setting.tsx index 2f28afa5d..37b6a5c70 100644 --- a/src/frontend/src/pages/SkillPage/components/editAssistant/Setting.tsx +++ b/src/frontend/src/pages/SkillPage/components/editAssistant/Setting.tsx @@ -1,6 +1,7 @@ +import { TitleIconBg } from "@/components/bs-comp/cardComponent"; import SkillSheet from "@/components/bs-comp/sheets/SkillSheet"; import ToolsSheet from "@/components/bs-comp/sheets/ToolsSheet"; -import { TitleIconBg } from "@/components/bs-comp/cardComponent"; +import { ToolIcon } from "@/components/bs-icons/tool"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/bs-ui/accordion"; import { Button } from "@/components/bs-ui/button"; import { InputList, Textarea } from "@/components/bs-ui/input"; @@ -133,7 +134,10 @@ export default function Setting() { dispatchAssistant('setting', { tool_list: [...assistantState.tool_list, tool] })}> - e.stopPropagation()}> + e.stopPropagation()} + >
@@ -143,7 +147,7 @@ export default function Setting() { assistantState.tool_list.map(tool => (
- +

{tool.name}

- + 调试预览
{ loadAssistantState(assisId).then((res) => { setShowGuideQuestion(true) setGuideQuestion(res.guide_question?.filter((item) => item) || []) - res.guide_word && insetSystemMsg(res.guide_word) + res.guide_word && insetBsMsg(res.guide_word) }) }, []) @@ -34,7 +34,7 @@ export default function editAssistant() { saveAfter() startNewRound() setGuideQuestion(assistantState.guide_question.filter((item) => item)) - assistantState.guide_word && insetSystemMsg(assistantState.guide_word) + assistantState.guide_word && insetBsMsg(assistantState.guide_word) } const { message, toast } = useToast() diff --git a/src/frontend/src/pages/SkillPage/tabAssistant.tsx b/src/frontend/src/pages/SkillPage/tabAssistant.tsx index 21f7b7d28..bcd4cee25 100644 --- a/src/frontend/src/pages/SkillPage/tabAssistant.tsx +++ b/src/frontend/src/pages/SkillPage/tabAssistant.tsx @@ -59,8 +59,8 @@ export default function Assistants() { type='skill' title="新建助手" description={(<> -

没有想法?

-

我们提供场景模板供您使用和参考

+

通过描述角色和任务来创建你的助手

+

助手可以调用多个技能和工具

)} onClick={() => console.log('新建')} > @@ -90,7 +90,7 @@ export default function Assistants() {
{/* footer */}
-

助手是可以调用一个或者多个技能的智能体

+

在此页面管理您的助手,对助手上下线、编辑等等

diff --git a/src/frontend/src/pages/SkillPage/tabSkills.tsx b/src/frontend/src/pages/SkillPage/tabSkills.tsx index 564859d12..73e54c3ba 100644 --- a/src/frontend/src/pages/SkillPage/tabSkills.tsx +++ b/src/frontend/src/pages/SkillPage/tabSkills.tsx @@ -91,7 +91,7 @@ export default function Skills() { type='skill' title={t('skills.createNew')} description={(<> -

没有想法?

+

技能通过可视化的流程编排,明确任务执行步骤

我们提供场景模板供您使用和参考

)} > diff --git a/src/frontend/src/pages/SystemPage/components/EditRole.tsx b/src/frontend/src/pages/SystemPage/components/EditRole.tsx index 87f107831..a8fcdd394 100644 --- a/src/frontend/src/pages/SystemPage/components/EditRole.tsx +++ b/src/frontend/src/pages/SystemPage/components/EditRole.tsx @@ -70,7 +70,7 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { case 1: useLibs.push(Number(item.third_id)); break; case 2: useSkills.push(item.third_id); break; case 3: manageLibs.push(Number(item.third_id)); break; - case 4: useAssistant.push(Number(item.third_id)); break; + case 5: useAssistant.push(item.third_id); break; } }) setForm({ name, useSkills, useLibs, useAssistant, manageLibs }) @@ -130,7 +130,7 @@ export default function EditRole({ id, name, onChange, onBeforeChange }) { updateRolePermissionsApi({ role_id: roleId, access_id: form.useSkills, type: 2 }), updateRolePermissionsApi({ role_id: roleId, access_id: form.useLibs, type: 1 }), updateRolePermissionsApi({ role_id: roleId, access_id: form.manageLibs, type: 3 }), - updateRolePermissionsApi({ role_id: roleId, access_id: form.useAssistant, type: 4 }) + updateRolePermissionsApi({ role_id: roleId, access_id: form.useAssistant, type: 5 }) ]) console.log('form :>> ', form, res); diff --git a/src/frontend/src/pages/SystemPage/components/Roles.tsx b/src/frontend/src/pages/SystemPage/components/Roles.tsx index 8ae234d46..d83503c23 100644 --- a/src/frontend/src/pages/SystemPage/components/Roles.tsx +++ b/src/frontend/src/pages/SystemPage/components/Roles.tsx @@ -69,7 +69,7 @@ export default function Roles() { return
- search(e.target.value)}> +