@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.
Files changed (34) 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 +392 -157
  12. package/dist/cjs/hooks/useADKChat.js.map +3 -3
  13. package/dist/cjs/types/FileGallery.d.ts +41 -0
  14. package/dist/cjs/types/FileGallery.js.map +1 -1
  15. package/dist/cjs/types/XAdkProvider.d.ts +4 -0
  16. package/dist/cjs/types/XAdkProvider.js.map +1 -1
  17. package/dist/esm/components/FileGallery/index.d.ts +0 -30
  18. package/dist/esm/components/FileGallery/index.js +362 -364
  19. package/dist/esm/components/FileGallery/index.js.map +1 -1
  20. package/dist/esm/components/FileGallery/styles.d.ts +5 -0
  21. package/dist/esm/components/FileGallery/styles.js +10 -2
  22. package/dist/esm/components/FileGallery/styles.js.map +1 -1
  23. package/dist/esm/components/XAdkProvider/compound/Sender.js +5 -3
  24. package/dist/esm/components/XAdkProvider/compound/Sender.js.map +1 -1
  25. package/dist/esm/components/XAdkSender/index.js +1 -0
  26. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  27. package/dist/esm/hooks/useADKChat.js +347 -130
  28. package/dist/esm/hooks/useADKChat.js.map +1 -1
  29. package/dist/esm/types/FileGallery.d.ts +41 -0
  30. package/dist/esm/types/FileGallery.js.map +1 -1
  31. package/dist/esm/types/XAdkProvider.d.ts +4 -0
  32. package/dist/esm/types/XAdkProvider.js.map +1 -1
  33. package/dist/umd/chat-sdk.min.js +1 -1
  34. package/package.json +1 -1
