@ai-group/chat-sdk 3.6.2 → 3.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/cjs/components/FileGallery/index.d.ts +0 -30
  2. package/dist/cjs/components/FileGallery/index.js +287 -209
  3. package/dist/cjs/components/FileGallery/index.js.map +2 -2
  4. package/dist/cjs/components/FileGallery/styles.d.ts +5 -0
  5. package/dist/cjs/components/FileGallery/styles.js +106 -0
  6. package/dist/cjs/components/FileGallery/styles.js.map +2 -2
  7. package/dist/cjs/components/XAdkProvider/compound/Sender.js +3 -2
  8. package/dist/cjs/components/XAdkProvider/compound/Sender.js.map +2 -2
  9. package/dist/cjs/components/XAdkSender/index.js +1 -0
  10. package/dist/cjs/components/XAdkSender/index.js.map +2 -2
  11. package/dist/cjs/hooks/useADKChat.js +365 -167
  12. package/dist/cjs/hooks/useADKChat.js.map +3 -3
  13. package/dist/cjs/hooks/useAgentGenerator.js +4 -3
  14. package/dist/cjs/hooks/useAgentGenerator.js.map +2 -2
  15. package/dist/cjs/types/FileGallery.d.ts +41 -0
  16. package/dist/cjs/types/FileGallery.js.map +1 -1
  17. package/dist/cjs/types/XAdkProvider.d.ts +4 -0
  18. package/dist/cjs/types/XAdkProvider.js.map +1 -1
  19. package/dist/cjs/types/XAiProvider.d.ts +13 -46
  20. package/dist/cjs/types/XAiProvider.js +2 -25
  21. package/dist/cjs/types/XAiProvider.js.map +3 -3
  22. package/dist/esm/components/FileGallery/index.d.ts +0 -30
  23. package/dist/esm/components/FileGallery/index.js +362 -364
  24. package/dist/esm/components/FileGallery/index.js.map +1 -1
  25. package/dist/esm/components/FileGallery/styles.d.ts +5 -0
  26. package/dist/esm/components/FileGallery/styles.js +10 -2
  27. package/dist/esm/components/FileGallery/styles.js.map +1 -1
  28. package/dist/esm/components/XAdkProvider/compound/Sender.js +5 -3
  29. package/dist/esm/components/XAdkProvider/compound/Sender.js.map +1 -1
  30. package/dist/esm/components/XAdkSender/index.js +1 -0
  31. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  32. package/dist/esm/hooks/useADKChat.js +314 -133
  33. package/dist/esm/hooks/useADKChat.js.map +1 -1
  34. package/dist/esm/hooks/useAgentGenerator.js +4 -3
  35. package/dist/esm/hooks/useAgentGenerator.js.map +1 -1
  36. package/dist/esm/types/FileGallery.d.ts +41 -0
  37. package/dist/esm/types/FileGallery.js.map +1 -1
  38. package/dist/esm/types/XAdkProvider.d.ts +4 -0
  39. package/dist/esm/types/XAdkProvider.js.map +1 -1
  40. package/dist/esm/types/XAiProvider.d.ts +13 -46
  41. package/dist/esm/types/XAiProvider.js +7 -39
  42. package/dist/esm/types/XAiProvider.js.map +1 -1
  43. package/dist/umd/chat-sdk.min.js +1 -1
  44. package/package.json +1 -1
@@ -49,6 +49,158 @@ var combineTextParts = (parts) => {
49
49
  }
50
50
  return result;
51
51
  };
