@ai-group/chat-sdk 0.2.5
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/README.md +239 -0
- package/dist/esm/assets/arrow-down.png +0 -0
- package/dist/esm/assets/arrow-up.png +0 -0
- package/dist/esm/assets/chatKnowledge.png +0 -0
- package/dist/esm/assets/completed-black.png +0 -0
- package/dist/esm/assets/completed.png +0 -0
- package/dist/esm/assets/document-black.png +0 -0
- package/dist/esm/assets/document.png +0 -0
- package/dist/esm/assets/document.svg +16 -0
- package/dist/esm/assets/empty.png +0 -0
- package/dist/esm/assets/group.png +0 -0
- package/dist/esm/assets/qa-black.png +0 -0
- package/dist/esm/assets/qa.png +0 -0
- package/dist/esm/assets/skillNo-black.png +0 -0
- package/dist/esm/assets/skillNo.png +0 -0
- package/dist/esm/assets/tools-black.png +0 -0
- package/dist/esm/assets/tools.png +0 -0
- package/dist/esm/client/base.js +2 -0
- package/dist/esm/client/base.js.map +1 -0
- package/dist/esm/client/restClient.js +2 -0
- package/dist/esm/client/restClient.js.map +1 -0
- package/dist/esm/client/wsClient.js +2 -0
- package/dist/esm/client/wsClient.js.map +1 -0
- package/dist/esm/components/XAiChatbot/XAiChatbot.stories.js +562 -0
- package/dist/esm/components/XAiChatbot/XAiChatbot.stories.js.map +1 -0
- package/dist/esm/components/XAiChatbot/index.js +586 -0
- package/dist/esm/components/XAiChatbot/index.js.map +1 -0
- package/dist/esm/components/XAiChatbot/styles.js +62 -0
- package/dist/esm/components/XAiChatbot/styles.js.map +1 -0
- package/dist/esm/components/XAiProvider/XAiProvider.stories.js +297 -0
- package/dist/esm/components/XAiProvider/XAiProvider.stories.js.map +1 -0
- package/dist/esm/components/XAiProvider/index.js +128 -0
- package/dist/esm/components/XAiProvider/index.js.map +1 -0
- package/dist/esm/components/XAiSDK.js +29 -0
- package/dist/esm/components/XAiSDK.js.map +1 -0
- package/dist/esm/components/XAiWebSDKWrapper.js +42 -0
- package/dist/esm/components/XAiWebSDKWrapper.js.map +1 -0
- package/dist/esm/context/AiProviderContext.js +62 -0
- package/dist/esm/context/AiProviderContext.js.map +1 -0
- package/dist/esm/context/ThemeContext.js +8 -0
- package/dist/esm/context/ThemeContext.js.map +1 -0
- package/dist/esm/hooks/useAgentGenerator.js +536 -0
- package/dist/esm/hooks/useAgentGenerator.js.map +1 -0
- package/dist/esm/hooks/useEventStreamRequest.js +229 -0
- package/dist/esm/hooks/useEventStreamRequest.js.map +1 -0
- package/dist/esm/hooks/useProviderContext.js +115 -0
- package/dist/esm/hooks/useProviderContext.js.map +1 -0
- package/dist/esm/hooks/useXAiSDK.js +49 -0
- package/dist/esm/hooks/useXAiSDK.js.map +1 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/services/api.js +73 -0
- package/dist/esm/services/api.js.map +1 -0
- package/dist/esm/styles/common.js +106 -0
- package/dist/esm/styles/common.js.map +1 -0
- package/dist/esm/styles/markdown.js +12 -0
- package/dist/esm/styles/markdown.js.map +1 -0
- package/dist/esm/types/XAiChatbot.js +2 -0
- package/dist/esm/types/XAiChatbot.js.map +1 -0
- package/dist/esm/types/XAiMessage.js +65 -0
- package/dist/esm/types/XAiMessage.js.map +1 -0
- package/dist/esm/types/XAiProvider.js +4 -0
- package/dist/esm/types/XAiProvider.js.map +1 -0
- package/dist/esm/types/index.js +4 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/mdx.d.ts +18 -0
- package/dist/esm/utils/chat.js +976 -0
- package/dist/esm/utils/chat.js.map +1 -0
- package/dist/esm/utils/index.js +19 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/providerManager.js +70 -0
- package/dist/esm/utils/providerManager.js.map +1 -0
- package/dist/esm/utils/request.example.js +379 -0
- package/dist/esm/utils/request.example.js.map +1 -0
- package/dist/esm/utils/request.js +491 -0
- package/dist/esm/utils/request.js.map +1 -0
- package/dist/esm/utils/umdEntry.js +109 -0
- package/dist/esm/utils/umdEntry.js.map +1 -0
- package/dist/umd/chat-sdk.min.js +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,976 @@
|
|
|
1
|
+
// import { fetchEventSource } from '@microsoft/fetch-event-source';
|
|
2
|
+
// import { message as messageAnt } from 'antd';
|
|
3
|
+
// import { getTokenAndServiceName } from '@/api/sso';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 处理发送消息并接收流式响应
|
|
7
|
+
* @param {Object} params - 参数对象
|
|
8
|
+
* @param {string} params.message - 用户输入的消息
|
|
9
|
+
* @param {Array} params.files - 上传的文件列表
|
|
10
|
+
* @param {string} params.botNo - 机器人编号
|
|
11
|
+
* @param {string} params.agentNo - 代理编号
|
|
12
|
+
* @param {string} params.agentVersionNo - 代理版本编号
|
|
13
|
+
* @param {string} params.sessionId - 会话ID
|
|
14
|
+
* @param {string} params.botPrefix - API前缀
|
|
15
|
+
* @param {string} params.mode - 模式
|
|
16
|
+
* @param {Function} params.setMessages - 设置消息列表的函数
|
|
17
|
+
* @param {Function} params.setLoading - 设置加载状态的函数
|
|
18
|
+
* @param {Function} params.setContent - 设置输入内容的函数
|
|
19
|
+
* @param {Function} params.setSessionId - 设置会话ID的函数
|
|
20
|
+
* @param {Function} params.scrollToBottom - 滚动到底部的函数
|
|
21
|
+
* @param {Object} params.controllerRef - AbortController引用
|
|
22
|
+
* @param {Object} params.timeoutRef - 超时计时器引用
|
|
23
|
+
* @param {Function} params.setServerTime - 设置服务器时间的函数
|
|
24
|
+
* @param {Function} params.processActionData - 处理动作数据的函数
|
|
25
|
+
* @param {Function} params.handleNeedApprove - 处理需要授权的回调函数
|
|
26
|
+
* @param {boolean} params.isJsonMode - 是否为JSON模式
|
|
27
|
+
* @param {boolean} params.skipUserMessage - 是否跳过添加用户消息(用于授权后重新发送)
|
|
28
|
+
* @param {string} params.aiMessageId - 已创建的AI消息ID(配合skipUserMessage使用)
|
|
29
|
+
* @returns {Promise<void>}
|
|
30
|
+
*/
|
|
31
|
+
// export const handleSendMessage = async ({
|
|
32
|
+
// isChat,
|
|
33
|
+
// message,
|
|
34
|
+
// files = [],
|
|
35
|
+
// botNo,
|
|
36
|
+
// agentNo,
|
|
37
|
+
// agentVersionNo,
|
|
38
|
+
// sessionId,
|
|
39
|
+
// botPrefix,
|
|
40
|
+
// mode,
|
|
41
|
+
// setMessages,
|
|
42
|
+
// setLoading,
|
|
43
|
+
// setContent,
|
|
44
|
+
// setSessionId,
|
|
45
|
+
// scrollToBottom,
|
|
46
|
+
// controllerRef,
|
|
47
|
+
// timeoutRef,
|
|
48
|
+
// setServerTime,
|
|
49
|
+
// processActionData,
|
|
50
|
+
// handleNeedApprove,
|
|
51
|
+
// isJsonMode = false,
|
|
52
|
+
// skipUserMessage = false,
|
|
53
|
+
// aiMessageId = null,
|
|
54
|
+
// metaAgentSessionVariables,
|
|
55
|
+
// }) => {
|
|
56
|
+
// if (!message && files.length === 0) return;
|
|
57
|
+
|
|
58
|
+
// // 清除之前的超时计时器
|
|
59
|
+
// if (timeoutRef.current) {
|
|
60
|
+
// clearTimeout(timeoutRef.current);
|
|
61
|
+
// timeoutRef.current = null;
|
|
62
|
+
// }
|
|
63
|
+
|
|
64
|
+
// // 如果不是跳过添加用户消息的情况,则添加用户消息
|
|
65
|
+
// if (!skipUserMessage) {
|
|
66
|
+
// // Add user message to chat
|
|
67
|
+
// const userMessageId = Date.now().toString();
|
|
68
|
+
// setMessages((prev) => [
|
|
69
|
+
// ...prev,
|
|
70
|
+
// {
|
|
71
|
+
// id: userMessageId,
|
|
72
|
+
// message,
|
|
73
|
+
// status: 'local',
|
|
74
|
+
// files,
|
|
75
|
+
// },
|
|
76
|
+
// ]);
|
|
77
|
+
|
|
78
|
+
// setContent('');
|
|
79
|
+
// }
|
|
80
|
+
|
|
81
|
+
// setLoading(true);
|
|
82
|
+
|
|
83
|
+
// // Prepare contents array for API request
|
|
84
|
+
// const contents = [];
|
|
85
|
+
|
|
86
|
+
// // Add text content if exists
|
|
87
|
+
// if (message) {
|
|
88
|
+
// // 根据模式和isJsonMode决定如何构建contents
|
|
89
|
+
// if (mode === 'single_agent_skill_mode' && isJsonMode) {
|
|
90
|
+
// // 工作流模式下的JSON格式化处理
|
|
91
|
+
// try {
|
|
92
|
+
// // 确保message是有效的JSON字符串
|
|
93
|
+
// const jsonMessage = typeof message === 'string' ? message : JSON.stringify(message);
|
|
94
|
+
|
|
95
|
+
// contents.push({
|
|
96
|
+
// contentType: 'TEXT',
|
|
97
|
+
// content: {
|
|
98
|
+
// text: jsonMessage,
|
|
99
|
+
// },
|
|
100
|
+
// });
|
|
101
|
+
// } catch (error) {
|
|
102
|
+
// console.error('JSON formatting error:', error);
|
|
103
|
+
// // 如果出错,使用原始消息
|
|
104
|
+
// contents.push({
|
|
105
|
+
// contentType: 'TEXT',
|
|
106
|
+
// content: {
|
|
107
|
+
// text: message,
|
|
108
|
+
// },
|
|
109
|
+
// });
|
|
110
|
+
// }
|
|
111
|
+
// } else {
|
|
112
|
+
// // 普通文本模式
|
|
113
|
+
// contents.push({
|
|
114
|
+
// contentType: 'TEXT',
|
|
115
|
+
// content: {
|
|
116
|
+
// text: message,
|
|
117
|
+
// },
|
|
118
|
+
// });
|
|
119
|
+
// }
|
|
120
|
+
// }
|
|
121
|
+
|
|
122
|
+
// // Add file contents if any
|
|
123
|
+
// files.forEach((file) => {
|
|
124
|
+
// if (file.type.startsWith('image/')) {
|
|
125
|
+
// contents.push({
|
|
126
|
+
// contentType: 'IMAGE',
|
|
127
|
+
// content: {
|
|
128
|
+
// imageUrl: {
|
|
129
|
+
// url: file.url,
|
|
130
|
+
// },
|
|
131
|
+
// },
|
|
132
|
+
// });
|
|
133
|
+
// } else {
|
|
134
|
+
// contents.push({
|
|
135
|
+
// contentType: 'FILE',
|
|
136
|
+
// content: {
|
|
137
|
+
// fileUrl: {
|
|
138
|
+
// url: file.url,
|
|
139
|
+
// fileName: file.name,
|
|
140
|
+
// suffix: file.name.split('.').pop(),
|
|
141
|
+
// },
|
|
142
|
+
// },
|
|
143
|
+
// });
|
|
144
|
+
// }
|
|
145
|
+
// });
|
|
146
|
+
|
|
147
|
+
// // Create a new AbortController for this request
|
|
148
|
+
// const controller = new AbortController();
|
|
149
|
+
// controllerRef.current = controller;
|
|
150
|
+
|
|
151
|
+
// // Create AI message placeholder if not already provided
|
|
152
|
+
// const aiMessageIdToUse = aiMessageId || (Date.now() + 1).toString();
|
|
153
|
+
|
|
154
|
+
// // 如果不是跳过用户消息的情况,或者没有提供aiMessageId,则创建新的AI消息
|
|
155
|
+
// if (!skipUserMessage || !aiMessageId) {
|
|
156
|
+
// setMessages((prev) => [
|
|
157
|
+
// ...prev,
|
|
158
|
+
// {
|
|
159
|
+
// id: aiMessageIdToUse,
|
|
160
|
+
// message: '',
|
|
161
|
+
// status: 'ai',
|
|
162
|
+
// loading: true,
|
|
163
|
+
// serverActions: [],
|
|
164
|
+
// },
|
|
165
|
+
// ]);
|
|
166
|
+
// }
|
|
167
|
+
|
|
168
|
+
// try {
|
|
169
|
+
// await fetchEventSource(
|
|
170
|
+
// isChat
|
|
171
|
+
// ? `${botPrefix}/bots/${botNo}/agents/${agentNo}/chat`
|
|
172
|
+
// : `${botPrefix}/bots/${botNo}/agents/${agentNo}/${agentVersionNo}/debug`,
|
|
173
|
+
// {
|
|
174
|
+
// method: 'POST',
|
|
175
|
+
// headers: {
|
|
176
|
+
// 'Content-Type': 'application/json',
|
|
177
|
+
// 'Cache-Control': 'no-cache',
|
|
178
|
+
// 'x-service-name': 'za-open-bot',
|
|
179
|
+
// 'X-Usercenter-Session': getTokenAndServiceName().token,
|
|
180
|
+
// ...(isChat ? { stream: true } : {}),
|
|
181
|
+
// ...(sessionId ? { 'X-Session-Id': sessionId } : ''),
|
|
182
|
+
// },
|
|
183
|
+
// body: JSON.stringify({
|
|
184
|
+
// sessionId,
|
|
185
|
+
// contents,
|
|
186
|
+
// metaAgentSessionVariables,
|
|
187
|
+
// }),
|
|
188
|
+
// signal: controller.signal,
|
|
189
|
+
// // 添加 keepalive 配置,保持连接活跃
|
|
190
|
+
// keepalive: true,
|
|
191
|
+
// // 配置重试机制
|
|
192
|
+
// openWhenHidden: true, // 允许在页面隐藏时保持连接
|
|
193
|
+
// retry: {
|
|
194
|
+
// maxRetries: 3, // 最大重试次数
|
|
195
|
+
// retryDelay: 1000, // 重试延迟时间(毫秒)
|
|
196
|
+
// onRetry: (err, retryCount) => {
|
|
197
|
+
// console.log(`重试连接 (${retryCount}/3):`, err);
|
|
198
|
+
// return true; // 继续重试
|
|
199
|
+
// },
|
|
200
|
+
// },
|
|
201
|
+
// onmessage(event) {
|
|
202
|
+
// // 收到消息时重置超时计时器
|
|
203
|
+
// if (timeoutRef.current) {
|
|
204
|
+
// clearTimeout(timeoutRef.current);
|
|
205
|
+
// }
|
|
206
|
+
|
|
207
|
+
// // 设置新的超时计时器,如果300秒内没有新消息,则关闭连接
|
|
208
|
+
// timeoutRef.current = setTimeout(() => {
|
|
209
|
+
// console.log('Response timeout, closing connection');
|
|
210
|
+
// controller.abort();
|
|
211
|
+
// setLoading(false);
|
|
212
|
+
// }, 300000);
|
|
213
|
+
|
|
214
|
+
// try {
|
|
215
|
+
// const parsedData = JSON.parse(event.data);
|
|
216
|
+
|
|
217
|
+
// // Update sessionId if it's returned
|
|
218
|
+
// if (parsedData.sessionId) {
|
|
219
|
+
// setSessionId(parsedData.sessionId);
|
|
220
|
+
// }
|
|
221
|
+
|
|
222
|
+
// // 检查是否需要授权
|
|
223
|
+
// if (
|
|
224
|
+
// parsedData.data
|
|
225
|
+
// && typeof parsedData.data === 'string'
|
|
226
|
+
// && parsedData.data.includes('"action":"NEED_APPROVE"')
|
|
227
|
+
// ) {
|
|
228
|
+
// try {
|
|
229
|
+
// const innerData = JSON.parse(parsedData.data);
|
|
230
|
+
// if (innerData.action === 'NEED_APPROVE' && innerData.data) {
|
|
231
|
+
// console.log('Need approve:', innerData.data);
|
|
232
|
+
|
|
233
|
+
// // 提取需要授权的工具列表
|
|
234
|
+
// const { waitForApproveTools } = innerData.data;
|
|
235
|
+
|
|
236
|
+
// if (
|
|
237
|
+
// waitForApproveTools
|
|
238
|
+
// && Array.isArray(waitForApproveTools)
|
|
239
|
+
// && waitForApproveTools.length > 0
|
|
240
|
+
// ) {
|
|
241
|
+
// // 收到NEED_APPROVE时终止流连接,需要重新请求
|
|
242
|
+
// controller.abort();
|
|
243
|
+
// setLoading(false);
|
|
244
|
+
|
|
245
|
+
// // 记录上一次消息内容,用于授权后重新发送
|
|
246
|
+
// const lastMessage = {
|
|
247
|
+
// message,
|
|
248
|
+
// files,
|
|
249
|
+
// aiMessageId: aiMessageIdToUse,
|
|
250
|
+
// };
|
|
251
|
+
|
|
252
|
+
// // 调用授权处理回调
|
|
253
|
+
// if (handleNeedApprove && typeof handleNeedApprove === 'function') {
|
|
254
|
+
// handleNeedApprove(waitForApproveTools, lastMessage, sessionId);
|
|
255
|
+
// }
|
|
256
|
+
|
|
257
|
+
// // 终止后续处理
|
|
258
|
+
// return;
|
|
259
|
+
// }
|
|
260
|
+
// }
|
|
261
|
+
// } catch (e) {
|
|
262
|
+
// console.error('Error parsing NEED_APPROVE data:', e);
|
|
263
|
+
// }
|
|
264
|
+
// }
|
|
265
|
+
|
|
266
|
+
// // 记录服务器时间戳,用于计算响应时间
|
|
267
|
+
// const serverTime = processActionData(parsedData)?.cost || 0;
|
|
268
|
+
|
|
269
|
+
// // 尝试从内部数据中提取cost
|
|
270
|
+
// let responseCost = 0;
|
|
271
|
+
// try {
|
|
272
|
+
// if (
|
|
273
|
+
// parsedData.data
|
|
274
|
+
// && typeof parsedData.data === 'string'
|
|
275
|
+
// && parsedData.data.includes('"action":"RESPONSE"')
|
|
276
|
+
// ) {
|
|
277
|
+
// const innerData = JSON.parse(parsedData.data);
|
|
278
|
+
// if (innerData.data && innerData.data.cost) {
|
|
279
|
+
// responseCost = innerData.data.cost;
|
|
280
|
+
// }
|
|
281
|
+
// }
|
|
282
|
+
// } catch (e) {
|
|
283
|
+
// console.error('Error extracting cost from inner data:', e);
|
|
284
|
+
// }
|
|
285
|
+
|
|
286
|
+
// // 计算响应时间(秒),并保留一位小数
|
|
287
|
+
// const responseTimeInSeconds = responseCost > 0 ? (responseCost / 1000).toFixed(2) : 0;
|
|
288
|
+
|
|
289
|
+
// console.log('serverTime', responseTimeInSeconds);
|
|
290
|
+
|
|
291
|
+
// // 更新组件状态中的服务器时间,仅当新值更大时才更新
|
|
292
|
+
// if (responseTimeInSeconds > 0) {
|
|
293
|
+
// setServerTime((prevTime) => {
|
|
294
|
+
// const prevTimeNum = parseFloat(prevTime || 0);
|
|
295
|
+
// return responseTimeInSeconds > prevTimeNum ? responseTimeInSeconds : prevTime;
|
|
296
|
+
// });
|
|
297
|
+
// }
|
|
298
|
+
|
|
299
|
+
// // Process action data for headers if processActionData function is provided
|
|
300
|
+
// if (processActionData && typeof processActionData === 'function') {
|
|
301
|
+
// const actionData = processActionData(parsedData);
|
|
302
|
+
// console.log('Received stream data:', actionData);
|
|
303
|
+
|
|
304
|
+
// if (actionData) {
|
|
305
|
+
// // Only process non-RESPONSE actions for headers
|
|
306
|
+
// if (actionData.actionType !== 'RESPONSE') {
|
|
307
|
+
// // Add this action to serverActions array in the message
|
|
308
|
+
// setMessages((prev) => {
|
|
309
|
+
// const updatedMessages = [...prev];
|
|
310
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
311
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
312
|
+
// );
|
|
313
|
+
|
|
314
|
+
// if (aiMessageIndex !== -1) {
|
|
315
|
+
// // Check if action with this uniqueId already exists
|
|
316
|
+
// const existingActionIndex = updatedMessages[
|
|
317
|
+
// aiMessageIndex
|
|
318
|
+
// ].serverActions?.findIndex((act) => act.uniqueId === actionData.uniqueId);
|
|
319
|
+
|
|
320
|
+
// if (existingActionIndex !== -1) {
|
|
321
|
+
// // Update existing action with new data
|
|
322
|
+
// updatedMessages[aiMessageIndex].serverActions[existingActionIndex] = {
|
|
323
|
+
// ...updatedMessages[aiMessageIndex].serverActions[existingActionIndex],
|
|
324
|
+
// ...actionData,
|
|
325
|
+
// };
|
|
326
|
+
// } else {
|
|
327
|
+
// // Add new action to the list
|
|
328
|
+
// if (!updatedMessages[aiMessageIndex].serverActions) {
|
|
329
|
+
// updatedMessages[aiMessageIndex].serverActions = [];
|
|
330
|
+
// }
|
|
331
|
+
// updatedMessages[aiMessageIndex].serverActions.push(actionData);
|
|
332
|
+
// }
|
|
333
|
+
// }
|
|
334
|
+
|
|
335
|
+
// return updatedMessages;
|
|
336
|
+
// });
|
|
337
|
+
// }
|
|
338
|
+
// }
|
|
339
|
+
// }
|
|
340
|
+
|
|
341
|
+
// // Handle streaming data
|
|
342
|
+
// if (parsedData.data) {
|
|
343
|
+
// try {
|
|
344
|
+
// // Handle the specific format from the example
|
|
345
|
+
// // data:{"data":"{\"action\":\"RESPONSE\",\"data\":{\"executeResult\":\"你好!...\"}}","code":"200",...}
|
|
346
|
+
// if (
|
|
347
|
+
// typeof parsedData.data === 'string'
|
|
348
|
+
// && parsedData.data.includes('"action":"RESPONSE"')
|
|
349
|
+
// ) {
|
|
350
|
+
// try {
|
|
351
|
+
// const innerData = JSON.parse(parsedData.data);
|
|
352
|
+
// if (innerData.action === 'RESPONSE' && innerData.data) {
|
|
353
|
+
// // 检查是否有错误信息
|
|
354
|
+
// if (innerData.data.errorMsg) {
|
|
355
|
+
// // 提取错误信息
|
|
356
|
+
// let errorMessage = innerData.data.errorMsg;
|
|
357
|
+
// try {
|
|
358
|
+
// // 展示完整的错误信息,而不是只提取message部分
|
|
359
|
+
// if (typeof errorMessage === 'string') {
|
|
360
|
+
// // 如果包含转义字符,去除转义符号
|
|
361
|
+
// errorMessage = errorMessage.replace(/\\"/g, '"');
|
|
362
|
+
|
|
363
|
+
// // 不再尝试提取json中的message字段,而是保留完整错误信息
|
|
364
|
+
// // 只做最基本的格式化处理
|
|
365
|
+
// if (
|
|
366
|
+
// errorMessage.includes('ERROR_CODE')
|
|
367
|
+
// || errorMessage.includes('Exception')
|
|
368
|
+
// || errorMessage.includes('statusCode')
|
|
369
|
+
// ) {
|
|
370
|
+
// errorMessage = `错误详情: ${errorMessage}`;
|
|
371
|
+
// }
|
|
372
|
+
// }
|
|
373
|
+
// } catch (e) {
|
|
374
|
+
// console.error('Error processing error message:', e);
|
|
375
|
+
// }
|
|
376
|
+
|
|
377
|
+
// // 更新消息状态为错误
|
|
378
|
+
// setMessages((prev) => {
|
|
379
|
+
// const updatedMessages = [...prev];
|
|
380
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
381
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
382
|
+
// );
|
|
383
|
+
|
|
384
|
+
// if (aiMessageIndex !== -1) {
|
|
385
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
386
|
+
// updatedMessages[aiMessageIndex].serverTime = responseTimeInSeconds;
|
|
387
|
+
// updatedMessages[aiMessageIndex].message = `[错误] ${errorMessage}`;
|
|
388
|
+
|
|
389
|
+
// // 更新serverActions中的错误状态
|
|
390
|
+
// if (updatedMessages[aiMessageIndex].serverActions) {
|
|
391
|
+
// updatedMessages[aiMessageIndex].serverActions = updatedMessages[
|
|
392
|
+
// aiMessageIndex
|
|
393
|
+
// ].serverActions.map((action) => ({
|
|
394
|
+
// ...action,
|
|
395
|
+
// processStatus: 'ERROR',
|
|
396
|
+
// errorMsg: errorMessage,
|
|
397
|
+
// }));
|
|
398
|
+
// }
|
|
399
|
+
// }
|
|
400
|
+
|
|
401
|
+
// return updatedMessages;
|
|
402
|
+
// });
|
|
403
|
+
|
|
404
|
+
// // 显示错误提示
|
|
405
|
+
// // messageAnt.error(errorMessage)
|
|
406
|
+
// return;
|
|
407
|
+
// }
|
|
408
|
+
|
|
409
|
+
// if (innerData.data.executeResult) {
|
|
410
|
+
// // Get the new content to add
|
|
411
|
+
// const newContent = innerData.data.executeResult;
|
|
412
|
+
|
|
413
|
+
// // 先检查当前消息内容
|
|
414
|
+
// setMessages((prev) => {
|
|
415
|
+
// const updatedMessages = [...prev];
|
|
416
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
417
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
418
|
+
// );
|
|
419
|
+
|
|
420
|
+
// if (aiMessageIndex !== -1) {
|
|
421
|
+
// const currentMessage = updatedMessages[aiMessageIndex].message || '';
|
|
422
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
423
|
+
// updatedMessages[aiMessageIndex].serverTime = responseTimeInSeconds;
|
|
424
|
+
|
|
425
|
+
// // 如果新内容已包含在当前内容中,不做更新
|
|
426
|
+
// if (currentMessage.includes(newContent)) {
|
|
427
|
+
// return prev; // 这里直接返回,跳过后续所有处理
|
|
428
|
+
// }
|
|
429
|
+
|
|
430
|
+
// // 检查是否是英文内容,如果是英文则直接显示完整内容,避免逐字符显示造成的重复问题
|
|
431
|
+
// if (!currentMessage && /^[a-zA-Z0-9\s\p{P}]*$/u.test(newContent)) {
|
|
432
|
+
// // 如果是纯英文内容,直接全部显示,避免字符重复问题
|
|
433
|
+
// updatedMessages[aiMessageIndex].message = newContent;
|
|
434
|
+
// return updatedMessages;
|
|
435
|
+
// }
|
|
436
|
+
// }
|
|
437
|
+
|
|
438
|
+
// return updatedMessages;
|
|
439
|
+
// });
|
|
440
|
+
|
|
441
|
+
// // 只对中文内容进行流式显示,避免乱序
|
|
442
|
+
// setMessages((prev) => {
|
|
443
|
+
// const updatedMessages = [...prev];
|
|
444
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
445
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
446
|
+
// );
|
|
447
|
+
|
|
448
|
+
// if (aiMessageIndex !== -1) {
|
|
449
|
+
// const currentMessage = updatedMessages[aiMessageIndex].message || '';
|
|
450
|
+
|
|
451
|
+
// // 如果当前无内容,开始流式显示
|
|
452
|
+
// if (!currentMessage) {
|
|
453
|
+
// // 根据内容长度决定流式输出参数
|
|
454
|
+
// const isLongContent = newContent.length > 10000; // 超过1万字的长内容
|
|
455
|
+
// const initialChunkSize = isLongContent
|
|
456
|
+
// ? 10
|
|
457
|
+
// : Math.min(3, newContent.length);
|
|
458
|
+
// const chunkSize = isLongContent ? 10 : 2; // 长内容每次处理10个字符,短内容2个字符
|
|
459
|
+
// const delayTime = isLongContent ? 10 : 20; // 长内容10毫秒延迟,短内容20毫秒延迟
|
|
460
|
+
|
|
461
|
+
// // 初始显示部分字符
|
|
462
|
+
// updatedMessages[aiMessageIndex].message = newContent.substring(
|
|
463
|
+
// 0,
|
|
464
|
+
// initialChunkSize,
|
|
465
|
+
// );
|
|
466
|
+
|
|
467
|
+
// // 如果内容较短,直接显示全部
|
|
468
|
+
// if (newContent.length <= initialChunkSize) {
|
|
469
|
+
// return updatedMessages;
|
|
470
|
+
// }
|
|
471
|
+
|
|
472
|
+
// // 剩余部分流式显示
|
|
473
|
+
// setTimeout(() => {
|
|
474
|
+
// let currentIndex = initialChunkSize;
|
|
475
|
+
|
|
476
|
+
// const streamInterval = setInterval(() => {
|
|
477
|
+
// if (currentIndex >= newContent.length) {
|
|
478
|
+
// clearInterval(streamInterval);
|
|
479
|
+
// return;
|
|
480
|
+
// }
|
|
481
|
+
|
|
482
|
+
// const endIndex = Math.min(
|
|
483
|
+
// currentIndex + chunkSize,
|
|
484
|
+
// newContent.length,
|
|
485
|
+
// );
|
|
486
|
+
// const chunk = newContent.substring(currentIndex, endIndex);
|
|
487
|
+
|
|
488
|
+
// setMessages((prev) => {
|
|
489
|
+
// const updatedMessages = [...prev];
|
|
490
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
491
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
492
|
+
// );
|
|
493
|
+
|
|
494
|
+
// if (aiMessageIndex !== -1) {
|
|
495
|
+
// updatedMessages[aiMessageIndex].message += chunk;
|
|
496
|
+
// }
|
|
497
|
+
|
|
498
|
+
// return updatedMessages;
|
|
499
|
+
// });
|
|
500
|
+
|
|
501
|
+
// currentIndex = endIndex;
|
|
502
|
+
// setTimeout(scrollToBottom, 0);
|
|
503
|
+
// }, delayTime); // 使用动态延迟时间
|
|
504
|
+
// }, 0);
|
|
505
|
+
// }
|
|
506
|
+
// }
|
|
507
|
+
|
|
508
|
+
// return updatedMessages;
|
|
509
|
+
// });
|
|
510
|
+
|
|
511
|
+
// return; // Skip the rest of the processing
|
|
512
|
+
// }
|
|
513
|
+
// }
|
|
514
|
+
|
|
515
|
+
// // Check for END action in the specific format
|
|
516
|
+
// if (innerData.action === 'END') {
|
|
517
|
+
// controller.abort();
|
|
518
|
+
|
|
519
|
+
// setLoading(false);
|
|
520
|
+
// return;
|
|
521
|
+
// }
|
|
522
|
+
// } catch (innerError) {
|
|
523
|
+
// console.error('Failed to parse inner data:', innerError, parsedData.data);
|
|
524
|
+
// }
|
|
525
|
+
// }
|
|
526
|
+
|
|
527
|
+
// // Continue with existing parsing logic for other formats
|
|
528
|
+
// const streamData = typeof parsedData.data === 'string'
|
|
529
|
+
// ? JSON.parse(parsedData.data)
|
|
530
|
+
// : parsedData.data;
|
|
531
|
+
|
|
532
|
+
// // Update the AI message with the streamed content
|
|
533
|
+
// setMessages((prev) => {
|
|
534
|
+
// const updatedMessages = [...prev];
|
|
535
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
536
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
537
|
+
// );
|
|
538
|
+
|
|
539
|
+
// if (aiMessageIndex !== -1) {
|
|
540
|
+
// // Handle different types of streaming data based on the new format
|
|
541
|
+
// if (streamData.action === 'RESPONSE' && streamData.data) {
|
|
542
|
+
// // Check if data.executeResult exists (new format)
|
|
543
|
+
// if (streamData.data.executeResult) {
|
|
544
|
+
// // 这部分逻辑已经在上面处理过了,跳过避免重复处理
|
|
545
|
+
// return updatedMessages;
|
|
546
|
+
// }
|
|
547
|
+
// // Fallback to old format
|
|
548
|
+
// if (streamData.data.content) {
|
|
549
|
+
// // 简化处理,避免重复逻辑
|
|
550
|
+
// const newContent = streamData.data.content;
|
|
551
|
+
// const currentMessage = updatedMessages[aiMessageIndex].message || '';
|
|
552
|
+
|
|
553
|
+
// // 检查是否重复内容
|
|
554
|
+
// if (!currentMessage.includes(newContent)) {
|
|
555
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
556
|
+
// updatedMessages[aiMessageIndex].serverTime = responseTimeInSeconds;
|
|
557
|
+
// updatedMessages[aiMessageIndex].message = currentMessage + newContent;
|
|
558
|
+
// }
|
|
559
|
+
// }
|
|
560
|
+
// }
|
|
561
|
+
// // Remove duplicate condition and handle other cases
|
|
562
|
+
// else if (streamData.data && typeof streamData.data === 'string') {
|
|
563
|
+
// // 简化处理字符串数据
|
|
564
|
+
// const newContent = streamData.data;
|
|
565
|
+
// const currentMessage = updatedMessages[aiMessageIndex].message || '';
|
|
566
|
+
|
|
567
|
+
// // 检查是否重复内容
|
|
568
|
+
// if (!currentMessage.includes(newContent)) {
|
|
569
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
570
|
+
// updatedMessages[aiMessageIndex].serverTime = responseTimeInSeconds;
|
|
571
|
+
// updatedMessages[aiMessageIndex].message = currentMessage + newContent;
|
|
572
|
+
// }
|
|
573
|
+
// }
|
|
574
|
+
// }
|
|
575
|
+
|
|
576
|
+
// return updatedMessages;
|
|
577
|
+
// });
|
|
578
|
+
|
|
579
|
+
// // Handle different types of streaming data based on the new format
|
|
580
|
+
// if (streamData.action === 'RESPONSE' && streamData.data) {
|
|
581
|
+
// // Check if data.executeResult exists (new format)
|
|
582
|
+
// if (streamData.data.executeResult) {
|
|
583
|
+
// // Get the new content to add
|
|
584
|
+
// const newContent = streamData.data.executeResult;
|
|
585
|
+
|
|
586
|
+
// // First update to turn off loading state and add serverTime
|
|
587
|
+
// setMessages((prev) => {
|
|
588
|
+
// const updatedMessages = [...prev];
|
|
589
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
590
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
591
|
+
// );
|
|
592
|
+
|
|
593
|
+
// if (aiMessageIndex !== -1) {
|
|
594
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
595
|
+
// updatedMessages[aiMessageIndex].serverTime = responseTimeInSeconds;
|
|
596
|
+
// }
|
|
597
|
+
|
|
598
|
+
// return updatedMessages;
|
|
599
|
+
// });
|
|
600
|
+
|
|
601
|
+
// // Update the message one character at a time
|
|
602
|
+
// let currentIndex = 0;
|
|
603
|
+
// const streamInterval = setInterval(() => {
|
|
604
|
+
// if (currentIndex >= newContent.length) {
|
|
605
|
+
// clearInterval(streamInterval);
|
|
606
|
+
// return;
|
|
607
|
+
// }
|
|
608
|
+
|
|
609
|
+
// setMessages((prev) => {
|
|
610
|
+
// const updatedMessages = [...prev];
|
|
611
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
612
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
613
|
+
// );
|
|
614
|
+
|
|
615
|
+
// if (aiMessageIndex !== -1) {
|
|
616
|
+
// const currentMessage = updatedMessages[aiMessageIndex].message || '';
|
|
617
|
+
// updatedMessages[aiMessageIndex].message = currentMessage + newContent.charAt(currentIndex);
|
|
618
|
+
// }
|
|
619
|
+
|
|
620
|
+
// return updatedMessages;
|
|
621
|
+
// });
|
|
622
|
+
|
|
623
|
+
// currentIndex++;
|
|
624
|
+
// // 使用多个延时确保在不同渲染阶段都能滚动到底部
|
|
625
|
+
// setTimeout(scrollToBottom, 0);
|
|
626
|
+
// setTimeout(scrollToBottom, 50);
|
|
627
|
+
// }, 20); // Adjust timing as needed
|
|
628
|
+
// }
|
|
629
|
+
// // Fallback to old format
|
|
630
|
+
// else if (streamData.data.content) {
|
|
631
|
+
// // Get the new content to add
|
|
632
|
+
// const newContent = streamData.data.content;
|
|
633
|
+
|
|
634
|
+
// // First update to turn off loading state and add serverTime
|
|
635
|
+
// setMessages((prev) => {
|
|
636
|
+
// const updatedMessages = [...prev];
|
|
637
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
638
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
639
|
+
// );
|
|
640
|
+
|
|
641
|
+
// if (aiMessageIndex !== -1) {
|
|
642
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
643
|
+
// updatedMessages[aiMessageIndex].serverTime = responseTimeInSeconds;
|
|
644
|
+
// }
|
|
645
|
+
|
|
646
|
+
// return updatedMessages;
|
|
647
|
+
// });
|
|
648
|
+
|
|
649
|
+
// // Update the message one character at a time
|
|
650
|
+
// let currentIndex = 0;
|
|
651
|
+
// const streamInterval = setInterval(() => {
|
|
652
|
+
// if (currentIndex >= newContent.length) {
|
|
653
|
+
// clearInterval(streamInterval);
|
|
654
|
+
// return;
|
|
655
|
+
// }
|
|
656
|
+
|
|
657
|
+
// setMessages((prev) => {
|
|
658
|
+
// const updatedMessages = [...prev];
|
|
659
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
660
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
661
|
+
// );
|
|
662
|
+
|
|
663
|
+
// if (aiMessageIndex !== -1) {
|
|
664
|
+
// const currentMessage = updatedMessages[aiMessageIndex].message || '';
|
|
665
|
+
// updatedMessages[aiMessageIndex].message = currentMessage + newContent.charAt(currentIndex);
|
|
666
|
+
// }
|
|
667
|
+
|
|
668
|
+
// return updatedMessages;
|
|
669
|
+
// });
|
|
670
|
+
|
|
671
|
+
// currentIndex++;
|
|
672
|
+
// // 使用多个延时确保在不同渲染阶段都能滚动到底部
|
|
673
|
+
// setTimeout(scrollToBottom, 0);
|
|
674
|
+
// setTimeout(scrollToBottom, 50);
|
|
675
|
+
// }, 20); // Adjust timing as needed
|
|
676
|
+
// }
|
|
677
|
+
// }
|
|
678
|
+
// // Remove duplicate condition and handle other cases
|
|
679
|
+
// else if (streamData.data && typeof streamData.data === 'string') {
|
|
680
|
+
// // Get the new content to add
|
|
681
|
+
// const newContent = streamData.data;
|
|
682
|
+
|
|
683
|
+
// // First update to turn off loading state and add serverTime
|
|
684
|
+
// setMessages((prev) => {
|
|
685
|
+
// const updatedMessages = [...prev];
|
|
686
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
687
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
688
|
+
// );
|
|
689
|
+
|
|
690
|
+
// if (aiMessageIndex !== -1) {
|
|
691
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
692
|
+
// updatedMessages[aiMessageIndex].serverTime = responseTimeInSeconds;
|
|
693
|
+
// }
|
|
694
|
+
|
|
695
|
+
// return updatedMessages;
|
|
696
|
+
// });
|
|
697
|
+
|
|
698
|
+
// // Update the message one character at a time
|
|
699
|
+
// let currentIndex = 0;
|
|
700
|
+
// const streamInterval = setInterval(() => {
|
|
701
|
+
// if (currentIndex >= newContent.length) {
|
|
702
|
+
// clearInterval(streamInterval);
|
|
703
|
+
// return;
|
|
704
|
+
// }
|
|
705
|
+
|
|
706
|
+
// setMessages((prev) => {
|
|
707
|
+
// const updatedMessages = [...prev];
|
|
708
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
709
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
710
|
+
// );
|
|
711
|
+
|
|
712
|
+
// if (aiMessageIndex !== -1) {
|
|
713
|
+
// const currentMessage = updatedMessages[aiMessageIndex].message || '';
|
|
714
|
+
// updatedMessages[aiMessageIndex].message = currentMessage + newContent.charAt(currentIndex);
|
|
715
|
+
// }
|
|
716
|
+
|
|
717
|
+
// return updatedMessages;
|
|
718
|
+
// });
|
|
719
|
+
|
|
720
|
+
// currentIndex++;
|
|
721
|
+
// // 使用多个延时确保在不同渲染阶段都能滚动到底部
|
|
722
|
+
// setTimeout(scrollToBottom, 0);
|
|
723
|
+
// setTimeout(scrollToBottom, 50);
|
|
724
|
+
// }, 20); // Adjust timing as needed
|
|
725
|
+
// }
|
|
726
|
+
|
|
727
|
+
// // 检查是否是结束标志
|
|
728
|
+
// if (streamData.action === 'END' || streamData.processStatus === 'END') {
|
|
729
|
+
// // 收到结束标志,主动关闭连接
|
|
730
|
+
// controller.abort();
|
|
731
|
+
|
|
732
|
+
// setLoading(false);
|
|
733
|
+
// }
|
|
734
|
+
|
|
735
|
+
// // Scroll to bottom with each update
|
|
736
|
+
// setTimeout(scrollToBottom, 0);
|
|
737
|
+
// } catch (error) {
|
|
738
|
+
// console.error('Failed to parse stream data:', error, parsedData.data);
|
|
739
|
+
|
|
740
|
+
// // Display error in the message if parsing fails
|
|
741
|
+
// setMessages((prev) => {
|
|
742
|
+
// const updatedMessages = [...prev];
|
|
743
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
744
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
745
|
+
// );
|
|
746
|
+
|
|
747
|
+
// if (aiMessageIndex !== -1) {
|
|
748
|
+
// // Turn off loading state
|
|
749
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
750
|
+
// }
|
|
751
|
+
|
|
752
|
+
// return updatedMessages;
|
|
753
|
+
// });
|
|
754
|
+
|
|
755
|
+
// // Try to extract any text content from the raw data
|
|
756
|
+
// try {
|
|
757
|
+
// const rawData = typeof parsedData.data === 'string'
|
|
758
|
+
// ? parsedData.data
|
|
759
|
+
// : JSON.stringify(parsedData.data);
|
|
760
|
+
|
|
761
|
+
// let contentToAdd = '[解析响应时出错]';
|
|
762
|
+
|
|
763
|
+
// // 检查是否包含具有完整错误信息的格式:"data":"{\"action\":\"RESPONSE\",\"data\":{\"success\":false,\"errorMsg\":\"...\"}}
|
|
764
|
+
// if (
|
|
765
|
+
// rawData.includes('"action":"RESPONSE"')
|
|
766
|
+
// && rawData.includes('"success":false')
|
|
767
|
+
// ) {
|
|
768
|
+
// try {
|
|
769
|
+
// // 尝试解析出errorMsg部分
|
|
770
|
+
// const innerData = typeof parsedData.data === 'string'
|
|
771
|
+
// ? JSON.parse(parsedData.data)
|
|
772
|
+
// : parsedData.data;
|
|
773
|
+
|
|
774
|
+
// if (
|
|
775
|
+
// innerData.action === 'RESPONSE'
|
|
776
|
+
// && innerData.data
|
|
777
|
+
// && innerData.data.errorMsg
|
|
778
|
+
// ) {
|
|
779
|
+
// const { errorMsg } = innerData.data;
|
|
780
|
+
|
|
781
|
+
// // 展示完整的错误信息,不只是提取message部分
|
|
782
|
+
// if (typeof errorMsg === 'string') {
|
|
783
|
+
// // 如果包含转义字符,去除转义符号
|
|
784
|
+
// const completeErrorMessage = errorMsg.replace(/\\"/g, '"');
|
|
785
|
+
// contentToAdd = `[错误] 调用失败: ${completeErrorMessage}`;
|
|
786
|
+
// } else {
|
|
787
|
+
// contentToAdd = `[错误] ${errorMsg}`;
|
|
788
|
+
// }
|
|
789
|
+
// }
|
|
790
|
+
// } catch (e) {
|
|
791
|
+
// // 如果以上解析失败,再尝试正则表达式提取
|
|
792
|
+
// const errorMsgMatch = rawData.match(/"errorMsg":"([^"]+)"/);
|
|
793
|
+
// if (errorMsgMatch && errorMsgMatch[1]) {
|
|
794
|
+
// const fullError = errorMsgMatch[1].replace(/\\"/g, '"');
|
|
795
|
+
// contentToAdd = `[错误] ${fullError}`;
|
|
796
|
+
// }
|
|
797
|
+
// }
|
|
798
|
+
// }
|
|
799
|
+
// // 检查是否包含HTML错误消息(如<span style="color: red">...错误信息...</span>)
|
|
800
|
+
// else if (rawData.includes('<span') && rawData.includes('</span>')) {
|
|
801
|
+
// // 提取span标签中的错误消息
|
|
802
|
+
// const spanMatch = rawData.match(/<span[^>]*>(.*?)<\/span>/);
|
|
803
|
+
// if (spanMatch && spanMatch[1]) {
|
|
804
|
+
// contentToAdd = spanMatch[1];
|
|
805
|
+
// }
|
|
806
|
+
// } else if (rawData.includes('executeResult')) {
|
|
807
|
+
// const match = rawData.match(/"executeResult":"([^"]+)"/);
|
|
808
|
+
// if (match && match[1]) {
|
|
809
|
+
// contentToAdd = match[1];
|
|
810
|
+
// } else {
|
|
811
|
+
// contentToAdd = '[解析响应时出错,但尝试显示内容]';
|
|
812
|
+
// }
|
|
813
|
+
// }
|
|
814
|
+
|
|
815
|
+
// // Update the message one character at a time
|
|
816
|
+
// let currentIndex = 0;
|
|
817
|
+
// const streamInterval = setInterval(() => {
|
|
818
|
+
// if (currentIndex >= contentToAdd.length) {
|
|
819
|
+
// clearInterval(streamInterval);
|
|
820
|
+
// return;
|
|
821
|
+
// }
|
|
822
|
+
|
|
823
|
+
// setMessages((prev) => {
|
|
824
|
+
// const updatedMessages = [...prev];
|
|
825
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
826
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
827
|
+
// );
|
|
828
|
+
|
|
829
|
+
// if (aiMessageIndex !== -1) {
|
|
830
|
+
// const currentMessage = updatedMessages[aiMessageIndex].message || '';
|
|
831
|
+
// updatedMessages[aiMessageIndex].message = currentMessage + contentToAdd.charAt(currentIndex);
|
|
832
|
+
// }
|
|
833
|
+
|
|
834
|
+
// return updatedMessages;
|
|
835
|
+
// });
|
|
836
|
+
|
|
837
|
+
// currentIndex++;
|
|
838
|
+
// // 使用多个延时确保在不同渲染阶段都能滚动到底部
|
|
839
|
+
// setTimeout(scrollToBottom, 0);
|
|
840
|
+
// setTimeout(scrollToBottom, 50);
|
|
841
|
+
// }, 20); // Adjust timing as needed
|
|
842
|
+
// } catch (e) {
|
|
843
|
+
// // If all else fails, show a simple error message
|
|
844
|
+
// const contentToAdd = '[解析响应时出错]';
|
|
845
|
+
|
|
846
|
+
// // Update the message one character at a time
|
|
847
|
+
// let currentIndex = 0;
|
|
848
|
+
// const streamInterval = setInterval(() => {
|
|
849
|
+
// if (currentIndex >= contentToAdd.length) {
|
|
850
|
+
// clearInterval(streamInterval);
|
|
851
|
+
// return;
|
|
852
|
+
// }
|
|
853
|
+
|
|
854
|
+
// setMessages((prev) => {
|
|
855
|
+
// const updatedMessages = [...prev];
|
|
856
|
+
// const aiMessageIndex = updatedMessages.findIndex(
|
|
857
|
+
// (msg) => msg.id === aiMessageIdToUse,
|
|
858
|
+
// );
|
|
859
|
+
|
|
860
|
+
// if (aiMessageIndex !== -1) {
|
|
861
|
+
// const currentMessage = updatedMessages[aiMessageIndex].message || '';
|
|
862
|
+
// updatedMessages[aiMessageIndex].message = currentMessage + contentToAdd.charAt(currentIndex);
|
|
863
|
+
// }
|
|
864
|
+
|
|
865
|
+
// return updatedMessages;
|
|
866
|
+
// });
|
|
867
|
+
|
|
868
|
+
// currentIndex++;
|
|
869
|
+
// // 使用多个延时确保在不同渲染阶段都能滚动到底部
|
|
870
|
+
// setTimeout(scrollToBottom, 0);
|
|
871
|
+
// setTimeout(scrollToBottom, 50);
|
|
872
|
+
// }, 20); // Adjust timing as needed
|
|
873
|
+
// }
|
|
874
|
+
// }
|
|
875
|
+
// }
|
|
876
|
+
// } catch (error) {
|
|
877
|
+
// console.error('Failed to parse message:', error, event.data);
|
|
878
|
+
// }
|
|
879
|
+
// },
|
|
880
|
+
// onclose() {
|
|
881
|
+
// // 连接关闭时清除超时计时器
|
|
882
|
+
// if (timeoutRef.current) {
|
|
883
|
+
// clearTimeout(timeoutRef.current);
|
|
884
|
+
// timeoutRef.current = null;
|
|
885
|
+
// }
|
|
886
|
+
|
|
887
|
+
// // Turn off loading state
|
|
888
|
+
// setMessages((prev) => {
|
|
889
|
+
// const updatedMessages = [...prev];
|
|
890
|
+
// const aiMessageIndex = updatedMessages.findIndex((msg) => msg.id === aiMessageIdToUse);
|
|
891
|
+
|
|
892
|
+
// if (aiMessageIndex !== -1) {
|
|
893
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
894
|
+
// }
|
|
895
|
+
|
|
896
|
+
// return updatedMessages;
|
|
897
|
+
// });
|
|
898
|
+
|
|
899
|
+
// setLoading(false);
|
|
900
|
+
// setTimeout(scrollToBottom, 0);
|
|
901
|
+
// },
|
|
902
|
+
// onerror(error) {
|
|
903
|
+
// // 发生错误时清除超时计时器
|
|
904
|
+
// if (timeoutRef.current) {
|
|
905
|
+
// clearTimeout(timeoutRef.current);
|
|
906
|
+
// timeoutRef.current = null;
|
|
907
|
+
// }
|
|
908
|
+
|
|
909
|
+
// // Turn off loading state
|
|
910
|
+
// setMessages((prev) => {
|
|
911
|
+
// const updatedMessages = [...prev];
|
|
912
|
+
// const aiMessageIndex = updatedMessages.findIndex((msg) => msg.id === aiMessageIdToUse);
|
|
913
|
+
|
|
914
|
+
// if (aiMessageIndex !== -1) {
|
|
915
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
916
|
+
// }
|
|
917
|
+
|
|
918
|
+
// return updatedMessages;
|
|
919
|
+
// });
|
|
920
|
+
|
|
921
|
+
// console.error('Stream failed:', error);
|
|
922
|
+
// setLoading(false);
|
|
923
|
+
// controller.abort();
|
|
924
|
+
|
|
925
|
+
// // Add error message
|
|
926
|
+
// messageAnt.error('对话请求失败,请重试');
|
|
927
|
+
// },
|
|
928
|
+
// },
|
|
929
|
+
// );
|
|
930
|
+
// } catch (error) {
|
|
931
|
+
// // 发生异常时清除超时计时器
|
|
932
|
+
// if (timeoutRef.current) {
|
|
933
|
+
// clearTimeout(timeoutRef.current);
|
|
934
|
+
// timeoutRef.current = null;
|
|
935
|
+
// }
|
|
936
|
+
|
|
937
|
+
// console.error('Failed to send message:', error);
|
|
938
|
+
// setLoading(false);
|
|
939
|
+
// }
|
|
940
|
+
// };
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* 停止生成响应
|
|
944
|
+
* @param {Object} params - 参数对象
|
|
945
|
+
* @param {Object} params.controllerRef - AbortController引用
|
|
946
|
+
* @param {Object} params.timeoutRef - 超时计时器引用
|
|
947
|
+
* @param {Function} params.setLoading - 设置加载状态的函数
|
|
948
|
+
* @param {Function} params.setMessages - 设置消息列表的函数
|
|
949
|
+
*/
|
|
950
|
+
// export const handleStopGenerate = ({ controllerRef, timeoutRef, setLoading, setMessages }) => {
|
|
951
|
+
// if (controllerRef.current) {
|
|
952
|
+
// controllerRef.current.abort();
|
|
953
|
+
// controllerRef.current = null;
|
|
954
|
+
// setLoading(false);
|
|
955
|
+
// }
|
|
956
|
+
|
|
957
|
+
// // 清除超时计时器
|
|
958
|
+
// if (timeoutRef.current) {
|
|
959
|
+
// clearTimeout(timeoutRef.current);
|
|
960
|
+
// timeoutRef.current = null;
|
|
961
|
+
// }
|
|
962
|
+
|
|
963
|
+
// // Turn off loading state for the last AI message
|
|
964
|
+
// setMessages((prev) => {
|
|
965
|
+
// const updatedMessages = [...prev];
|
|
966
|
+
// // Find the last AI message
|
|
967
|
+
// const aiMessageIndex = updatedMessages.findIndex((msg) => msg.status === 'ai' && msg.loading);
|
|
968
|
+
|
|
969
|
+
// if (aiMessageIndex !== -1) {
|
|
970
|
+
// updatedMessages[aiMessageIndex].loading = false;
|
|
971
|
+
// }
|
|
972
|
+
|
|
973
|
+
// return updatedMessages;
|
|
974
|
+
// });
|
|
975
|
+
// };
|
|
976
|
+
//# sourceMappingURL=chat.js.map
|