@lobehub/chat 1.123.4 → 1.124.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/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/locales/ar/chat.json +6 -2
- package/locales/ar/editor.json +47 -0
- package/locales/bg-BG/chat.json +6 -2
- package/locales/bg-BG/editor.json +47 -0
- package/locales/de-DE/chat.json +6 -2
- package/locales/de-DE/editor.json +47 -0
- package/locales/en-US/chat.json +6 -2
- package/locales/en-US/editor.json +47 -0
- package/locales/es-ES/chat.json +6 -2
- package/locales/es-ES/editor.json +47 -0
- package/locales/es-ES/models.json +3 -1
- package/locales/fa-IR/chat.json +6 -2
- package/locales/fa-IR/editor.json +47 -0
- package/locales/fr-FR/chat.json +6 -2
- package/locales/fr-FR/editor.json +47 -0
- package/locales/it-IT/chat.json +6 -2
- package/locales/it-IT/editor.json +47 -0
- package/locales/ja-JP/chat.json +6 -2
- package/locales/ja-JP/editor.json +47 -0
- package/locales/ko-KR/chat.json +6 -2
- package/locales/ko-KR/editor.json +47 -0
- package/locales/ko-KR/models.json +3 -1
- package/locales/nl-NL/chat.json +6 -2
- package/locales/nl-NL/editor.json +47 -0
- package/locales/nl-NL/models.json +3 -1
- package/locales/pl-PL/chat.json +6 -2
- package/locales/pl-PL/editor.json +47 -0
- package/locales/pt-BR/chat.json +6 -2
- package/locales/pt-BR/editor.json +47 -0
- package/locales/ru-RU/chat.json +6 -2
- package/locales/ru-RU/editor.json +47 -0
- package/locales/tr-TR/chat.json +6 -2
- package/locales/tr-TR/editor.json +47 -0
- package/locales/vi-VN/chat.json +6 -2
- package/locales/vi-VN/editor.json +47 -0
- package/locales/zh-CN/chat.json +6 -2
- package/locales/zh-CN/editor.json +47 -0
- package/locales/zh-TW/chat.json +6 -2
- package/locales/zh-TW/editor.json +47 -0
- package/locales/zh-TW/models.json +3 -1
- package/next.config.ts +4 -0
- package/package.json +4 -2
- package/packages/const/src/layoutTokens.ts +1 -0
- package/packages/types/src/index.ts +1 -0
- package/packages/utils/src/index.ts +1 -0
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/{Footer/MessageFromUrl.tsx → MessageFromUrl.tsx} +3 -2
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/index.tsx +129 -28
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/index.tsx +44 -66
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/useSend.ts +141 -0
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/Content.tsx +7 -1
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/InboxWelcome/QuestionSuggest.tsx +3 -2
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/OpeningQuestions.tsx +3 -2
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/HeaderAction.tsx +18 -2
- package/src/features/ChatInput/ActionBar/STT/common.tsx +41 -47
- package/src/features/ChatInput/{Topic → ActionBar/SaveTopic}/index.tsx +15 -4
- package/src/features/ChatInput/ActionBar/Typo/index.tsx +22 -0
- package/src/features/ChatInput/ActionBar/components/Action.tsx +4 -0
- package/src/features/ChatInput/ActionBar/config.ts +7 -1
- package/src/features/ChatInput/ActionBar/index.tsx +40 -51
- package/src/features/ChatInput/ChatInputProvider.tsx +54 -0
- package/src/features/ChatInput/Desktop/FilePreview/FileItem/index.tsx +20 -11
- package/src/features/ChatInput/Desktop/FilePreview/FileList.tsx +16 -15
- package/src/features/ChatInput/Desktop/index.tsx +81 -68
- package/src/features/ChatInput/InputEditor/index.tsx +134 -0
- package/src/{app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files → features/ChatInput/Mobile/FilePreview}/FileItem/File.tsx +1 -2
- package/src/features/ChatInput/Mobile/FilePreview/index.tsx +44 -0
- package/src/features/ChatInput/Mobile/index.tsx +72 -0
- package/src/features/ChatInput/SendArea/ExpandButton.tsx +30 -0
- package/src/features/ChatInput/SendArea/SendButton.tsx +29 -0
- package/src/features/ChatInput/SendArea/ShortcutHint.tsx +52 -0
- package/src/features/ChatInput/SendArea/index.tsx +36 -0
- package/src/features/ChatInput/StoreUpdater.tsx +41 -0
- package/src/features/ChatInput/TypoBar/index.tsx +139 -0
- package/src/features/ChatInput/hooks/useChatInputEditor.ts +36 -0
- package/src/features/ChatInput/index.ts +7 -0
- package/src/features/ChatInput/store/action.ts +75 -0
- package/src/features/ChatInput/store/index.ts +23 -0
- package/src/features/ChatInput/store/initialState.ts +54 -0
- package/src/features/ChatInput/store/selectors.ts +5 -0
- package/src/features/Conversation/components/BackBottom/style.ts +1 -1
- package/src/features/Conversation/components/SkeletonList.tsx +10 -3
- package/src/features/Conversation/components/VirtualizedList/index.tsx +53 -44
- package/src/features/Conversation/components/WideScreenContainer/index.tsx +43 -0
- package/src/features/Portal/Thread/Chat/ChatInput/index.tsx +49 -42
- package/src/features/Portal/Thread/Chat/ChatInput/useSend.ts +48 -22
- package/src/features/Portal/Thread/Chat/index.tsx +2 -2
- package/src/features/Portal/Thread/Header/index.tsx +1 -1
- package/src/hooks/useHotkeys/chatScope.ts +5 -3
- package/src/layout/GlobalProvider/Editor.tsx +27 -0
- package/src/layout/GlobalProvider/Locale.tsx +3 -23
- package/src/locales/default/chat.ts +7 -2
- package/src/locales/default/editor.ts +47 -0
- package/src/locales/default/index.ts +2 -0
- package/src/services/aiChat.ts +8 -2
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +42 -33
- package/src/store/chat/slices/aiChat/actions/generateAIChatV2.ts +174 -35
- package/src/store/chat/slices/aiChat/initialState.ts +19 -0
- package/src/store/chat/slices/aiChat/selectors.ts +18 -0
- package/src/store/global/action.test.ts +6 -5
- package/src/store/global/actions/__tests__/general.test.ts +6 -6
- package/src/store/global/actions/workspacePane.ts +6 -0
- package/src/store/global/initialState.ts +2 -4
- package/src/store/global/selectors/systemStatus.test.ts +1 -2
- package/src/store/global/selectors/systemStatus.ts +2 -5
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/SendMore.tsx +0 -104
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/ShortcutHint.tsx +0 -40
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/index.tsx +0 -125
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/TextArea.test.tsx +0 -332
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/TextArea.tsx +0 -29
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files/index.tsx +0 -33
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/InputArea/Container.tsx +0 -41
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/InputArea/index.tsx +0 -156
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Send.tsx +0 -33
- package/src/features/ChatInput/Desktop/Header/index.tsx +0 -30
- package/src/features/ChatInput/Desktop/InputArea/index.tsx +0 -143
- package/src/features/ChatInput/Desktop/__tests__/useAutoFocus.test.ts +0 -45
- package/src/features/ChatInput/Desktop/useAutoFocus.ts +0 -13
- package/src/features/ChatInput/useSend.ts +0 -102
- package/src/features/Portal/Thread/Chat/ChatInput/Footer.tsx +0 -90
- package/src/features/Portal/Thread/Chat/ChatInput/TextArea.tsx +0 -30
- package/src/libs/trpc/client/types.ts +0 -18
- /package/src/{app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files → features/ChatInput/Mobile/FilePreview}/FileItem/Image.tsx +0 -0
- /package/src/{app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files → features/ChatInput/Mobile/FilePreview}/FileItem/index.tsx +0 -0
- /package/src/{app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files → features/ChatInput/Mobile/FilePreview}/FileItem/style.ts +0 -0
@@ -4,63 +4,70 @@ import { Alert } from '@lobehub/ui';
|
|
4
4
|
import Link from 'next/link';
|
5
5
|
import { memo } from 'react';
|
6
6
|
import { Trans } from 'react-i18next';
|
7
|
+
import { Flexbox } from 'react-layout-kit';
|
7
8
|
|
8
|
-
import { ActionKeys } from '@/features/ChatInput
|
9
|
-
import
|
9
|
+
import { type ActionKeys, ChatInputProvider, DesktopChatInput } from '@/features/ChatInput';
|
10
|
+
import WideScreenContainer from '@/features/Conversation/components/WideScreenContainer';
|
11
|
+
import { useChatStore } from '@/store/chat';
|
10
12
|
import { useGlobalStore } from '@/store/global';
|
11
13
|
import { systemStatusSelectors } from '@/store/global/selectors';
|
12
14
|
|
13
|
-
import
|
14
|
-
import TextArea from './TextArea';
|
15
|
+
import { useSendThreadMessage } from './useSend';
|
15
16
|
|
16
|
-
const
|
17
|
-
|
18
|
-
const rightActions = [] as ActionKeys[];
|
19
|
-
|
20
|
-
const renderTextArea = (onSend: () => void) => <TextArea onSend={onSend} />;
|
21
|
-
const renderFooter: FooterRender = (props) => <Footer {...props} />;
|
17
|
+
const threadActions: ActionKeys[] = ['typo', 'stt', 'portalToken'];
|
22
18
|
|
23
19
|
const Desktop = memo(() => {
|
24
|
-
const [
|
25
|
-
systemStatusSelectors.threadInputHeight(s),
|
20
|
+
const [hideThreadLimitAlert, updateSystemStatus] = useGlobalStore((s) => [
|
26
21
|
systemStatusSelectors.systemStatus(s).hideThreadLimitAlert,
|
27
22
|
s.updateSystemStatus,
|
28
23
|
]);
|
29
24
|
|
25
|
+
const { send, disabled, generating, stop } = useSendThreadMessage();
|
26
|
+
|
30
27
|
return (
|
31
|
-
|
28
|
+
<WideScreenContainer>
|
32
29
|
{!hideThreadLimitAlert && (
|
33
|
-
<
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
30
|
+
<Flexbox paddingBlock={'0 6px'} paddingInline={12}>
|
31
|
+
<Alert
|
32
|
+
closable
|
33
|
+
message={
|
34
|
+
<Trans i18nKey={'notSupportMultiModals'} ns={'thread'}>
|
35
|
+
子话题暂不支持文件/图片上传,如有需求,欢迎留言:
|
36
|
+
<Link
|
37
|
+
href={'https://github.com/lobehub/lobe-chat/discussions/4717'}
|
38
|
+
style={{ textDecoration: 'underline' }}
|
39
|
+
>
|
40
|
+
💬 讨论
|
41
|
+
</Link>
|
42
|
+
</Trans>
|
43
|
+
}
|
44
|
+
onClose={() => {
|
45
|
+
updateSystemStatus({ hideThreadLimitAlert: true });
|
46
|
+
}}
|
47
|
+
type={'info'}
|
48
|
+
/>
|
49
|
+
</Flexbox>
|
52
50
|
)}
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
51
|
+
|
52
|
+
<ChatInputProvider
|
53
|
+
chatInputEditorRef={(instance) => {
|
54
|
+
if (!instance) return;
|
55
|
+
useChatStore.setState({ threadInputEditor: instance });
|
56
|
+
}}
|
57
|
+
leftActions={threadActions}
|
58
|
+
onSend={() => {
|
59
|
+
send();
|
60
|
+
}}
|
61
|
+
sendButtonProps={{
|
62
|
+
disabled,
|
63
|
+
generating,
|
64
|
+
onStop: stop,
|
65
|
+
shape: 'round',
|
58
66
|
}}
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
</>
|
67
|
+
>
|
68
|
+
<DesktopChatInput />
|
69
|
+
</ChatInputProvider>
|
70
|
+
</WideScreenContainer>
|
64
71
|
);
|
65
72
|
});
|
66
73
|
|
@@ -1,5 +1,8 @@
|
|
1
|
-
import {
|
1
|
+
import { useMemo, useState } from 'react';
|
2
2
|
|
3
|
+
import { useGeminiChineseWarning } from '@/hooks/useGeminiChineseWarning';
|
4
|
+
import { getAgentStoreState } from '@/store/agent';
|
5
|
+
import { agentSelectors } from '@/store/agent/slices/chat';
|
3
6
|
import { useChatStore } from '@/store/chat';
|
4
7
|
import { threadSelectors } from '@/store/chat/selectors';
|
5
8
|
import { SendMessageParams } from '@/types/message';
|
@@ -10,41 +13,64 @@ export type UseSendMessageParams = Pick<
|
|
10
13
|
>;
|
11
14
|
|
12
15
|
export const useSendThreadMessage = () => {
|
16
|
+
const [loading, setLoading] = useState(false);
|
17
|
+
const canNotSend = useChatStore(threadSelectors.isSendButtonDisabledByMessage);
|
18
|
+
const generating = useChatStore((s) => threadSelectors.isThreadAIGenerating(s));
|
19
|
+
const stop = useChatStore((s) => s.stopGenerateMessage);
|
13
20
|
const [sendMessage, updateInputMessage] = useChatStore((s) => [
|
14
21
|
s.sendThreadMessage,
|
15
22
|
s.updateThreadInputMessage,
|
16
23
|
]);
|
24
|
+
const checkGeminiChineseWarning = useGeminiChineseWarning();
|
17
25
|
|
18
|
-
const
|
19
|
-
|
20
|
-
const canSend = !isSendButtonDisabledByMessage;
|
21
|
-
|
22
|
-
const send = useCallback((params: UseSendMessageParams = {}) => {
|
26
|
+
const handleSend = async (params: UseSendMessageParams = {}) => {
|
23
27
|
const store = useChatStore.getState();
|
28
|
+
|
24
29
|
if (threadSelectors.isThreadAIGenerating(store)) return;
|
30
|
+
const canNotSend = threadSelectors.isSendButtonDisabledByMessage(store);
|
31
|
+
|
32
|
+
if (canNotSend) return;
|
33
|
+
|
34
|
+
const threadInputEditor = store.threadInputEditor;
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
|
36
|
+
if (!threadInputEditor) {
|
37
|
+
console.warn('not found threadInputEditor instance');
|
38
|
+
return;
|
39
|
+
}
|
29
40
|
|
30
|
-
const
|
31
|
-
if (!canSend) return;
|
41
|
+
const inputMessage = threadInputEditor.getMarkdownContent();
|
32
42
|
|
33
43
|
// if there is no message and no image, then we should not send the message
|
34
|
-
if (!
|
44
|
+
if (!inputMessage) return;
|
35
45
|
|
36
|
-
|
46
|
+
// Check for Chinese text warning with Gemini model
|
47
|
+
const agentStore = getAgentStoreState();
|
48
|
+
const currentModel = agentSelectors.currentAgentModel(agentStore);
|
49
|
+
const shouldContinue = await checkGeminiChineseWarning({
|
50
|
+
model: currentModel,
|
51
|
+
prompt: inputMessage,
|
52
|
+
scenario: 'chat',
|
53
|
+
});
|
37
54
|
|
38
|
-
|
55
|
+
if (!shouldContinue) return;
|
56
|
+
|
57
|
+
updateInputMessage(inputMessage);
|
39
58
|
|
40
|
-
|
41
|
-
|
59
|
+
sendMessage({ message: inputMessage, ...params });
|
60
|
+
|
61
|
+
updateInputMessage('');
|
62
|
+
threadInputEditor.clearContent();
|
63
|
+
threadInputEditor.focus();
|
64
|
+
};
|
42
65
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
}
|
66
|
+
const send = async (params: UseSendMessageParams = {}) => {
|
67
|
+
setLoading(true);
|
68
|
+
await handleSend(params);
|
69
|
+
setLoading(false);
|
70
|
+
};
|
48
71
|
|
49
|
-
return useMemo(
|
72
|
+
return useMemo(
|
73
|
+
() => ({ disabled: canNotSend, generating, loading, send, stop }),
|
74
|
+
[canNotSend, send, generating, stop, loading],
|
75
|
+
);
|
50
76
|
};
|
@@ -11,7 +11,7 @@ interface ConversationProps {
|
|
11
11
|
}
|
12
12
|
|
13
13
|
const Conversation = memo<ConversationProps>(({ mobile }) => (
|
14
|
-
|
14
|
+
<>
|
15
15
|
<Suspense
|
16
16
|
fallback={
|
17
17
|
<Flexbox flex={1} height={'100%'}>
|
@@ -22,7 +22,7 @@ const Conversation = memo<ConversationProps>(({ mobile }) => (
|
|
22
22
|
<ChatList mobile={mobile} />
|
23
23
|
</Suspense>
|
24
24
|
<ChatInput />
|
25
|
-
|
25
|
+
</>
|
26
26
|
));
|
27
27
|
|
28
28
|
export default Conversation;
|
@@ -40,7 +40,7 @@ const Header = memo(() => {
|
|
40
40
|
paddingBlock={6}
|
41
41
|
paddingInline={8}
|
42
42
|
style={{
|
43
|
-
|
43
|
+
borderBottom: `1px solid ${theme.colorBorderSecondary}`,
|
44
44
|
}}
|
45
45
|
title={<Title />}
|
46
46
|
/>
|
@@ -2,8 +2,8 @@ import isEqual from 'fast-deep-equal';
|
|
2
2
|
import { useEffect } from 'react';
|
3
3
|
import { useHotkeysContext } from 'react-hotkeys-hook';
|
4
4
|
|
5
|
+
import { useSend } from '@/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/useSend';
|
5
6
|
import { useClearCurrentMessages } from '@/features/ChatInput/ActionBar/Clear';
|
6
|
-
import { useSendMessage } from '@/features/ChatInput/useSend';
|
7
7
|
import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes';
|
8
8
|
import { useActionSWR } from '@/libs/swr';
|
9
9
|
import { useChatStore } from '@/store/chat';
|
@@ -75,8 +75,10 @@ export const useToggleRightPanelHotkey = () => {
|
|
75
75
|
};
|
76
76
|
|
77
77
|
export const useAddUserMessageHotkey = () => {
|
78
|
-
const { send } =
|
79
|
-
return useHotkeyById(HotkeyEnum.AddUserMessage, () =>
|
78
|
+
const { send } = useSend();
|
79
|
+
return useHotkeyById(HotkeyEnum.AddUserMessage, () => {
|
80
|
+
send({ onlyAddUserMessage: true });
|
81
|
+
});
|
80
82
|
};
|
81
83
|
|
82
84
|
export const useClearCurrentMessagesHotkey = () => {
|
@@ -0,0 +1,27 @@
|
|
1
|
+
'use client';
|
2
|
+
|
3
|
+
import { EditorProvider } from '@lobehub/editor/react';
|
4
|
+
import { PropsWithChildren, memo, useMemo } from 'react';
|
5
|
+
import { useTranslation } from 'react-i18next';
|
6
|
+
|
7
|
+
const Editor = memo<PropsWithChildren>(({ children }) => {
|
8
|
+
const {
|
9
|
+
i18n: { language, getResourceBundle },
|
10
|
+
} = useTranslation('editor');
|
11
|
+
|
12
|
+
const localization = useMemo(() => getResourceBundle(language, 'editor'), [language]);
|
13
|
+
|
14
|
+
return (
|
15
|
+
<EditorProvider
|
16
|
+
config={{
|
17
|
+
locale: localization,
|
18
|
+
}}
|
19
|
+
>
|
20
|
+
{children}
|
21
|
+
</EditorProvider>
|
22
|
+
);
|
23
|
+
});
|
24
|
+
|
25
|
+
Editor.displayName = 'Editor';
|
26
|
+
|
27
|
+
export default Editor;
|
@@ -1,7 +1,6 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
3
|
import { ConfigProvider } from 'antd';
|
4
|
-
import { useTheme } from 'antd-style';
|
5
4
|
import dayjs from 'dayjs';
|
6
5
|
import { PropsWithChildren, memo, useEffect, useState } from 'react';
|
7
6
|
import { isRtlLang } from 'rtl-detect';
|
@@ -10,6 +9,8 @@ import { createI18nNext } from '@/locales/create';
|
|
10
9
|
import { isOnServerSide } from '@/utils/env';
|
11
10
|
import { getAntdLocale } from '@/utils/locale';
|
12
11
|
|
12
|
+
import Editor from './Editor';
|
13
|
+
|
13
14
|
const updateDayjs = async (lang: string) => {
|
14
15
|
// load default lang
|
15
16
|
let dayJSLocale;
|
@@ -36,7 +37,6 @@ const Locale = memo<LocaleLayoutProps>(({ children, defaultLang, antdLocale }) =
|
|
36
37
|
const [i18n] = useState(createI18nNext(defaultLang));
|
37
38
|
const [lang, setLang] = useState(defaultLang);
|
38
39
|
const [locale, setLocale] = useState(antdLocale);
|
39
|
-
const theme = useTheme();
|
40
40
|
|
41
41
|
// if run on server side, init i18n instance everytime
|
42
42
|
if (isOnServerSide) {
|
@@ -91,30 +91,10 @@ const Locale = memo<LocaleLayoutProps>(({ children, defaultLang, antdLocale }) =
|
|
91
91
|
Button: {
|
92
92
|
contentFontSizeSM: 12,
|
93
93
|
},
|
94
|
-
DatePicker: {
|
95
|
-
activeBorderColor: theme.colorBorder,
|
96
|
-
hoverBorderColor: theme.colorBorder,
|
97
|
-
},
|
98
|
-
Input: {
|
99
|
-
activeBorderColor: theme.colorBorder,
|
100
|
-
hoverBorderColor: theme.colorBorder,
|
101
|
-
},
|
102
|
-
InputNumber: {
|
103
|
-
activeBorderColor: theme.colorBorder,
|
104
|
-
hoverBorderColor: theme.colorBorder,
|
105
|
-
},
|
106
|
-
Mentions: {
|
107
|
-
activeBorderColor: theme.colorBorder,
|
108
|
-
hoverBorderColor: theme.colorBorder,
|
109
|
-
},
|
110
|
-
Select: {
|
111
|
-
activeBorderColor: theme.colorBorder,
|
112
|
-
hoverBorderColor: theme.colorBorder,
|
113
|
-
},
|
114
94
|
},
|
115
95
|
}}
|
116
96
|
>
|
117
|
-
{children}
|
97
|
+
<Editor>{children}</Editor>
|
118
98
|
</ConfigProvider>
|
119
99
|
);
|
120
100
|
});
|
@@ -71,10 +71,11 @@ export default {
|
|
71
71
|
input: {
|
72
72
|
addAi: '添加一条 AI 消息',
|
73
73
|
addUser: '添加一条用户消息',
|
74
|
+
errorMsg: '消息发送失败,请检查网络后重试: {{errorMsg}}',
|
74
75
|
more: '更多',
|
75
76
|
send: '发送',
|
76
|
-
sendWithCmdEnter: '按
|
77
|
-
sendWithEnter: '按
|
77
|
+
sendWithCmdEnter: '按 <key/> 键发送',
|
78
|
+
sendWithEnter: '按 <key/> 键发送',
|
78
79
|
stop: '停止',
|
79
80
|
warp: '换行',
|
80
81
|
},
|
@@ -236,6 +237,10 @@ export default {
|
|
236
237
|
threadMessageCount: '{{messageCount}} 条消息',
|
237
238
|
title: '子话题',
|
238
239
|
},
|
240
|
+
toggleWideScreen: {
|
241
|
+
off: '关闭宽屏模式',
|
242
|
+
on: '开启宽屏模式',
|
243
|
+
},
|
239
244
|
tokenDetails: {
|
240
245
|
chats: '会话消息',
|
241
246
|
historySummary: '历史总结',
|
@@ -0,0 +1,47 @@
|
|
1
|
+
export default {
|
2
|
+
actions: {
|
3
|
+
expand: {
|
4
|
+
off: '收起',
|
5
|
+
on: '展开',
|
6
|
+
},
|
7
|
+
typobar: {
|
8
|
+
off: '隐藏格式工具栏',
|
9
|
+
on: '显示格式工具栏',
|
10
|
+
},
|
11
|
+
},
|
12
|
+
file: {
|
13
|
+
error: '错误:{{message}}',
|
14
|
+
uploading: '正在上传文件...',
|
15
|
+
},
|
16
|
+
image: {
|
17
|
+
broken: '图片损坏',
|
18
|
+
},
|
19
|
+
link: {
|
20
|
+
edit: '编辑链接',
|
21
|
+
open: '打开链接',
|
22
|
+
placeholder: '输入链接 URL',
|
23
|
+
unlink: '取消链接',
|
24
|
+
},
|
25
|
+
table: {
|
26
|
+
delete: '删除表格',
|
27
|
+
deleteColumn: '删除列',
|
28
|
+
deleteRow: '删除行',
|
29
|
+
insertColumnLeft: '在左侧插入 {{count}} 列',
|
30
|
+
insertColumnRight: '在右侧插入 {{count}} 列',
|
31
|
+
insertRowAbove: '在上方插入 {{count}} 行',
|
32
|
+
insertRowBelow: '在下方插入 {{count}} 行',
|
33
|
+
},
|
34
|
+
typobar: {
|
35
|
+
blockquote: '引用',
|
36
|
+
bold: '加粗',
|
37
|
+
bulletList: '无序列表',
|
38
|
+
code: '行内代码',
|
39
|
+
codeblock: '代码块',
|
40
|
+
italic: '斜体',
|
41
|
+
link: '链接',
|
42
|
+
numberList: '有序列表',
|
43
|
+
strikethrough: '删除线',
|
44
|
+
table: '插入表格',
|
45
|
+
underline: '下划线',
|
46
|
+
},
|
47
|
+
};
|
@@ -6,6 +6,7 @@ import color from './color';
|
|
6
6
|
import common from './common';
|
7
7
|
import components from './components';
|
8
8
|
import discover from './discover';
|
9
|
+
import editor from './editor';
|
9
10
|
import electron from './electron';
|
10
11
|
import error from './error';
|
11
12
|
import file from './file';
|
@@ -37,6 +38,7 @@ const resources = {
|
|
37
38
|
common,
|
38
39
|
components,
|
39
40
|
discover,
|
41
|
+
editor,
|
40
42
|
electron,
|
41
43
|
error,
|
42
44
|
file,
|
package/src/services/aiChat.ts
CHANGED
@@ -4,8 +4,14 @@ import { cleanObject } from '@lobechat/utils';
|
|
4
4
|
import { lambdaClient } from '@/libs/trpc/client';
|
5
5
|
|
6
6
|
class AiChatService {
|
7
|
-
sendMessageInServer = async (
|
8
|
-
|
7
|
+
sendMessageInServer = async (
|
8
|
+
params: SendMessageServerParams,
|
9
|
+
abortController: AbortController,
|
10
|
+
) => {
|
11
|
+
return lambdaClient.aiChat.sendMessageInServer.mutate(cleanObject(params), {
|
12
|
+
context: { showNotification: false },
|
13
|
+
signal: abortController?.signal,
|
14
|
+
});
|
9
15
|
};
|
10
16
|
}
|
11
17
|
|
@@ -187,18 +187,21 @@ describe('generateAIChatV2 actions', () => {
|
|
187
187
|
await result.current.sendMessage({ message, files });
|
188
188
|
});
|
189
189
|
|
190
|
-
expect(aiChatService.sendMessageInServer).toHaveBeenCalledWith(
|
191
|
-
|
192
|
-
|
193
|
-
|
190
|
+
expect(aiChatService.sendMessageInServer).toHaveBeenCalledWith(
|
191
|
+
{
|
192
|
+
newAssistantMessage: {
|
193
|
+
model: DEFAULT_MODEL,
|
194
|
+
provider: DEFAULT_PROVIDER,
|
195
|
+
},
|
196
|
+
newUserMessage: {
|
197
|
+
content: message,
|
198
|
+
files: files.map((f) => f.id),
|
199
|
+
},
|
200
|
+
sessionId: mockState.activeId,
|
201
|
+
topicId: mockState.activeTopicId,
|
194
202
|
},
|
195
|
-
|
196
|
-
|
197
|
-
files: files.map((f) => f.id),
|
198
|
-
},
|
199
|
-
sessionId: mockState.activeId,
|
200
|
-
topicId: mockState.activeTopicId,
|
201
|
-
});
|
203
|
+
expect.anything(),
|
204
|
+
);
|
202
205
|
expect(result.current.internal_execAgentRuntime).toHaveBeenCalled();
|
203
206
|
});
|
204
207
|
|
@@ -270,18 +273,21 @@ describe('generateAIChatV2 actions', () => {
|
|
270
273
|
await result.current.sendMessage({ message: '', files: [{ id: 'file-1' }] as any });
|
271
274
|
});
|
272
275
|
|
273
|
-
expect(aiChatService.sendMessageInServer).toHaveBeenCalledWith(
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
276
|
+
expect(aiChatService.sendMessageInServer).toHaveBeenCalledWith(
|
277
|
+
{
|
278
|
+
newAssistantMessage: {
|
279
|
+
model: DEFAULT_MODEL,
|
280
|
+
provider: DEFAULT_PROVIDER,
|
281
|
+
},
|
282
|
+
newUserMessage: {
|
283
|
+
content: '',
|
284
|
+
files: ['file-1'],
|
285
|
+
},
|
286
|
+
sessionId: 'session-id',
|
287
|
+
topicId: 'topic-id',
|
281
288
|
},
|
282
|
-
|
283
|
-
|
284
|
-
});
|
289
|
+
expect.anything(),
|
290
|
+
);
|
285
291
|
});
|
286
292
|
|
287
293
|
it('当同时有文件和消息内容时,正确发送消息并关联文件', async () => {
|
@@ -291,18 +297,21 @@ describe('generateAIChatV2 actions', () => {
|
|
291
297
|
await result.current.sendMessage({ message: 'test', files: [{ id: 'file-1' }] as any });
|
292
298
|
});
|
293
299
|
|
294
|
-
expect(aiChatService.sendMessageInServer).toHaveBeenCalledWith(
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
300
|
+
expect(aiChatService.sendMessageInServer).toHaveBeenCalledWith(
|
301
|
+
{
|
302
|
+
newAssistantMessage: {
|
303
|
+
model: DEFAULT_MODEL,
|
304
|
+
provider: DEFAULT_PROVIDER,
|
305
|
+
},
|
306
|
+
newUserMessage: {
|
307
|
+
content: 'test',
|
308
|
+
files: ['file-1'],
|
309
|
+
},
|
310
|
+
sessionId: 'session-id',
|
311
|
+
topicId: 'topic-id',
|
302
312
|
},
|
303
|
-
|
304
|
-
|
305
|
-
});
|
313
|
+
expect.anything(),
|
314
|
+
);
|
306
315
|
});
|
307
316
|
|
308
317
|
it('当 createMessage 抛出错误时,正确处理错误而不影响整个应用', async () => {
|