@lobehub/chat 0.91.0 → 0.92.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.
Files changed (79) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/locales/en_US/chat.json +55 -0
  3. package/locales/en_US/common.json +17 -51
  4. package/locales/ja_JP/chat.json +55 -0
  5. package/locales/ja_JP/common.json +14 -48
  6. package/locales/ko_KR/chat.json +55 -0
  7. package/locales/ko_KR/common.json +25 -59
  8. package/locales/ru_RU/chat.json +55 -0
  9. package/locales/ru_RU/common.json +11 -45
  10. package/locales/zh_CN/chat.json +55 -0
  11. package/locales/zh_CN/common.json +11 -45
  12. package/locales/zh_TW/chat.json +55 -0
  13. package/locales/zh_TW/common.json +30 -64
  14. package/package.json +2 -1
  15. package/src/app/chat/(desktop)/features/ChatHeader.tsx +1 -1
  16. package/src/app/chat/(desktop)/features/SessionHeader.tsx +1 -1
  17. package/src/app/chat/(mobile)/features/ChatHeader.tsx +1 -1
  18. package/src/app/chat/(mobile)/features/TopicList.tsx +1 -1
  19. package/src/app/chat/features/ChatHeader/ShareButton/Inner.tsx +1 -1
  20. package/src/app/chat/features/ChatHeader/ShareButton/Preview.tsx +1 -1
  21. package/src/app/chat/features/ChatInputContent/ActionBar/ActionRight.tsx +3 -3
  22. package/src/app/chat/features/ChatInputContent/ActionBar/Token.tsx +1 -1
  23. package/src/app/chat/features/ChatInputContent/Footer/SaveTopic.tsx +1 -1
  24. package/src/app/chat/features/ChatInputContent/Footer/index.tsx +1 -1
  25. package/src/app/chat/features/ChatInputContent/index.tsx +1 -1
  26. package/src/app/chat/features/Conversation/ChatList/Actions/Assistant.tsx +22 -0
  27. package/src/app/chat/features/Conversation/ChatList/Actions/Error.tsx +15 -0
  28. package/src/app/chat/features/Conversation/ChatList/{Messages/System.tsx → Actions/Fallback.tsx} +1 -1
  29. package/src/app/chat/features/Conversation/ChatList/Actions/Function.tsx +14 -0
  30. package/src/app/chat/features/Conversation/ChatList/{Messages → Actions}/User.tsx +6 -1
  31. package/src/app/chat/features/Conversation/ChatList/Actions/customAction.ts +21 -0
  32. package/src/app/chat/features/Conversation/ChatList/Actions/index.ts +13 -0
  33. package/src/app/chat/features/Conversation/ChatList/Extras/Assistant.tsx +39 -0
  34. package/src/app/chat/features/Conversation/ChatList/Extras/Translate.tsx +75 -0
  35. package/src/app/chat/features/Conversation/ChatList/Extras/User.tsx +24 -0
  36. package/src/app/chat/features/Conversation/ChatList/Extras/index.ts +9 -0
  37. package/src/app/chat/features/Conversation/ChatList/Loading.tsx +53 -0
  38. package/src/app/chat/features/Conversation/ChatList/Messages/Assistant.tsx +5 -58
  39. package/src/app/chat/features/Conversation/ChatList/Messages/Default.tsx +7 -1
  40. package/src/app/chat/features/Conversation/ChatList/Messages/Function.tsx +4 -23
  41. package/src/app/chat/features/Conversation/ChatList/Messages/index.ts +4 -17
  42. package/src/app/chat/features/Conversation/ChatList/Plugins/FunctionCall.tsx +0 -2
  43. package/src/app/chat/features/Conversation/ChatList/Plugins/PluginMessage.tsx +3 -4
  44. package/src/app/chat/features/Conversation/ChatList/index.tsx +17 -2
  45. package/src/app/chat/features/Conversation/index.tsx +1 -1
  46. package/src/app/chat/features/SessionListContent/Inbox/index.tsx +1 -1
  47. package/src/app/chat/features/SessionListContent/List/AddButton.tsx +1 -1
  48. package/src/app/chat/features/SessionSearchBar/index.tsx +1 -1
  49. package/src/app/chat/features/TopicListContent/Topic/DefaultContent.tsx +1 -1
  50. package/src/app/chat/features/TopicListContent/Topic/TopicContent.tsx +1 -1
  51. package/src/app/chat/features/TopicListContent/Topic/index.tsx +1 -1
  52. package/src/app/chat/features/TopicListContent/TopicSearchBar/index.tsx +1 -1
  53. package/src/app/home/index.tsx +2 -2
  54. package/src/chains/chat.ts +77 -0
  55. package/src/features/AgentSetting/AgentPrompt/index.tsx +3 -3
  56. package/src/features/AgentSetting/store/action.ts +1 -1
  57. package/src/layout/ResponsiveLayout.client.tsx +4 -2
  58. package/src/locales/create.ts +2 -1
  59. package/src/locales/default/chat.ts +60 -0
  60. package/src/locales/default/common.ts +10 -45
  61. package/src/locales/options.ts +10 -0
  62. package/src/locales/resources/en_US.ts +2 -0
  63. package/src/locales/resources/index.ts +1 -1
  64. package/src/locales/resources/ja_JP.ts +2 -0
  65. package/src/locales/resources/ko_KR.ts +2 -0
  66. package/src/locales/resources/ru_RU.ts +2 -0
  67. package/src/locales/resources/zh_CN.ts +2 -0
  68. package/src/locales/resources/zh_TW.ts +2 -0
  69. package/src/store/global/selectors/settings.ts +4 -0
  70. package/src/store/session/slices/chat/actions/index.ts +7 -1
  71. package/src/store/session/slices/chat/actions/message.ts +2 -2
  72. package/src/store/session/slices/chat/actions/topic.ts +2 -2
  73. package/src/store/session/slices/chat/actions/translate.ts +87 -0
  74. package/src/store/session/slices/chat/selectors/chat.ts +23 -17
  75. package/src/store/session/slices/chat/selectors/index.ts +2 -2
  76. package/src/types/chatMessage.ts +5 -4
  77. package/src/types/translate.ts +4 -0
  78. package/src/prompts/chat.ts +0 -32
  79. /package/src/{prompts → chains}/agent.ts +0 -0