52
+ var DEFAULT_SESSION_EVENTS_POLLING_INTERVAL = 1e4;
53
+ var getMessageEventId = (messageItem) => {
54
+ var _a;
55
+ return messageItem.eventId || ((_a = messageItem.raw) == null ? void 0 : _a.id);
56
+ };
57
+ var mapSessionMessages = (sessionEvents) => {
58
+ const mapped = [];
59
+ sessionEvents.forEach((item) => {
60
+ if (!item || !item.content || !Array.isArray(item.content.parts))
61
+ return;
62
+ if (item.author === "user" && item.content.parts.some((part) => part.task))
63
+ return;
64
+ const role = (item.content.role || "").toLowerCase() === "user" ? "user" : "bot";
65
+ const parts = item.content.parts.filter((part) => {
66
+ if (!part)
67
+ return false;
68
+ return Boolean(
69
+ part.text || part.inlineData || part.functionCall || part.functionResponse || part.fileData || part.executableCode || part.codeExecutionResult || part.errorMessage
70
+ );
71
+ });
72
+ if (parts.length === 0)
73
+ return;
74
+ const textParts = parts.filter(
75
+ (part) => part.text || part.errorMessage || part.inlineData
76
+ );
77
+ const fileDataParts = parts.filter((part) => part.fileData);
78
+ const otherParts = parts.filter(
79
+ (part) => !part.text && !part.errorMessage && !part.inlineData && !part.fileData
80
+ );
81
+ if (textParts.length > 0 || fileDataParts.length > 0) {
82
+ const messageItem = {
83
+ id: (0, import_uuid.v4)(),
84
+ author: item.author,
85
+ invocationId: item.invocationId,
86
+ eventId: item.id,
87
+ timestamp: item.timestamp,
88
+ isLike: item.isLike,
89
+ role,
90
+ modelCode: item.modelCode,
91
+ usageMetadata: item.usageMetadata,
92
+ finishReason: item.finishReason,
93
+ raw: item
94
+ };
95
+ textParts.forEach((part) => {
96
+ if (part.inlineData) {
97
+ messageItem.inlineData = {
98
+ displayName: part.inlineData.displayName,
99
+ data: part.inlineData.data,
100
+ mimeType: part.inlineData.mimeType
101
+ };
102
+ }
103
+ if (part.text) {
104
+ messageItem.text = (messageItem.text ? `${messageItem.text}
105
+ ` : "") + part.text;
106
+ if (typeof part.thought !== "undefined")
107
+ messageItem.thought = part.thought;
108
+ }
109
+ if (part.errorMessage) {
110
+ messageItem.text = (messageItem.text ? `${messageItem.text}
111
+ ` : "") + part.errorMessage;
112
+ }
113
+ });
114
+ if (fileDataParts.length > 0) {
115
+ messageItem.fileData = fileDataParts.map((part) => ({
116
+ displayName: part.fileData.displayName || "",
117
+ fileUri: part.fileData.fileUri,
118
+ mimeType: part.fileData.mimeType
119
+ }));
120
+ }
121
+ mapped.push(messageItem);
122
+ }
123
+ otherParts.forEach((part) => {
124
+ const messageItem = {
125
+ id: (0, import_uuid.v4)(),
126
+ author: item.author,
127
+ invocationId: item.invocationId,
128
+ eventId: item.id,
129
+ timestamp: item.timestamp,
130
+ isLike: item.isLike,
131
+ role,
132
+ modelCode: item.modelCode,
133
+ usageMetadata: item.usageMetadata,
134
+ finishReason: item.finishReason,
135
+ raw: item
136
+ };
137
+ if (part.functionCall)
138
+ messageItem.functionCall = part.functionCall;
139
+ if (part.executableCode)
140
+ messageItem.executableCode = part.executableCode;
141
+ if (part.codeExecutionResult)
142
+ messageItem.codeExecutionResult = part.codeExecutionResult;
143
+ if (part.functionResponse) {
144
+ const functionCallMessage = mapped.find(
145
+ (currentMessage) => {
146
+ var _a, _b;
147
+ return ((_a = currentMessage.functionCall) == null ? void 0 : _a.id) === ((_b = part.functionResponse) == null ? void 0 : _b.id);
148
+ }
149
+ );
150
+ if (functionCallMessage) {
151
+ functionCallMessage.functionResponse = part.functionResponse;
152
+ }
153
+ return;
154
+ }
155
+ mapped.push(messageItem);
156
+ });
157
+ });
158
+ return mapped;
159
+ };
160
+ var insertMissingSessionEvents = (currentMessages, sessionEvents) => {
161
+ const renderedEventIds = new Set(
162
+ currentMessages.map(getMessageEventId).filter(Boolean)
163
+ );
164
+ const missingEvents = sessionEvents.filter((event) => {
165
+ var _a, _b;
166
+ const parts = (_a = event.content) == null ? void 0 : _a.parts;
167
+ return Boolean(event.id) && ((_b = event.content) == null ? void 0 : _b.role) === "model" && Array.isArray(parts) && parts.length > 0 && !renderedEventIds.has(event.id);
168
+ });
169
+ if (missingEvents.length === 0)
170
+ return currentMessages;
171
+ const missingMessages = mapSessionMessages(missingEvents);
172
+ if (missingMessages.length === 0)
173
+ return currentMessages;
174
+ const eventOrder = new Map(
175
+ sessionEvents.map((event, index) => [event.id, index])
176
+ );
177
+ const getMessageOrder = (messageItem) => {
178
+ var _a;
179
+ const eventId = getMessageEventId(messageItem);
180
+ if (eventId && eventOrder.has(eventId))
181
+ return eventOrder.get(eventId);
182
+ const timestamp = messageItem.timestamp ?? ((_a = messageItem.raw) == null ? void 0 : _a.timestamp);
183
+ if (timestamp !== void 0) {
184
+ const nextEventIndex = sessionEvents.findIndex(
185
+ (event) => (event.timestamp || 0) > timestamp
186
+ );
187
+ return nextEventIndex < 0 ? sessionEvents.length + 0.5 : nextEventIndex - 0.5;
188
+ }
189
+ return Number.POSITIVE_INFINITY;
190
+ };
191
+ const nextMessages = [...currentMessages];
192
+ missingMessages.forEach((messageItem) => {
193
+ const targetOrder = getMessageOrder(messageItem);
194
+ let insertIndex = nextMessages.findIndex((currentMessage) => {
195
+ const currentOrder = getMessageOrder(currentMessage);
196
+ return Number.isFinite(currentOrder) && currentOrder > targetOrder;
197
+ });
198
+ if (insertIndex < 0)
199
+ insertIndex = nextMessages.length;
200
+ nextMessages.splice(insertIndex, 0, messageItem);
201
+ });
202
+ return nextMessages;
203
+ };
52
204
  function useADKChat({
53
205
  url = window.location.origin,
54
206
  token,
@@ -62,13 +214,24 @@ function useADKChat({
62
214
  onSuccess,
63
215
  onStream
64
216
  }) {
65
- const [loading, setLoading] = (0, import_react.useState)(false);
217
+ var _a, _b;
218
+ const [loading, setLoadingState] = (0, import_react.useState)(false);
219
+ const loadingRef = (0, import_react.useRef)(false);
220
+ const setLoading = (0, import_react.useCallback)((nextLoading) => {
221
+ loadingRef.current = nextLoading;
222
+ setLoadingState(nextLoading);
223
+ }, []);
66
224
  const [sessionLoading, setSessionLoading] = (0, import_react.useState)(false);
67
225
  const sendingRef = (0, import_react.useRef)(false);
68
226
  const ctrl = (0, import_react.useRef)(null);
69
227
  const tokenRef = (0, import_react.useRef)(token);
70
228
  tokenRef.current = token;
71
229
  const { appNo, showFirstSession } = config || {};
230
+ const pollSessionEvents = ((_a = config == null ? void 0 : config.session) == null ? void 0 : _a.pollSessionEvents) ?? true;
231
+ const sessionEventsPollingInterval = Math.max(
232
+ ((_b = config == null ? void 0 : config.session) == null ? void 0 : _b.sessionEventsPollingInterval) ?? DEFAULT_SESSION_EVENTS_POLLING_INTERVAL,
233
+ 1e3
234
+ );
72
235
  const [appInfo, setAppInfo] = (0, import_react.useState)(null);
73
236
  const [initialized, setInitialized] = (0, import_react.useState)(false);
74
237
  const [sessionList, setSessionList] = (0, import_react.useState)([]);
@@ -81,6 +244,10 @@ function useADKChat({
81
244
  const [prologue, setPrologue] = (0, import_react.useState)("");
82
245
  const [suggestedQuestions, setSuggestedQuestions] = (0, import_react.useState)([]);
83
246
  const [messages, setMessages] = (0, import_react.useState)([]);
247
+ const pendingSessionEventsRef = (0, import_react.useRef)(null);
248
+ const sessionEventsFlushTimerRef = (0, import_react.useRef)(null);
249
+ const sessionEventsSyncingRef = (0, import_react.useRef)(false);
250
+ const sessionDetailLoadingRef = (0, import_react.useRef)(false);
84
251
  const stateDeltaRef = (0, import_react.useRef)(void 0);
85
252
  const backgroundRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
86
253
  const messagesRef = (0, import_react.useRef)(messages);
@@ -90,17 +257,17 @@ function useADKChat({
90
257
  const mergedMessages = (0, import_react.useMemo)(() => {
91
258
  const fnResMap = {};
92
259
  messages.forEach((msg) => {
93
- var _a;
260
+ var _a2;
94
261
  if (msg.functionResponse) {
95
- fnResMap[((_a = msg == null ? void 0 : msg.functionResponse) == null ? void 0 : _a.id) || ""] = msg.functionResponse;
262
+ fnResMap[((_a2 = msg == null ? void 0 : msg.functionResponse) == null ? void 0 : _a2.id) || ""] = msg.functionResponse;
96
263
  }
97
264
  });
98
265
  return messages.map((msg) => {
99
- var _a;
266
+ var _a2;
100
267
  if (msg.functionCall) {
101
268
  return {
102
269
  ...msg,
103
- functionResponse: fnResMap[((_a = msg == null ? void 0 : msg.functionCall) == null ? void 0 : _a.id) || ""]
270
+ functionResponse: fnResMap[((_a2 = msg == null ? void 0 : msg.functionCall) == null ? void 0 : _a2.id) || ""]
104
271
  };
105
272
  }
106
273
  return msg;
@@ -108,6 +275,66 @@ function useADKChat({
108
275
  }, [messages]);
109
276
  const textMsgRef = (0, import_react.useRef)(null);
110
277
  const eventDataRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
278
+ const cancelSessionEventsFlush = (0, import_react.useCallback)(() => {
279
+ if (sessionEventsFlushTimerRef.current === null)
280
+ return;
281
+ clearTimeout(sessionEventsFlushTimerRef.current);
282
+ sessionEventsFlushTimerRef.current = null;
283
+ }, []);
284
+ const flushPendingSessionEvents = (0, import_react.useCallback)(() => {
285
+ const pending = pendingSessionEventsRef.current;
286
+ const replyInProgress = loadingRef.current || sendingRef.current || textMsgRef.current !== null;
287
+ if (!pending || replyInProgress || pending.sessionId !== currentSessionIdRef.current)
288
+ return;
289
+ const previewMessages = insertMissingSessionEvents(
290
+ messagesRef.current,
291
+ pending.events
292
+ );
293
+ pendingSessionEventsRef.current = null;
294
+ if (previewMessages === messagesRef.current)
295
+ return;
296
+ sessionEventsSyncingRef.current = true;
297
+ setLoading(true);
298
+ sessionEventsFlushTimerRef.current = setTimeout(() => {
299
+ sessionEventsFlushTimerRef.current = null;
300
+ if (pending.sessionId === currentSessionIdRef.current) {
301
+ setMessages((prev) => {
302
+ const nextMessages = insertMissingSessionEvents(
303
+ prev,
304
+ pending.events
305
+ );
306
+ messagesRef.current = nextMessages;
307
+ return nextMessages;
308
+ });
309
+ }
310
+ sessionEventsSyncingRef.current = false;
311
+ setLoading(false);
312
+ }, 0);
313
+ }, [setLoading]);
314
+ const syncSessionEvents = (0, import_react.useCallback)(
315
+ (events, targetSessionId) => {
316
+ if (targetSessionId !== currentSessionIdRef.current)
317
+ return;
318
+ pendingSessionEventsRef.current = {
319
+ sessionId: targetSessionId,
320
+ events
321
+ };
322
+ flushPendingSessionEvents();
323
+ },
324
+ [flushPendingSessionEvents]
325
+ );
326
+ (0, import_react.useEffect)(() => {
327
+ pendingSessionEventsRef.current = null;
328
+ cancelSessionEventsFlush();
329
+ if (sessionEventsSyncingRef.current) {
330
+ sessionEventsSyncingRef.current = false;
331
+ setLoading(false);
332
+ }
333
+ }, [cancelSessionEventsFlush, currentSessionId, setLoading]);
334
+ (0, import_react.useEffect)(() => {
335
+ if (!loading)
336
+ flushPendingSessionEvents();
337
+ }, [flushPendingSessionEvents, loading]);
111
338
  const insertMessage = (0, import_react.useCallback)((msg) => {
112
339
  setMessages((prev) => {
113
340
  const lastMessage = prev[prev.length - 1];
@@ -167,9 +394,9 @@ function useADKChat({
167
394
  [withEventMeta]
168
395
  );
169
396
  const storeEvents = (0, import_react.useCallback)((part, event) => {
170
- var _a, _b;
397
+ var _a2, _b2;
171
398
  let title = "";
172
- if (part == null && ((_a = event.actions) == null ? void 0 : _a.artifactDelta)) {
399
+ if (part == null && ((_a2 = event.actions) == null ? void 0 : _a2.artifactDelta)) {
173
400
  title += "eventAction: artifact";
174
401
  } else if (part) {
175
402
  if (part.text) {
@@ -179,7 +406,7 @@ function useADKChat({
179
406
  } else if (part.functionResponse) {
180
407
  title += `functionResponse:${part.functionResponse.name}`;
181
408
  } else if (part.executableCode) {
182
- title += `executableCode:${(_b = part.executableCode.code) == null ? void 0 : _b.slice(0, 10)}`;
409
+ title += `executableCode:${(_b2 = part.executableCode.code) == null ? void 0 : _b2.slice(0, 10)}`;
183
410
  } else if (part.codeExecutionResult) {
184
411
  title += `codeExecutionResult:${part.codeExecutionResult.outcome}`;
185
412
  } else if (part.errorMessage) {
@@ -193,7 +420,7 @@ function useADKChat({
193
420
  }, []);
194
421
  const storeMessage = (0, import_react.useCallback)(
195
422
  (part, event, role) => {
196
- var _a, _b;
423
+ var _a2, _b2;
197
424
  const msg = {
198
425
  id: (0, import_uuid.v4)(),
199
426
  author: event.author,
@@ -217,7 +444,7 @@ function useADKChat({
217
444
  } else if (part.text) {
218
445
  msg.text = part.text;
219
446
  msg.thought = part.thought;
220
- if ((_b = (_a = event == null ? void 0 : event.groundingMetadata) == null ? void 0 : _a.searchEntryPoint) == null ? void 0 : _b.renderedContent) {
447
+ if ((_b2 = (_a2 = event == null ? void 0 : event.groundingMetadata) == null ? void 0 : _a2.searchEntryPoint) == null ? void 0 : _b2.renderedContent) {
221
448
  msg.renderedContent = event.groundingMetadata.searchEntryPoint.renderedContent;
222
449
  }
223
450
  } else if (part.fileData) {
@@ -240,8 +467,8 @@ function useADKChat({
240
467
  );
241
468
  const processPart = (0, import_react.useCallback)(
242
469
  (event, part, ignore = false) => {
243
- var _a, _b;
244
- const renderedContent = (_b = (_a = event.groundingMetadata) == null ? void 0 : _a.searchEntryPoint) == null ? void 0 : _b.renderedContent;
470
+ var _a2, _b2;
471
+ const renderedContent = (_b2 = (_a2 = event.groundingMetadata) == null ? void 0 : _a2.searchEntryPoint) == null ? void 0 : _b2.renderedContent;
245
472
  if (part.text) {
246
473
  if (ignore)
247
474
  return;
@@ -295,8 +522,8 @@ function useADKChat({
295
522
  );
296
523
  const processFollowupPart = (0, import_react.useCallback)(
297
524
  (event) => {
298
- var _a, _b;
299
- const part = ((_b = (_a = event == null ? void 0 : event.content) == null ? void 0 : _a.parts) == null ? void 0 : _b[0]) || null;
525
+ var _a2, _b2;
526
+ const part = ((_b2 = (_a2 = event == null ? void 0 : event.content) == null ? void 0 : _a2.parts) == null ? void 0 : _b2[0]) || null;
300
527
  const text = (part == null ? void 0 : part.text) || "";
301
528
  storeEvents(part, event);
302
529
  if (text) {
@@ -337,9 +564,13 @@ function useADKChat({
337
564
  setLoading(true);
338
565
  ctrl.current = newCtrl;
339
566
  }
340
- newCtrl.signal.addEventListener("abort", () => {
341
- resolve();
342
- });
567
+ newCtrl.signal.addEventListener(
568
+ "abort",
569
+ () => {
570
+ resolve();
571
+ },
572
+ { once: true }
573
+ );
343
574
  const requestUrl = `${url}/api/gateway-web/openApi/v1/aizt/app/${appNo}/sendMsgStreaming`;
344
575
  let bgTextMsg = null;
345
576
  (0, import_fetch_event_source.fetchEventSource)(requestUrl, {
@@ -358,7 +589,7 @@ function useADKChat({
358
589
  } else if (response.status === 401 || response.status === 403) {
359
590
  setLoading(false);
360
591
  onError == null ? void 0 : onError({
361
- code: import_types.ErrorCode.API_ERROR,
592
+ code: import_types.ErrorCode.AUTH_ERROR,
362
593
  message: response.status === 401 ? "认证失败,token 无效或已过期" : "无权限访问该资源"
363
594
  });
364
595
  resolve();
@@ -476,7 +707,7 @@ function useADKChat({
476
707
  }
477
708
  },
478
709
  onclose: () => {
479
- var _a;
710
+ var _a2;
480
711
  const isBackground = currentSessionIdRef.current !== targetSessionId;
481
712
  if (isBackground) {
482
713
  const bg = backgroundRef.current.get(targetSessionId);
@@ -487,10 +718,7 @@ function useADKChat({
487
718
  } else {
488
719
  setLoading(false);
489
720
  if (textMsgRef.current) {
490
- onMessage == null ? void 0 : onMessage(
491
- ((_a = textMsgRef.current) == null ? void 0 : _a.text) || "",
492
- textMsgRef.current
493
- );
721
+ onMessage == null ? void 0 : onMessage(((_a2 = textMsgRef.current) == null ? void 0 : _a2.text) || "", textMsgRef.current);
494
722
  }
495
723
  textMsgRef.current = null;
496
724
  }
@@ -526,7 +754,7 @@ function useADKChat({
526
754
  files = [],
527
755
  functionResponse
528
756
  }) => {
529
- if (loading || sendingRef.current)
757
+ if (loadingRef.current || sendingRef.current)
530
758
  return;
531
759
  if (!text.trim() && !(files == null ? void 0 : files.length) && !functionResponse)
532
760
  return;
@@ -546,11 +774,11 @@ function useADKChat({
546
774
  id: (0, import_uuid.v4)(),
547
775
  role: "user",
548
776
  fileData: files.map((file) => {
549
- var _a, _b, _c;
777
+ var _a2, _b2, _c;
550
778
  return {
551
779
  displayName: file.fileName || file.name,
552
- mimeType: file.mimeType || ((_a = file.response) == null ? void 0 : _a.mimeType),
553
- fileUri: file.tempUrl || ((_b = file.response) == null ? void 0 : _b.fileUrl) || ((_c = file.response) == null ? void 0 : _c.tempUrl)
780
+ mimeType: file.mimeType || ((_a2 = file.response) == null ? void 0 : _a2.mimeType),
781
+ fileUri: file.tempUrl || ((_b2 = file.response) == null ? void 0 : _b2.fileUrl) || ((_c = file.response) == null ? void 0 : _c.tempUrl)
554
782
  };
555
783
  })
556
784
  });
@@ -573,10 +801,10 @@ function useADKChat({
573
801
  parts: functionResponse ? [{ functionResponse }] : [{ text }]
574
802
  },
575
803
  files: files.map((file) => {
576
- var _a, _b, _c, _d, _e, _f;
804
+ var _a2, _b2, _c, _d, _e, _f;
577
805
  return {
578
- fileName: file.fileName || ((_a = file.response) == null ? void 0 : _a.fileName),
579
- fileId: file.fileId || ((_b = file.response) == null ? void 0 : _b.fileId),
806
+ fileName: file.fileName || ((_a2 = file.response) == null ? void 0 : _a2.fileName),
807
+ fileId: file.fileId || ((_b2 = file.response) == null ? void 0 : _b2.fileId),
580
808
  tempUrl: file.tempUrl || ((_c = file.response) == null ? void 0 : _c.fileUrl) || ((_d = file.response) == null ? void 0 : _d.tempUrl),
581
809
  type: file.type || ((_e = file.response) == null ? void 0 : _e.fileType),
582
810
  mimeType: file.mimeType || ((_f = file.response) == null ? void 0 : _f.mimeType)
@@ -592,7 +820,7 @@ function useADKChat({
592
820
  initAppConversations();
593
821
  };
594
822
  const reChat = async () => {
595
- if (loading || sendingRef.current)
823
+ if (loadingRef.current || sendingRef.current)
596
824
  return;
597
825
  if (messages.length === 0)
598
826
  return;
@@ -631,8 +859,8 @@ function useADKChat({
631
859
  }
632
860
  };
633
861
  const confirmFnCall = (fnCall, confirmed) => {
634
- var _a;
635
- const functionResponse = ((_a = strategies == null ? void 0 : strategies.createFunctionResponse) == null ? void 0 : _a.call(
862
+ var _a2;
863
+ const functionResponse = ((_a2 = strategies == null ? void 0 : strategies.createFunctionResponse) == null ? void 0 : _a2.call(
636
864
  strategies,
637
865
  fnCall,
638
866
  confirmed
@@ -644,7 +872,7 @@ function useADKChat({
644
872
  startChat({ functionResponse });
645
873
  };
646
874
  const suggestChat = (text) => {
647
- if (loading)
875
+ if (loadingRef.current)
648
876
  return;
649
877
  if (!text.trim())
650
878
  return;
@@ -652,126 +880,43 @@ function useADKChat({
652
880
  startChat({ text });
653
881
  };
654
882
  const stopChat = (0, import_react.useCallback)(() => {
655
- var _a;
656
- (_a = ctrl.current) == null ? void 0 : _a.abort();
883
+ var _a2;
884
+ pendingSessionEventsRef.current = null;
885
+ cancelSessionEventsFlush();
886
+ sessionEventsSyncingRef.current = false;
887
+ (_a2 = ctrl.current) == null ? void 0 : _a2.abort();
657
888
  ctrl.current = null;
658
889
  setLoading(false);
659
890
  textMsgRef.current = null;
660
- }, []);
891
+ }, [cancelSessionEventsFlush, setLoading]);
661
892
  const clearChat = () => {
662
- var _a, _b;
893
+ var _a2, _b2;
663
894
  const newSessionId = (0, import_uuid.v4)();
664
895
  setCurrentSessionId(newSessionId);
665
896
  stopChat();
666
- setPrologue(((_a = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a.prologue) || "");
897
+ setPrologue(((_a2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a2.prologue) || "");
667
898
  setMessages([]);
668
- setSuggestedQuestions(((_b = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b.suggested_questions) || []);
669
- };
670
- const formatMessages = (messages2, isReplace = false) => {
671
- const mapped = [];
672
- messages2.forEach((item) => {
673
- if (!item || !item.content || !Array.isArray(item.content.parts))
674
- return;
675
- const role = (item.content.role || "").toLowerCase() === "user" ? "user" : "bot";
676
- const parts = Array.isArray(item.content.parts) ? item.content.parts.filter((p) => {
677
- if (!p)
678
- return false;
679
- return Boolean(
680
- p.text || p.inlineData || p.functionCall || p.functionResponse || p.fileData || p.executableCode || p.codeExecutionResult || p.errorMessage
681
- );
682
- }) : [];
683
- if (parts.length === 0)
684
- return;
685
- const textParts = parts.filter(
686
- (p) => p.text || p.errorMessage || p.inlineData
687
- );
688
- const fileDataParts = parts.filter((p) => p.fileData);
689
- const otherParts = parts.filter(
690
- (p) => !p.text && !p.errorMessage && !p.inlineData && !p.fileData
691
- );
692
- if (textParts.length > 0 || fileDataParts.length > 0) {
693
- const msg = {
694
- id: (0, import_uuid.v4)(),
695
- author: item.author,
696
- invocationId: item.invocationId,
697
- eventId: item.id,
698
- timestamp: item.timestamp,
699
- isLike: item.isLike,
700
- role,
701
- modelCode: item.modelCode,
702
- usageMetadata: item.usageMetadata,
703
- finishReason: item.finishReason,
704
- raw: item
705
- };
706
- for (const part of textParts) {
707
- if (part.inlineData) {
708
- msg.inlineData = {
709
- displayName: part.inlineData.displayName,
710
- data: part.inlineData.data,
711
- mimeType: part.inlineData.mimeType
712
- };
713
- }
714
- if (part.text) {
715
- msg.text = (msg.text ? msg.text + "\n" : "") + part.text;
716
- if (typeof part.thought !== "undefined")
717
- msg.thought = part.thought;
718
- }
719
- if (part.errorMessage) {
720
- msg.text = (msg.text ? msg.text + "\n" : "") + part.errorMessage;
721
- }
722
- }
723
- if (fileDataParts.length > 0) {
724
- msg.fileData = fileDataParts.map((part) => ({
725
- displayName: part.fileData.displayName || "",
726
- fileUri: part.fileData.fileUri,
727
- mimeType: part.fileData.mimeType
728
- }));
729
- }
730
- mapped.push(msg);
731
- }
732
- otherParts.forEach((part) => {
733
- const msg = {
734
- id: (0, import_uuid.v4)(),
735
- author: item.author,
736
- invocationId: item.invocationId,
737
- eventId: item.id,
738
- timestamp: item.timestamp,
739
- isLike: item.isLike,
740
- role,
741
- modelCode: item.modelCode,
742
- usageMetadata: item.usageMetadata,
743
- finishReason: item.finishReason,
744
- raw: item
745
- };
746
- if (part.functionCall)
747
- msg.functionCall = part.functionCall;
748
- if (part.executableCode)
749
- msg.executableCode = part.executableCode;
750
- if (part.codeExecutionResult)
751
- msg.codeExecutionResult = part.codeExecutionResult;
752
- if (part.functionResponse) {
753
- const functionCallMsg = mapped.find(
754
- (msg2) => {
755
- var _a, _b;
756
- return ((_a = msg2.functionCall) == null ? void 0 : _a.id) === ((_b = part.functionResponse) == null ? void 0 : _b.id);
757
- }
758
- );
759
- if (functionCallMsg) {
760
- functionCallMsg.functionResponse = part.functionResponse;
761
- }
762
- return;
763
- }
764
- mapped.push(msg);
765
- });
766
- });
767
- setMessages((prev) => isReplace ? mapped : [...prev, ...mapped]);
899
+ setSuggestedQuestions(((_b2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b2.suggested_questions) || []);
768
900
  };
901
+ const formatMessages = (0, import_react.useCallback)(
902
+ (sessionEvents, isReplace = false) => {
903
+ const mapped = mapSessionMessages(sessionEvents);
904
+ setMessages((prev) => isReplace ? mapped : [...prev, ...mapped]);
905
+ },
906
+ []
907
+ );
769
908
  const setCurrentSession = async (sessionId) => {
770
- var _a, _b;
909
+ var _a2, _b2;
771
910
  if (sessionId) {
772
911
  if (sessionId === currentSessionId) {
773
912
  return;
774
913
  }
914
+ pendingSessionEventsRef.current = null;
915
+ cancelSessionEventsFlush();
916
+ if (sessionEventsSyncingRef.current) {
917
+ sessionEventsSyncingRef.current = false;
918
+ setLoading(false);
919
+ }
775
920
  const prevSessionId = currentSessionId;
776
921
  if (ctrl.current) {
777
922
  backgroundRef.current.set(prevSessionId, {
@@ -804,29 +949,34 @@ function useADKChat({
804
949
  }
805
950
  setInitialized(false);
806
951
  setCurrentSessionId(sessionId);
807
- const { data, result } = await (0, import_api.fetchSessionDetail)({
808
- url,
809
- appNo,
810
- sessionId,
811
- token: tokenRef.current
812
- });
813
- if ((result == null ? void 0 : result.code) === import_constants.API_SUCCESS_CODE) {
814
- setPrologue(((_a = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a.prologue) || "");
815
- if (Array.isArray(data) && data.length > 0) {
816
- formatMessages(data, true);
817
- } else {
818
- setSuggestedQuestions(
819
- ((_b = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b.suggested_questions) || []
820
- );
952
+ sessionDetailLoadingRef.current = true;
953
+ try {
954
+ const { data, result } = await (0, import_api.fetchSessionDetail)({
955
+ url,
956
+ appNo,
957
+ sessionId,
958
+ token: tokenRef.current
959
+ });
960
+ if ((result == null ? void 0 : result.code) === import_constants.API_SUCCESS_CODE) {
961
+ setPrologue(((_a2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a2.prologue) || "");
962
+ if (Array.isArray(data) && data.length > 0) {
963
+ formatMessages(data, true);
964
+ } else {
965
+ setSuggestedQuestions(
966
+ ((_b2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b2.suggested_questions) || []
967
+ );
968
+ }
821
969
  }
970
+ } finally {
971
+ sessionDetailLoadingRef.current = false;
972
+ setInitialized(true);
822
973
  }
823
- setInitialized(true);
824
974
  } else {
825
975
  setCurrentSessionId((0, import_uuid.v4)());
826
976
  }
827
977
  };
828
978
  const initAppConversations = async (fetchDetail = false) => {
829
- var _a, _b;
979
+ var _a2, _b2;
830
980
  try {
831
981
  setSessionLoading(true);
832
982
  const {
@@ -862,9 +1012,9 @@ function useADKChat({
862
1012
  if (showFirstSession) {
863
1013
  setCurrentSession(sessionId);
864
1014
  } else {
865
- fetchDetail && setPrologue(((_a = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a.prologue) || "");
1015
+ fetchDetail && setPrologue(((_a2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a2.prologue) || "");
866
1016
  fetchDetail && setSuggestedQuestions(
867
- ((_b = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b.suggested_questions) || []
1017
+ ((_b2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b2.suggested_questions) || []
868
1018
  );
869
1019
  }
870
1020
  if (!initialized) {
@@ -881,6 +1031,11 @@ function useADKChat({
881
1031
  clearChat();
882
1032
  }
883
1033
  } else {
1034
+ onError == null ? void 0 : onError({
1035
+ code: (result == null ? void 0 : result.code) || "UNKNOWN_ERROR",
1036
+ message: (result == null ? void 0 : result.message) || "获取会话列表失败",
1037
+ raw: result
1038
+ });
884
1039
  setSessionList([]);
885
1040
  setCurrentSessionId((0, import_uuid.v4)());
886
1041
  setPrologue("");
@@ -888,7 +1043,7 @@ function useADKChat({
888
1043
  }
889
1044
  } catch {
890
1045
  onError == null ? void 0 : onError({
891
- code: import_types.ErrorCode.API_ERROR,
1046
+ code: import_types.ErrorCode.NETWORK_ERROR,
892
1047
  message: "获取会话列表失败"
893
1048
  });
894
1049
  } finally {
@@ -962,13 +1117,14 @@ function useADKChat({
962
1117
  });
963
1118
  } else {
964
1119
  onError == null ? void 0 : onError({
965
- code: result.code || import_types.ErrorCode.APP_NOT_FOUND,
966
- message: result.message || "获取应用配置失败"
1120
+ code: result.code || "UNKNOWN_ERROR",
1121
+ message: result.message || "获取应用配置失败",
1122
+ raw: result
967
1123
  });
968
1124
  }
969
1125
  } catch (error) {
970
1126
  onError == null ? void 0 : onError({
971
- code: import_types.ErrorCode.API_ERROR,
1127
+ code: import_types.ErrorCode.NETWORK_ERROR,
972
1128
  message: "获取应用配置失败"
973
1129
  });
974
1130
  } finally {
@@ -985,17 +1141,59 @@ function useADKChat({
985
1141
  initAppConversations(true);
986
1142
  }
987
1143
  }, [appInfo]);
1144
+ (0, import_react.useEffect)(() => {
1145
+ if (!enabled || !initialized || !pollSessionEvents || !appNo || !currentSessionId)
1146
+ return;
1147
+ let disposed = false;
1148
+ let requesting = false;
1149
+ const pollingSessionId = currentSessionId;
1150
+ const poll = async () => {
1151
+ if (requesting || sessionDetailLoadingRef.current)
1152
+ return;
1153
+ requesting = true;
1154
+ try {
1155
+ const { data, result } = await (0, import_api.fetchSessionDetail)({
1156
+ url,
1157
+ appNo,
1158
+ sessionId: pollingSessionId,
1159
+ token: tokenRef.current
1160
+ });
1161
+ if (!disposed && (result == null ? void 0 : result.code) === import_constants.API_SUCCESS_CODE && Array.isArray(data)) {
1162
+ syncSessionEvents(data, pollingSessionId);
1163
+ }
1164
+ } catch {
1165
+ } finally {
1166
+ requesting = false;
1167
+ }
1168
+ };
1169
+ void poll();
1170
+ const timer = window.setInterval(poll, sessionEventsPollingInterval);
1171
+ return () => {
1172
+ disposed = true;
1173
+ window.clearInterval(timer);
1174
+ };
1175
+ }, [
1176
+ appNo,
1177
+ currentSessionId,
1178
+ enabled,
1179
+ initialized,
1180
+ pollSessionEvents,
1181
+ sessionEventsPollingInterval,
1182
+ syncSessionEvents,
1183
+ url
1184
+ ]);
988
1185
  (0, import_react.useEffect)(() => {
989
1186
  return () => {
990
- var _a;
991
- (_a = ctrl.current) == null ? void 0 : _a.abort();
1187
+ var _a2;
1188
+ cancelSessionEventsFlush();
1189
+ (_a2 = ctrl.current) == null ? void 0 : _a2.abort();
992
1190
  backgroundRef.current.forEach((bg) => {
993
- var _a2;
994
- return (_a2 = bg.ctrl) == null ? void 0 : _a2.abort();
1191
+ var _a3;
1192
+ return (_a3 = bg.ctrl) == null ? void 0 : _a3.abort();
995
1193
  });
996
1194
  backgroundRef.current.clear();
997
1195
  };
998
- }, []);
1196
+ }, [cancelSessionEventsFlush]);
999
1197
  return {
1000
1198
  appInfo,
1001
1199
  startChat,