@@ -49,6 +49,202 @@ 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 getComparableMessageContent = (messageItem) => {
161
+ var _a;
162
+ return JSON.stringify({
163
+ role: messageItem.role,
164
+ text: ((_a = messageItem.text) == null ? void 0 : _a.replace(/\r\n/g, "\n").trim()) || "",
165
+ thought: Boolean(messageItem.thought),
166
+ inlineData: messageItem.inlineData || null,
167
+ fileData: messageItem.fileData || null,
168
+ functionCall: messageItem.functionCall || null,
169
+ functionResponse: messageItem.functionResponse || null,
170
+ executableCode: messageItem.executableCode || null,
171
+ codeExecutionResult: messageItem.codeExecutionResult || null
172
+ });
173
+ };
174
+ var isStreamMessageWithoutServerEventId = (messageItem) => {
175
+ const eventId = getMessageEventId(messageItem);
176
+ return Boolean(messageItem.invocationId) && (!eventId || eventId === messageItem.invocationId);
177
+ };
178
+ var insertMissingSessionEvents = (currentMessages, sessionEvents) => {
179
+ const renderedEventIds = new Set(
180
+ currentMessages.map(getMessageEventId).filter(Boolean)
181
+ );
182
+ const unmatchedStreamMessageIndexes = new Set(
183
+ currentMessages.map(
184
+ (messageItem, index) => isStreamMessageWithoutServerEventId(messageItem) ? index : -1
185
+ ).filter((index) => index >= 0)
186
+ );
187
+ const missingEvents = sessionEvents.filter((event) => {
188
+ var _a, _b;
189
+ const parts = (_a = event.content) == null ? void 0 : _a.parts;
190
+ const canRender = Boolean(event.id) && ((_b = event.content) == null ? void 0 : _b.role) === "model" && Array.isArray(parts) && parts.length > 0;
191
+ if (!canRender || renderedEventIds.has(event.id))
192
+ return false;
193
+ const eventMessages = mapSessionMessages([event]);
194
+ const matchedIndexes = [];
195
+ const isRenderedByStream = eventMessages.length > 0 && eventMessages.every((eventMessage) => {
196
+ const comparableContent = getComparableMessageContent(eventMessage);
197
+ const matchedIndex = currentMessages.findIndex(
198
+ (currentMessage, index) => unmatchedStreamMessageIndexes.has(index) && !matchedIndexes.includes(index) && currentMessage.invocationId === eventMessage.invocationId && getComparableMessageContent(currentMessage) === comparableContent
199
+ );
200
+ if (matchedIndex < 0)
201
+ return false;
202
+ matchedIndexes.push(matchedIndex);
203
+ return true;
204
+ });
205
+ if (isRenderedByStream) {
206
+ matchedIndexes.forEach(
207
+ (index) => unmatchedStreamMessageIndexes.delete(index)
208
+ );
209
+ return false;
210
+ }
211
+ return true;
212
+ });
213
+ if (missingEvents.length === 0)
214
+ return currentMessages;
215
+ const missingMessages = mapSessionMessages(missingEvents);
216
+ if (missingMessages.length === 0)
217
+ return currentMessages;
218
+ const eventOrder = new Map(
219
+ sessionEvents.map((event, index) => [event.id, index])
220
+ );
221
+ const getMessageOrder = (messageItem) => {
222
+ var _a;
223
+ const eventId = getMessageEventId(messageItem);
224
+ if (eventId && eventOrder.has(eventId))
225
+ return eventOrder.get(eventId);
226
+ const timestamp = messageItem.timestamp ?? ((_a = messageItem.raw) == null ? void 0 : _a.timestamp);
227
+ if (timestamp !== void 0) {
228
+ const nextEventIndex = sessionEvents.findIndex(
229
+ (event) => (event.timestamp || 0) > timestamp
230
+ );
231
+ return nextEventIndex < 0 ? sessionEvents.length + 0.5 : nextEventIndex - 0.5;
232
+ }
233
+ return Number.POSITIVE_INFINITY;
234
+ };
235
+ const nextMessages = [...currentMessages];
236
+ missingMessages.forEach((messageItem) => {
237
+ const targetOrder = getMessageOrder(messageItem);
238
+ let insertIndex = nextMessages.findIndex((currentMessage) => {
239
+ const currentOrder = getMessageOrder(currentMessage);
240
+ return Number.isFinite(currentOrder) && currentOrder > targetOrder;
241
+ });
242
+ if (insertIndex < 0)
243
+ insertIndex = nextMessages.length;
244
+ nextMessages.splice(insertIndex, 0, messageItem);
245
+ });
246
+ return nextMessages;
247
+ };
52
248
  function useADKChat({
53
249
  url = window.location.origin,
54
250
  token,
@@ -62,13 +258,24 @@ function useADKChat({
62
258
  onSuccess,
63
259
  onStream
64
260
  }) {
65
- const [loading, setLoading] = (0, import_react.useState)(false);
261
+ var _a, _b;
262
+ const [loading, setLoadingState] = (0, import_react.useState)(false);
263
+ const loadingRef = (0, import_react.useRef)(false);
264
+ const setLoading = (0, import_react.useCallback)((nextLoading) => {
265
+ loadingRef.current = nextLoading;
266
+ setLoadingState(nextLoading);
267
+ }, []);
66
268
  const [sessionLoading, setSessionLoading] = (0, import_react.useState)(false);
67
269
  const sendingRef = (0, import_react.useRef)(false);
68
270
  const ctrl = (0, import_react.useRef)(null);
69
271
  const tokenRef = (0, import_react.useRef)(token);
70
272
  tokenRef.current = token;
71
273
  const { appNo, showFirstSession } = config || {};
274
+ const pollSessionEvents = ((_a = config == null ? void 0 : config.session) == null ? void 0 : _a.pollSessionEvents) ?? true;
275
+ const sessionEventsPollingInterval = Math.max(
276
+ ((_b = config == null ? void 0 : config.session) == null ? void 0 : _b.sessionEventsPollingInterval) ?? DEFAULT_SESSION_EVENTS_POLLING_INTERVAL,
277
+ 1e3
278
+ );
72
279
  const [appInfo, setAppInfo] = (0, import_react.useState)(null);
73
280
  const [initialized, setInitialized] = (0, import_react.useState)(false);
74
281
  const [sessionList, setSessionList] = (0, import_react.useState)([]);
@@ -81,6 +288,10 @@ function useADKChat({
81
288
  const [prologue, setPrologue] = (0, import_react.useState)("");
82
289
  const [suggestedQuestions, setSuggestedQuestions] = (0, import_react.useState)([]);
83
290
  const [messages, setMessages] = (0, import_react.useState)([]);
291
+ const pendingSessionEventsRef = (0, import_react.useRef)(null);
292
+ const sessionEventsFlushTimerRef = (0, import_react.useRef)(null);
293
+ const sessionEventsSyncingRef = (0, import_react.useRef)(false);
294
+ const sessionDetailLoadingRef = (0, import_react.useRef)(false);
84
295
  const stateDeltaRef = (0, import_react.useRef)(void 0);
85
296
  const backgroundRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
86
297
  const messagesRef = (0, import_react.useRef)(messages);
@@ -90,17 +301,17 @@ function useADKChat({
90
301
  const mergedMessages = (0, import_react.useMemo)(() => {
91
302
  const fnResMap = {};
92
303
  messages.forEach((msg) => {
93
- var _a;
304
+ var _a2;
94
305
  if (msg.functionResponse) {
95
- fnResMap[((_a = msg == null ? void 0 : msg.functionResponse) == null ? void 0 : _a.id) || ""] = msg.functionResponse;
306
+ fnResMap[((_a2 = msg == null ? void 0 : msg.functionResponse) == null ? void 0 : _a2.id) || ""] = msg.functionResponse;
96
307
  }
97
308
  });
98
309
  return messages.map((msg) => {
99
- var _a;
310
+ var _a2;
100
311
  if (msg.functionCall) {
101
312
  return {
102
313
  ...msg,
103
- functionResponse: fnResMap[((_a = msg == null ? void 0 : msg.functionCall) == null ? void 0 : _a.id) || ""]
314
+ functionResponse: fnResMap[((_a2 = msg == null ? void 0 : msg.functionCall) == null ? void 0 : _a2.id) || ""]
104
315
  };
105
316
  }
106
317
  return msg;
@@ -108,6 +319,66 @@ function useADKChat({
108
319
  }, [messages]);
109
320
  const textMsgRef = (0, import_react.useRef)(null);
110
321
  const eventDataRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
322
+ const cancelSessionEventsFlush = (0, import_react.useCallback)(() => {
323
+ if (sessionEventsFlushTimerRef.current === null)
324
+ return;
325
+ clearTimeout(sessionEventsFlushTimerRef.current);
326
+ sessionEventsFlushTimerRef.current = null;
327
+ }, []);
328
+ const flushPendingSessionEvents = (0, import_react.useCallback)(() => {
329
+ const pending = pendingSessionEventsRef.current;
330
+ const replyInProgress = loadingRef.current || sendingRef.current || textMsgRef.current !== null;
331
+ if (!pending || replyInProgress || pending.sessionId !== currentSessionIdRef.current)
332
+ return;
333
+ const previewMessages = insertMissingSessionEvents(
334
+ messagesRef.current,
335
+ pending.events
336
+ );
337
+ pendingSessionEventsRef.current = null;
338
+ if (previewMessages === messagesRef.current)
339
+ return;
340
+ sessionEventsSyncingRef.current = true;
341
+ setLoading(true);
342
+ sessionEventsFlushTimerRef.current = setTimeout(() => {
343
+ sessionEventsFlushTimerRef.current = null;
344
+ if (pending.sessionId === currentSessionIdRef.current) {
345
+ setMessages((prev) => {
346
+ const nextMessages = insertMissingSessionEvents(
347
+ prev,
348
+ pending.events
349
+ );
350
+ messagesRef.current = nextMessages;
351
+ return nextMessages;
352
+ });
353
+ }
354
+ sessionEventsSyncingRef.current = false;
355
+ setLoading(false);
356
+ }, 0);
357
+ }, [setLoading]);
358
+ const syncSessionEvents = (0, import_react.useCallback)(
359
+ (events, targetSessionId) => {
360
+ if (targetSessionId !== currentSessionIdRef.current)
361
+ return;
362
+ pendingSessionEventsRef.current = {
363
+ sessionId: targetSessionId,
364
+ events
365
+ };
366
+ flushPendingSessionEvents();
367
+ },
368
+ [flushPendingSessionEvents]
369
+ );
370
+ (0, import_react.useEffect)(() => {
371
+ pendingSessionEventsRef.current = null;
372
+ cancelSessionEventsFlush();
373
+ if (sessionEventsSyncingRef.current) {
374
+ sessionEventsSyncingRef.current = false;
375
+ setLoading(false);
376
+ }
377
+ }, [cancelSessionEventsFlush, currentSessionId, setLoading]);
378
+ (0, import_react.useEffect)(() => {
379
+ if (!loading)
380
+ flushPendingSessionEvents();
381
+ }, [flushPendingSessionEvents, loading]);
111
382
  const insertMessage = (0, import_react.useCallback)((msg) => {
112
383
  setMessages((prev) => {
113
384
  const lastMessage = prev[prev.length - 1];
@@ -167,9 +438,9 @@ function useADKChat({
167
438
  [withEventMeta]
168
439
  );
169
440
  const storeEvents = (0, import_react.useCallback)((part, event) => {
170
- var _a, _b;
441
+ var _a2, _b2;
171
442
  let title = "";
172
- if (part == null && ((_a = event.actions) == null ? void 0 : _a.artifactDelta)) {
443
+ if (part == null && ((_a2 = event.actions) == null ? void 0 : _a2.artifactDelta)) {
173
444
  title += "eventAction: artifact";
174
445
  } else if (part) {
175
446
  if (part.text) {
@@ -179,7 +450,7 @@ function useADKChat({
179
450
  } else if (part.functionResponse) {
180
451
  title += `functionResponse:${part.functionResponse.name}`;
181
452
  } else if (part.executableCode) {
182
- title += `executableCode:${(_b = part.executableCode.code) == null ? void 0 : _b.slice(0, 10)}`;
453
+ title += `executableCode:${(_b2 = part.executableCode.code) == null ? void 0 : _b2.slice(0, 10)}`;
183
454
  } else if (part.codeExecutionResult) {
184
455
  title += `codeExecutionResult:${part.codeExecutionResult.outcome}`;
185
456
  } else if (part.errorMessage) {
@@ -193,7 +464,7 @@ function useADKChat({
193
464
  }, []);
194
465
  const storeMessage = (0, import_react.useCallback)(
195
466
  (part, event, role) => {
196
- var _a, _b;
467
+ var _a2, _b2;
197
468
  const msg = {
198
469
  id: (0, import_uuid.v4)(),
199
470
  author: event.author,
@@ -217,7 +488,7 @@ function useADKChat({
217
488
  } else if (part.text) {
218
489
  msg.text = part.text;
219
490
  msg.thought = part.thought;
220
- if ((_b = (_a = event == null ? void 0 : event.groundingMetadata) == null ? void 0 : _a.searchEntryPoint) == null ? void 0 : _b.renderedContent) {
491
+ if ((_b2 = (_a2 = event == null ? void 0 : event.groundingMetadata) == null ? void 0 : _a2.searchEntryPoint) == null ? void 0 : _b2.renderedContent) {
221
492
  msg.renderedContent = event.groundingMetadata.searchEntryPoint.renderedContent;
222
493
  }
223
494
  } else if (part.fileData) {
@@ -240,8 +511,8 @@ function useADKChat({
240
511
  );
241
512
  const processPart = (0, import_react.useCallback)(
242
513
  (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;
514
+ var _a2, _b2;
515
+ const renderedContent = (_b2 = (_a2 = event.groundingMetadata) == null ? void 0 : _a2.searchEntryPoint) == null ? void 0 : _b2.renderedContent;
245
516
  if (part.text) {
246
517
  if (ignore)
247
518
  return;
@@ -295,8 +566,8 @@ function useADKChat({
295
566
  );
296
567
  const processFollowupPart = (0, import_react.useCallback)(
297
568
  (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;
569
+ var _a2, _b2;
570
+ const part = ((_b2 = (_a2 = event == null ? void 0 : event.content) == null ? void 0 : _a2.parts) == null ? void 0 : _b2[0]) || null;
300
571
  const text = (part == null ? void 0 : part.text) || "";
301
572
  storeEvents(part, event);
302
573
  if (text) {
@@ -381,7 +652,7 @@ function useADKChat({
381
652
  content: rawData.data,
382
653
  invocationId: rawData.result.invocationId,
383
654
  sessionId: rawData.result.sessionId,
384
- id: rawData.result.invocationId
655
+ id: rawData.data.id || rawData.result.id || rawData.result.eventId || rawData.result.invocationId
385
656
  };
386
657
  }
387
658
  if (chunkJson.error) {
@@ -480,7 +751,7 @@ function useADKChat({
480
751
  }
481
752
  },
482
753
  onclose: () => {
483
- var _a;
754
+ var _a2;
484
755
  const isBackground = currentSessionIdRef.current !== targetSessionId;
485
756
  if (isBackground) {
486
757
  const bg = backgroundRef.current.get(targetSessionId);
@@ -491,7 +762,7 @@ function useADKChat({
491
762
  } else {
492
763
  setLoading(false);
493
764
  if (textMsgRef.current) {
494
- onMessage == null ? void 0 : onMessage(((_a = textMsgRef.current) == null ? void 0 : _a.text) || "", textMsgRef.current);
765
+ onMessage == null ? void 0 : onMessage(((_a2 = textMsgRef.current) == null ? void 0 : _a2.text) || "", textMsgRef.current);
495
766
  }
496
767
  textMsgRef.current = null;
497
768
  }
@@ -527,7 +798,7 @@ function useADKChat({
527
798
  files = [],
528
799
  functionResponse
529
800
  }) => {
530
- if (loading || sendingRef.current)
801
+ if (loadingRef.current || sendingRef.current)
531
802
  return;
532
803
  if (!text.trim() && !(files == null ? void 0 : files.length) && !functionResponse)
533
804
  return;
@@ -547,11 +818,11 @@ function useADKChat({
547
818
  id: (0, import_uuid.v4)(),
548
819
  role: "user",
549
820
  fileData: files.map((file) => {
550
- var _a, _b, _c;
821
+ var _a2, _b2, _c;
551
822
  return {
552
823
  displayName: file.fileName || file.name,
553
- mimeType: file.mimeType || ((_a = file.response) == null ? void 0 : _a.mimeType),
554
- fileUri: file.tempUrl || ((_b = file.response) == null ? void 0 : _b.fileUrl) || ((_c = file.response) == null ? void 0 : _c.tempUrl)
824
+ mimeType: file.mimeType || ((_a2 = file.response) == null ? void 0 : _a2.mimeType),
825
+ fileUri: file.tempUrl || ((_b2 = file.response) == null ? void 0 : _b2.fileUrl) || ((_c = file.response) == null ? void 0 : _c.tempUrl)
555
826
  };
556
827
  })
557
828
  });
@@ -574,10 +845,10 @@ function useADKChat({
574
845
  parts: functionResponse ? [{ functionResponse }] : [{ text }]
575
846
  },
576
847
  files: files.map((file) => {
577
- var _a, _b, _c, _d, _e, _f;
848
+ var _a2, _b2, _c, _d, _e, _f;
578
849
  return {
579
- fileName: file.fileName || ((_a = file.response) == null ? void 0 : _a.fileName),
580
- fileId: file.fileId || ((_b = file.response) == null ? void 0 : _b.fileId),
850
+ fileName: file.fileName || ((_a2 = file.response) == null ? void 0 : _a2.fileName),
851
+ fileId: file.fileId || ((_b2 = file.response) == null ? void 0 : _b2.fileId),
581
852
  tempUrl: file.tempUrl || ((_c = file.response) == null ? void 0 : _c.fileUrl) || ((_d = file.response) == null ? void 0 : _d.tempUrl),
582
853
  type: file.type || ((_e = file.response) == null ? void 0 : _e.fileType),
583
854
  mimeType: file.mimeType || ((_f = file.response) == null ? void 0 : _f.mimeType)
@@ -593,7 +864,7 @@ function useADKChat({
593
864
  initAppConversations();
594
865
  };
595
866
  const reChat = async () => {
596
- if (loading || sendingRef.current)
867
+ if (loadingRef.current || sendingRef.current)
597
868
  return;
598
869
  if (messages.length === 0)
599
870
  return;
@@ -632,8 +903,8 @@ function useADKChat({
632
903
  }
633
904
  };
634
905
  const confirmFnCall = (fnCall, confirmed) => {
635
- var _a;
636
- const functionResponse = ((_a = strategies == null ? void 0 : strategies.createFunctionResponse) == null ? void 0 : _a.call(
906
+ var _a2;
907
+ const functionResponse = ((_a2 = strategies == null ? void 0 : strategies.createFunctionResponse) == null ? void 0 : _a2.call(
637
908
  strategies,
638
909
  fnCall,
639
910
  confirmed
@@ -645,7 +916,7 @@ function useADKChat({
645
916
  startChat({ functionResponse });
646
917
  };
647
918
  const suggestChat = (text) => {
648
- if (loading)
919
+ if (loadingRef.current)
649
920
  return;
650
921
  if (!text.trim())
651
922
  return;
@@ -653,126 +924,43 @@ function useADKChat({
653
924
  startChat({ text });
654
925
  };
655
926
  const stopChat = (0, import_react.useCallback)(() => {
656
- var _a;
657
- (_a = ctrl.current) == null ? void 0 : _a.abort();
927
+ var _a2;
928
+ pendingSessionEventsRef.current = null;
929
+ cancelSessionEventsFlush();
930
+ sessionEventsSyncingRef.current = false;
931
+ (_a2 = ctrl.current) == null ? void 0 : _a2.abort();
658
932
  ctrl.current = null;
659
933
  setLoading(false);
660
934
  textMsgRef.current = null;
661
- }, []);
935
+ }, [cancelSessionEventsFlush, setLoading]);
662
936
  const clearChat = () => {
663
- var _a, _b;
937
+ var _a2, _b2;
664
938
  const newSessionId = (0, import_uuid.v4)();
665
939
  setCurrentSessionId(newSessionId);
666
940
  stopChat();
667
- setPrologue(((_a = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a.prologue) || "");
941
+ setPrologue(((_a2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a2.prologue) || "");
668
942
  setMessages([]);
669
- setSuggestedQuestions(((_b = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b.suggested_questions) || []);
670
- };
671
- const formatMessages = (messages2, isReplace = false) => {
672
- const mapped = [];
673
- messages2.forEach((item) => {
674
- if (!item || !item.content || !Array.isArray(item.content.parts))
675
- return;
676
- const role = (item.content.role || "").toLowerCase() === "user" ? "user" : "bot";
677
- const parts = Array.isArray(item.content.parts) ? item.content.parts.filter((p) => {
678
- if (!p)
679
- return false;
680
- return Boolean(
681
- p.text || p.inlineData || p.functionCall || p.functionResponse || p.fileData || p.executableCode || p.codeExecutionResult || p.errorMessage
682
- );
683
- }) : [];
684
- if (parts.length === 0)
685
- return;
686
- const textParts = parts.filter(
687
- (p) => p.text || p.errorMessage || p.inlineData
688
- );
689
- const fileDataParts = parts.filter((p) => p.fileData);
690
- const otherParts = parts.filter(
691
- (p) => !p.text && !p.errorMessage && !p.inlineData && !p.fileData
692
- );
693
- if (textParts.length > 0 || fileDataParts.length > 0) {
694
- const msg = {
695
- id: (0, import_uuid.v4)(),
696
- author: item.author,
697
- invocationId: item.invocationId,
698
- eventId: item.id,
699
- timestamp: item.timestamp,
700
- isLike: item.isLike,
701
- role,
702
- modelCode: item.modelCode,
703
- usageMetadata: item.usageMetadata,
704
- finishReason: item.finishReason,
705
- raw: item
706
- };
707
- for (const part of textParts) {
708
- if (part.inlineData) {
709
- msg.inlineData = {
710
- displayName: part.inlineData.displayName,
711
- data: part.inlineData.data,
712
- mimeType: part.inlineData.mimeType
713
- };
714
- }
715
- if (part.text) {
716
- msg.text = (msg.text ? msg.text + "\n" : "") + part.text;
717
- if (typeof part.thought !== "undefined")
718
- msg.thought = part.thought;
719
- }
720
- if (part.errorMessage) {
721
- msg.text = (msg.text ? msg.text + "\n" : "") + part.errorMessage;
722
- }
723
- }
724
- if (fileDataParts.length > 0) {
725
- msg.fileData = fileDataParts.map((part) => ({
726
- displayName: part.fileData.displayName || "",
727
- fileUri: part.fileData.fileUri,
728
- mimeType: part.fileData.mimeType
729
- }));
730
- }
731
- mapped.push(msg);
732
- }
733
- otherParts.forEach((part) => {
734
- const msg = {
735
- id: (0, import_uuid.v4)(),
736
- author: item.author,
737
- invocationId: item.invocationId,
738
- eventId: item.id,
739
- timestamp: item.timestamp,
740
- isLike: item.isLike,
741
- role,
742
- modelCode: item.modelCode,
743
- usageMetadata: item.usageMetadata,
744
- finishReason: item.finishReason,
745
- raw: item
746
- };
747
- if (part.functionCall)
748
- msg.functionCall = part.functionCall;
749
- if (part.executableCode)
750
- msg.executableCode = part.executableCode;
751
- if (part.codeExecutionResult)
752
- msg.codeExecutionResult = part.codeExecutionResult;
753
- if (part.functionResponse) {
754
- const functionCallMsg = mapped.find(
755
- (msg2) => {
756
- var _a, _b;
757
- return ((_a = msg2.functionCall) == null ? void 0 : _a.id) === ((_b = part.functionResponse) == null ? void 0 : _b.id);
758
- }
759
- );
760
- if (functionCallMsg) {
761
- functionCallMsg.functionResponse = part.functionResponse;
762
- }
763
- return;
764
- }
765
- mapped.push(msg);
766
- });
767
- });
768
- setMessages((prev) => isReplace ? mapped : [...prev, ...mapped]);
943
+ setSuggestedQuestions(((_b2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b2.suggested_questions) || []);
769
944
  };
945
+ const formatMessages = (0, import_react.useCallback)(
946
+ (sessionEvents, isReplace = false) => {
947
+ const mapped = mapSessionMessages(sessionEvents);
948
+ setMessages((prev) => isReplace ? mapped : [...prev, ...mapped]);
949
+ },
950
+ []
951
+ );
770
952
  const setCurrentSession = async (sessionId) => {
771
- var _a, _b;
953
+ var _a2, _b2;
772
954
  if (sessionId) {
773
955
  if (sessionId === currentSessionId) {
774
956
  return;
775
957
  }
958
+ pendingSessionEventsRef.current = null;
959
+ cancelSessionEventsFlush();
960
+ if (sessionEventsSyncingRef.current) {
961
+ sessionEventsSyncingRef.current = false;
962
+ setLoading(false);
963
+ }
776
964
  const prevSessionId = currentSessionId;
777
965
  if (ctrl.current) {
778
966
  backgroundRef.current.set(prevSessionId, {
@@ -805,29 +993,34 @@ function useADKChat({
805
993
  }
806
994
  setInitialized(false);
807
995
  setCurrentSessionId(sessionId);
808
- const { data, result } = await (0, import_api.fetchSessionDetail)({
809
- url,
810
- appNo,
811
- sessionId,
812
- token: tokenRef.current
813
- });
814
- if ((result == null ? void 0 : result.code) === import_constants.API_SUCCESS_CODE) {
815
- setPrologue(((_a = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a.prologue) || "");
816
- if (Array.isArray(data) && data.length > 0) {
817
- formatMessages(data, true);
818
- } else {
819
- setSuggestedQuestions(
820
- ((_b = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b.suggested_questions) || []
821
- );
996
+ sessionDetailLoadingRef.current = true;
997
+ try {
998
+ const { data, result } = await (0, import_api.fetchSessionDetail)({
999
+ url,
1000
+ appNo,
1001
+ sessionId,
1002
+ token: tokenRef.current
1003
+ });
1004
+ if ((result == null ? void 0 : result.code) === import_constants.API_SUCCESS_CODE) {
1005
+ setPrologue(((_a2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a2.prologue) || "");
1006
+ if (Array.isArray(data) && data.length > 0) {
1007
+ formatMessages(data, true);
1008
+ } else {
1009
+ setSuggestedQuestions(
1010
+ ((_b2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b2.suggested_questions) || []
1011
+ );
1012
+ }
822
1013
  }
1014
+ } finally {
1015
+ sessionDetailLoadingRef.current = false;
1016
+ setInitialized(true);
823
1017
  }
824
- setInitialized(true);
825
1018
  } else {
826
1019
  setCurrentSessionId((0, import_uuid.v4)());
827
1020
  }
828
1021
  };
829
1022
  const initAppConversations = async (fetchDetail = false) => {
830
- var _a, _b;
1023
+ var _a2, _b2;
831
1024
  try {
832
1025
  setSessionLoading(true);
833
1026
  const {
@@ -863,9 +1056,9 @@ function useADKChat({
863
1056
  if (showFirstSession) {
864
1057
  setCurrentSession(sessionId);
865
1058
  } else {
866
- fetchDetail && setPrologue(((_a = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a.prologue) || "");
1059
+ fetchDetail && setPrologue(((_a2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a2.prologue) || "");
867
1060
  fetchDetail && setSuggestedQuestions(
868
- ((_b = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b.suggested_questions) || []
1061
+ ((_b2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _b2.suggested_questions) || []
869
1062
  );
870
1063
  }
871
1064
  if (!initialized) {
@@ -992,17 +1185,59 @@ function useADKChat({
992
1185
  initAppConversations(true);
993
1186
  }
994
1187
  }, [appInfo]);
1188
+ (0, import_react.useEffect)(() => {
1189
+ if (!enabled || !initialized || !pollSessionEvents || !appNo || !currentSessionId)
1190
+ return;
1191
+ let disposed = false;
1192
+ let requesting = false;
1193
+ const pollingSessionId = currentSessionId;
1194
+ const poll = async () => {
1195
+ if (requesting || sessionDetailLoadingRef.current)
1196
+ return;
1197
+ requesting = true;
1198
+ try {
1199
+ const { data, result } = await (0, import_api.fetchSessionDetail)({
1200
+ url,
1201
+ appNo,
1202
+ sessionId: pollingSessionId,
1203
+ token: tokenRef.current
1204
+ });
1205
+ if (!disposed && (result == null ? void 0 : result.code) === import_constants.API_SUCCESS_CODE && Array.isArray(data)) {
1206
+ syncSessionEvents(data, pollingSessionId);
1207
+ }
1208
+ } catch {
1209
+ } finally {
1210
+ requesting = false;
1211
+ }
1212
+ };
1213
+ void poll();
1214
+ const timer = window.setInterval(poll, sessionEventsPollingInterval);
1215
+ return () => {
1216
+ disposed = true;
1217
+ window.clearInterval(timer);
1218
+ };
1219
+ }, [
1220
+ appNo,
1221
+ currentSessionId,
1222
+ enabled,
1223
+ initialized,
1224
+ pollSessionEvents,
1225
+ sessionEventsPollingInterval,
1226
+ syncSessionEvents,
1227
+ url
1228
+ ]);
995
1229
  (0, import_react.useEffect)(() => {
996
1230
  return () => {
997
- var _a;
998
- (_a = ctrl.current) == null ? void 0 : _a.abort();
1231
+ var _a2;
1232
+ cancelSessionEventsFlush();
1233
+ (_a2 = ctrl.current) == null ? void 0 : _a2.abort();
999
1234
  backgroundRef.current.forEach((bg) => {
1000
- var _a2;
1001
- return (_a2 = bg.ctrl) == null ? void 0 : _a2.abort();
1235
+ var _a3;
1236
+ return (_a3 = bg.ctrl) == null ? void 0 : _a3.abort();
1002
1237
  });
1003
1238
  backgroundRef.current.clear();
1004
1239
  };
1005
- }, []);
1240
+ }, [cancelSessionEventsFlush]);
1006
1241
  return {
1007
1242
  appInfo,
1008
1243
  startChat,