@@ -0,0 +1,14 @@
1
+ import { ActionIconGroup, RenderAction, useChatListActionsBar } from '@lobehub/ui';
2
+ import { memo } from 'react';
3
+
4
+ export const FunctionActionsBar: RenderAction = memo(({ text, onActionClick }) => {
5
+ const { regenerate, divider, del } = useChatListActionsBar(text);
6
+ return (
7
+ <ActionIconGroup
8
+ dropdownMenu={[regenerate, divider, del]}
9
+ items={[regenerate]}
10
+ onActionClick={onActionClick}
11
+ type="ghost"
12
+ />
13
+ );
14
+ });
@@ -1,11 +1,16 @@
1
1
  import { ActionIconGroup, RenderAction, useChatListActionsBar } from '@lobehub/ui';
2
2
  import { memo } from 'react';
3
3
 
4
+ import { useCustomActions } from './customAction';
5
+
4
6
  export const UserActionsBar: RenderAction = memo(({ text, onActionClick }) => {
5
7
  const { regenerate, edit, copy, divider, del } = useChatListActionsBar(text);
8
+ const { translate } = useCustomActions();
9
+
10
+
6
11
  return (
7
12
  <ActionIconGroup
8
- dropdownMenu={[edit, copy, regenerate, divider, del]}
13
+ dropdownMenu={[edit, copy, regenerate, divider, translate, divider, del]}
9
14
  items={[regenerate, edit]}
10
15
  onActionClick={onActionClick}
11
16
  type="ghost"
@@ -0,0 +1,21 @@
1
+ import { ActionIconGroupItems } from '@lobehub/ui/es/ActionIconGroup';
2
+ import { LanguagesIcon } from 'lucide-react';
3
+ import { useTranslation } from 'react-i18next';
4
+
5
+ export const useCustomActions = () => {
6
+ const { t } = useTranslation('chat');
7
+
8
+ const translate = {
9
+ // children: localeOptions.map((i) => ({
10
+ // key: i.value,
11
+ // label: t(`lang.${i.value}`, { ns: 'common' }),
12
+ // })),
13
+ icon: LanguagesIcon,
14
+ key: 'translate',
15
+ label: t('translateTo'),
16
+ } as ActionIconGroupItems;
17
+
18
+ return {
19
+ translate,
20
+ };
21
+ };
@@ -0,0 +1,13 @@
1
+ import { ChatListProps } from '@lobehub/ui';
2
+
3
+ import { AssistantActionsBar } from './Assistant';
4
+ import { DefaultActionsBar } from './Fallback';
5
+ import { FunctionActionsBar } from './Function';
6
+ import { UserActionsBar } from './User';
7
+
8
+ export const renderActions: ChatListProps['renderActions'] = {
9
+ assistant: AssistantActionsBar,
10
+ function: FunctionActionsBar,
11
+ system: DefaultActionsBar,
12
+ user: UserActionsBar,
13
+ };
@@ -0,0 +1,39 @@
1
+ import { SiOpenai } from '@icons-pack/react-simple-icons';
2
+ import { RenderMessageExtra, Tag } from '@lobehub/ui';
3
+ import { Divider } from 'antd';
4
+ import { memo } from 'react';
5
+ import { Flexbox } from 'react-layout-kit';
6
+
7
+ import { useSessionStore } from '@/store/session';
8
+ import { agentSelectors } from '@/store/session/selectors';
9
+
10
+ import Translate from './Translate';
11
+
12
+ export const AssistantMessageExtra: RenderMessageExtra = memo(({ extra, id }) => {
13
+ const model = useSessionStore(agentSelectors.currentAgentModel);
14
+
15
+ const showModelTag = extra?.fromModel && model !== extra?.fromModel;
16
+ const hasTranslate = !!extra?.translate;
17
+
18
+ const showExtra = showModelTag || hasTranslate;
19
+
20
+ const loading = useSessionStore((s) => s.chatLoadingId === id);
21
+
22
+ if (!showExtra) return;
23
+
24
+ return (
25
+ <Flexbox gap={8} style={{ marginTop: 8 }}>
26
+ {showModelTag && (
27
+ <div>
28
+ <Tag icon={<SiOpenai size={'1em'} />}>{extra?.fromModel as string}</Tag>
29
+ </div>
30
+ )}
31
+ {extra.translate && (
32
+ <div>
33
+ <Divider style={{ margin: '12px 0' }} />
34
+ <Translate id={id} loading={loading} {...extra.translate} />
35
+ </div>
36
+ )}
37
+ </Flexbox>
38
+ );
39
+ });
@@ -0,0 +1,75 @@
1
+ import { ActionIcon, Icon, Markdown, Tag } from '@lobehub/ui';
2
+ import { App } from 'antd';
3
+ import { createStyles } from 'antd-style';
4
+ import copy from 'copy-to-clipboard';
5
+ import { ChevronDown, ChevronUp, ChevronsRight, CopyIcon, TrashIcon } from 'lucide-react';
6
+ import { memo, useState } from 'react';
7
+ import { useTranslation } from 'react-i18next';
8
+ import { Flexbox } from 'react-layout-kit';
9
+
10
+ import { useSessionStore } from '@/store/session';
11
+ import { ChatTranslate } from '@/types/chatMessage';
12
+
13
+ import BubblesLoading from '../Loading';
14
+
15
+ const useStyles = createStyles(({ css }) => ({
16
+ container: css`
17
+ margin-top: 8px;
18
+ `,
19
+ }));
20
+
21
+ interface TranslateProps extends ChatTranslate {
22
+ id: string;
23
+ loading?: boolean;
24
+ }
25
+
26
+ const Translate = memo<TranslateProps>(({ content = '', from, to, id, loading }) => {
27
+ const { theme } = useStyles();
28
+ const { t } = useTranslation('common');
29
+ const [show, setShow] = useState(true);
30
+ const clearTranslate = useSessionStore((s) => s.clearTranslate);
31
+
32
+ const { message } = App.useApp();
33
+ return (
34
+ <Flexbox gap={8}>
35
+ <Flexbox align={'center'} horizontal justify={'space-between'}>
36
+ <div>
37
+ <Flexbox gap={4} horizontal>
38
+ <Tag style={{ margin: 0 }}>{from ? t(`lang.${from}` as any) : '...'}</Tag>
39
+ <Icon color={theme.colorTextTertiary} icon={ChevronsRight} />
40
+ <Tag>{t(`lang.${to}` as any)}</Tag>
41
+ </Flexbox>
42
+ </div>
43
+ <Flexbox horizontal>
44
+ <ActionIcon
45
+ icon={CopyIcon}
46
+ onClick={() => {
47
+ copy(content);
48
+ message.success(t('copySuccess'));
49
+ }}
50
+ size={'small'}
51
+ title={t('copy')}
52
+ />
53
+ <ActionIcon
54
+ icon={TrashIcon}
55
+ onClick={() => {
56
+ clearTranslate(id);
57
+ }}
58
+ size={'small'}
59
+ title={t('translate.clear', { ns: 'chat' })}
60
+ />
61
+ <ActionIcon
62
+ icon={show ? ChevronDown : ChevronUp}
63
+ onClick={() => {
64
+ setShow(!show);
65
+ }}
66
+ size={'small'}
67
+ />
68
+ </Flexbox>
69
+ </Flexbox>
70
+ {!show ? null : loading && !content ? <BubblesLoading /> : <Markdown>{content}</Markdown>}
71
+ </Flexbox>
72
+ );
73
+ });
74
+
75
+ export default Translate;
@@ -0,0 +1,24 @@
1
+ import { RenderMessageExtra } from '@lobehub/ui';
2
+ import { Divider } from 'antd';
3
+ import { memo } from 'react';
4
+ import { Flexbox } from 'react-layout-kit';
5
+
6
+ import { useSessionStore } from '@/store/session';
7
+
8
+ import Translate from './Translate';
9
+
10
+ export const UserMessageExtra: RenderMessageExtra = memo(({ extra, id }) => {
11
+ const hasTranslate = !!extra?.translate;
12
+
13
+ const loading = useSessionStore((s) => s.chatLoadingId === id);
14
+ return (
15
+ <Flexbox gap={8} style={{ marginTop: hasTranslate ? 8 : 0 }}>
16
+ {extra?.translate && (
17
+ <div>
18
+ <Divider style={{ margin: '12px 0' }} />
19
+ <Translate id={id} {...extra.translate} loading={loading} />
20
+ </div>
21
+ )}
22
+ </Flexbox>
23
+ );
24
+ });
@@ -0,0 +1,9 @@
1
+ import { ChatListProps } from '@lobehub/ui';
2
+
3
+ import { AssistantMessageExtra } from './Assistant';
4
+ import { UserMessageExtra } from './User';
5
+
6
+ export const renderMessagesExtra: ChatListProps['renderMessagesExtra'] = {
7
+ assistant: AssistantMessageExtra,
8
+ user: UserMessageExtra,
9
+ };
@@ -0,0 +1,53 @@
1
+ import { useTheme } from 'antd-style';
2
+
3
+ const Svg = () => (
4
+ <svg viewBox="0 0 32 24" xmlns="http://www.w3.org/2000/svg">
5
+ <circle cx="0" cy="12" r="0" transform="translate(8 0)">
6
+ <animate
7
+ attributeName="r"
8
+ begin="0"
9
+ calcMode="spline"
10
+ dur="1.2s"
11
+ keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8"
12
+ keyTimes="0;0.2;0.7;1"
13
+ repeatCount="indefinite"
14
+ values="0; 4; 0; 0"
15
+ />
16
+ </circle>
17
+ <circle cx="0" cy="12" r="0" transform="translate(16 0)">
18
+ <animate
19
+ attributeName="r"
20
+ begin="0.3"
21
+ calcMode="spline"
22
+ dur="1.2s"
23
+ keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8"
24
+ keyTimes="0;0.2;0.7;1"
25
+ repeatCount="indefinite"
26
+ values="0; 4; 0; 0"
27
+ />
28
+ </circle>
29
+ <circle cx="0" cy="12" r="0" transform="translate(24 0)">
30
+ <animate
31
+ attributeName="r"
32
+ begin="0.6"
33
+ calcMode="spline"
34
+ dur="1.2s"
35
+ keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8;0.2 0.6 0.4 0.8"
36
+ keyTimes="0;0.2;0.7;1"
37
+ repeatCount="indefinite"
38
+ values="0; 4; 0; 0"
39
+ />
40
+ </circle>
41
+ </svg>
42
+ );
43
+
44
+ const BubblesLoading = () => {
45
+ const { colorTextTertiary } = useTheme();
46
+ return (
47
+ <div style={{ fill: colorTextTertiary, height: 24, width: 32 }}>
48
+ <Svg />
49
+ </div>
50
+ );
51
+ };
52
+
53
+ export default BubblesLoading;
@@ -1,41 +1,18 @@
1
- import { SiOpenai } from '@icons-pack/react-simple-icons';
2
- import {
3
- ActionIconGroup,
4
- RenderAction,
5
- RenderMessage,
6
- RenderMessageExtra,
7
- Tag,
8
- useChatListActionsBar,
9
- } from '@lobehub/ui';
10
- import { createStyles } from 'antd-style';
1
+ import { RenderMessage } from '@lobehub/ui';
11
2
  import { memo } from 'react';
12
- import { Flexbox } from 'react-layout-kit';
13
3
 
14
4
  import { useSessionStore } from '@/store/session';
15
- import { agentSelectors } from '@/store/session/slices/agentConfig';
16
- import { chatSelectors } from '@/store/session/slices/chat/selectors';
5
+ import { chatSelectors } from '@/store/session/selectors';
17
6
  import { isFunctionMessage } from '@/utils/message';
18
7
 
19
8
  import FunctionCall from '../Plugins/FunctionCall';
20
- import { DefautMessage } from './Default';
21
-
22
- const useStyles = createStyles(({ css }) => ({
23
- container: css`
24
- margin-top: 8px;
25
- `,
26
- plugin: css`
27
- display: flex;
28
- gap: 4px;
29
- align-items: center;
30
- width: fit-content;
31
- `,
32
- }));
9
+ import { DefaultMessage } from './Default';
33
10
 
34
11
  export const AssistantMessage: RenderMessage = memo(
35
12
  ({ id, plugin, function_call, content, ...props }) => {
36
- const genFunctionCallProps = useSessionStore(chatSelectors.currentFunctionCallProps);
13
+ const genFunctionCallProps = useSessionStore(chatSelectors.getFunctionMessageParams);
37
14
 
38
- if (!isFunctionMessage(content)) return <DefautMessage content={content} id={id} {...props} />;
15
+ if (!isFunctionMessage(content)) return <DefaultMessage content={content} id={id} {...props} />;
39
16
 
40
17
  const fcProps = genFunctionCallProps({ content, function_call, id, plugin });
41
18
 
@@ -46,33 +23,3 @@ export const AssistantMessage: RenderMessage = memo(
46
23
  );
47
24
  },
48
25
  );
49
-
50
- export const AssistantMessageExtra: RenderMessageExtra = memo(({ extra, function_call }) => {
51
- const { styles } = useStyles();
52
- const model = useSessionStore(agentSelectors.currentAgentModel);
53
-
54
- const hasModelTag = extra?.fromModel && model !== extra?.fromModel;
55
- const hasFuncTag = !!function_call;
56
- if (!(hasModelTag || hasFuncTag)) return;
57
-
58
- return (
59
- <Flexbox className={styles.container} horizontal>
60
- <div>
61
- <Tag icon={<SiOpenai size={'1em'} />}>{extra?.fromModel as string}</Tag>
62
- </div>
63
- </Flexbox>
64
- );
65
- });
66
-
67
- export const AssistantActionsBar: RenderAction = memo(({ text, error, id, onActionClick }) => {
68
- const { regenerate, edit, copy, divider, del } = useChatListActionsBar(text);
69
- if (id === 'default') return;
70
- return (
71
- <ActionIconGroup
72
- dropdownMenu={error ? [regenerate, divider, del] : [edit, copy, regenerate, divider, del]}
73
- items={[regenerate]}
74
- onActionClick={onActionClick}
75
- type="ghost"
76
- />
77
- );
78
- });
@@ -1,6 +1,12 @@
1
1
  import { RenderMessage } from '@lobehub/ui';
2
2
  import { memo } from 'react';
3
3
 
4
- export const DefautMessage: RenderMessage = memo(({ id, editableContent }) => {
4
+ import { LOADING_FLAT } from '@/const/message';
5
+
6
+ import BubblesLoading from '../Loading';
7
+
8
+ export const DefaultMessage: RenderMessage = memo(({ id, editableContent, content }) => {
9
+ if (content === LOADING_FLAT) return <BubblesLoading />;
10
+
5
11
  return <div id={id}>{editableContent}</div>;
6
12
  });
@@ -1,4 +1,4 @@
1
- import { ActionIconGroup, RenderAction, RenderMessage, useChatListActionsBar } from '@lobehub/ui';
1
+ import { RenderMessage } from '@lobehub/ui';
2
2
  import { memo } from 'react';
3
3
  import { Flexbox } from 'react-layout-kit';
4
4
 
@@ -9,34 +9,15 @@ import FunctionCall from '../Plugins/FunctionCall';
9
9
  import PluginMessage from '../Plugins/PluginMessage';
10
10
 
11
11
  export const FunctionMessage: RenderMessage = memo(
12
- ({ id, content, plugin, function_call, ...props }) => {
13
- const genFunctionCallProps = useSessionStore(chatSelectors.currentFunctionCallProps);
12
+ ({ id, content, plugin, function_call, name }) => {
13
+ const genFunctionCallProps = useSessionStore(chatSelectors.getFunctionMessageParams);
14
14
  const fcProps = genFunctionCallProps({ content, function_call, id, plugin });
15
15
 
16
16
  return (
17
17
  <Flexbox gap={12} id={id}>
18
18
  <FunctionCall {...fcProps} />
19
- <PluginMessage
20
- content={content}
21
- function_call={function_call}
22
- id={id}
23
- loading={fcProps.loading}
24
- plugin={plugin}
25
- {...props}
26
- />
19
+ <PluginMessage content={content} loading={fcProps.loading} name={name} />
27
20
  </Flexbox>
28
21
  );
29
22
  },
30
23
  );
31
-
32
- export const FunctionActionsBar: RenderAction = memo(({ text, onActionClick }) => {
33
- const { regenerate, divider, del } = useChatListActionsBar(text);
34
- return (
35
- <ActionIconGroup
36
- dropdownMenu={[regenerate, divider, del]}
37
- items={[regenerate]}
38
- onActionClick={onActionClick}
39
- type="ghost"
40
- />
41
- );
42
- });
@@ -1,24 +1,11 @@
1
1
  import { ChatListProps } from '@lobehub/ui';
2
2
 
3
- import { AssistantActionsBar, AssistantMessage, AssistantMessageExtra } from './Assistant';
4
- import { DefautMessage } from './Default';
5
- import { FunctionActionsBar, FunctionMessage } from './Function';
6
- import { SystemActionsBar } from './System';
7
- import { UserActionsBar } from './User';
3
+ import { AssistantMessage } from './Assistant';
4
+ import { DefaultMessage } from './Default';
5
+ import { FunctionMessage } from './Function';
8
6
 
9
7
  export const renderMessages: ChatListProps['renderMessages'] = {
10
8
  assistant: AssistantMessage,
11
- default: DefautMessage,
9
+ default: DefaultMessage,
12
10
  function: FunctionMessage,
13
11
  };
14
-
15
- export const renderMessagesExtra: ChatListProps['renderMessagesExtra'] = {
16
- assistant: AssistantMessageExtra,
17
- };
18
-
19
- export const renderActions: ChatListProps['renderActions'] = {
20
- assistant: AssistantActionsBar,
21
- function: FunctionActionsBar,
22
- system: SystemActionsBar,
23
- user: UserActionsBar,
24
- };
@@ -30,8 +30,6 @@ const FunctionCall = memo<FunctionCallProps>(
30
30
  const pluginAvatar = pluginHelpers.getPluginAvatar(item?.meta);
31
31
  const pluginTitle = pluginHelpers.getPluginTitle(item?.meta);
32
32
 
33
- console.log(item?.meta);
34
-
35
33
  const avatar = pluginAvatar ? (
36
34
  <Avatar avatar={pluginAvatar} size={32} />
37
35
  ) : (
@@ -6,14 +6,15 @@ import { useTranslation } from 'react-i18next';
6
6
  import { Flexbox } from 'react-layout-kit';
7
7
 
8
8
  import { usePluginStore } from '@/store/plugin';
9
- import { ChatMessage } from '@/types/chatMessage';
10
9
 
11
10
  import IFrameRender from './IFrameRender';
12
11
 
13
12
  const SystemJsRender = dynamic(() => import('./SystemJsRender'), { ssr: false });
14
13
 
15
- export interface FunctionMessageProps extends ChatMessage {
14
+ export interface FunctionMessageProps {
15
+ content: string;
16
16
  loading?: boolean;
17
+ name?: string;
17
18
  }
18
19
 
19
20
  const PluginMessage = memo<FunctionMessageProps>(({ content, name }) => {
@@ -29,8 +30,6 @@ const PluginMessage = memo<FunctionMessageProps>(({ content, name }) => {
29
30
 
30
31
  const contentObj = useMemo(() => (isJSON ? JSON.parse(content) : content), [content]);
31
32
 
32
- // if (!loading)
33
-
34
33
  if (!isJSON) {
35
34
  return (
36
35
  <Flexbox gap={8} horizontal>
@@ -5,11 +5,14 @@ import { useHotkeys } from 'react-hotkeys-hook';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { PREFIX_KEY, REGENERATE_KEY } from '@/const/hotkeys';
8
+ import { settingsSelectors, useGlobalStore } from '@/store/global';
8
9
  import { useSessionChatInit, useSessionStore } from '@/store/session';
9
10
  import { agentSelectors, chatSelectors } from '@/store/session/selectors';
10
11
 
12
+ import { renderActions } from './Actions';
11
13
  import { renderErrorMessages } from './Error';
12
- import { renderActions, renderMessages, renderMessagesExtra } from './Messages';
14
+ import { renderMessagesExtra } from './Extras';
15
+ import { renderMessages } from './Messages';
13
16
  import SkeletonList from './SkeletonList';
14
17
 
15
18
  const List = memo(() => {
@@ -25,6 +28,7 @@ const List = memo(() => {
25
28
  deleteMessage,
26
29
  resendMessage,
27
30
  dispatchMessage,
31
+ translateMessage,
28
32
  ] = useSessionStore((s) => {
29
33
  const config = agentSelectors.currentAgentConfig(s);
30
34
  return [
@@ -35,9 +39,12 @@ const List = memo(() => {
35
39
  s.deleteMessage,
36
40
  s.resendMessage,
37
41
  s.dispatchMessage,
42
+ s.translateMessage,
38
43
  ];
39
44
  });
40
45
 
46
+ const targetLang = useGlobalStore(settingsSelectors.currentLanguage);
47
+
41
48
  const hotkeys = [PREFIX_KEY, REGENERATE_KEY].join('+');
42
49
 
43
50
  useHotkeys(
@@ -63,7 +70,15 @@ const List = memo(() => {
63
70
  loadingId={chatLoadingId}
64
71
  onActionsClick={{
65
72
  del: ({ id }) => deleteMessage(id),
66
- regenerate: ({ id }) => resendMessage(id),
73
+ regenerate: ({ id, error }) => {
74
+ resendMessage(id);
75
+
76
+ // if this message is an error message, we need to delete it
77
+ if (error) deleteMessage(id);
78
+ },
79
+ translate: ({ id }) => {
80
+ translateMessage(id, targetLang);
81
+ },
67
82
  }}
68
83
  onMessageChange={(id, content) =>
69
84
  dispatchMessage({ id, key: 'content', type: 'updateMessage', value: content })
@@ -28,7 +28,7 @@ interface ConversationProps {
28
28
 
29
29
  const Conversation = memo<ConversationProps>(({ mobile, chatInput }) => {
30
30
  const ref = useRef(null);
31
- const { t } = useTranslation('common');
31
+ const { t } = useTranslation('chat');
32
32
  const { styles } = useStyles();
33
33
 
34
34
  const useFetchPluginList = usePluginStore((s) => s.useFetchPluginList);
@@ -15,7 +15,7 @@ const { Item } = List;
15
15
  const Inbox = memo(() => {
16
16
  const ref = useRef(null);
17
17
  const isHovering = useHover(ref);
18
- const { t } = useTranslation('common');
18
+ const { t } = useTranslation('chat');
19
19
  const { mobile } = useResponsive();
20
20
  const [activeId, activeSession, switchSession] = useSessionStore((s) => [
21
21
  s.activeId,
@@ -8,7 +8,7 @@ import { Flexbox } from 'react-layout-kit';
8
8
  import { useSessionStore } from '@/store/session';
9
9
 
10
10
  const AddButton = memo<ButtonProps>((props) => {
11
- const { t } = useTranslation('common');
11
+ const { t } = useTranslation('chat');
12
12
  const createSession = useSessionStore((s) => s.createSession);
13
13
  return (
14
14
  <Flexbox style={{ margin: '12px 16px' }}>
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
  import { useSessionStore } from '@/store/session';
7
7
 
8
8
  const SessionSearchBar = memo(() => {
9
- const { t } = useTranslation('common');
9
+ const { t } = useTranslation('chat');
10
10
  const [keywords] = useSessionStore((s) => [s.searchKeywords]);
11
11
  const { mobile } = useResponsive();
12
12
  return (
@@ -19,7 +19,7 @@ const DefaultContent = memo(() => {
19
19
  <Icon color={theme.colorTextDescription} icon={MessageSquareDashed} />
20
20
  </Flexbox>
21
21
  <Paragraph ellipsis={{ rows: 1 }} style={{ margin: 0 }}>
22
- {t('topic.defaultTitle')}
22
+ {t('topic.defaultTitle', { ns: 'chat' })}
23
23
  </Paragraph>
24
24
  <Tag>{t('temp')}</Tag>
25
25
  </Flexbox>
@@ -74,7 +74,7 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav }) => {
74
74
  onOk: () => {
75
75
  removeTopic(id);
76
76
  },
77
- title: t('topic.confirmRemoveTopic'),
77
+ title: t('topic.confirmRemoveTopic', { ns: 'chat' }),
78
78
  });
79
79
  },
80
80
  },
@@ -54,7 +54,7 @@ export const Topic = () => {
54
54
  <TopicItem
55
55
  active={!activeTopicId}
56
56
  fav={false}
57
- title={t('topic.defaultTitle', { ns: 'common' })}
57
+ title={t('topic.defaultTitle', { ns: 'chat' })}
58
58
  />
59
59
 
60
60
  {topicsData.map(({ id, favorite, title }) => (
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
  import { useSessionStore } from '@/store/session';
7
7
 
8
8
  const TopicSearchBar = memo(() => {
9
- const { t } = useTranslation('common');
9
+ const { t } = useTranslation('chat');
10
10
  const [keywords] = useSessionStore((s) => [s.topicSearchKeywords]);
11
11
  const { mobile } = useResponsive();
12
12
  return (
@@ -5,9 +5,9 @@ import { useTranslation } from 'react-i18next';
5
5
  import FullscreenLoading from '@/components/FullscreenLoading';
6
6
 
7
7
  const Loading = () => {
8
- const { t } = useTranslation();
8
+ const { t } = useTranslation('common');
9
9
 
10
- return <FullscreenLoading title={t('appInitializing', { ns: 'common' })} />;
10
+ return <FullscreenLoading title={t('appInitializing')} />;
11
11
  };
12
12
 
13
13
  export default Loading;