@ai-group/chat-sdk 3.6.3 → 3.6.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/dist/cjs/components/FileGallery/index.d.ts +0 -30
- package/dist/cjs/components/FileGallery/index.js +287 -209
- package/dist/cjs/components/FileGallery/index.js.map +2 -2
- package/dist/cjs/components/FileGallery/styles.d.ts +5 -0
- package/dist/cjs/components/FileGallery/styles.js +106 -0
- package/dist/cjs/components/FileGallery/styles.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/compound/Sender.js +3 -2
- package/dist/cjs/components/XAdkProvider/compound/Sender.js.map +2 -2
- package/dist/cjs/components/XAdkSender/index.js +1 -0
- package/dist/cjs/components/XAdkSender/index.js.map +2 -2
- package/dist/cjs/hooks/useADKChat.js +392 -157
- package/dist/cjs/hooks/useADKChat.js.map +3 -3
- package/dist/cjs/types/FileGallery.d.ts +41 -0
- package/dist/cjs/types/FileGallery.js.map +1 -1
- package/dist/cjs/types/XAdkProvider.d.ts +4 -0
- package/dist/cjs/types/XAdkProvider.js.map +1 -1
- package/dist/esm/components/FileGallery/index.d.ts +0 -30
- package/dist/esm/components/FileGallery/index.js +362 -364
- package/dist/esm/components/FileGallery/index.js.map +1 -1
- package/dist/esm/components/FileGallery/styles.d.ts +5 -0
- package/dist/esm/components/FileGallery/styles.js +10 -2
- package/dist/esm/components/FileGallery/styles.js.map +1 -1
- package/dist/esm/components/XAdkProvider/compound/Sender.js +5 -3
- package/dist/esm/components/XAdkProvider/compound/Sender.js.map +1 -1
- package/dist/esm/components/XAdkSender/index.js +1 -0
- package/dist/esm/components/XAdkSender/index.js.map +1 -1
- package/dist/esm/hooks/useADKChat.js +347 -130
- package/dist/esm/hooks/useADKChat.js.map +1 -1
- package/dist/esm/types/FileGallery.d.ts +41 -0
- package/dist/esm/types/FileGallery.js.map +1 -1
- package/dist/esm/types/XAdkProvider.d.ts +4 -0
- package/dist/esm/types/XAdkProvider.js.map +1 -1
- package/dist/umd/chat-sdk.min.js +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
2
2
|
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
|
-
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
4
3
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
4
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
5
5
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
6
6
|
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
|
|
7
7
|
import { useEffect, useCallback, useMemo, useRef, useState } from "react";
|
|
@@ -44,10 +44,196 @@ var combineTextParts = function combineTextParts(parts) {
|
|
|
44
44
|
}
|
|
45
45
|
return result;
|
|
46
46
|
};
|
|
47
|
+
var DEFAULT_SESSION_EVENTS_POLLING_INTERVAL = 10000;
|
|
48
|
+
var getMessageEventId = function getMessageEventId(messageItem) {
|
|
49
|
+
var _messageItem$raw;
|
|
50
|
+
return messageItem.eventId || ((_messageItem$raw = messageItem.raw) === null || _messageItem$raw === void 0 ? void 0 : _messageItem$raw.id);
|
|
51
|
+
};
|
|
52
|
+
var mapSessionMessages = function mapSessionMessages(sessionEvents) {
|
|
53
|
+
var mapped = [];
|
|
54
|
+
sessionEvents.forEach(function (item) {
|
|
55
|
+
if (!item || !item.content || !Array.isArray(item.content.parts)) return;
|
|
56
|
+
// 后端为异步任务插入的用户事件仅用于关联任务,不在页面展示。
|
|
57
|
+
if (item.author === "user" && item.content.parts.some(function (part) {
|
|
58
|
+
return part.task;
|
|
59
|
+
})) return;
|
|
60
|
+
var role = (item.content.role || "").toLowerCase() === "user" ? "user" : "bot";
|
|
61
|
+
var parts = item.content.parts.filter(function (part) {
|
|
62
|
+
if (!part) return false;
|
|
63
|
+
return Boolean(part.text || part.inlineData || part.functionCall || part.functionResponse || part.fileData || part.executableCode || part.codeExecutionResult || part.errorMessage);
|
|
64
|
+
});
|
|
65
|
+
if (parts.length === 0) return;
|
|
66
|
+
var textParts = parts.filter(function (part) {
|
|
67
|
+
return part.text || part.errorMessage || part.inlineData;
|
|
68
|
+
});
|
|
69
|
+
var fileDataParts = parts.filter(function (part) {
|
|
70
|
+
return part.fileData;
|
|
71
|
+
});
|
|
72
|
+
var otherParts = parts.filter(function (part) {
|
|
73
|
+
return !part.text && !part.errorMessage && !part.inlineData && !part.fileData;
|
|
74
|
+
});
|
|
75
|
+
if (textParts.length > 0 || fileDataParts.length > 0) {
|
|
76
|
+
var messageItem = {
|
|
77
|
+
id: v4(),
|
|
78
|
+
author: item.author,
|
|
79
|
+
invocationId: item.invocationId,
|
|
80
|
+
eventId: item.id,
|
|
81
|
+
timestamp: item.timestamp,
|
|
82
|
+
isLike: item.isLike,
|
|
83
|
+
role: role,
|
|
84
|
+
modelCode: item.modelCode,
|
|
85
|
+
usageMetadata: item.usageMetadata,
|
|
86
|
+
finishReason: item.finishReason,
|
|
87
|
+
raw: item
|
|
88
|
+
};
|
|
89
|
+
textParts.forEach(function (part) {
|
|
90
|
+
if (part.inlineData) {
|
|
91
|
+
messageItem.inlineData = {
|
|
92
|
+
displayName: part.inlineData.displayName,
|
|
93
|
+
data: part.inlineData.data,
|
|
94
|
+
mimeType: part.inlineData.mimeType
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (part.text) {
|
|
98
|
+
messageItem.text = (messageItem.text ? "".concat(messageItem.text, "\n") : "") + part.text;
|
|
99
|
+
if (typeof part.thought !== "undefined") messageItem.thought = part.thought;
|
|
100
|
+
}
|
|
101
|
+
if (part.errorMessage) {
|
|
102
|
+
messageItem.text = (messageItem.text ? "".concat(messageItem.text, "\n") : "") + part.errorMessage;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
if (fileDataParts.length > 0) {
|
|
106
|
+
messageItem.fileData = fileDataParts.map(function (part) {
|
|
107
|
+
return {
|
|
108
|
+
displayName: part.fileData.displayName || "",
|
|
109
|
+
fileUri: part.fileData.fileUri,
|
|
110
|
+
mimeType: part.fileData.mimeType
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
mapped.push(messageItem);
|
|
115
|
+
}
|
|
116
|
+
otherParts.forEach(function (part) {
|
|
117
|
+
var messageItem = {
|
|
118
|
+
id: v4(),
|
|
119
|
+
author: item.author,
|
|
120
|
+
invocationId: item.invocationId,
|
|
121
|
+
eventId: item.id,
|
|
122
|
+
timestamp: item.timestamp,
|
|
123
|
+
isLike: item.isLike,
|
|
124
|
+
role: role,
|
|
125
|
+
modelCode: item.modelCode,
|
|
126
|
+
usageMetadata: item.usageMetadata,
|
|
127
|
+
finishReason: item.finishReason,
|
|
128
|
+
raw: item
|
|
129
|
+
};
|
|
130
|
+
if (part.functionCall) messageItem.functionCall = part.functionCall;
|
|
131
|
+
if (part.executableCode) messageItem.executableCode = part.executableCode;
|
|
132
|
+
if (part.codeExecutionResult) messageItem.codeExecutionResult = part.codeExecutionResult;
|
|
133
|
+
if (part.functionResponse) {
|
|
134
|
+
var functionCallMessage = mapped.find(function (currentMessage) {
|
|
135
|
+
var _currentMessage$funct, _part$functionRespons;
|
|
136
|
+
return ((_currentMessage$funct = currentMessage.functionCall) === null || _currentMessage$funct === void 0 ? void 0 : _currentMessage$funct.id) === ((_part$functionRespons = part.functionResponse) === null || _part$functionRespons === void 0 ? void 0 : _part$functionRespons.id);
|
|
137
|
+
});
|
|
138
|
+
if (functionCallMessage) {
|
|
139
|
+
functionCallMessage.functionResponse = part.functionResponse;
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
mapped.push(messageItem);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
return mapped;
|
|
147
|
+
};
|
|
148
|
+
var getComparableMessageContent = function getComparableMessageContent(messageItem) {
|
|
149
|
+
var _messageItem$text;
|
|
150
|
+
return JSON.stringify({
|
|
151
|
+
role: messageItem.role,
|
|
152
|
+
text: ((_messageItem$text = messageItem.text) === null || _messageItem$text === void 0 ? void 0 : _messageItem$text.replace(/\r\n/g, "\n").trim()) || "",
|
|
153
|
+
thought: Boolean(messageItem.thought),
|
|
154
|
+
inlineData: messageItem.inlineData || null,
|
|
155
|
+
fileData: messageItem.fileData || null,
|
|
156
|
+
functionCall: messageItem.functionCall || null,
|
|
157
|
+
functionResponse: messageItem.functionResponse || null,
|
|
158
|
+
executableCode: messageItem.executableCode || null,
|
|
159
|
+
codeExecutionResult: messageItem.codeExecutionResult || null
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
var isStreamMessageWithoutServerEventId = function isStreamMessageWithoutServerEventId(messageItem) {
|
|
163
|
+
var eventId = getMessageEventId(messageItem);
|
|
164
|
+
return Boolean(messageItem.invocationId) && (!eventId || eventId === messageItem.invocationId);
|
|
165
|
+
};
|
|
166
|
+
var insertMissingSessionEvents = function insertMissingSessionEvents(currentMessages, sessionEvents) {
|
|
167
|
+
var renderedEventIds = new Set(currentMessages.map(getMessageEventId).filter(Boolean));
|
|
168
|
+
var unmatchedStreamMessageIndexes = new Set(currentMessages.map(function (messageItem, index) {
|
|
169
|
+
return isStreamMessageWithoutServerEventId(messageItem) ? index : -1;
|
|
170
|
+
}).filter(function (index) {
|
|
171
|
+
return index >= 0;
|
|
172
|
+
}));
|
|
173
|
+
var missingEvents = sessionEvents.filter(function (event) {
|
|
174
|
+
var _event$content, _event$content2;
|
|
175
|
+
var parts = (_event$content = event.content) === null || _event$content === void 0 ? void 0 : _event$content.parts;
|
|
176
|
+
var canRender = Boolean(event.id) && ((_event$content2 = event.content) === null || _event$content2 === void 0 ? void 0 : _event$content2.role) === "model" && Array.isArray(parts) && parts.length > 0;
|
|
177
|
+
if (!canRender || renderedEventIds.has(event.id)) return false;
|
|
178
|
+
|
|
179
|
+
// 新版 SSE 包装数据没有事件 id,只能临时使用 invocationId。
|
|
180
|
+
// 用 invocationId + 完整渲染内容做一次性身份对齐,避免会话轮询重复插入;
|
|
181
|
+
// 同 invocation 下内容不同或后续出现的事件,仍然按独立 event.id 补入。
|
|
182
|
+
var eventMessages = mapSessionMessages([event]);
|
|
183
|
+
var matchedIndexes = [];
|
|
184
|
+
var isRenderedByStream = eventMessages.length > 0 && eventMessages.every(function (eventMessage) {
|
|
185
|
+
var comparableContent = getComparableMessageContent(eventMessage);
|
|
186
|
+
var matchedIndex = currentMessages.findIndex(function (currentMessage, index) {
|
|
187
|
+
return unmatchedStreamMessageIndexes.has(index) && !matchedIndexes.includes(index) && currentMessage.invocationId === eventMessage.invocationId && getComparableMessageContent(currentMessage) === comparableContent;
|
|
188
|
+
});
|
|
189
|
+
if (matchedIndex < 0) return false;
|
|
190
|
+
matchedIndexes.push(matchedIndex);
|
|
191
|
+
return true;
|
|
192
|
+
});
|
|
193
|
+
if (isRenderedByStream) {
|
|
194
|
+
matchedIndexes.forEach(function (index) {
|
|
195
|
+
return unmatchedStreamMessageIndexes.delete(index);
|
|
196
|
+
});
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
return true;
|
|
200
|
+
});
|
|
201
|
+
if (missingEvents.length === 0) return currentMessages;
|
|
202
|
+
var missingMessages = mapSessionMessages(missingEvents);
|
|
203
|
+
if (missingMessages.length === 0) return currentMessages;
|
|
204
|
+
var eventOrder = new Map(sessionEvents.map(function (event, index) {
|
|
205
|
+
return [event.id, index];
|
|
206
|
+
}));
|
|
207
|
+
var getMessageOrder = function getMessageOrder(messageItem) {
|
|
208
|
+
var _messageItem$timestam, _messageItem$raw2;
|
|
209
|
+
var eventId = getMessageEventId(messageItem);
|
|
210
|
+
if (eventId && eventOrder.has(eventId)) return eventOrder.get(eventId);
|
|
211
|
+
var timestamp = (_messageItem$timestam = messageItem.timestamp) !== null && _messageItem$timestam !== void 0 ? _messageItem$timestam : (_messageItem$raw2 = messageItem.raw) === null || _messageItem$raw2 === void 0 ? void 0 : _messageItem$raw2.timestamp;
|
|
212
|
+
if (timestamp !== undefined) {
|
|
213
|
+
var nextEventIndex = sessionEvents.findIndex(function (event) {
|
|
214
|
+
return (event.timestamp || 0) > timestamp;
|
|
215
|
+
});
|
|
216
|
+
return nextEventIndex < 0 ? sessionEvents.length + 0.5 : nextEventIndex - 0.5;
|
|
217
|
+
}
|
|
218
|
+
return Number.POSITIVE_INFINITY;
|
|
219
|
+
};
|
|
220
|
+
var nextMessages = _toConsumableArray(currentMessages);
|
|
221
|
+
missingMessages.forEach(function (messageItem) {
|
|
222
|
+
var targetOrder = getMessageOrder(messageItem);
|
|
223
|
+
var insertIndex = nextMessages.findIndex(function (currentMessage) {
|
|
224
|
+
var currentOrder = getMessageOrder(currentMessage);
|
|
225
|
+
return Number.isFinite(currentOrder) && currentOrder > targetOrder;
|
|
226
|
+
});
|
|
227
|
+
if (insertIndex < 0) insertIndex = nextMessages.length;
|
|
228
|
+
nextMessages.splice(insertIndex, 0, messageItem);
|
|
229
|
+
});
|
|
230
|
+
return nextMessages;
|
|
231
|
+
};
|
|
47
232
|
|
|
48
233
|
// 后台会话连接状态
|
|
49
234
|
|
|
50
235
|
function useADKChat(_ref) {
|
|
236
|
+
var _config$session$pollS, _config$session, _config$session$sessi, _config$session2;
|
|
51
237
|
var _ref$url = _ref.url,
|
|
52
238
|
url = _ref$url === void 0 ? window.location.origin : _ref$url,
|
|
53
239
|
token = _ref.token,
|
|
@@ -65,7 +251,12 @@ function useADKChat(_ref) {
|
|
|
65
251
|
var _useState = useState(false),
|
|
66
252
|
_useState2 = _slicedToArray(_useState, 2),
|
|
67
253
|
loading = _useState2[0],
|
|
68
|
-
|
|
254
|
+
setLoadingState = _useState2[1];
|
|
255
|
+
var loadingRef = useRef(false);
|
|
256
|
+
var setLoading = useCallback(function (nextLoading) {
|
|
257
|
+
loadingRef.current = nextLoading;
|
|
258
|
+
setLoadingState(nextLoading);
|
|
259
|
+
}, []);
|
|
69
260
|
var _useState3 = useState(false),
|
|
70
261
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
71
262
|
sessionLoading = _useState4[0],
|
|
@@ -78,6 +269,8 @@ function useADKChat(_ref) {
|
|
|
78
269
|
var _ref2 = config || {},
|
|
79
270
|
appNo = _ref2.appNo,
|
|
80
271
|
showFirstSession = _ref2.showFirstSession;
|
|
272
|
+
var pollSessionEvents = (_config$session$pollS = config === null || config === void 0 || (_config$session = config.session) === null || _config$session === void 0 ? void 0 : _config$session.pollSessionEvents) !== null && _config$session$pollS !== void 0 ? _config$session$pollS : true;
|
|
273
|
+
var sessionEventsPollingInterval = Math.max((_config$session$sessi = config === null || config === void 0 || (_config$session2 = config.session) === null || _config$session2 === void 0 ? void 0 : _config$session2.sessionEventsPollingInterval) !== null && _config$session$sessi !== void 0 ? _config$session$sessi : DEFAULT_SESSION_EVENTS_POLLING_INTERVAL, 1000);
|
|
81
274
|
var _useState5 = useState(null),
|
|
82
275
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
83
276
|
appInfo = _useState6[0],
|
|
@@ -122,6 +315,10 @@ function useADKChat(_ref) {
|
|
|
122
315
|
_useState20 = _slicedToArray(_useState19, 2),
|
|
123
316
|
messages = _useState20[0],
|
|
124
317
|
setMessages = _useState20[1];
|
|
318
|
+
var pendingSessionEventsRef = useRef(null);
|
|
319
|
+
var sessionEventsFlushTimerRef = useRef(null);
|
|
320
|
+
var sessionEventsSyncingRef = useRef(false);
|
|
321
|
+
var sessionDetailLoadingRef = useRef(false);
|
|
125
322
|
// 用户自定义业务参数 (stateDelta),每次发送请求时携带
|
|
126
323
|
var stateDeltaRef = useRef(undefined);
|
|
127
324
|
|
|
@@ -151,6 +348,52 @@ function useADKChat(_ref) {
|
|
|
151
348
|
}, [messages]);
|
|
152
349
|
var textMsgRef = useRef(null);
|
|
153
350
|
var eventDataRef = useRef(new Map());
|
|
351
|
+
var cancelSessionEventsFlush = useCallback(function () {
|
|
352
|
+
if (sessionEventsFlushTimerRef.current === null) return;
|
|
353
|
+
clearTimeout(sessionEventsFlushTimerRef.current);
|
|
354
|
+
sessionEventsFlushTimerRef.current = null;
|
|
355
|
+
}, []);
|
|
356
|
+
var flushPendingSessionEvents = useCallback(function () {
|
|
357
|
+
var pending = pendingSessionEventsRef.current;
|
|
358
|
+
var replyInProgress = loadingRef.current || sendingRef.current || textMsgRef.current !== null;
|
|
359
|
+
if (!pending || replyInProgress || pending.sessionId !== currentSessionIdRef.current) return;
|
|
360
|
+
var previewMessages = insertMissingSessionEvents(messagesRef.current, pending.events);
|
|
361
|
+
pendingSessionEventsRef.current = null;
|
|
362
|
+
if (previewMessages === messagesRef.current) return;
|
|
363
|
+
sessionEventsSyncingRef.current = true;
|
|
364
|
+
setLoading(true);
|
|
365
|
+
sessionEventsFlushTimerRef.current = setTimeout(function () {
|
|
366
|
+
sessionEventsFlushTimerRef.current = null;
|
|
367
|
+
if (pending.sessionId === currentSessionIdRef.current) {
|
|
368
|
+
setMessages(function (prev) {
|
|
369
|
+
var nextMessages = insertMissingSessionEvents(prev, pending.events);
|
|
370
|
+
messagesRef.current = nextMessages;
|
|
371
|
+
return nextMessages;
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
sessionEventsSyncingRef.current = false;
|
|
375
|
+
setLoading(false);
|
|
376
|
+
}, 0);
|
|
377
|
+
}, [setLoading]);
|
|
378
|
+
var syncSessionEvents = useCallback(function (events, targetSessionId) {
|
|
379
|
+
if (targetSessionId !== currentSessionIdRef.current) return;
|
|
380
|
+
pendingSessionEventsRef.current = {
|
|
381
|
+
sessionId: targetSessionId,
|
|
382
|
+
events: events
|
|
383
|
+
};
|
|
384
|
+
flushPendingSessionEvents();
|
|
385
|
+
}, [flushPendingSessionEvents]);
|
|
386
|
+
useEffect(function () {
|
|
387
|
+
pendingSessionEventsRef.current = null;
|
|
388
|
+
cancelSessionEventsFlush();
|
|
389
|
+
if (sessionEventsSyncingRef.current) {
|
|
390
|
+
sessionEventsSyncingRef.current = false;
|
|
391
|
+
setLoading(false);
|
|
392
|
+
}
|
|
393
|
+
}, [cancelSessionEventsFlush, currentSessionId, setLoading]);
|
|
394
|
+
useEffect(function () {
|
|
395
|
+
if (!loading) flushPendingSessionEvents();
|
|
396
|
+
}, [flushPendingSessionEvents, loading]);
|
|
154
397
|
|
|
155
398
|
// 插入消息
|
|
156
399
|
var insertMessage = useCallback(function (msg) {
|
|
@@ -345,9 +588,9 @@ function useADKChat(_ref) {
|
|
|
345
588
|
|
|
346
589
|
// 处理建议类消息
|
|
347
590
|
var processFollowupPart = useCallback(function (event) {
|
|
348
|
-
var _event$
|
|
591
|
+
var _event$content3;
|
|
349
592
|
// 获取建议类消息的文本内容
|
|
350
|
-
var part = (event === null || event === void 0 || (_event$
|
|
593
|
+
var part = (event === null || event === void 0 || (_event$content3 = event.content) === null || _event$content3 === void 0 || (_event$content3 = _event$content3.parts) === null || _event$content3 === void 0 ? void 0 : _event$content3[0]) || null;
|
|
351
594
|
var text = (part === null || part === void 0 ? void 0 : part.text) || "";
|
|
352
595
|
storeEvents(part, event);
|
|
353
596
|
if (text) {
|
|
@@ -449,7 +692,7 @@ function useADKChat(_ref) {
|
|
|
449
692
|
content: rawData.data,
|
|
450
693
|
invocationId: rawData.result.invocationId,
|
|
451
694
|
sessionId: rawData.result.sessionId,
|
|
452
|
-
id: rawData.result.invocationId
|
|
695
|
+
id: rawData.data.id || rawData.result.id || rawData.result.eventId || rawData.result.invocationId
|
|
453
696
|
});
|
|
454
697
|
}
|
|
455
698
|
if (chunkJson.error) {
|
|
@@ -605,7 +848,7 @@ function useADKChat(_ref) {
|
|
|
605
848
|
while (1) switch (_context2.prev = _context2.next) {
|
|
606
849
|
case 0:
|
|
607
850
|
_ref3$text = _ref3.text, text = _ref3$text === void 0 ? "" : _ref3$text, _ref3$files = _ref3.files, files = _ref3$files === void 0 ? [] : _ref3$files, functionResponse = _ref3.functionResponse;
|
|
608
|
-
if (!(
|
|
851
|
+
if (!(loadingRef.current || sendingRef.current)) {
|
|
609
852
|
_context2.next = 3;
|
|
610
853
|
break;
|
|
611
854
|
}
|
|
@@ -707,7 +950,7 @@ function useADKChat(_ref) {
|
|
|
707
950
|
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
708
951
|
while (1) switch (_context3.prev = _context3.next) {
|
|
709
952
|
case 0:
|
|
710
|
-
if (!(
|
|
953
|
+
if (!(loadingRef.current || sendingRef.current)) {
|
|
711
954
|
_context3.next = 2;
|
|
712
955
|
break;
|
|
713
956
|
}
|
|
@@ -791,7 +1034,7 @@ function useADKChat(_ref) {
|
|
|
791
1034
|
|
|
792
1035
|
// 使用建议问题
|
|
793
1036
|
var suggestChat = function suggestChat(text) {
|
|
794
|
-
if (
|
|
1037
|
+
if (loadingRef.current) return;
|
|
795
1038
|
if (!text.trim()) return;
|
|
796
1039
|
setSuggestedQuestions([]);
|
|
797
1040
|
startChat({
|
|
@@ -802,11 +1045,14 @@ function useADKChat(_ref) {
|
|
|
802
1045
|
// 停止会话(只中断前台连接)
|
|
803
1046
|
var stopChat = useCallback(function () {
|
|
804
1047
|
var _ctrl$current;
|
|
1048
|
+
pendingSessionEventsRef.current = null;
|
|
1049
|
+
cancelSessionEventsFlush();
|
|
1050
|
+
sessionEventsSyncingRef.current = false;
|
|
805
1051
|
(_ctrl$current = ctrl.current) === null || _ctrl$current === void 0 || _ctrl$current.abort();
|
|
806
1052
|
ctrl.current = null;
|
|
807
1053
|
setLoading(false);
|
|
808
1054
|
textMsgRef.current = null;
|
|
809
|
-
}, []);
|
|
1055
|
+
}, [cancelSessionEventsFlush, setLoading]);
|
|
810
1056
|
|
|
811
1057
|
// 清除/重置会话
|
|
812
1058
|
var clearChat = function clearChat() {
|
|
@@ -821,118 +1067,13 @@ function useADKChat(_ref) {
|
|
|
821
1067
|
};
|
|
822
1068
|
|
|
823
1069
|
// 格式化会话记录
|
|
824
|
-
var formatMessages = function
|
|
1070
|
+
var formatMessages = useCallback(function (sessionEvents) {
|
|
825
1071
|
var isReplace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
826
|
-
var mapped =
|
|
827
|
-
messages.forEach(function (item) {
|
|
828
|
-
if (!item || !item.content || !Array.isArray(item.content.parts)) return;
|
|
829
|
-
var role = (item.content.role || "").toLowerCase() === "user" ? "user" : "bot";
|
|
830
|
-
var parts = Array.isArray(item.content.parts) ? item.content.parts.filter(function (p) {
|
|
831
|
-
if (!p) return false;
|
|
832
|
-
return Boolean(p.text || p.inlineData || p.functionCall || p.functionResponse || p.fileData || p.executableCode || p.codeExecutionResult || p.errorMessage);
|
|
833
|
-
}) : [];
|
|
834
|
-
if (parts.length === 0) return;
|
|
835
|
-
|
|
836
|
-
// 将同一条历史消息的 text/fileData parts 合并到一条 IMessage,避免拆分显示
|
|
837
|
-
var textParts = parts.filter(function (p) {
|
|
838
|
-
return p.text || p.errorMessage || p.inlineData;
|
|
839
|
-
});
|
|
840
|
-
var fileDataParts = parts.filter(function (p) {
|
|
841
|
-
return p.fileData;
|
|
842
|
-
});
|
|
843
|
-
var otherParts = parts.filter(function (p) {
|
|
844
|
-
return !p.text && !p.errorMessage && !p.inlineData && !p.fileData;
|
|
845
|
-
});
|
|
846
|
-
|
|
847
|
-
// 如果有 text/fileData,合并为一条消息
|
|
848
|
-
if (textParts.length > 0 || fileDataParts.length > 0) {
|
|
849
|
-
var msg = {
|
|
850
|
-
id: v4(),
|
|
851
|
-
author: item.author,
|
|
852
|
-
invocationId: item.invocationId,
|
|
853
|
-
eventId: item.id,
|
|
854
|
-
timestamp: item.timestamp,
|
|
855
|
-
isLike: item.isLike,
|
|
856
|
-
role: role,
|
|
857
|
-
modelCode: item.modelCode,
|
|
858
|
-
usageMetadata: item.usageMetadata,
|
|
859
|
-
finishReason: item.finishReason,
|
|
860
|
-
raw: item
|
|
861
|
-
};
|
|
862
|
-
var _iterator4 = _createForOfIteratorHelper(textParts),
|
|
863
|
-
_step4;
|
|
864
|
-
try {
|
|
865
|
-
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
866
|
-
var part = _step4.value;
|
|
867
|
-
if (part.inlineData) {
|
|
868
|
-
msg.inlineData = {
|
|
869
|
-
displayName: part.inlineData.displayName,
|
|
870
|
-
data: part.inlineData.data,
|
|
871
|
-
mimeType: part.inlineData.mimeType
|
|
872
|
-
};
|
|
873
|
-
}
|
|
874
|
-
if (part.text) {
|
|
875
|
-
msg.text = (msg.text ? msg.text + "\n" : "") + part.text;
|
|
876
|
-
if (typeof part.thought !== "undefined") msg.thought = part.thought;
|
|
877
|
-
}
|
|
878
|
-
if (part.errorMessage) {
|
|
879
|
-
msg.text = (msg.text ? msg.text + "\n" : "") + part.errorMessage;
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
} catch (err) {
|
|
883
|
-
_iterator4.e(err);
|
|
884
|
-
} finally {
|
|
885
|
-
_iterator4.f();
|
|
886
|
-
}
|
|
887
|
-
if (fileDataParts.length > 0) {
|
|
888
|
-
msg.fileData = fileDataParts.map(function (part) {
|
|
889
|
-
return {
|
|
890
|
-
displayName: part.fileData.displayName || "",
|
|
891
|
-
fileUri: part.fileData.fileUri,
|
|
892
|
-
mimeType: part.fileData.mimeType
|
|
893
|
-
};
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
mapped.push(msg);
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
// 处理其他类型的 parts(functionCall、executableCode 等)
|
|
900
|
-
otherParts.forEach(function (part) {
|
|
901
|
-
var msg = {
|
|
902
|
-
id: v4(),
|
|
903
|
-
author: item.author,
|
|
904
|
-
invocationId: item.invocationId,
|
|
905
|
-
eventId: item.id,
|
|
906
|
-
timestamp: item.timestamp,
|
|
907
|
-
isLike: item.isLike,
|
|
908
|
-
role: role,
|
|
909
|
-
modelCode: item.modelCode,
|
|
910
|
-
usageMetadata: item.usageMetadata,
|
|
911
|
-
finishReason: item.finishReason,
|
|
912
|
-
raw: item
|
|
913
|
-
};
|
|
914
|
-
if (part.functionCall) msg.functionCall = part.functionCall;
|
|
915
|
-
if (part.executableCode) msg.executableCode = part.executableCode;
|
|
916
|
-
if (part.codeExecutionResult) msg.codeExecutionResult = part.codeExecutionResult;
|
|
917
|
-
// 补全函数调用结果
|
|
918
|
-
if (part.functionResponse) {
|
|
919
|
-
// 通过 functionCall.id 寻找对应的函数调用消息,在那条消息上添加functionResponse
|
|
920
|
-
var functionCallMsg = mapped.find(function (msg) {
|
|
921
|
-
var _msg$functionCall2, _part$functionRespons;
|
|
922
|
-
return ((_msg$functionCall2 = msg.functionCall) === null || _msg$functionCall2 === void 0 ? void 0 : _msg$functionCall2.id) === ((_part$functionRespons = part.functionResponse) === null || _part$functionRespons === void 0 ? void 0 : _part$functionRespons.id);
|
|
923
|
-
});
|
|
924
|
-
if (functionCallMsg) {
|
|
925
|
-
functionCallMsg.functionResponse = part.functionResponse;
|
|
926
|
-
}
|
|
927
|
-
return;
|
|
928
|
-
}
|
|
929
|
-
mapped.push(msg);
|
|
930
|
-
});
|
|
931
|
-
});
|
|
1072
|
+
var mapped = mapSessionMessages(sessionEvents);
|
|
932
1073
|
setMessages(function (prev) {
|
|
933
|
-
return isReplace ? mapped : [].concat(_toConsumableArray(prev), mapped);
|
|
1074
|
+
return isReplace ? mapped : [].concat(_toConsumableArray(prev), _toConsumableArray(mapped));
|
|
934
1075
|
});
|
|
935
|
-
};
|
|
1076
|
+
}, []);
|
|
936
1077
|
|
|
937
1078
|
// 设置当前会话详情
|
|
938
1079
|
var setCurrentSession = /*#__PURE__*/function () {
|
|
@@ -942,7 +1083,7 @@ function useADKChat(_ref) {
|
|
|
942
1083
|
while (1) switch (_context4.prev = _context4.next) {
|
|
943
1084
|
case 0:
|
|
944
1085
|
if (!sessionId) {
|
|
945
|
-
_context4.next =
|
|
1086
|
+
_context4.next = 34;
|
|
946
1087
|
break;
|
|
947
1088
|
}
|
|
948
1089
|
if (!(sessionId === currentSessionId)) {
|
|
@@ -951,6 +1092,13 @@ function useADKChat(_ref) {
|
|
|
951
1092
|
}
|
|
952
1093
|
return _context4.abrupt("return");
|
|
953
1094
|
case 3:
|
|
1095
|
+
pendingSessionEventsRef.current = null;
|
|
1096
|
+
cancelSessionEventsFlush();
|
|
1097
|
+
if (sessionEventsSyncingRef.current) {
|
|
1098
|
+
sessionEventsSyncingRef.current = false;
|
|
1099
|
+
setLoading(false);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
954
1102
|
// 1. 将当前会话挂起到后台(不中断 SSE 连接)
|
|
955
1103
|
prevSessionId = currentSessionId;
|
|
956
1104
|
if (ctrl.current) {
|
|
@@ -977,7 +1125,7 @@ function useADKChat(_ref) {
|
|
|
977
1125
|
// 2. 尝试从后台恢复目标会话
|
|
978
1126
|
bg = backgroundRef.current.get(sessionId);
|
|
979
1127
|
if (!bg) {
|
|
980
|
-
_context4.next =
|
|
1128
|
+
_context4.next = 18;
|
|
981
1129
|
break;
|
|
982
1130
|
}
|
|
983
1131
|
setMessages(bg.messages);
|
|
@@ -988,18 +1136,20 @@ function useADKChat(_ref) {
|
|
|
988
1136
|
setInitialized(true);
|
|
989
1137
|
backgroundRef.current.delete(sessionId);
|
|
990
1138
|
return _context4.abrupt("return");
|
|
991
|
-
case
|
|
1139
|
+
case 18:
|
|
992
1140
|
// 3. 后台没有目标 session,走 API 加载(原有逻辑)
|
|
993
1141
|
setInitialized(false);
|
|
994
1142
|
setCurrentSessionId(sessionId);
|
|
995
|
-
|
|
1143
|
+
sessionDetailLoadingRef.current = true;
|
|
1144
|
+
_context4.prev = 21;
|
|
1145
|
+
_context4.next = 24;
|
|
996
1146
|
return fetchSessionDetail({
|
|
997
1147
|
url: url,
|
|
998
1148
|
appNo: appNo,
|
|
999
1149
|
sessionId: sessionId,
|
|
1000
1150
|
token: tokenRef.current
|
|
1001
1151
|
});
|
|
1002
|
-
case
|
|
1152
|
+
case 24:
|
|
1003
1153
|
_yield$fetchSessionDe = _context4.sent;
|
|
1004
1154
|
data = _yield$fetchSessionDe.data;
|
|
1005
1155
|
result = _yield$fetchSessionDe.result;
|
|
@@ -1011,16 +1161,21 @@ function useADKChat(_ref) {
|
|
|
1011
1161
|
setSuggestedQuestions((appInfo === null || appInfo === void 0 || (_appInfo$onboardingIn4 = appInfo.onboardingInfo) === null || _appInfo$onboardingIn4 === void 0 ? void 0 : _appInfo$onboardingIn4.suggested_questions) || []);
|
|
1012
1162
|
}
|
|
1013
1163
|
}
|
|
1164
|
+
case 28:
|
|
1165
|
+
_context4.prev = 28;
|
|
1166
|
+
sessionDetailLoadingRef.current = false;
|
|
1014
1167
|
setInitialized(true);
|
|
1015
|
-
_context4.
|
|
1168
|
+
return _context4.finish(28);
|
|
1169
|
+
case 32:
|
|
1170
|
+
_context4.next = 35;
|
|
1016
1171
|
break;
|
|
1017
|
-
case
|
|
1172
|
+
case 34:
|
|
1018
1173
|
setCurrentSessionId(v4());
|
|
1019
|
-
case
|
|
1174
|
+
case 35:
|
|
1020
1175
|
case "end":
|
|
1021
1176
|
return _context4.stop();
|
|
1022
1177
|
}
|
|
1023
|
-
}, _callee4);
|
|
1178
|
+
}, _callee4, null, [[21,, 28, 32]]);
|
|
1024
1179
|
}));
|
|
1025
1180
|
return function setCurrentSession(_x2) {
|
|
1026
1181
|
return _ref6.apply(this, arguments);
|
|
@@ -1104,7 +1259,7 @@ function useADKChat(_ref) {
|
|
|
1104
1259
|
} else {
|
|
1105
1260
|
// 服务端业务错误,透传原始 code + message 给接入方自行处理
|
|
1106
1261
|
onError === null || onError === void 0 || onError({
|
|
1107
|
-
code: (result === null || result === void 0 ? void 0 : result.code) ||
|
|
1262
|
+
code: (result === null || result === void 0 ? void 0 : result.code) || "UNKNOWN_ERROR",
|
|
1108
1263
|
message: (result === null || result === void 0 ? void 0 : result.message) || "获取会话列表失败",
|
|
1109
1264
|
raw: result
|
|
1110
1265
|
});
|
|
@@ -1299,7 +1454,7 @@ function useADKChat(_ref) {
|
|
|
1299
1454
|
} else {
|
|
1300
1455
|
// 服务端业务错误,透传原始 code + message
|
|
1301
1456
|
onError === null || onError === void 0 || onError({
|
|
1302
|
-
code: result.code ||
|
|
1457
|
+
code: result.code || "UNKNOWN_ERROR",
|
|
1303
1458
|
message: result.message || "获取应用配置失败",
|
|
1304
1459
|
raw: result
|
|
1305
1460
|
});
|
|
@@ -1343,10 +1498,72 @@ function useADKChat(_ref) {
|
|
|
1343
1498
|
}
|
|
1344
1499
|
}, [appInfo]);
|
|
1345
1500
|
|
|
1501
|
+
// 轮询当前会话详情,空闲时补入后端异步任务产生的模型消息。
|
|
1502
|
+
useEffect(function () {
|
|
1503
|
+
if (!enabled || !initialized || !pollSessionEvents || !appNo || !currentSessionId) return;
|
|
1504
|
+
var disposed = false;
|
|
1505
|
+
var requesting = false;
|
|
1506
|
+
var pollingSessionId = currentSessionId;
|
|
1507
|
+
var poll = /*#__PURE__*/function () {
|
|
1508
|
+
var _ref12 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10() {
|
|
1509
|
+
var _yield$fetchSessionDe2, data, result;
|
|
1510
|
+
return _regeneratorRuntime().wrap(function _callee10$(_context10) {
|
|
1511
|
+
while (1) switch (_context10.prev = _context10.next) {
|
|
1512
|
+
case 0:
|
|
1513
|
+
if (!(requesting || sessionDetailLoadingRef.current)) {
|
|
1514
|
+
_context10.next = 2;
|
|
1515
|
+
break;
|
|
1516
|
+
}
|
|
1517
|
+
return _context10.abrupt("return");
|
|
1518
|
+
case 2:
|
|
1519
|
+
requesting = true;
|
|
1520
|
+
_context10.prev = 3;
|
|
1521
|
+
_context10.next = 6;
|
|
1522
|
+
return fetchSessionDetail({
|
|
1523
|
+
url: url,
|
|
1524
|
+
appNo: appNo,
|
|
1525
|
+
sessionId: pollingSessionId,
|
|
1526
|
+
token: tokenRef.current
|
|
1527
|
+
});
|
|
1528
|
+
case 6:
|
|
1529
|
+
_yield$fetchSessionDe2 = _context10.sent;
|
|
1530
|
+
data = _yield$fetchSessionDe2.data;
|
|
1531
|
+
result = _yield$fetchSessionDe2.result;
|
|
1532
|
+
if (!disposed && (result === null || result === void 0 ? void 0 : result.code) === API_SUCCESS_CODE && Array.isArray(data)) {
|
|
1533
|
+
syncSessionEvents(data, pollingSessionId);
|
|
1534
|
+
}
|
|
1535
|
+
_context10.next = 14;
|
|
1536
|
+
break;
|
|
1537
|
+
case 12:
|
|
1538
|
+
_context10.prev = 12;
|
|
1539
|
+
_context10.t0 = _context10["catch"](3);
|
|
1540
|
+
case 14:
|
|
1541
|
+
_context10.prev = 14;
|
|
1542
|
+
requesting = false;
|
|
1543
|
+
return _context10.finish(14);
|
|
1544
|
+
case 17:
|
|
1545
|
+
case "end":
|
|
1546
|
+
return _context10.stop();
|
|
1547
|
+
}
|
|
1548
|
+
}, _callee10, null, [[3, 12, 14, 17]]);
|
|
1549
|
+
}));
|
|
1550
|
+
return function poll() {
|
|
1551
|
+
return _ref12.apply(this, arguments);
|
|
1552
|
+
};
|
|
1553
|
+
}();
|
|
1554
|
+
void poll();
|
|
1555
|
+
var timer = window.setInterval(poll, sessionEventsPollingInterval);
|
|
1556
|
+
return function () {
|
|
1557
|
+
disposed = true;
|
|
1558
|
+
window.clearInterval(timer);
|
|
1559
|
+
};
|
|
1560
|
+
}, [appNo, currentSessionId, enabled, initialized, pollSessionEvents, sessionEventsPollingInterval, syncSessionEvents, url]);
|
|
1561
|
+
|
|
1346
1562
|
// 组件卸载时清理所有连接(前台 + 后台)
|
|
1347
1563
|
useEffect(function () {
|
|
1348
1564
|
return function () {
|
|
1349
1565
|
var _ctrl$current2;
|
|
1566
|
+
cancelSessionEventsFlush();
|
|
1350
1567
|
(_ctrl$current2 = ctrl.current) === null || _ctrl$current2 === void 0 || _ctrl$current2.abort();
|
|
1351
1568
|
backgroundRef.current.forEach(function (bg) {
|
|
1352
1569
|
var _bg$ctrl;
|
|
@@ -1354,7 +1571,7 @@ function useADKChat(_ref) {
|
|
|
1354
1571
|
});
|
|
1355
1572
|
backgroundRef.current.clear();
|
|
1356
1573
|
};
|
|
1357
|
-
}, []);
|
|
1574
|
+
}, [cancelSessionEventsFlush]);
|
|
1358
1575
|
return {
|
|
1359
1576
|
appInfo: appInfo,
|
|
1360
1577
|
startChat: startChat,
|