@lobehub/chat 0.118.9 → 0.119.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 +69 -0
- package/locales/de-DE/chat.json +10 -0
- package/locales/de-DE/common.json +1 -0
- package/locales/de-DE/error.json +19 -0
- package/locales/en-US/chat.json +10 -0
- package/locales/en-US/common.json +1 -0
- package/locales/en-US/error.json +19 -0
- package/locales/es-ES/chat.json +10 -0
- package/locales/es-ES/common.json +1 -0
- package/locales/es-ES/error.json +20 -1
- package/locales/fr-FR/chat.json +10 -0
- package/locales/fr-FR/common.json +1 -0
- package/locales/fr-FR/error.json +19 -0
- package/locales/it-IT/chat.json +10 -0
- package/locales/it-IT/common.json +1 -0
- package/locales/it-IT/error.json +19 -0
- package/locales/ja-JP/chat.json +10 -0
- package/locales/ja-JP/common.json +1 -0
- package/locales/ja-JP/error.json +20 -1
- package/locales/ko-KR/chat.json +10 -0
- package/locales/ko-KR/common.json +1 -0
- package/locales/ko-KR/error.json +20 -1
- package/locales/nl-NL/chat.json +10 -0
- package/locales/nl-NL/common.json +1 -0
- package/locales/nl-NL/error.json +20 -1
- package/locales/pl-PL/chat.json +10 -0
- package/locales/pl-PL/common.json +1 -0
- package/locales/pl-PL/error.json +20 -1
- package/locales/pt-BR/chat.json +10 -0
- package/locales/pt-BR/common.json +1 -0
- package/locales/pt-BR/error.json +20 -1
- package/locales/ru-RU/chat.json +10 -0
- package/locales/ru-RU/common.json +1 -0
- package/locales/ru-RU/error.json +19 -0
- package/locales/tr-TR/chat.json +10 -0
- package/locales/tr-TR/common.json +1 -0
- package/locales/tr-TR/error.json +20 -1
- package/locales/vi-VN/chat.json +10 -0
- package/locales/vi-VN/common.json +1 -0
- package/locales/vi-VN/error.json +19 -0
- package/locales/zh-CN/chat.json +10 -0
- package/locales/zh-CN/common.json +1 -0
- package/locales/zh-CN/error.json +19 -0
- package/locales/zh-TW/chat.json +10 -0
- package/locales/zh-TW/common.json +1 -0
- package/locales/zh-TW/error.json +20 -1
- package/package.json +3 -3
- package/scripts/readmeWorkflow/syncPluginIndex.ts +9 -7
- package/src/app/chat/(desktop)/features/Conversation.tsx +17 -0
- package/src/app/chat/(desktop)/features/HotKeys.tsx +44 -0
- package/src/app/chat/(desktop)/index.tsx +2 -3
- package/src/app/chat/features/ChatHeader/ShareButton/Preview.tsx +1 -1
- package/src/app/chat/features/ChatHeader/ShareButton/ShareModal.tsx +40 -41
- package/src/app/chat/features/SessionListContent/List/Item/Actions.tsx +24 -3
- package/src/app/chat/features/TopicListContent/Topic/TopicContent.tsx +43 -2
- package/src/database/models/__tests__/message.test.ts +48 -0
- package/src/database/models/__tests__/topic.test.ts +135 -0
- package/src/database/models/message.ts +35 -0
- package/src/database/models/session.ts +11 -1
- package/src/database/models/topic.ts +34 -2
- package/src/features/ChatInput/ActionBar/Clear.tsx +0 -6
- package/src/features/Conversation/Actions/Assistant.tsx +16 -5
- package/src/features/Conversation/Actions/Error.tsx +2 -2
- package/src/features/Conversation/Actions/Fallback.tsx +4 -3
- package/src/features/Conversation/Actions/Function.tsx +3 -3
- package/src/features/Conversation/Actions/User.tsx +3 -3
- package/src/features/Conversation/Actions/customAction.ts +2 -4
- package/src/features/Conversation/Actions/index.ts +50 -45
- package/src/features/Conversation/Error/InvalidAccess.tsx +1 -1
- package/src/features/Conversation/Error/OpenAPIKey.tsx +1 -1
- package/src/features/Conversation/Error/OpenAiBizError.tsx +1 -1
- package/src/features/Conversation/Error/Plugin/PluginError.tsx +1 -1
- package/src/features/Conversation/Error/Plugin/PluginSettings.tsx +1 -1
- package/src/features/Conversation/Error/index.tsx +2 -2
- package/src/features/Conversation/Extras/Assistant.tsx +32 -29
- package/src/features/Conversation/Extras/User.tsx +2 -1
- package/src/features/Conversation/Extras/index.ts +4 -4
- package/src/features/Conversation/Messages/index.ts +3 -3
- package/src/features/Conversation/components/ChatItem/ActionsBar.tsx +58 -0
- package/src/features/Conversation/components/ChatItem/index.tsx +126 -0
- package/src/features/Conversation/components/ChatList/HistoryDivider.tsx +6 -3
- package/src/features/Conversation/components/ChatList/index.tsx +35 -79
- package/src/features/Conversation/hooks/useChatListActionsBar.tsx +43 -31
- package/src/features/Conversation/hooks/useInitConversation.ts +4 -1
- package/src/features/Conversation/index.tsx +4 -3
- package/src/features/Conversation/types/index.tsx +35 -0
- package/src/features/PluginStore/PluginItem/EditCustomPlugin.tsx +7 -2
- package/src/locales/create.ts +1 -1
- package/src/locales/default/chat.ts +10 -1
- package/src/locales/default/common.ts +1 -0
- package/src/locales/default/error.ts +19 -0
- package/src/services/config.ts +22 -0
- package/src/services/session.ts +6 -0
- package/src/services/topic.ts +4 -0
- package/src/store/chat/slices/message/selectors.ts +10 -0
- package/src/store/chat/slices/topic/action.ts +22 -0
- package/src/store/global/slices/common/action.ts +2 -0
- package/src/store/session/slices/session/action.test.ts +136 -0
- package/src/store/session/slices/session/action.ts +26 -6
- package/src/types/topic.ts +1 -0
- package/src/features/Conversation/components/ChatList/ActionsBar.tsx +0 -27
- package/src/features/Conversation/components/ChatList/Item.tsx +0 -236
- package/src/features/Conversation/container/index.tsx +0 -83
|
@@ -1,88 +1,44 @@
|
|
|
1
|
+
import isEqual from 'fast-deep-equal';
|
|
1
2
|
import { Fragment, memo } from 'react';
|
|
2
3
|
import { Flexbox } from 'react-layout-kit';
|
|
3
4
|
|
|
4
|
-
import
|
|
5
|
+
import { useChatStore } from '@/store/chat';
|
|
6
|
+
import { chatSelectors } from '@/store/chat/selectors';
|
|
7
|
+
import { useSessionStore } from '@/store/session';
|
|
8
|
+
import { agentSelectors } from '@/store/session/selectors';
|
|
5
9
|
|
|
10
|
+
import Item from '../ChatItem';
|
|
6
11
|
import HistoryDivider from './HistoryDivider';
|
|
7
|
-
import Item, { ListItemProps } from './Item';
|
|
8
12
|
import { useStyles } from './style';
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
text,
|
|
40
|
-
showTitle,
|
|
41
|
-
onMessageChange,
|
|
42
|
-
renderMessages,
|
|
43
|
-
renderErrorMessages,
|
|
44
|
-
loadingId,
|
|
45
|
-
renderItems,
|
|
46
|
-
enableHistoryCount,
|
|
47
|
-
renderActions,
|
|
48
|
-
historyCount = 0,
|
|
49
|
-
}) => {
|
|
50
|
-
const { cx, styles } = useStyles();
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<Flexbox className={cx(styles.container, className)}>
|
|
54
|
-
{data.map((item, index) => {
|
|
55
|
-
const itemProps = {
|
|
56
|
-
loading: loadingId === item.id,
|
|
57
|
-
onActionsClick,
|
|
58
|
-
onAvatarsClick,
|
|
59
|
-
onMessageChange,
|
|
60
|
-
renderActions,
|
|
61
|
-
renderErrorMessages,
|
|
62
|
-
renderItems,
|
|
63
|
-
renderMessages,
|
|
64
|
-
renderMessagesExtra,
|
|
65
|
-
showTitle,
|
|
66
|
-
text,
|
|
67
|
-
type,
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const historyLength = data.length;
|
|
71
|
-
const enableHistoryDivider =
|
|
72
|
-
enableHistoryCount &&
|
|
73
|
-
historyLength > historyCount &&
|
|
74
|
-
historyCount === historyLength - index + 1;
|
|
75
|
-
|
|
76
|
-
return (
|
|
77
|
-
<Fragment key={item.id}>
|
|
78
|
-
<HistoryDivider enable={enableHistoryDivider} text={text?.history} />
|
|
79
|
-
<Item {...itemProps} {...item} />
|
|
80
|
-
</Fragment>
|
|
81
|
-
);
|
|
82
|
-
})}
|
|
83
|
-
</Flexbox>
|
|
84
|
-
);
|
|
85
|
-
},
|
|
86
|
-
);
|
|
14
|
+
const ChatList = memo(() => {
|
|
15
|
+
const { styles } = useStyles();
|
|
16
|
+
|
|
17
|
+
const data = useChatStore(chatSelectors.currentChatIDsWithGuideMessage, isEqual);
|
|
18
|
+
|
|
19
|
+
const [enableHistoryCount, historyCount = 0] = useSessionStore((s) => {
|
|
20
|
+
const config = agentSelectors.currentAgentConfig(s);
|
|
21
|
+
return [config.enableHistoryCount, config.historyCount];
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Flexbox className={styles.container}>
|
|
26
|
+
{data.map((item, index) => {
|
|
27
|
+
const historyLength = data.length;
|
|
28
|
+
const enableHistoryDivider =
|
|
29
|
+
enableHistoryCount &&
|
|
30
|
+
historyLength > historyCount &&
|
|
31
|
+
historyCount === historyLength - index + 1;
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Fragment key={item}>
|
|
35
|
+
<HistoryDivider enable={enableHistoryDivider} />
|
|
36
|
+
<Item index={index} />
|
|
37
|
+
</Fragment>
|
|
38
|
+
);
|
|
39
|
+
})}
|
|
40
|
+
</Flexbox>
|
|
41
|
+
);
|
|
42
|
+
});
|
|
87
43
|
|
|
88
44
|
export default ChatList;
|
|
@@ -1,43 +1,55 @@
|
|
|
1
1
|
import { ActionIconGroupItems } from '@lobehub/ui/es/ActionIconGroup';
|
|
2
2
|
import { Copy, Edit, RotateCw, Trash } from 'lucide-react';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
3
5
|
|
|
4
6
|
interface ChatListActionsBar {
|
|
5
7
|
copy: ActionIconGroupItems;
|
|
6
8
|
del: ActionIconGroupItems;
|
|
9
|
+
delAndRegenerate: ActionIconGroupItems;
|
|
7
10
|
divider: { type: 'divider' };
|
|
8
11
|
edit: ActionIconGroupItems;
|
|
9
12
|
regenerate: ActionIconGroupItems;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
|
-
export const useChatListActionsBar = (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
15
|
+
export const useChatListActionsBar = (): ChatListActionsBar => {
|
|
16
|
+
const { t } = useTranslation('common');
|
|
17
|
+
|
|
18
|
+
return useMemo(
|
|
19
|
+
() => ({
|
|
20
|
+
copy: {
|
|
21
|
+
icon: Copy,
|
|
22
|
+
key: 'copy',
|
|
23
|
+
label: t('copy', { defaultValue: 'Copy' }),
|
|
24
|
+
},
|
|
25
|
+
del: {
|
|
26
|
+
danger: true,
|
|
27
|
+
icon: Trash,
|
|
28
|
+
key: 'del',
|
|
29
|
+
label: t('delete', { defaultValue: 'Delete' }),
|
|
30
|
+
},
|
|
31
|
+
delAndRegenerate: {
|
|
32
|
+
icon: RotateCw,
|
|
33
|
+
key: 'delAndRegenerate',
|
|
34
|
+
label: t('messageAction.delAndRegenerate', {
|
|
35
|
+
defaultValue: 'Delete and regenerate',
|
|
36
|
+
ns: 'chat',
|
|
37
|
+
}),
|
|
38
|
+
},
|
|
39
|
+
divider: {
|
|
40
|
+
type: 'divider',
|
|
41
|
+
},
|
|
42
|
+
edit: {
|
|
43
|
+
icon: Edit,
|
|
44
|
+
key: 'edit',
|
|
45
|
+
label: t('edit', { defaultValue: 'Edit' }),
|
|
46
|
+
},
|
|
47
|
+
regenerate: {
|
|
48
|
+
icon: RotateCw,
|
|
49
|
+
key: 'regenerate',
|
|
50
|
+
label: t('regenerate', { defaultValue: 'Regenerate' }),
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
[],
|
|
54
|
+
);
|
|
43
55
|
};
|
|
@@ -8,7 +8,8 @@ import { useToolStore } from '@/store/tool';
|
|
|
8
8
|
export const useInitConversation = () => {
|
|
9
9
|
const [sessionId] = useSessionStore((s) => [s.activeId]);
|
|
10
10
|
const plugins = useSessionStore((s) => agentSelectors.currentAgentPlugins(s));
|
|
11
|
-
const [activeTopicId, switchTopic, useFetchMessages, useFetchTopics] = useChatStore((s) => [
|
|
11
|
+
const [init, activeTopicId, switchTopic, useFetchMessages, useFetchTopics] = useChatStore((s) => [
|
|
12
|
+
s.messagesInit,
|
|
12
13
|
s.activeTopicId,
|
|
13
14
|
s.switchTopic,
|
|
14
15
|
s.useFetchMessages,
|
|
@@ -40,4 +41,6 @@ export const useInitConversation = () => {
|
|
|
40
41
|
unsubscribe();
|
|
41
42
|
};
|
|
42
43
|
}, []);
|
|
44
|
+
|
|
45
|
+
return init;
|
|
43
46
|
};
|
|
@@ -8,8 +8,9 @@ import SafeSpacing from '@/components/SafeSpacing';
|
|
|
8
8
|
import { useGlobalStore } from '@/store/global';
|
|
9
9
|
import { settingsSelectors } from '@/store/global/selectors';
|
|
10
10
|
|
|
11
|
+
import ChatList from './components/ChatList';
|
|
11
12
|
import ChatScrollAnchor from './components/ScrollAnchor';
|
|
12
|
-
import
|
|
13
|
+
import SkeletonList from './components/SkeletonList';
|
|
13
14
|
import { useInitConversation } from './hooks/useInitConversation';
|
|
14
15
|
|
|
15
16
|
const useStyles = createStyles(({ css, responsive, stylish, cx }, fontSize: number = 14) =>
|
|
@@ -52,14 +53,14 @@ const Conversation = memo<ConversationProps>(({ mobile, chatInput }) => {
|
|
|
52
53
|
const { styles } = useStyles(fontSize);
|
|
53
54
|
|
|
54
55
|
// init conversation
|
|
55
|
-
useInitConversation();
|
|
56
|
+
const init = useInitConversation();
|
|
56
57
|
|
|
57
58
|
return (
|
|
58
59
|
<Flexbox flex={1} style={{ position: 'relative' }}>
|
|
59
60
|
<div style={{ flex: 1, overflow: 'hidden', position: 'relative' }}>
|
|
60
61
|
<div className={styles} ref={ref}>
|
|
61
62
|
{!mobile && <SafeSpacing />}
|
|
62
|
-
<ChatList />
|
|
63
|
+
{init ? <ChatList /> : <SkeletonList />}
|
|
63
64
|
<ChatScrollAnchor />
|
|
64
65
|
</div>
|
|
65
66
|
<BackBottom target={ref} text={t('backToBottom')} />
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type AlertProps, type ChatItemProps } from '@lobehub/ui';
|
|
2
|
+
import { ActionEvent } from '@lobehub/ui';
|
|
3
|
+
import { FC, ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
import { LLMRoleType } from '@/types/llm';
|
|
6
|
+
import { ChatMessage } from '@/types/message';
|
|
7
|
+
|
|
8
|
+
import { type ActionsBarProps } from '../components/ChatItem/ActionsBar';
|
|
9
|
+
|
|
10
|
+
export type OnActionsClick = (action: ActionEvent, message: ChatMessage) => void;
|
|
11
|
+
export type OnAvatarsClick = (role: RenderRole) => ChatItemProps['onAvatarClick'];
|
|
12
|
+
export type RenderRole = LLMRoleType | 'default' | string;
|
|
13
|
+
export type RenderMessage = FC<ChatMessage & { editableContent: ReactNode }>;
|
|
14
|
+
export type RenderMessageExtra = FC<ChatMessage>;
|
|
15
|
+
export interface RenderErrorMessage {
|
|
16
|
+
Render?: FC<ChatMessage>;
|
|
17
|
+
config?: AlertProps;
|
|
18
|
+
}
|
|
19
|
+
export type RenderAction = FC<ActionsBarProps & ChatMessage>;
|
|
20
|
+
|
|
21
|
+
export type RenderItem = FC<{ key: string } & ChatMessage & ListItemProps>;
|
|
22
|
+
|
|
23
|
+
export interface ListItemProps {
|
|
24
|
+
groupNav?: ChatItemProps['avatarAddon'];
|
|
25
|
+
|
|
26
|
+
renderItems?: {
|
|
27
|
+
[role: RenderRole]: RenderItem;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @description 是否显示聊天项的名称
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
showTitle?: boolean;
|
|
35
|
+
}
|
|
@@ -12,9 +12,10 @@ const EditCustomPlugin = memo<{ identifier: string }>(({ identifier }) => {
|
|
|
12
12
|
const { t } = useTranslation('plugin');
|
|
13
13
|
const [showModal, setModal] = useState(false);
|
|
14
14
|
|
|
15
|
-
const [installCustomPlugin, updateNewDevPlugin] = useToolStore((s) => [
|
|
15
|
+
const [installCustomPlugin, updateNewDevPlugin, uninstallCustomPlugin] = useToolStore((s) => [
|
|
16
16
|
s.installCustomPlugin,
|
|
17
17
|
s.updateNewCustomPlugin,
|
|
18
|
+
s.uninstallCustomPlugin,
|
|
18
19
|
]);
|
|
19
20
|
|
|
20
21
|
const customPlugin = useToolStore(pluginSelectors.getCustomPluginById(identifier), isEqual);
|
|
@@ -27,10 +28,14 @@ const EditCustomPlugin = memo<{ identifier: string }>(({ identifier }) => {
|
|
|
27
28
|
>
|
|
28
29
|
<DevModal
|
|
29
30
|
mode={'edit'}
|
|
31
|
+
onDelete={() => {
|
|
32
|
+
uninstallCustomPlugin(identifier);
|
|
33
|
+
setModal(false);
|
|
34
|
+
}}
|
|
30
35
|
onOpenChange={setModal}
|
|
31
36
|
onSave={async (devPlugin) => {
|
|
32
37
|
await installCustomPlugin(devPlugin);
|
|
33
|
-
|
|
38
|
+
setModal(false);
|
|
34
39
|
}}
|
|
35
40
|
onValueChange={updateNewDevPlugin}
|
|
36
41
|
open={showModal}
|
package/src/locales/create.ts
CHANGED
|
@@ -28,7 +28,7 @@ export const createI18nNext = (lang?: string) => {
|
|
|
28
28
|
init: () =>
|
|
29
29
|
instance.init({
|
|
30
30
|
debug: debugMode,
|
|
31
|
-
defaultNS: ['error', 'common', 'empty'],
|
|
31
|
+
defaultNS: ['error', 'common', 'empty', 'chat'],
|
|
32
32
|
detection: {
|
|
33
33
|
caches: ['cookie'],
|
|
34
34
|
cookieMinutes: 60 * 24 * COOKIE_CACHE_DAYS,
|
|
@@ -8,6 +8,7 @@ export default {
|
|
|
8
8
|
confirmRemoveSessionItemAlert: '即将删除该助手,删除后该将无法找回,请确认你的操作',
|
|
9
9
|
defaultAgent: '自定义助手',
|
|
10
10
|
defaultSession: '自定义助手',
|
|
11
|
+
duplicateTitle: '{{title}} 副本',
|
|
11
12
|
historyRange: '历史范围',
|
|
12
13
|
inbox: {
|
|
13
14
|
defaultMessage:
|
|
@@ -15,9 +16,12 @@ export default {
|
|
|
15
16
|
desc: '开启大脑集群,激发思维火花。你的智能助理,在这里与你交流一切',
|
|
16
17
|
title: '随便聊聊',
|
|
17
18
|
},
|
|
19
|
+
messageAction: {
|
|
20
|
+
delAndRegenerate: '删除并重新生成',
|
|
21
|
+
regenerate: '重新生成',
|
|
22
|
+
},
|
|
18
23
|
newAgent: '新建助手',
|
|
19
24
|
noDescription: '暂无描述',
|
|
20
|
-
|
|
21
25
|
pin: '置顶',
|
|
22
26
|
pinOff: '取消置顶',
|
|
23
27
|
regenerate: '重新生成',
|
|
@@ -52,6 +56,11 @@ export default {
|
|
|
52
56
|
used: '使用',
|
|
53
57
|
},
|
|
54
58
|
topic: {
|
|
59
|
+
actions: {
|
|
60
|
+
autoRename: '智能重命名',
|
|
61
|
+
duplicate: '创建副本',
|
|
62
|
+
export: '导出话题',
|
|
63
|
+
},
|
|
55
64
|
confirmRemoveAll: '即将删除全部话题,删除后将不可恢复,请谨慎操作。',
|
|
56
65
|
confirmRemoveTopic: '即将删除该话题,删除后将不可恢复,请谨慎操作。',
|
|
57
66
|
confirmRemoveUnstarred: '即将删除未收藏话题,删除后将不可恢复,请谨慎操作。',
|
|
@@ -9,7 +9,26 @@ export default {
|
|
|
9
9
|
403: '很抱歉,服务器拒绝了您的请求,您没有访问此内容的权限 ',
|
|
10
10
|
404: '很抱歉,服务器找不到您请求的页面或资源,请确认您的 URL 是否正确',
|
|
11
11
|
405: '很抱歉,服务器不支持您使用的请求方法,请确认您的请求方法是否正确',
|
|
12
|
+
406: '很抱歉,服务器无法根据您请求的内容特性完成请求',
|
|
13
|
+
407: '很抱歉,您需要进行代理认证后才能继续此请求',
|
|
14
|
+
408: '很抱歉,服务器在等待请求时超时,请检查您的网络连接后再试',
|
|
15
|
+
409: '很抱歉,请求存在冲突无法处理,可能是因为资源状态与请求不兼容',
|
|
16
|
+
410: '很抱歉,您请求的资源已被永久移除,无法找到',
|
|
17
|
+
411: '很抱歉,服务器无法处理不含有效内容长度的请求',
|
|
18
|
+
412: '很抱歉,您的请求未满足服务器端的条件,无法完成请求',
|
|
19
|
+
413: '很抱歉,您的请求数据量过大,服务器无法处理',
|
|
20
|
+
414: '很抱歉,您的请求的 URI 过长,服务器无法处理',
|
|
21
|
+
415: '很抱歉,服务器无法处理请求附带的媒体格式',
|
|
22
|
+
416: '很抱歉,服务器无法满足您请求的范围',
|
|
23
|
+
417: '很抱歉,服务器无法满足您的期望值',
|
|
24
|
+
422: '很抱歉,您的请求格式正确,但是由于含有语义错误,无法响应',
|
|
25
|
+
423: '很抱歉,您请求的资源被锁定',
|
|
26
|
+
424: '很抱歉,由于之前的请求失败,导致当前请求无法完成',
|
|
27
|
+
426: '很抱歉,服务器要求您的客户端升级到更高的协议版本',
|
|
28
|
+
428: '很抱歉,服务器要求先决条件,要求您的请求包含正确的条件头',
|
|
12
29
|
429: '很抱歉,您的请求太多,服务器有点累了,请稍后再试',
|
|
30
|
+
431: '很抱歉,您的请求头字段太大,服务器无法处理',
|
|
31
|
+
451: '很抱歉,由于法律原因,服务器拒绝提供此资源',
|
|
13
32
|
500: '很抱歉,服务器似乎遇到了一些困难,暂时无法完成您的请求,请稍后再试',
|
|
14
33
|
502: '很抱歉,服务器似乎迷失了方向,暂时无法提供服务,请稍后再试',
|
|
15
34
|
503: '很抱歉,服务器当前无法处理您的请求,可能是由于过载或正在进行维护,请稍后再试',
|
package/src/services/config.ts
CHANGED
|
@@ -127,6 +127,28 @@ class ConfigService {
|
|
|
127
127
|
exportConfigFile(config, `${session.meta?.title}-session`);
|
|
128
128
|
};
|
|
129
129
|
|
|
130
|
+
/**
|
|
131
|
+
* export a topic
|
|
132
|
+
*/
|
|
133
|
+
exportSingleTopic = async (sessionId: string, topicId: string) => {
|
|
134
|
+
const session = this.getSession(sessionId);
|
|
135
|
+
if (!session) return;
|
|
136
|
+
|
|
137
|
+
const messages = await messageService.getMessages(sessionId, topicId);
|
|
138
|
+
const topics = await topicService.getTopics({ sessionId });
|
|
139
|
+
|
|
140
|
+
const topic = topics.find((item) => item.id === topicId);
|
|
141
|
+
if (!topic) return;
|
|
142
|
+
|
|
143
|
+
const config = createConfigFile('singleSession', {
|
|
144
|
+
messages,
|
|
145
|
+
sessions: [session],
|
|
146
|
+
topics: [topic],
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
exportConfigFile(config, `${topic.title}-topic`);
|
|
150
|
+
};
|
|
151
|
+
|
|
130
152
|
exportSingleAgent = async (id: string) => {
|
|
131
153
|
const agent = this.getAgent(id);
|
|
132
154
|
if (!agent) return;
|
package/src/services/session.ts
CHANGED
|
@@ -58,6 +58,12 @@ class SessionService {
|
|
|
58
58
|
async searchSessions(keyword: string) {
|
|
59
59
|
return SessionModel.queryByKeyword(keyword);
|
|
60
60
|
}
|
|
61
|
+
|
|
62
|
+
async duplicateSession(id: string, newTitle: string): Promise<string | undefined> {
|
|
63
|
+
const res = await SessionModel.duplicate(id, newTitle);
|
|
64
|
+
|
|
65
|
+
if (res) return res?.id;
|
|
66
|
+
}
|
|
61
67
|
}
|
|
62
68
|
|
|
63
69
|
export const sessionService = new SessionService();
|
package/src/services/topic.ts
CHANGED
|
@@ -51,6 +51,10 @@ class TopicService {
|
|
|
51
51
|
async searchTopics(keyword: string) {
|
|
52
52
|
return TopicModel.queryByKeyword(keyword);
|
|
53
53
|
}
|
|
54
|
+
|
|
55
|
+
async duplicateTopic(id: string, newTitle?: string) {
|
|
56
|
+
return TopicModel.duplicateTopic(id, newTitle);
|
|
57
|
+
}
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
export const topicService = new TopicService();
|
|
@@ -84,6 +84,12 @@ const currentChatsWithGuideMessage =
|
|
|
84
84
|
return [emptyInboxGuideMessage];
|
|
85
85
|
};
|
|
86
86
|
|
|
87
|
+
const currentChatIDsWithGuideMessage = (s: ChatStore) => {
|
|
88
|
+
const meta = agentSelectors.currentAgentMeta(useSessionStore.getState());
|
|
89
|
+
|
|
90
|
+
return currentChatsWithGuideMessage(meta)(s).map((s) => s.id);
|
|
91
|
+
};
|
|
92
|
+
|
|
87
93
|
const currentChatsWithHistoryConfig = (s: ChatStore): ChatMessage[] => {
|
|
88
94
|
const chats = currentChats(s);
|
|
89
95
|
const config = agentSelectors.currentAgentConfig(useSessionStore.getState());
|
|
@@ -109,11 +115,15 @@ const getFunctionMessageProps =
|
|
|
109
115
|
|
|
110
116
|
const getMessageById = (id: string) => (s: ChatStore) => chatHelpers.getMessageById(s.messages, id);
|
|
111
117
|
|
|
118
|
+
const latestMessage = (s: ChatStore) => currentChats(s).at(-1);
|
|
119
|
+
|
|
112
120
|
export const chatSelectors = {
|
|
113
121
|
chatsMessageString,
|
|
122
|
+
currentChatIDsWithGuideMessage,
|
|
114
123
|
currentChats,
|
|
115
124
|
currentChatsWithGuideMessage,
|
|
116
125
|
currentChatsWithHistoryConfig,
|
|
117
126
|
getFunctionMessageProps,
|
|
118
127
|
getMessageById,
|
|
128
|
+
latestMessage,
|
|
119
129
|
};
|
|
@@ -30,6 +30,8 @@ export interface ChatTopicAction {
|
|
|
30
30
|
removeTopic: (id: string) => Promise<void>;
|
|
31
31
|
removeUnstarredTopic: () => void;
|
|
32
32
|
saveToTopic: () => Promise<string | undefined>;
|
|
33
|
+
autoRenameTopicTitle: (id: string) => Promise<void>;
|
|
34
|
+
duplicateTopic: (id: string) => Promise<void>;
|
|
33
35
|
summaryTopicTitle: (topicId: string, messages: ChatMessage[]) => Promise<void>;
|
|
34
36
|
switchTopic: (id?: string) => Promise<void>;
|
|
35
37
|
updateTopicTitleInSummary: (id: string, title: string) => void;
|
|
@@ -78,6 +80,19 @@ export const chatTopic: StateCreator<
|
|
|
78
80
|
|
|
79
81
|
return topicId;
|
|
80
82
|
},
|
|
83
|
+
duplicateTopic: async (id) => {
|
|
84
|
+
const { refreshTopic, switchTopic } = get();
|
|
85
|
+
|
|
86
|
+
const topic = topicSelectors.getTopicById(id)(get());
|
|
87
|
+
if (!topic) return;
|
|
88
|
+
|
|
89
|
+
const newTitle = t('duplicateTitle', { ns: 'chat', title: topic?.title });
|
|
90
|
+
|
|
91
|
+
const newTopicId = await topicService.duplicateTopic(id, newTitle);
|
|
92
|
+
await refreshTopic();
|
|
93
|
+
|
|
94
|
+
switchTopic(newTopicId);
|
|
95
|
+
},
|
|
81
96
|
// update
|
|
82
97
|
summaryTopicTitle: async (topicId, messages) => {
|
|
83
98
|
const { updateTopicTitleInSummary, updateTopicLoading, refreshTopic } = get();
|
|
@@ -115,6 +130,13 @@ export const chatTopic: StateCreator<
|
|
|
115
130
|
await topicService.updateTitle(id, title);
|
|
116
131
|
await get().refreshTopic();
|
|
117
132
|
},
|
|
133
|
+
|
|
134
|
+
autoRenameTopicTitle: async (id) => {
|
|
135
|
+
const { activeId: sessionId, summaryTopicTitle } = get();
|
|
136
|
+
const messages = await messageService.getMessages(sessionId, id);
|
|
137
|
+
|
|
138
|
+
await summaryTopicTitle(id, messages);
|
|
139
|
+
},
|
|
118
140
|
// query
|
|
119
141
|
useFetchTopics: (sessionId) =>
|
|
120
142
|
useSWR<ChatTopic[]>(sessionId, async (sessionId) => topicService.getTopics({ sessionId }), {
|
|
@@ -75,6 +75,8 @@ export const createCommonSlice: StateCreator<
|
|
|
75
75
|
},
|
|
76
76
|
useCheckLatestVersion: () =>
|
|
77
77
|
useSWR('checkLatestVersion', globalService.getLatestVersion, {
|
|
78
|
+
// check latest version every 30 minutes
|
|
79
|
+
focusThrottleInterval: 1000 * 60 * 30,
|
|
78
80
|
onSuccess: (data: string) => {
|
|
79
81
|
if (gt(data, CURRENT_VERSION))
|
|
80
82
|
set({ hasNewVersion: true, latestVersion: data }, false, n('checkLatestVersion'));
|