From c3b03776aeba64fe55e9a8c7738ee51a3c22b686 Mon Sep 17 00:00:00 2001 From: xilesun <2013xile@gmail.com> Date: Wed, 9 Apr 2025 23:51:59 +0800 Subject: [PATCH] chore: update --- .../plugins/@nocobase/plugin-ai/package.json | 2 +- .../ai-employees/AIEmployeesProvider.tsx | 9 +- .../src/client/ai-employees/ProfileCard.tsx | 85 +++++ .../ai-employees/chatbox/AIEmployeeHeader.tsx | 58 +++ .../client/ai-employees/chatbox/ChatBox.tsx | 317 +--------------- .../ai-employees/chatbox/ChatBoxContext.tsx | 207 ++++++++--- .../ai-employees/chatbox/ChatBoxProvider.tsx | 4 +- .../ai-employees/chatbox/Conversations.tsx | 112 ++++++ .../ai-employees/chatbox/FieldSelector.tsx | 33 ++ .../client/ai-employees/chatbox/InfoForm.tsx | 125 +++++++ .../client/ai-employees/chatbox/Messages.tsx | 42 +++ .../client/ai-employees/chatbox/Sender.tsx | 61 ++++ .../ai-employees/chatbox/SenderFooter.tsx | 34 ++ .../ai-employees/chatbox/SenderHeader.tsx | 78 ++++ .../ai-employees/chatbox/SenderPrefix.tsx | 25 ++ .../ai-employees/chatbox/useChatMessages.ts | 80 ++--- .../initializer/AIEmployeeButton.tsx | 132 ++----- .../ai-employees/manager/ChatSettings.tsx | 116 ++++++ .../client/ai-employees/manager/Employees.tsx | 102 +----- .../manager/InputsFormSettings.tsx | 242 +++++++++++++ .../ai-employees/manager/ModelSettings.tsx | 48 ++- .../ai-employees/manager/ProfileSettings.tsx | 72 ++++ .../selector/AISelectorProvider.tsx | 47 +++ .../ai-employees/selector/BlockSelector.tsx | 68 ++++ .../selector/withAISelectable.tsx | 71 ++++ .../settings/AIEmployeeButton.tsx | 340 +++++++++--------- .../src/client/ai-employees/types.ts | 21 +- .../@nocobase/plugin-ai/src/client/index.tsx | 9 +- .../plugin-ai/src/collections/ai-employees.ts | 4 + .../src/server/collections/ai-messages.ts | 11 +- .../src/server/resource/aiConversations.ts | 68 ++-- 31 files changed, 1806 insertions(+), 817 deletions(-) create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/ProfileCard.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/AIEmployeeHeader.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/Conversations.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/FieldSelector.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/InfoForm.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/Messages.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/Sender.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/SenderFooter.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/SenderHeader.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/SenderPrefix.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/manager/ChatSettings.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/manager/InputsFormSettings.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/manager/ProfileSettings.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/selector/AISelectorProvider.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/selector/BlockSelector.tsx create mode 100644 packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/selector/withAISelectable.tsx diff --git a/packages/plugins/@nocobase/plugin-ai/package.json b/packages/plugins/@nocobase/plugin-ai/package.json index 20853a6328..fa999e2040 100644 --- a/packages/plugins/@nocobase/plugin-ai/package.json +++ b/packages/plugins/@nocobase/plugin-ai/package.json @@ -13,7 +13,7 @@ "@nocobase/test": "1.x" }, "devDependencies": { - "@ant-design/x": "^1.0.5", + "@ant-design/x": "^1.1.0", "@langchain/core": "^0.3.39", "@langchain/deepseek": "^0.0.1", "@langchain/openai": "^0.4.3", diff --git a/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/AIEmployeesProvider.tsx b/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/AIEmployeesProvider.tsx index 2b5ee907eb..e9c60d7758 100644 --- a/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/AIEmployeesProvider.tsx +++ b/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/AIEmployeesProvider.tsx @@ -12,6 +12,7 @@ import { createContext } from 'react'; import { ChatBoxProvider } from './chatbox/ChatBoxProvider'; import { useAPIClient, useRequest } from '@nocobase/client'; import { AIEmployee } from './types'; +import { AISelectionProvider } from './selector/AISelectorProvider'; export const AIEmployeesContext = createContext<{ aiEmployees: AIEmployee[]; @@ -24,9 +25,11 @@ export const AIEmployeesProvider: React.FC<{ const [aiEmployees, setAIEmployees] = React.useState(null); return ( - - {props.children} - + + + {props.children} + + ); }; diff --git a/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/ProfileCard.tsx b/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/ProfileCard.tsx new file mode 100644 index 0000000000..f4f8452a65 --- /dev/null +++ b/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/ProfileCard.tsx @@ -0,0 +1,85 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import React from 'react'; +import { Avatar, Divider } from 'antd'; +import { useToken } from '@nocobase/client'; +import { AIEmployee } from './types'; +import { avatars } from './avatars'; +import { useT } from '../locale'; + +export const ProfileCard: React.FC<{ + aiEmployee: AIEmployee; + taskDesc?: string; +}> = (props) => { + const { aiEmployee, taskDesc } = props; + const { token } = useToken(); + const t = useT(); + + return ( +
+ {aiEmployee ? ( + <> +
+ +
+ {aiEmployee.nickname} +
+
+ + {t('Bio')} + +

{aiEmployee.bio}

+ {taskDesc && ( + <> + + {t('Task description')} + +

{taskDesc}

+ + )} + + ) : null} +
+ ); +}; diff --git a/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/AIEmployeeHeader.tsx b/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/AIEmployeeHeader.tsx new file mode 100644 index 0000000000..2eeedbb8bf --- /dev/null +++ b/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/AIEmployeeHeader.tsx @@ -0,0 +1,58 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import React from 'react'; +import { List, Popover, Button, Avatar, Divider } from 'antd'; +import { useToken } from '@nocobase/client'; +import { useAIEmployeesContext } from '../AIEmployeesProvider'; +import { useT } from '../../locale'; +import { useChatBoxContext } from './ChatBoxContext'; +import { avatars } from '../avatars'; +import { css } from '@emotion/css'; +import { Sender } from '@ant-design/x'; +import { ProfileCard } from '../ProfileCard'; + +export const AIEmployeeHeader: React.FC = () => { + const t = useT(); + const { token } = useToken(); + const { + service: { loading }, + aiEmployees, + } = useAIEmployeesContext(); + const { switchAIEmployee } = useChatBoxContext(); + return ( + + { + return ( + }> + + + ); + }} + /> + + ); +}; diff --git a/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/ChatBox.tsx b/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/ChatBox.tsx index ed501efb65..b00f78b117 100644 --- a/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/ChatBox.tsx +++ b/packages/plugins/@nocobase/plugin-ai/src/client/ai-employees/chatbox/ChatBox.tsx @@ -8,77 +8,21 @@ */ import React, { useContext, useState } from 'react'; -import { Layout, Card, Divider, Button, Avatar, List, Input, Popover, Empty, Spin, App } from 'antd'; -import { Conversations, Sender, Bubble } from '@ant-design/x'; -import type { ConversationsProps } from '@ant-design/x'; -import { CloseOutlined, ExpandOutlined, EditOutlined, LayoutOutlined, DeleteOutlined } from '@ant-design/icons'; -import { useAPIClient, useToken } from '@nocobase/client'; -import { useT } from '../../locale'; +import { Layout, Card, Button } from 'antd'; +import { CloseOutlined, ExpandOutlined, EditOutlined, LayoutOutlined } from '@ant-design/icons'; +import { useToken } from '@nocobase/client'; const { Header, Footer, Sider, Content } = Layout; -import { avatars } from '../avatars'; -import { useAIEmployeesContext } from '../AIEmployeesProvider'; -import { css } from '@emotion/css'; -import { ReactComponent as EmptyIcon } from '../empty-icon.svg'; -import { Attachment } from './Attachment'; import { ChatBoxContext } from './ChatBoxContext'; -import { AIEmployee } from '../types'; +import { Conversations } from './Conversations'; +import { Messages } from './Messages'; +import { Sender } from './Sender'; +import { useAISelectionContext } from '../selector/AISelectorProvider'; export const ChatBox: React.FC = () => { - const { modal, message } = App.useApp(); - const api = useAPIClient(); - const { - send, - setOpen, - filterEmployee, - setFilterEmployee, - conversations: conversationsService, - currentConversation, - setCurrentConversation, - messages, - setMessages, - roles, - attachments, - setAttachments, - responseLoading, - senderRef, - senderValue, - setSenderValue, - clear, - } = useContext(ChatBoxContext); - const { loading: ConversationsLoading, data: conversationsRes } = conversationsService; - const { - aiEmployees, - service: { loading }, - } = useAIEmployeesContext(); - const t = useT(); + const { setOpen, startNewConversation, currentEmployee } = useContext(ChatBoxContext); const { token } = useToken(); const [showConversations, setShowConversations] = useState(false); - const aiEmployeesList = [{ username: 'all' } as AIEmployee, ...(aiEmployees || [])]; - const conversations: ConversationsProps['items'] = (conversationsRes || []).map((conversation) => ({ - key: conversation.sessionId, - label: conversation.title, - timestamp: new Date(conversation.updatedAt).getTime(), - })); - - const deleteConversation = async (sessionId: string) => { - await api.resource('aiConversations').destroy({ - filterByTk: sessionId, - }); - message.success(t('Deleted successfully')); - conversationsService.refresh(); - clear(); - }; - - const getMessages = async (sessionId: string) => { - const res = await api.resource('aiConversations').getMessages({ - sessionId, - }); - const messages = res?.data?.data; - if (!messages) { - return; - } - setMessages(messages.reverse()); - }; + const { selectable } = useAISelectionContext(); return (
{ maxWidth: '760px', height: '90%', maxHeight: '560px', - zIndex: 1000, + zIndex: selectable ? -1 : 1000, }} > - + - - { - const highlight = - aiEmployee.username === filterEmployee - ? `color: ${token.colorPrimary}; - border-color: ${token.colorPrimary};` - : ''; - return aiEmployee.username === 'all' ? ( - - ) : ( - -
- -
- {aiEmployee.nickname} -
-
- - {t('Bio')} - -

{aiEmployee.bio}

-
- } - > - - - ); - }} - /> - { marginRight: '5px', }} > - -
- -
- - - {conversations && conversations.length ? ( - { - if (sessionId === currentConversation) { - return; - } - setCurrentConversation(sessionId); - getMessages(sessionId); - }} - items={conversations} - menu={(conversation) => ({ - items: [ - { - label: 'Delete', - key: 'delete', - icon: , - }, - ], - onClick: ({ key }) => { - switch (key) { - case 'delete': - modal.confirm({ - title: t('Delete this conversation?'), - content: t('Are you sure to delete this conversation?'), - onOk: () => deleteConversation(conversation.key), - }); - break; - } - }, - })} - /> - ) : ( - - )} - - -
+
{ type="text" onClick={() => setShowConversations(!showConversations)} /> - {filterEmployee !== 'all' ? ( -