@lobehub/chat 1.33.4 → 1.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.i18nrc.js +8 -2
- package/.releaserc.js +10 -1
- package/CHANGELOG.md +51 -16624
- package/changelog/CHANGELOG.v0.md +16621 -0
- package/changelog/v0.json +6064 -0
- package/changelog/v1.json +3356 -0
- package/docs/changelog/2024-11-25-november-providers.mdx +19 -0
- package/docs/changelog/2024-11-25-november-providers.zh-CN.mdx +17 -0
- package/docs/changelog/index.json +12 -0
- package/docs/changelog/schema.json +70 -0
- package/docs/self-hosting/advanced/auth/clerk.mdx +19 -23
- package/docs/self-hosting/advanced/auth/clerk.zh-CN.mdx +5 -4
- package/docs/self-hosting/advanced/auth/next-auth/authelia.mdx +2 -4
- package/docs/self-hosting/advanced/auth/next-auth/authelia.zh-CN.mdx +3 -5
- package/docs/self-hosting/advanced/auth/next-auth/authentik.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/casdoor.mdx +49 -44
- package/docs/self-hosting/advanced/auth/next-auth/casdoor.zh-CN.mdx +42 -41
- package/docs/self-hosting/advanced/auth/next-auth/logto.mdx +29 -21
- package/docs/self-hosting/advanced/auth/next-auth/logto.zh-CN.mdx +2 -1
- package/docs/self-hosting/advanced/auth.mdx +10 -10
- package/docs/self-hosting/advanced/auth.zh-CN.mdx +10 -10
- package/docs/self-hosting/advanced/feature-flags.zh-CN.mdx +1 -1
- package/docs/self-hosting/advanced/model-list.mdx +1 -1
- package/docs/self-hosting/advanced/s3/cloudflare-r2.mdx +17 -12
- package/docs/self-hosting/advanced/s3/tencent-cloud.mdx +33 -20
- package/docs/self-hosting/advanced/s3.mdx +31 -28
- package/docs/self-hosting/advanced/s3.zh-CN.mdx +1 -0
- package/docs/self-hosting/advanced/webrtc.mdx +1 -0
- package/docs/self-hosting/environment-variables/s3.mdx +4 -3
- package/docs/self-hosting/environment-variables/s3.zh-CN.mdx +1 -0
- package/docs/self-hosting/environment-variables.mdx +6 -9
- package/docs/self-hosting/platform/alibaba-cloud.mdx +1 -2
- package/docs/self-hosting/platform/alibaba-cloud.zh-CN.mdx +1 -2
- package/docs/self-hosting/platform/btpanel.mdx +7 -13
- package/docs/self-hosting/platform/btpanel.zh-CN.mdx +8 -13
- package/docs/self-hosting/platform/docker.zh-CN.mdx +2 -1
- package/docs/self-hosting/platform/netlify.zh-CN.mdx +2 -1
- package/docs/self-hosting/server-database/docker.mdx +18 -5
- package/docs/self-hosting/server-database/docker.zh-CN.mdx +9 -6
- package/docs/self-hosting/server-database/netlify.mdx +0 -1
- package/docs/self-hosting/server-database/railway.mdx +0 -1
- package/docs/self-hosting/server-database/repocloud.mdx +5 -2
- package/docs/self-hosting/server-database/repocloud.zh-CN.mdx +23 -3
- package/docs/self-hosting/server-database/sealos.mdx +3 -0
- package/docs/self-hosting/server-database/vercel.mdx +35 -32
- package/docs/self-hosting/server-database/vercel.zh-CN.mdx +25 -25
- package/docs/self-hosting/server-database/zeabur.mdx +2 -2
- package/docs/self-hosting/server-database/zeabur.zh-CN.mdx +3 -4
- package/docs/self-hosting/server-database.mdx +23 -8
- package/docs/self-hosting/start.mdx +8 -2
- package/docs/usage/features/database.zh-CN.mdx +1 -1
- package/docs/usage/foundation/text2image.mdx +1 -2
- package/docs/usage/foundation/text2image.zh-CN.mdx +1 -3
- package/docs/usage/providers/ai21.mdx +14 -15
- package/docs/usage/providers/ai21.zh-CN.mdx +1 -3
- package/docs/usage/providers/ai360.mdx +14 -15
- package/docs/usage/providers/ai360.zh-CN.mdx +1 -3
- package/docs/usage/providers/cloudflare.mdx +1 -1
- package/docs/usage/providers/fireworksai.mdx +19 -19
- package/docs/usage/providers/fireworksai.zh-CN.mdx +1 -3
- package/docs/usage/providers/github.mdx +22 -21
- package/docs/usage/providers/github.zh-CN.mdx +6 -6
- package/docs/usage/providers/hunyuan.mdx +17 -18
- package/docs/usage/providers/hunyuan.zh-CN.mdx +1 -3
- package/docs/usage/providers/siliconcloud.mdx +14 -15
- package/docs/usage/providers/siliconcloud.zh-CN.mdx +3 -5
- package/docs/usage/providers/spark.mdx +17 -18
- package/docs/usage/providers/spark.zh-CN.mdx +1 -3
- package/docs/usage/providers/upstage.mdx +14 -15
- package/docs/usage/providers/upstage.zh-CN.mdx +1 -3
- package/docs/usage/providers/wenxin.mdx +17 -18
- package/docs/usage/providers/wenxin.zh-CN.mdx +1 -3
- package/docs/usage/providers/zeroone.mdx +2 -2
- package/locales/ar/chat.json +7 -0
- package/locales/ar/common.json +2 -0
- package/locales/ar/models.json +24 -0
- package/locales/ar/providers.json +3 -0
- package/locales/ar/setting.json +5 -0
- package/locales/ar/thread.json +5 -0
- package/locales/bg-BG/chat.json +7 -0
- package/locales/bg-BG/common.json +2 -0
- package/locales/bg-BG/models.json +24 -0
- package/locales/bg-BG/providers.json +3 -0
- package/locales/bg-BG/setting.json +5 -0
- package/locales/bg-BG/thread.json +5 -0
- package/locales/de-DE/chat.json +7 -0
- package/locales/de-DE/common.json +2 -0
- package/locales/de-DE/models.json +24 -0
- package/locales/de-DE/providers.json +3 -0
- package/locales/de-DE/setting.json +5 -0
- package/locales/de-DE/thread.json +5 -0
- package/locales/en-US/chat.json +7 -0
- package/locales/en-US/common.json +2 -0
- package/locales/en-US/models.json +24 -0
- package/locales/en-US/providers.json +3 -0
- package/locales/en-US/setting.json +5 -0
- package/locales/en-US/thread.json +5 -0
- package/locales/es-ES/chat.json +7 -0
- package/locales/es-ES/common.json +2 -0
- package/locales/es-ES/models.json +24 -0
- package/locales/es-ES/providers.json +3 -0
- package/locales/es-ES/setting.json +5 -0
- package/locales/es-ES/thread.json +5 -0
- package/locales/fa-IR/chat.json +7 -0
- package/locales/fa-IR/common.json +2 -0
- package/locales/fa-IR/models.json +24 -0
- package/locales/fa-IR/providers.json +3 -0
- package/locales/fa-IR/setting.json +5 -0
- package/locales/fa-IR/thread.json +5 -0
- package/locales/fr-FR/chat.json +7 -0
- package/locales/fr-FR/common.json +2 -0
- package/locales/fr-FR/models.json +24 -0
- package/locales/fr-FR/providers.json +3 -0
- package/locales/fr-FR/setting.json +5 -0
- package/locales/fr-FR/thread.json +5 -0
- package/locales/it-IT/chat.json +7 -0
- package/locales/it-IT/common.json +2 -0
- package/locales/it-IT/models.json +24 -0
- package/locales/it-IT/providers.json +3 -0
- package/locales/it-IT/setting.json +5 -0
- package/locales/it-IT/thread.json +5 -0
- package/locales/ja-JP/chat.json +7 -0
- package/locales/ja-JP/common.json +2 -0
- package/locales/ja-JP/models.json +24 -0
- package/locales/ja-JP/providers.json +3 -0
- package/locales/ja-JP/setting.json +5 -0
- package/locales/ja-JP/thread.json +5 -0
- package/locales/ko-KR/chat.json +7 -0
- package/locales/ko-KR/common.json +2 -0
- package/locales/ko-KR/models.json +24 -0
- package/locales/ko-KR/providers.json +3 -0
- package/locales/ko-KR/setting.json +5 -0
- package/locales/ko-KR/thread.json +5 -0
- package/locales/nl-NL/chat.json +7 -0
- package/locales/nl-NL/common.json +2 -0
- package/locales/nl-NL/models.json +24 -0
- package/locales/nl-NL/providers.json +3 -0
- package/locales/nl-NL/setting.json +5 -0
- package/locales/nl-NL/thread.json +5 -0
- package/locales/pl-PL/chat.json +7 -0
- package/locales/pl-PL/common.json +2 -0
- package/locales/pl-PL/models.json +24 -0
- package/locales/pl-PL/providers.json +3 -0
- package/locales/pl-PL/setting.json +5 -0
- package/locales/pl-PL/thread.json +5 -0
- package/locales/pt-BR/chat.json +7 -0
- package/locales/pt-BR/common.json +2 -0
- package/locales/pt-BR/models.json +24 -0
- package/locales/pt-BR/providers.json +3 -0
- package/locales/pt-BR/setting.json +5 -0
- package/locales/pt-BR/thread.json +5 -0
- package/locales/ru-RU/chat.json +7 -0
- package/locales/ru-RU/common.json +2 -0
- package/locales/ru-RU/models.json +24 -0
- package/locales/ru-RU/providers.json +3 -0
- package/locales/ru-RU/setting.json +5 -0
- package/locales/ru-RU/thread.json +5 -0
- package/locales/tr-TR/chat.json +7 -0
- package/locales/tr-TR/common.json +2 -0
- package/locales/tr-TR/models.json +24 -0
- package/locales/tr-TR/providers.json +3 -0
- package/locales/tr-TR/setting.json +5 -0
- package/locales/tr-TR/thread.json +5 -0
- package/locales/vi-VN/chat.json +7 -0
- package/locales/vi-VN/common.json +2 -0
- package/locales/vi-VN/models.json +24 -0
- package/locales/vi-VN/providers.json +3 -0
- package/locales/vi-VN/setting.json +5 -0
- package/locales/vi-VN/thread.json +5 -0
- package/locales/zh-CN/chat.json +7 -0
- package/locales/zh-CN/common.json +2 -0
- package/locales/zh-CN/models.json +24 -0
- package/locales/zh-CN/providers.json +3 -0
- package/locales/zh-CN/setting.json +5 -0
- package/locales/zh-CN/thread.json +5 -0
- package/locales/zh-TW/chat.json +7 -0
- package/locales/zh-TW/common.json +2 -0
- package/locales/zh-TW/models.json +24 -0
- package/locales/zh-TW/providers.json +3 -0
- package/locales/zh-TW/setting.json +5 -0
- package/locales/zh-TW/thread.json +5 -0
- package/package.json +6 -1
- package/scripts/changelogWorkflow/buildStaticChangelog.ts +135 -0
- package/scripts/changelogWorkflow/const.ts +11 -0
- package/scripts/changelogWorkflow/index.ts +10 -0
- package/src/app/(main)/chat/(workspace)/@conversation/default.tsx +2 -0
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatHydration/index.tsx +11 -2
- package/src/{features → app/(main)/chat/(workspace)/@conversation/features}/ChatInput/Desktop/Footer/index.tsx +7 -9
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/index.tsx +7 -2
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/Thread.tsx +62 -0
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/ThreadItem.tsx +68 -0
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +62 -2
- package/src/app/(main)/chat/(workspace)/@conversation/features/ThreadHydration.tsx +47 -0
- package/src/app/(main)/chat/(workspace)/@portal/_layout/Desktop.tsx +3 -2
- package/src/app/(main)/chat/(workspace)/@portal/_layout/Mobile.tsx +47 -6
- package/src/app/(main)/chat/(workspace)/@topic/features/SkeletonList.tsx +3 -2
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ByTimeMode/index.tsx +10 -3
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/FlatMode/index.tsx +1 -1
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ThreadItem/Content.tsx +164 -0
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ThreadItem/index.tsx +98 -0
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/{TopicItem.tsx → TopicItem/index.tsx} +33 -22
- package/src/app/(main)/chat/(workspace)/_layout/Desktop/Portal.tsx +12 -5
- package/src/app/(main)/chat/(workspace)/_layout/Mobile/index.tsx +1 -2
- package/src/const/message.ts +2 -0
- package/src/const/settings/systemAgent.ts +1 -0
- package/src/database/server/migrations/0012_add_thread.sql +39 -0
- package/src/database/server/migrations/meta/0012_snapshot.json +3671 -0
- package/src/database/server/migrations/meta/_journal.json +7 -0
- package/src/database/server/models/_template.ts +2 -2
- package/src/database/server/models/message.ts +1 -0
- package/src/database/server/models/thread.ts +79 -0
- package/src/database/server/schemas/lobechat/message.ts +2 -1
- package/src/database/server/schemas/lobechat/relations.ts +13 -1
- package/src/database/server/schemas/lobechat/topic.ts +30 -1
- package/src/database/server/utils/idGenerator.ts +1 -0
- package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +6 -4
- package/src/features/ChatInput/ActionBar/Token/index.tsx +24 -5
- package/src/features/ChatInput/ActionBar/config.ts +3 -2
- package/src/features/ChatInput/Desktop/index.tsx +15 -7
- package/src/features/ChatInput/Mobile/index.tsx +4 -4
- package/src/features/Conversation/Actions/Assistant.tsx +24 -5
- package/src/features/Conversation/Actions/User.tsx +21 -4
- package/src/features/Conversation/Actions/index.ts +1 -66
- package/src/features/Conversation/Messages/{Tool → Assistant/ToolCallItem}/Inspector/index.tsx +3 -1
- package/src/features/Conversation/Messages/{Tool/index.tsx → Assistant/ToolCallItem/Tool.tsx} +10 -11
- package/src/features/Conversation/Messages/Assistant/ToolCallItem/index.tsx +5 -3
- package/src/features/Conversation/Messages/Assistant/index.tsx +22 -14
- package/src/features/Conversation/Messages/index.ts +0 -2
- package/src/features/Conversation/components/AutoScroll.tsx +1 -1
- package/src/features/Conversation/components/ChatItem/ActionsBar.tsx +79 -5
- package/src/features/Conversation/components/ChatItem/InPortalThreadContext.ts +3 -0
- package/src/features/Conversation/components/ChatItem/index.tsx +16 -5
- package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/index.tsx +9 -1
- package/src/features/Conversation/components/ThreadDivider/index.tsx +19 -0
- package/src/features/Conversation/hooks/useChatListActionsBar.tsx +19 -4
- package/src/features/Portal/Thread/Chat/ChatInput/Footer.tsx +90 -0
- package/src/features/Portal/Thread/Chat/ChatInput/TextArea.tsx +30 -0
- package/src/features/Portal/Thread/Chat/ChatInput/index.tsx +66 -0
- package/src/features/Portal/Thread/Chat/ChatInput/useSend.ts +50 -0
- package/src/features/Portal/Thread/Chat/ChatItem.tsx +62 -0
- package/src/features/Portal/Thread/Chat/ChatList.tsx +49 -0
- package/src/features/Portal/Thread/Chat/ThreadDivider/index.tsx +19 -0
- package/src/features/Portal/Thread/Chat/index.tsx +28 -0
- package/src/features/Portal/Thread/Header/Active.tsx +35 -0
- package/src/features/Portal/Thread/Header/New.tsx +37 -0
- package/src/features/Portal/Thread/Header/Title.tsx +18 -0
- package/src/features/Portal/Thread/Header/index.tsx +20 -0
- package/src/features/Portal/Thread/hook.ts +8 -0
- package/src/features/Portal/Thread/index.ts +12 -0
- package/src/features/Portal/router.tsx +2 -1
- package/src/hooks/useFetchTopics.ts +7 -1
- package/src/locales/default/chat.ts +8 -1
- package/src/locales/default/common.ts +3 -0
- package/src/locales/default/index.ts +2 -0
- package/src/locales/default/setting.ts +5 -0
- package/src/locales/default/thread.ts +5 -0
- package/src/server/routers/lambda/index.ts +2 -0
- package/src/server/routers/lambda/thread.ts +83 -0
- package/src/services/thread.ts +54 -0
- package/src/store/chat/initialState.ts +3 -0
- package/src/store/chat/selectors.ts +2 -1
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +1 -1
- package/src/store/chat/slices/aiChat/actions/__tests__/rag.test.ts +1 -1
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +31 -8
- package/src/store/chat/slices/aiChat/actions/rag.ts +1 -1
- package/src/store/chat/slices/message/selectors.test.ts +3 -3
- package/src/store/chat/slices/message/selectors.ts +50 -29
- package/src/store/chat/slices/plugin/action.ts +26 -8
- package/src/store/chat/slices/portal/action.ts +1 -0
- package/src/store/chat/slices/portal/initialState.ts +1 -0
- package/src/store/chat/slices/portal/selectors/thread.ts +17 -0
- package/src/store/chat/slices/portal/selectors.ts +2 -0
- package/src/store/chat/slices/thread/action.ts +326 -0
- package/src/store/chat/slices/thread/initialState.ts +34 -0
- package/src/store/chat/slices/thread/reducer.ts +48 -0
- package/src/store/chat/slices/thread/selectors/index.ts +202 -0
- package/src/store/chat/slices/thread/selectors/util.ts +22 -0
- package/src/store/chat/slices/topic/action.ts +5 -1
- package/src/store/chat/store.ts +5 -2
- package/src/store/global/initialState.ts +4 -0
- package/src/store/global/selectors.ts +4 -0
- package/src/store/user/slices/settings/selectors/systemAgent.ts +2 -0
- package/src/types/message/index.ts +17 -1
- package/src/types/topic/index.ts +1 -0
- package/src/types/topic/thread.ts +42 -0
- package/src/types/user/settings/systemAgent.ts +1 -0
- package/src/app/(main)/chat/(workspace)/@portal/features/Header.tsx +0 -11
- package/src/app/(main)/chat/(workspace)/_layout/Mobile/PortalModal.tsx +0 -35
- /package/src/{features → app/(main)/chat/(workspace)/@conversation/features}/ChatInput/Desktop/Footer/SendMore.tsx +0 -0
- /package/src/{features → app/(main)/chat/(workspace)/@conversation/features}/ChatInput/Desktop/Footer/ShortcutHint.tsx +0 -0
- /package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/{DefaultContent.tsx → TopicItem/DefaultContent.tsx} +0 -0
- /package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/{TopicContent.tsx → TopicItem/TopicContent.tsx} +0 -0
- /package/src/features/Conversation/Messages/{Tool → Assistant/ToolCallItem}/Inspector/PluginResultJSON.tsx +0 -0
- /package/src/features/Conversation/Messages/{Tool → Assistant/ToolCallItem}/Inspector/Settings.tsx +0 -0
- /package/src/features/Conversation/Messages/{Tool → Assistant/ToolCallItem}/Inspector/style.ts +0 -0
@@ -1,7 +1,9 @@
|
|
1
|
-
import {
|
1
|
+
import { Skeleton } from 'antd';
|
2
|
+
import { ReactNode, Suspense, memo, useContext } from 'react';
|
2
3
|
import { Flexbox } from 'react-layout-kit';
|
3
4
|
|
4
5
|
import { LOADING_FLAT } from '@/const/message';
|
6
|
+
import { InPortalThreadContext } from '@/features/Conversation/components/ChatItem/InPortalThreadContext';
|
5
7
|
import { useChatStore } from '@/store/chat';
|
6
8
|
import { chatSelectors } from '@/store/chat/selectors';
|
7
9
|
import { ChatMessage } from '@/types/message';
|
@@ -18,6 +20,7 @@ export const AssistantMessage = memo<
|
|
18
20
|
const editing = useChatStore(chatSelectors.isMessageEditing(id));
|
19
21
|
const generating = useChatStore(chatSelectors.isMessageGenerating(id));
|
20
22
|
|
23
|
+
const inThread = useContext(InPortalThreadContext);
|
21
24
|
const isToolCallGenerating = generating && (content === LOADING_FLAT || !content) && !!tools;
|
22
25
|
|
23
26
|
return editing ? (
|
@@ -40,19 +43,24 @@ export const AssistantMessage = memo<
|
|
40
43
|
/>
|
41
44
|
)}
|
42
45
|
{tools && (
|
43
|
-
<
|
44
|
-
{
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
46
|
+
<Suspense
|
47
|
+
fallback={<Skeleton.Button active style={{ height: 46, minWidth: 200, width: '100%' }} />}
|
48
|
+
>
|
49
|
+
<Flexbox gap={8}>
|
50
|
+
{tools.map((toolCall, index) => (
|
51
|
+
<ToolCall
|
52
|
+
apiName={toolCall.apiName}
|
53
|
+
arguments={toolCall.arguments}
|
54
|
+
id={toolCall.id}
|
55
|
+
identifier={toolCall.identifier}
|
56
|
+
index={index}
|
57
|
+
key={toolCall.id}
|
58
|
+
messageId={id}
|
59
|
+
showPortal={!inThread}
|
60
|
+
/>
|
61
|
+
))}
|
62
|
+
</Flexbox>
|
63
|
+
</Suspense>
|
56
64
|
)}
|
57
65
|
</Flexbox>
|
58
66
|
);
|
@@ -8,14 +8,12 @@ import { sessionSelectors } from '@/store/session/selectors';
|
|
8
8
|
import { MarkdownCustomRender, RenderBelowMessage, RenderMessage } from '../types';
|
9
9
|
import { AssistantMessage } from './Assistant';
|
10
10
|
import { DefaultBelowMessage, DefaultMessage } from './Default';
|
11
|
-
import { ToolMessage } from './Tool';
|
12
11
|
import { UserBelowMessage, UserMarkdownRender, UserMessage } from './User';
|
13
12
|
|
14
13
|
export const renderMessages: Record<string, RenderMessage> = {
|
15
14
|
assistant: AssistantMessage,
|
16
15
|
default: DefaultMessage,
|
17
16
|
function: DefaultMessage,
|
18
|
-
tool: ToolMessage,
|
19
17
|
user: UserMessage,
|
20
18
|
};
|
21
19
|
|
@@ -12,7 +12,7 @@ interface AutoScrollProps {
|
|
12
12
|
}
|
13
13
|
const AutoScroll = memo<AutoScrollProps>(({ atBottom, isScrolling, onScrollToBottom }) => {
|
14
14
|
const trackVisibility = useChatStore(chatSelectors.isAIGenerating);
|
15
|
-
const str = useChatStore(chatSelectors.
|
15
|
+
const str = useChatStore(chatSelectors.mainAIChatsMessageString);
|
16
16
|
|
17
17
|
useEffect(() => {
|
18
18
|
if (atBottom && trackVisibility && !isScrolling) {
|
@@ -1,18 +1,21 @@
|
|
1
1
|
import { ActionEvent, ActionIconGroup, type ActionIconGroupProps } from '@lobehub/ui';
|
2
|
+
import { App } from 'antd';
|
2
3
|
import isEqual from 'fast-deep-equal';
|
3
4
|
import { memo, useCallback } from 'react';
|
5
|
+
import { useTranslation } from 'react-i18next';
|
4
6
|
|
5
7
|
import { useChatStore } from '@/store/chat';
|
6
8
|
import { chatSelectors } from '@/store/chat/selectors';
|
7
9
|
import { MessageRoleType } from '@/types/message';
|
8
10
|
|
9
|
-
import { renderActions
|
11
|
+
import { renderActions } from '../../Actions';
|
10
12
|
import { useChatListActionsBar } from '../../hooks/useChatListActionsBar';
|
11
13
|
|
12
14
|
export type ActionsBarProps = ActionIconGroupProps;
|
13
15
|
|
14
16
|
const ActionsBar = memo<ActionsBarProps>((props) => {
|
15
17
|
const { regenerate, edit, copy, divider, del } = useChatListActionsBar();
|
18
|
+
|
16
19
|
return (
|
17
20
|
<ActionIconGroup
|
18
21
|
dropdownMenu={[edit, copy, regenerate, divider, del]}
|
@@ -25,12 +28,36 @@ const ActionsBar = memo<ActionsBarProps>((props) => {
|
|
25
28
|
|
26
29
|
interface ActionsProps {
|
27
30
|
id: string;
|
31
|
+
inPortalThread?: boolean;
|
28
32
|
}
|
29
33
|
|
30
|
-
const Actions = memo<ActionsProps>(({ id }) => {
|
34
|
+
const Actions = memo<ActionsProps>(({ id, inPortalThread }) => {
|
31
35
|
const item = useChatStore(chatSelectors.getMessageById(id), isEqual);
|
32
|
-
const
|
33
|
-
const
|
36
|
+
const { t } = useTranslation('common');
|
37
|
+
const [
|
38
|
+
deleteMessage,
|
39
|
+
regenerateMessage,
|
40
|
+
translateMessage,
|
41
|
+
ttsMessage,
|
42
|
+
delAndRegenerateMessage,
|
43
|
+
copyMessage,
|
44
|
+
openThreadCreator,
|
45
|
+
resendThreadMessage,
|
46
|
+
delAndResendThreadMessage,
|
47
|
+
toggleMessageEditing,
|
48
|
+
] = useChatStore((s) => [
|
49
|
+
s.deleteMessage,
|
50
|
+
s.regenerateMessage,
|
51
|
+
s.translateMessage,
|
52
|
+
s.ttsMessage,
|
53
|
+
s.delAndRegenerateMessage,
|
54
|
+
s.copyMessage,
|
55
|
+
s.openThreadCreator,
|
56
|
+
s.resendThreadMessage,
|
57
|
+
s.delAndResendThreadMessage,
|
58
|
+
s.toggleMessageEditing,
|
59
|
+
]);
|
60
|
+
const { message } = App.useApp();
|
34
61
|
|
35
62
|
const handleActionClick = useCallback(
|
36
63
|
async (action: ActionEvent) => {
|
@@ -41,7 +68,54 @@ const Actions = memo<ActionsProps>(({ id }) => {
|
|
41
68
|
}
|
42
69
|
if (!item) return;
|
43
70
|
|
44
|
-
|
71
|
+
switch (action.key) {
|
72
|
+
case 'copy': {
|
73
|
+
await copyMessage(id, item.content);
|
74
|
+
message.success(t('copySuccess', { defaultValue: 'Copy Success' }));
|
75
|
+
break;
|
76
|
+
}
|
77
|
+
case 'branching': {
|
78
|
+
openThreadCreator(id);
|
79
|
+
break;
|
80
|
+
}
|
81
|
+
|
82
|
+
case 'del': {
|
83
|
+
deleteMessage(id);
|
84
|
+
break;
|
85
|
+
}
|
86
|
+
|
87
|
+
case 'regenerate': {
|
88
|
+
if (inPortalThread) {
|
89
|
+
resendThreadMessage(id);
|
90
|
+
} else regenerateMessage(id);
|
91
|
+
|
92
|
+
// if this message is an error message, we need to delete it
|
93
|
+
if (item.error) deleteMessage(id);
|
94
|
+
break;
|
95
|
+
}
|
96
|
+
|
97
|
+
case 'delAndRegenerate': {
|
98
|
+
if (inPortalThread) {
|
99
|
+
delAndResendThreadMessage(id);
|
100
|
+
} else {
|
101
|
+
delAndRegenerateMessage(id);
|
102
|
+
}
|
103
|
+
break;
|
104
|
+
}
|
105
|
+
|
106
|
+
case 'tts': {
|
107
|
+
ttsMessage(id);
|
108
|
+
break;
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
if (action.keyPath.at(-1) === 'translate') {
|
113
|
+
// click the menu item with translate item, the result is:
|
114
|
+
// key: 'en-US'
|
115
|
+
// keyPath: ['en-US','translate']
|
116
|
+
const lang = action.keyPath[0];
|
117
|
+
translateMessage(id, lang);
|
118
|
+
}
|
45
119
|
},
|
46
120
|
[item],
|
47
121
|
);
|
@@ -25,6 +25,7 @@ import {
|
|
25
25
|
} from '../../Messages';
|
26
26
|
import History from '../History';
|
27
27
|
import { markdownElements } from '../MarkdownElements';
|
28
|
+
import { InPortalThreadContext } from './InPortalThreadContext';
|
28
29
|
import { processWithArtifact } from './utils';
|
29
30
|
|
30
31
|
const rehypePlugins = markdownElements.map((element) => element.rehypePlugin);
|
@@ -45,14 +46,24 @@ const useStyles = createStyles(({ css, prefixCls }) => ({
|
|
45
46
|
export interface ChatListItemProps {
|
46
47
|
actionBar?: ReactNode;
|
47
48
|
className?: string;
|
49
|
+
disableEditing?: boolean;
|
48
50
|
enableHistoryDivider?: boolean;
|
49
51
|
endRender?: ReactNode;
|
50
52
|
id: string;
|
53
|
+
inPortalThread?: boolean;
|
51
54
|
index: number;
|
52
55
|
}
|
53
56
|
|
54
57
|
const Item = memo<ChatListItemProps>(
|
55
|
-
({
|
58
|
+
({
|
59
|
+
className,
|
60
|
+
enableHistoryDivider,
|
61
|
+
id,
|
62
|
+
actionBar,
|
63
|
+
endRender,
|
64
|
+
disableEditing,
|
65
|
+
inPortalThread = false,
|
66
|
+
}) => {
|
56
67
|
const fontSize = useUserStore(userGeneralSettingsSelectors.fontSize);
|
57
68
|
const { t } = useTranslation('common');
|
58
69
|
const { styles, cx } = useStyles();
|
@@ -169,13 +180,13 @@ const Item = memo<ChatListItemProps>(
|
|
169
180
|
|
170
181
|
const onDoubleClick = useCallback<MouseEventHandler<HTMLDivElement>>(
|
171
182
|
(e) => {
|
172
|
-
if (!item) return;
|
183
|
+
if (!item || disableEditing) return;
|
173
184
|
if (item.id === 'default' || item.error) return;
|
174
185
|
if (item.role && ['assistant', 'user'].includes(item.role) && e.altKey) {
|
175
186
|
toggleMessageEditing(id, true);
|
176
187
|
}
|
177
188
|
},
|
178
|
-
[item],
|
189
|
+
[item, disableEditing],
|
179
190
|
);
|
180
191
|
|
181
192
|
const text = useMemo(
|
@@ -197,7 +208,7 @@ const Item = memo<ChatListItemProps>(
|
|
197
208
|
|
198
209
|
return (
|
199
210
|
item && (
|
200
|
-
|
211
|
+
<InPortalThreadContext.Provider value={inPortalThread}>
|
201
212
|
{enableHistoryDivider && <History />}
|
202
213
|
<Flexbox className={cx(styles.message, className, isMessageLoading && styles.loading)}>
|
203
214
|
<ChatItem
|
@@ -225,7 +236,7 @@ const Item = memo<ChatListItemProps>(
|
|
225
236
|
/>
|
226
237
|
{endRender}
|
227
238
|
</Flexbox>
|
228
|
-
|
239
|
+
</InPortalThreadContext.Provider>
|
229
240
|
)
|
230
241
|
);
|
231
242
|
},
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import { Icon } from '@lobehub/ui';
|
2
|
+
import { App } from 'antd';
|
2
3
|
import { createStyles } from 'antd-style';
|
3
4
|
import { Loader2 } from 'lucide-react';
|
4
|
-
import { memo, useEffect } from 'react';
|
5
|
+
import { memo, useContext, useEffect } from 'react';
|
5
6
|
import { useTranslation } from 'react-i18next';
|
6
7
|
import { Center, Flexbox } from 'react-layout-kit';
|
7
8
|
|
@@ -9,6 +10,7 @@ import { useChatStore } from '@/store/chat';
|
|
9
10
|
import { chatPortalSelectors, chatSelectors } from '@/store/chat/selectors';
|
10
11
|
import { dotLoading } from '@/styles/loading';
|
11
12
|
|
13
|
+
import { InPortalThreadContext } from '../../../ChatItem/InPortalThreadContext';
|
12
14
|
import { MarkdownElementProps } from '../../type';
|
13
15
|
import ArtifactIcon from './Icon';
|
14
16
|
|
@@ -60,6 +62,8 @@ const Render = memo<ArtifactProps>(({ identifier, title, type, language, childre
|
|
60
62
|
const hasChildren = !!children;
|
61
63
|
const str = ((children as string) || '').toString?.();
|
62
64
|
|
65
|
+
const inThread = useContext(InPortalThreadContext);
|
66
|
+
const { message } = App.useApp();
|
63
67
|
const [isGenerating, isArtifactTagClosed, currentArtifactMessageId, openArtifact, closeArtifact] =
|
64
68
|
useChatStore((s) => {
|
65
69
|
return [
|
@@ -90,6 +94,10 @@ const Render = memo<ArtifactProps>(({ identifier, title, type, language, childre
|
|
90
94
|
if (currentArtifactMessageId === id) {
|
91
95
|
closeArtifact();
|
92
96
|
} else {
|
97
|
+
if (inThread) {
|
98
|
+
message.info(t('artifact.inThread'));
|
99
|
+
return;
|
100
|
+
}
|
93
101
|
openArtifactUI();
|
94
102
|
}
|
95
103
|
}}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { Icon, Tag } from '@lobehub/ui';
|
2
|
+
import { Divider } from 'antd';
|
3
|
+
import { GitBranch } from 'lucide-react';
|
4
|
+
import { memo } from 'react';
|
5
|
+
import { useTranslation } from 'react-i18next';
|
6
|
+
|
7
|
+
const ThreadDivider = memo(() => {
|
8
|
+
const { t } = useTranslation('chat');
|
9
|
+
|
10
|
+
return (
|
11
|
+
<div style={{ padding: '0 20px' }}>
|
12
|
+
<Divider style={{ margin: 0, padding: '20px 0' }}>
|
13
|
+
<Tag icon={<Icon icon={GitBranch} />}>{t('thread.divider')}</Tag>
|
14
|
+
</Divider>
|
15
|
+
</div>
|
16
|
+
);
|
17
|
+
});
|
18
|
+
|
19
|
+
export default ThreadDivider;
|
@@ -1,9 +1,12 @@
|
|
1
1
|
import { ActionIconGroupItems } from '@lobehub/ui/es/ActionIconGroup';
|
2
|
-
import { Copy, Edit, ListRestart, RotateCcw, Trash } from 'lucide-react';
|
2
|
+
import { Copy, Edit, ListRestart, RotateCcw, Split, Trash } from 'lucide-react';
|
3
3
|
import { useMemo } from 'react';
|
4
4
|
import { useTranslation } from 'react-i18next';
|
5
5
|
|
6
|
+
import { isServerMode } from '@/const/version';
|
7
|
+
|
6
8
|
interface ChatListActionsBar {
|
9
|
+
branching: ActionIconGroupItems;
|
7
10
|
copy: ActionIconGroupItems;
|
8
11
|
del: ActionIconGroupItems;
|
9
12
|
delAndRegenerate: ActionIconGroupItems;
|
@@ -12,11 +15,21 @@ interface ChatListActionsBar {
|
|
12
15
|
regenerate: ActionIconGroupItems;
|
13
16
|
}
|
14
17
|
|
15
|
-
export const useChatListActionsBar = (
|
18
|
+
export const useChatListActionsBar = ({
|
19
|
+
hasThread,
|
20
|
+
}: { hasThread?: boolean } = {}): ChatListActionsBar => {
|
16
21
|
const { t } = useTranslation('common');
|
17
22
|
|
18
23
|
return useMemo(
|
19
24
|
() => ({
|
25
|
+
branching: {
|
26
|
+
disable: !isServerMode,
|
27
|
+
icon: Split,
|
28
|
+
key: 'branching',
|
29
|
+
label: isServerMode
|
30
|
+
? t('branching', { defaultValue: 'Create Sub Topic' })
|
31
|
+
: t('branchingDisable'),
|
32
|
+
},
|
20
33
|
copy: {
|
21
34
|
icon: Copy,
|
22
35
|
key: 'copy',
|
@@ -24,11 +37,13 @@ export const useChatListActionsBar = (): ChatListActionsBar => {
|
|
24
37
|
},
|
25
38
|
del: {
|
26
39
|
danger: true,
|
40
|
+
disable: hasThread,
|
27
41
|
icon: Trash,
|
28
42
|
key: 'del',
|
29
|
-
label: t('
|
43
|
+
label: hasThread ? t('messageAction.deleteDisabledByThreads', { ns: 'chat' }) : t('delete'),
|
30
44
|
},
|
31
45
|
delAndRegenerate: {
|
46
|
+
disable: hasThread,
|
32
47
|
icon: ListRestart,
|
33
48
|
key: 'delAndRegenerate',
|
34
49
|
label: t('messageAction.delAndRegenerate', {
|
@@ -50,6 +65,6 @@ export const useChatListActionsBar = (): ChatListActionsBar => {
|
|
50
65
|
label: t('regenerate', { defaultValue: 'Regenerate' }),
|
51
66
|
},
|
52
67
|
}),
|
53
|
-
[],
|
68
|
+
[hasThread],
|
54
69
|
);
|
55
70
|
};
|
@@ -0,0 +1,90 @@
|
|
1
|
+
import { Button } from 'antd';
|
2
|
+
import { createStyles } from 'antd-style';
|
3
|
+
import { rgba } from 'polished';
|
4
|
+
import { memo } from 'react';
|
5
|
+
import { useTranslation } from 'react-i18next';
|
6
|
+
import { Flexbox } from 'react-layout-kit';
|
7
|
+
|
8
|
+
import StopLoadingIcon from '@/components/StopLoading';
|
9
|
+
import { useChatStore } from '@/store/chat';
|
10
|
+
import { threadSelectors } from '@/store/chat/selectors';
|
11
|
+
|
12
|
+
import { useSendThreadMessage } from './useSend';
|
13
|
+
|
14
|
+
const useStyles = createStyles(({ css, prefixCls, token }) => {
|
15
|
+
return {
|
16
|
+
loadingButton: css`
|
17
|
+
display: flex;
|
18
|
+
align-items: center;
|
19
|
+
`,
|
20
|
+
overrideAntdIcon: css`
|
21
|
+
.${prefixCls}-btn.${prefixCls}-btn-icon-only {
|
22
|
+
display: flex;
|
23
|
+
align-items: center;
|
24
|
+
justify-content: center;
|
25
|
+
}
|
26
|
+
|
27
|
+
.${prefixCls}-btn.${prefixCls}-dropdown-trigger {
|
28
|
+
&::before {
|
29
|
+
background-color: ${rgba(token.colorBgLayout, 0.1)} !important;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
`,
|
33
|
+
};
|
34
|
+
});
|
35
|
+
|
36
|
+
interface FooterProps {
|
37
|
+
onExpandChange: (expand: boolean) => void;
|
38
|
+
}
|
39
|
+
|
40
|
+
const Footer = memo<FooterProps>(({ onExpandChange }) => {
|
41
|
+
const { t } = useTranslation('chat');
|
42
|
+
|
43
|
+
const { styles } = useStyles();
|
44
|
+
|
45
|
+
const [isAIGenerating, stopGenerateMessage] = useChatStore((s) => [
|
46
|
+
threadSelectors.isThreadAIGenerating(s),
|
47
|
+
s.stopGenerateMessage,
|
48
|
+
]);
|
49
|
+
|
50
|
+
const { send: sendMessage, canSend } = useSendThreadMessage();
|
51
|
+
|
52
|
+
return (
|
53
|
+
<Flexbox
|
54
|
+
align={'end'}
|
55
|
+
className={styles.overrideAntdIcon}
|
56
|
+
distribution={'space-between'}
|
57
|
+
flex={'none'}
|
58
|
+
gap={8}
|
59
|
+
horizontal
|
60
|
+
padding={'0 24px'}
|
61
|
+
>
|
62
|
+
<div />
|
63
|
+
{isAIGenerating ? (
|
64
|
+
<Button
|
65
|
+
className={styles.loadingButton}
|
66
|
+
icon={<StopLoadingIcon />}
|
67
|
+
onClick={stopGenerateMessage}
|
68
|
+
>
|
69
|
+
{t('input.stop')}
|
70
|
+
</Button>
|
71
|
+
) : (
|
72
|
+
<Button
|
73
|
+
disabled={!canSend}
|
74
|
+
loading={!canSend}
|
75
|
+
onClick={() => {
|
76
|
+
sendMessage();
|
77
|
+
onExpandChange?.(false);
|
78
|
+
}}
|
79
|
+
type={'primary'}
|
80
|
+
>
|
81
|
+
{t('input.send')}
|
82
|
+
</Button>
|
83
|
+
)}
|
84
|
+
</Flexbox>
|
85
|
+
);
|
86
|
+
});
|
87
|
+
|
88
|
+
Footer.displayName = 'Footer';
|
89
|
+
|
90
|
+
export default Footer;
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { memo } from 'react';
|
2
|
+
|
3
|
+
import InputArea from '@/features/ChatInput/Desktop/InputArea';
|
4
|
+
import { useChatStore } from '@/store/chat';
|
5
|
+
import { chatSelectors } from '@/store/chat/selectors';
|
6
|
+
|
7
|
+
import { useSendThreadMessage } from './useSend';
|
8
|
+
|
9
|
+
const TextArea = memo<{ onSend?: () => void }>(({ onSend }) => {
|
10
|
+
const [loading, value, updateInputMessage] = useChatStore((s) => [
|
11
|
+
chatSelectors.isAIGenerating(s),
|
12
|
+
s.threadInputMessage,
|
13
|
+
s.updateThreadInputMessage,
|
14
|
+
]);
|
15
|
+
const { send: sendMessage } = useSendThreadMessage();
|
16
|
+
|
17
|
+
return (
|
18
|
+
<InputArea
|
19
|
+
loading={loading}
|
20
|
+
onChange={updateInputMessage}
|
21
|
+
onSend={() => {
|
22
|
+
sendMessage();
|
23
|
+
onSend?.();
|
24
|
+
}}
|
25
|
+
value={value}
|
26
|
+
/>
|
27
|
+
);
|
28
|
+
});
|
29
|
+
|
30
|
+
export default TextArea;
|
@@ -0,0 +1,66 @@
|
|
1
|
+
'use client';
|
2
|
+
|
3
|
+
import { Alert } from '@lobehub/ui';
|
4
|
+
import Link from 'next/link';
|
5
|
+
import { memo } from 'react';
|
6
|
+
|
7
|
+
import { ActionKeys } from '@/features/ChatInput/ActionBar/config';
|
8
|
+
import DesktopChatInput, { FooterRender } from '@/features/ChatInput/Desktop';
|
9
|
+
import { useGlobalStore } from '@/store/global';
|
10
|
+
import { systemStatusSelectors } from '@/store/global/selectors';
|
11
|
+
|
12
|
+
import Footer from './Footer';
|
13
|
+
import TextArea from './TextArea';
|
14
|
+
|
15
|
+
const leftActions = ['stt', 'portalToken'] as ActionKeys[];
|
16
|
+
|
17
|
+
const rightActions = [] as ActionKeys[];
|
18
|
+
|
19
|
+
const renderTextArea = (onSend: () => void) => <TextArea onSend={onSend} />;
|
20
|
+
const renderFooter: FooterRender = (props) => <Footer {...props} />;
|
21
|
+
|
22
|
+
const Desktop = memo(() => {
|
23
|
+
const [inputHeight, hideThreadLimitAlert, updateSystemStatus] = useGlobalStore((s) => [
|
24
|
+
systemStatusSelectors.threadInputHeight(s),
|
25
|
+
systemStatusSelectors.systemStatus(s).hideThreadLimitAlert,
|
26
|
+
s.updateSystemStatus,
|
27
|
+
]);
|
28
|
+
|
29
|
+
return (
|
30
|
+
<>
|
31
|
+
{!hideThreadLimitAlert && (
|
32
|
+
<Alert
|
33
|
+
banner
|
34
|
+
closable
|
35
|
+
message={
|
36
|
+
<div>
|
37
|
+
子话题暂不支持文件/图片上传,如有需求,欢迎留言:
|
38
|
+
<Link
|
39
|
+
href={'https://github.com/lobehub/lobe-chat/discussions/4717'}
|
40
|
+
style={{ textDecoration: 'underline' }}
|
41
|
+
>
|
42
|
+
💬 讨论
|
43
|
+
</Link>
|
44
|
+
</div>
|
45
|
+
}
|
46
|
+
onClose={() => {
|
47
|
+
updateSystemStatus({ hideThreadLimitAlert: true });
|
48
|
+
}}
|
49
|
+
type={'info'}
|
50
|
+
/>
|
51
|
+
)}
|
52
|
+
<DesktopChatInput
|
53
|
+
inputHeight={inputHeight}
|
54
|
+
leftActions={leftActions}
|
55
|
+
onInputHeightChange={(height) => {
|
56
|
+
updateSystemStatus({ threadInputHeight: height });
|
57
|
+
}}
|
58
|
+
renderFooter={renderFooter}
|
59
|
+
renderTextArea={renderTextArea}
|
60
|
+
rightActions={rightActions}
|
61
|
+
/>
|
62
|
+
</>
|
63
|
+
);
|
64
|
+
});
|
65
|
+
|
66
|
+
export default Desktop;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
2
|
+
|
3
|
+
import { useChatStore } from '@/store/chat';
|
4
|
+
import { threadSelectors } from '@/store/chat/selectors';
|
5
|
+
import { SendMessageParams } from '@/types/message';
|
6
|
+
|
7
|
+
export type UseSendMessageParams = Pick<
|
8
|
+
SendMessageParams,
|
9
|
+
'onlyAddUserMessage' | 'isWelcomeQuestion'
|
10
|
+
>;
|
11
|
+
|
12
|
+
export const useSendThreadMessage = () => {
|
13
|
+
const [sendMessage, updateInputMessage] = useChatStore((s) => [
|
14
|
+
s.sendThreadMessage,
|
15
|
+
s.updateThreadInputMessage,
|
16
|
+
]);
|
17
|
+
|
18
|
+
const isSendButtonDisabledByMessage = useChatStore(threadSelectors.isSendButtonDisabledByMessage);
|
19
|
+
|
20
|
+
const canSend = !isSendButtonDisabledByMessage;
|
21
|
+
|
22
|
+
const send = useCallback((params: UseSendMessageParams = {}) => {
|
23
|
+
const store = useChatStore.getState();
|
24
|
+
if (threadSelectors.isThreadAIGenerating(store)) return;
|
25
|
+
|
26
|
+
const isSendButtonDisabledByMessage = threadSelectors.isSendButtonDisabledByMessage(
|
27
|
+
useChatStore.getState(),
|
28
|
+
);
|
29
|
+
|
30
|
+
const canSend = !isSendButtonDisabledByMessage;
|
31
|
+
if (!canSend) return;
|
32
|
+
|
33
|
+
// if there is no message and no image, then we should not send the message
|
34
|
+
if (!store.threadInputMessage) return;
|
35
|
+
|
36
|
+
sendMessage({ message: store.threadInputMessage, ...params });
|
37
|
+
|
38
|
+
updateInputMessage('');
|
39
|
+
|
40
|
+
// const hasSystemRole = agentSelectors.hasSystemRole(useAgentStore.getState());
|
41
|
+
// const agentSetting = useAgentStore.getState().agentSettingInstance;
|
42
|
+
|
43
|
+
// // if there is a system role, then we need to use agent setting instance to autocomplete agent meta
|
44
|
+
// if (hasSystemRole && !!agentSetting) {
|
45
|
+
// agentSetting.autocompleteAllMeta();
|
46
|
+
// }
|
47
|
+
}, []);
|
48
|
+
|
49
|
+
return useMemo(() => ({ canSend, send }), [canSend]);
|
50
|
+
};
|