@lobehub/chat 0.118.10 → 0.119.1
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 +61 -0
- package/README.md +8 -8
- package/README.zh-CN.md +8 -8
- package/docs/Home.md +1 -1
- package/docs/_Sidebar.md +1 -1
- package/locales/de-DE/chat.json +10 -0
- package/locales/de-DE/common.json +1 -0
- package/locales/de-DE/error.json +4 -4
- package/locales/en-US/chat.json +10 -0
- package/locales/en-US/common.json +1 -0
- package/locales/en-US/error.json +1 -1
- package/locales/es-ES/chat.json +10 -0
- package/locales/es-ES/common.json +1 -0
- package/locales/fr-FR/chat.json +10 -0
- package/locales/fr-FR/common.json +1 -0
- package/locales/fr-FR/error.json +1 -2
- package/locales/it-IT/chat.json +10 -0
- package/locales/it-IT/common.json +1 -0
- package/locales/it-IT/error.json +5 -5
- package/locales/ja-JP/chat.json +10 -0
- package/locales/ja-JP/common.json +1 -0
- package/locales/ko-KR/chat.json +10 -0
- package/locales/ko-KR/common.json +1 -0
- package/locales/ko-KR/error.json +4 -4
- package/locales/nl-NL/chat.json +10 -0
- package/locales/nl-NL/common.json +1 -0
- package/locales/pl-PL/chat.json +10 -0
- package/locales/pl-PL/common.json +1 -0
- package/locales/pl-PL/error.json +2 -3
- package/locales/pt-BR/chat.json +10 -0
- package/locales/pt-BR/common.json +1 -0
- package/locales/ru-RU/chat.json +10 -0
- package/locales/ru-RU/common.json +1 -0
- package/locales/ru-RU/error.json +3 -3
- package/locales/tr-TR/chat.json +10 -0
- package/locales/tr-TR/common.json +1 -0
- package/locales/vi-VN/chat.json +10 -0
- package/locales/vi-VN/common.json +1 -0
- package/locales/vi-VN/error.json +1 -1
- package/locales/zh-CN/chat.json +10 -0
- package/locales/zh-CN/common.json +1 -0
- package/locales/zh-TW/chat.json +10 -0
- package/locales/zh-TW/common.json +1 -0
- package/package.json +6 -6
- 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/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/default/chat.ts +10 -1
- package/src/locales/default/common.ts +1 -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/action.ts +89 -2
- 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/utils/fetch.test.ts +131 -0
- package/src/utils/fetch.ts +26 -10
- 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
- /package/docs/Development/{Steup-Development.md → Setup-Development.md} +0 -0
- /package/docs/Development/{Steup-Development.zh-CN.md → Setup-Development.zh-CN.md} +0 -0
package/src/utils/fetch.ts
CHANGED
|
@@ -11,13 +11,13 @@ export const getMessageError = async (response: Response) => {
|
|
|
11
11
|
const data = (await response.json()) as ErrorResponse;
|
|
12
12
|
chatMessageError = {
|
|
13
13
|
body: data.body,
|
|
14
|
-
message: t(`response.${data.errorType}`),
|
|
14
|
+
message: t(`response.${data.errorType}` as any, { ns: 'error' }),
|
|
15
15
|
type: data.errorType,
|
|
16
16
|
};
|
|
17
17
|
} catch {
|
|
18
18
|
// 如果无法正常返回,说明是常规报错
|
|
19
19
|
chatMessageError = {
|
|
20
|
-
message: t(`response.${response.status}`),
|
|
20
|
+
message: t(`response.${response.status}` as any, { ns: 'error' }),
|
|
21
21
|
type: response.status as ErrorType,
|
|
22
22
|
};
|
|
23
23
|
}
|
|
@@ -25,9 +25,12 @@ export const getMessageError = async (response: Response) => {
|
|
|
25
25
|
return chatMessageError;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
type SSEFinishType = 'done' | 'error' | 'abort';
|
|
29
|
+
|
|
28
30
|
export interface FetchSSEOptions {
|
|
31
|
+
onAbort?: (text: string) => Promise<void>;
|
|
29
32
|
onErrorHandle?: (error: ChatMessageError) => void;
|
|
30
|
-
onFinish?: (text: string) => Promise<void>;
|
|
33
|
+
onFinish?: (text: string, type: SSEFinishType) => Promise<void>;
|
|
31
34
|
onMessageHandle?: (text: string) => void;
|
|
32
35
|
}
|
|
33
36
|
|
|
@@ -57,17 +60,30 @@ export const fetchSSE = async (fetchFn: () => Promise<Response>, options: FetchS
|
|
|
57
60
|
const decoder = new TextDecoder();
|
|
58
61
|
|
|
59
62
|
let done = false;
|
|
63
|
+
let finishedType: SSEFinishType = 'done';
|
|
60
64
|
|
|
61
65
|
while (!done) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
try {
|
|
67
|
+
const { value, done: doneReading } = await reader.read();
|
|
68
|
+
done = doneReading;
|
|
69
|
+
const chunkValue = decoder.decode(value, { stream: true });
|
|
70
|
+
|
|
71
|
+
output += chunkValue;
|
|
72
|
+
options.onMessageHandle?.(chunkValue);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
done = true;
|
|
75
|
+
|
|
76
|
+
if ((error as TypeError).name === 'AbortError') {
|
|
77
|
+
finishedType = 'abort';
|
|
78
|
+
options?.onAbort?.(output);
|
|
79
|
+
} else {
|
|
80
|
+
finishedType = 'error';
|
|
81
|
+
console.error(error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
68
84
|
}
|
|
69
85
|
|
|
70
|
-
await options?.onFinish?.(output);
|
|
86
|
+
await options?.onFinish?.(output, finishedType);
|
|
71
87
|
|
|
72
88
|
return returnRes;
|
|
73
89
|
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { ActionIconGroup, type ActionIconGroupProps } from '@lobehub/ui';
|
|
2
|
-
import { memo } from 'react';
|
|
3
|
-
|
|
4
|
-
import { useChatListActionsBar } from '../../hooks/useChatListActionsBar';
|
|
5
|
-
|
|
6
|
-
export interface ActionsBarProps extends ActionIconGroupProps {
|
|
7
|
-
text?: {
|
|
8
|
-
copy?: string;
|
|
9
|
-
delete?: string;
|
|
10
|
-
edit?: string;
|
|
11
|
-
regenerate?: string;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const ActionsBar = memo<ActionsBarProps>(({ text, ...rest }) => {
|
|
16
|
-
const { regenerate, edit, copy, divider, del } = useChatListActionsBar(text);
|
|
17
|
-
return (
|
|
18
|
-
<ActionIconGroup
|
|
19
|
-
dropdownMenu={[edit, copy, regenerate, divider, del]}
|
|
20
|
-
items={[regenerate, edit]}
|
|
21
|
-
type="ghost"
|
|
22
|
-
{...rest}
|
|
23
|
-
/>
|
|
24
|
-
);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
export default ActionsBar;
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import { type AlertProps, ChatItem, type ChatItemProps } from '@lobehub/ui';
|
|
2
|
-
import { ActionEvent, copyToClipboard } from '@lobehub/ui';
|
|
3
|
-
import { App } from 'antd';
|
|
4
|
-
import { FC, ReactNode, memo, useCallback, useMemo, useState } from 'react';
|
|
5
|
-
|
|
6
|
-
import { LLMRoleType } from '@/types/llm';
|
|
7
|
-
import { ChatMessage } from '@/types/message';
|
|
8
|
-
|
|
9
|
-
import ActionsBar, { type ActionsBarProps } from './ActionsBar';
|
|
10
|
-
|
|
11
|
-
export type OnMessageChange = (id: string, content: string) => void;
|
|
12
|
-
export type OnActionsClick = (action: ActionEvent, message: ChatMessage) => void;
|
|
13
|
-
export type OnAvatatsClick = (role: RenderRole) => ChatItemProps['onAvatarClick'];
|
|
14
|
-
export type RenderRole = LLMRoleType | 'default' | string;
|
|
15
|
-
export type RenderItem = FC<{ key: string } & ChatMessage & ListItemProps>;
|
|
16
|
-
export type RenderMessage = FC<ChatMessage & { editableContent: ReactNode }>;
|
|
17
|
-
export type RenderMessageExtra = FC<ChatMessage>;
|
|
18
|
-
export interface RenderErrorMessage {
|
|
19
|
-
Render?: FC<ChatMessage>;
|
|
20
|
-
config?: AlertProps;
|
|
21
|
-
}
|
|
22
|
-
export type RenderAction = FC<ActionsBarProps & ChatMessage>;
|
|
23
|
-
|
|
24
|
-
export interface ListItemProps {
|
|
25
|
-
groupNav?: ChatItemProps['avatarAddon'];
|
|
26
|
-
loading?: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* @description 点击操作按钮的回调函数
|
|
29
|
-
*/
|
|
30
|
-
onActionsClick?: OnActionsClick;
|
|
31
|
-
onAvatarsClick?: OnAvatatsClick;
|
|
32
|
-
/**
|
|
33
|
-
* @description 消息变化的回调函数
|
|
34
|
-
*/
|
|
35
|
-
onMessageChange?: OnMessageChange;
|
|
36
|
-
renderActions?: {
|
|
37
|
-
[actionKey: string]: RenderAction;
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* @description 渲染错误消息的函数
|
|
41
|
-
*/
|
|
42
|
-
renderErrorMessages?: {
|
|
43
|
-
[errorType: 'default' | string]: RenderErrorMessage;
|
|
44
|
-
};
|
|
45
|
-
renderItems?: {
|
|
46
|
-
[role: RenderRole]: RenderItem;
|
|
47
|
-
};
|
|
48
|
-
/**
|
|
49
|
-
* @description 渲染消息的函数
|
|
50
|
-
*/
|
|
51
|
-
renderMessages?: {
|
|
52
|
-
[role: RenderRole]: RenderMessage;
|
|
53
|
-
};
|
|
54
|
-
/**
|
|
55
|
-
* @description 渲染消息额外内容的函数
|
|
56
|
-
*/
|
|
57
|
-
renderMessagesExtra?: {
|
|
58
|
-
[role: RenderRole]: RenderMessageExtra;
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* @description 是否显示聊天项的名称
|
|
62
|
-
* @default false
|
|
63
|
-
*/
|
|
64
|
-
showTitle?: boolean;
|
|
65
|
-
/**
|
|
66
|
-
* @description 文本内容
|
|
67
|
-
*/
|
|
68
|
-
text?: ChatItemProps['text'] &
|
|
69
|
-
ActionsBarProps['text'] & {
|
|
70
|
-
copySuccess?: string;
|
|
71
|
-
history?: string;
|
|
72
|
-
} & {
|
|
73
|
-
[key: string]: string;
|
|
74
|
-
};
|
|
75
|
-
/**
|
|
76
|
-
* @description 聊天列表的类型
|
|
77
|
-
* @default 'chat'
|
|
78
|
-
*/
|
|
79
|
-
type?: 'docs' | 'chat';
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export type ChatListItemProps = ChatMessage & ListItemProps;
|
|
83
|
-
|
|
84
|
-
const Item = memo<ChatListItemProps>((props) => {
|
|
85
|
-
const {
|
|
86
|
-
renderMessagesExtra,
|
|
87
|
-
showTitle,
|
|
88
|
-
onActionsClick,
|
|
89
|
-
onAvatarsClick,
|
|
90
|
-
onMessageChange,
|
|
91
|
-
type,
|
|
92
|
-
text,
|
|
93
|
-
renderMessages,
|
|
94
|
-
renderErrorMessages,
|
|
95
|
-
renderActions,
|
|
96
|
-
loading,
|
|
97
|
-
groupNav,
|
|
98
|
-
renderItems,
|
|
99
|
-
...item
|
|
100
|
-
} = props;
|
|
101
|
-
|
|
102
|
-
const [editing, setEditing] = useState(false);
|
|
103
|
-
|
|
104
|
-
const { message } = App.useApp();
|
|
105
|
-
|
|
106
|
-
const RenderItem = useMemo(() => {
|
|
107
|
-
if (!renderItems || !item?.role) return;
|
|
108
|
-
let renderFunction;
|
|
109
|
-
if (renderItems?.[item.role]) renderFunction = renderItems[item.role];
|
|
110
|
-
if (!renderFunction && renderItems?.['default']) renderFunction = renderItems['default'];
|
|
111
|
-
if (!renderFunction) return;
|
|
112
|
-
return renderFunction;
|
|
113
|
-
}, [renderItems?.[item.role]]);
|
|
114
|
-
|
|
115
|
-
const RenderMessage = useCallback(
|
|
116
|
-
({ editableContent, data }: { data: ChatMessage; editableContent: ReactNode }) => {
|
|
117
|
-
if (!renderMessages || !item?.role) return;
|
|
118
|
-
let RenderFunction;
|
|
119
|
-
if (renderMessages?.[item.role]) RenderFunction = renderMessages[item.role];
|
|
120
|
-
if (!RenderFunction && renderMessages?.['default'])
|
|
121
|
-
RenderFunction = renderMessages['default'];
|
|
122
|
-
if (!RenderFunction) return;
|
|
123
|
-
return <RenderFunction {...data} editableContent={editableContent} />;
|
|
124
|
-
},
|
|
125
|
-
[renderMessages?.[item.role]],
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
const MessageExtra = useCallback(
|
|
129
|
-
({ data }: { data: ChatMessage }) => {
|
|
130
|
-
if (!renderMessagesExtra || !item?.role) return;
|
|
131
|
-
let RenderFunction;
|
|
132
|
-
if (renderMessagesExtra?.[item.role]) RenderFunction = renderMessagesExtra[item.role];
|
|
133
|
-
if (renderMessagesExtra?.['default']) RenderFunction = renderMessagesExtra['default'];
|
|
134
|
-
if (!RenderFunction) return;
|
|
135
|
-
return <RenderFunction {...data} />;
|
|
136
|
-
},
|
|
137
|
-
[renderMessagesExtra?.[item.role]],
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
const ErrorMessage = useCallback(
|
|
141
|
-
({ data }: { data: ChatMessage }) => {
|
|
142
|
-
if (!renderErrorMessages || !item?.error?.type) return;
|
|
143
|
-
let RenderFunction;
|
|
144
|
-
if (renderErrorMessages?.[item.error.type])
|
|
145
|
-
RenderFunction = renderErrorMessages[item.error.type].Render;
|
|
146
|
-
if (!RenderFunction && renderErrorMessages?.['default'])
|
|
147
|
-
RenderFunction = renderErrorMessages['default'].Render;
|
|
148
|
-
if (!RenderFunction) return;
|
|
149
|
-
return <RenderFunction {...data} />;
|
|
150
|
-
},
|
|
151
|
-
[renderErrorMessages?.[item?.error?.type]],
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
const Actions = useCallback(
|
|
155
|
-
({ data }: { data: ChatMessage }) => {
|
|
156
|
-
if (!renderActions || !item?.role) return;
|
|
157
|
-
let RenderFunction;
|
|
158
|
-
if (renderActions?.[item.role]) RenderFunction = renderActions[item.role];
|
|
159
|
-
if (renderActions?.['default']) RenderFunction = renderActions['default'];
|
|
160
|
-
if (!RenderFunction) RenderFunction = ActionsBar;
|
|
161
|
-
|
|
162
|
-
const handleActionClick: ListItemProps['onActionsClick'] = async (action, data) => {
|
|
163
|
-
switch (action.key) {
|
|
164
|
-
case 'copy': {
|
|
165
|
-
await copyToClipboard(data.content);
|
|
166
|
-
message.success(text?.copySuccess || 'Copy Success');
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
case 'edit': {
|
|
170
|
-
setEditing(true);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
onActionsClick?.(action, data);
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
return (
|
|
178
|
-
<RenderFunction
|
|
179
|
-
{...data}
|
|
180
|
-
onActionClick={(actionKey) => handleActionClick?.(actionKey, data)}
|
|
181
|
-
text={text}
|
|
182
|
-
/>
|
|
183
|
-
);
|
|
184
|
-
},
|
|
185
|
-
[renderActions?.[item.role], text, onActionsClick],
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
const error = useMemo(() => {
|
|
189
|
-
if (!item.error) return;
|
|
190
|
-
const message = item.error?.message;
|
|
191
|
-
let alertConfig = {};
|
|
192
|
-
if (item.error.type && renderErrorMessages?.[item.error.type]) {
|
|
193
|
-
alertConfig = renderErrorMessages[item.error.type]?.config as AlertProps;
|
|
194
|
-
}
|
|
195
|
-
return {
|
|
196
|
-
message,
|
|
197
|
-
...alertConfig,
|
|
198
|
-
};
|
|
199
|
-
}, [renderErrorMessages, item.error]);
|
|
200
|
-
|
|
201
|
-
if (RenderItem) return <RenderItem key={item.id} {...props} />;
|
|
202
|
-
|
|
203
|
-
return (
|
|
204
|
-
<ChatItem
|
|
205
|
-
actions={<Actions data={item} />}
|
|
206
|
-
avatar={item.meta}
|
|
207
|
-
avatarAddon={groupNav}
|
|
208
|
-
editing={editing}
|
|
209
|
-
error={error}
|
|
210
|
-
errorMessage={<ErrorMessage data={item} />}
|
|
211
|
-
loading={loading}
|
|
212
|
-
message={item.content}
|
|
213
|
-
messageExtra={<MessageExtra data={item} />}
|
|
214
|
-
onAvatarClick={onAvatarsClick?.(item.role)}
|
|
215
|
-
onChange={(value) => onMessageChange?.(item.id, value)}
|
|
216
|
-
onDoubleClick={(e) => {
|
|
217
|
-
if (item.id === 'default' || item.error) return;
|
|
218
|
-
if (item.role && ['assistant', 'user'].includes(item.role) && e.altKey) {
|
|
219
|
-
setEditing(true);
|
|
220
|
-
}
|
|
221
|
-
}}
|
|
222
|
-
onEditingChange={setEditing}
|
|
223
|
-
placement={type === 'chat' ? (item.role === 'user' ? 'right' : 'left') : 'left'}
|
|
224
|
-
primary={item.role === 'user'}
|
|
225
|
-
renderMessage={(editableContent) => (
|
|
226
|
-
<RenderMessage data={item} editableContent={editableContent} />
|
|
227
|
-
)}
|
|
228
|
-
showTitle={showTitle}
|
|
229
|
-
text={text}
|
|
230
|
-
time={item.updateAt || item.createAt}
|
|
231
|
-
type={type === 'chat' ? 'block' : 'pure'}
|
|
232
|
-
/>
|
|
233
|
-
);
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
export default Item;
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import isEqual from 'fast-deep-equal';
|
|
2
|
-
import { memo } from 'react';
|
|
3
|
-
import { useHotkeys } from 'react-hotkeys-hook';
|
|
4
|
-
import { useTranslation } from 'react-i18next';
|
|
5
|
-
|
|
6
|
-
import { PREFIX_KEY, REGENERATE_KEY } from '@/const/hotkeys';
|
|
7
|
-
import { useChatStore } from '@/store/chat';
|
|
8
|
-
import { chatSelectors } from '@/store/chat/selectors';
|
|
9
|
-
import { useSessionStore } from '@/store/session';
|
|
10
|
-
import { agentSelectors } from '@/store/session/selectors';
|
|
11
|
-
|
|
12
|
-
import { renderActions, useActionsClick } from '../Actions';
|
|
13
|
-
import { renderErrorMessages } from '../Error';
|
|
14
|
-
import { renderMessagesExtra } from '../Extras';
|
|
15
|
-
import { renderMessages, useAvatarsClick } from '../Messages';
|
|
16
|
-
import ChatList from '../components/ChatList';
|
|
17
|
-
import SkeletonList from '../components/SkeletonList';
|
|
18
|
-
|
|
19
|
-
const List = memo(() => {
|
|
20
|
-
const { t } = useTranslation('common');
|
|
21
|
-
const meta = useSessionStore(agentSelectors.currentAgentMeta, isEqual);
|
|
22
|
-
const data = useChatStore(chatSelectors.currentChatsWithGuideMessage(meta), isEqual);
|
|
23
|
-
|
|
24
|
-
const [init, chatLoadingId, resendMessage, updateMessageContent] = useChatStore((s) => [
|
|
25
|
-
s.messagesInit,
|
|
26
|
-
s.chatLoadingId,
|
|
27
|
-
s.resendMessage,
|
|
28
|
-
s.updateMessageContent,
|
|
29
|
-
]);
|
|
30
|
-
|
|
31
|
-
const [displayMode, enableHistoryCount, historyCount] = useSessionStore((s) => {
|
|
32
|
-
const config = agentSelectors.currentAgentConfig(s);
|
|
33
|
-
return [config.displayMode, config.enableHistoryCount, config.historyCount];
|
|
34
|
-
});
|
|
35
|
-
const onActionsClick = useActionsClick();
|
|
36
|
-
const onAvatarsClick = useAvatarsClick();
|
|
37
|
-
|
|
38
|
-
const hotkeys = [PREFIX_KEY, REGENERATE_KEY].join('+');
|
|
39
|
-
|
|
40
|
-
useHotkeys(
|
|
41
|
-
hotkeys,
|
|
42
|
-
() => {
|
|
43
|
-
const lastMessage = data.at(-1);
|
|
44
|
-
if (!lastMessage || lastMessage.id === 'default' || lastMessage.role === 'system') return;
|
|
45
|
-
resendMessage(lastMessage.id);
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
enableOnFormTags: true,
|
|
49
|
-
preventDefault: true,
|
|
50
|
-
},
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
if (!init) return <SkeletonList />;
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<ChatList
|
|
57
|
-
data={data as any}
|
|
58
|
-
enableHistoryCount={enableHistoryCount}
|
|
59
|
-
historyCount={historyCount}
|
|
60
|
-
loadingId={chatLoadingId}
|
|
61
|
-
onActionsClick={onActionsClick}
|
|
62
|
-
onAvatarsClick={onAvatarsClick}
|
|
63
|
-
onMessageChange={(id, content) => updateMessageContent(id, content)}
|
|
64
|
-
renderActions={renderActions}
|
|
65
|
-
renderErrorMessages={renderErrorMessages}
|
|
66
|
-
renderMessages={renderMessages}
|
|
67
|
-
renderMessagesExtra={renderMessagesExtra}
|
|
68
|
-
text={{
|
|
69
|
-
cancel: t('cancel'),
|
|
70
|
-
confirm: t('ok'),
|
|
71
|
-
copy: t('copy'),
|
|
72
|
-
copySuccess: t('copySuccess'),
|
|
73
|
-
delete: t('delete'),
|
|
74
|
-
edit: t('edit'),
|
|
75
|
-
history: t('historyRange'),
|
|
76
|
-
regenerate: t('regenerate'),
|
|
77
|
-
}}
|
|
78
|
-
type={displayMode || 'chat'}
|
|
79
|
-
/>
|
|
80
|
-
);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
export default List;
|
|
File without changes
|
|
File without changes
|