@ai-group/chat-sdk 3.6.6 → 3.6.8

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/components/XAdkChatbot/components/FunctionCallRender/index.tsx"],
4
- "sourcesContent": ["import React from \"react\";\nimport { Alert, Button, Flex, Form, Popover, Tooltip, Typography } from \"antd\";\nimport {\n CopyOutlined,\n ToolOutlined,\n CheckCircleTwoTone,\n LoadingOutlined,\n UserSwitchOutlined,\n InfoCircleOutlined,\n} from \"@ant-design/icons\";\nimport type { FunctionCallRenderProps, FunctionCall } from \"@/types\";\nimport { useStyles } from \"./styles\";\nimport { defaultToolKindResolver } from \"@/types/FunctionCallRender\";\nimport JsonView from \"@/components/XAiJsonView\";\n\nconst FunctionCallRender: React.FC<FunctionCallRenderProps> = ({\n msg,\n showDetail,\n onConfirm,\n kind: kindProp,\n toolKindResolver = defaultToolKindResolver,\n renderApproval,\n renderHandoff,\n}) => {\n const styles = useStyles();\n const fnCall = msg.functionCall as FunctionCall;\n const fnRes = msg.functionResponse;\n const name = fnCall?.name || fnRes?.name;\n const kind = kindProp ?? toolKindResolver(name);\n\n if (kind === \"approval\") {\n if (renderApproval) {\n const custom = renderApproval(msg, onConfirm);\n if (custom !== null && custom !== undefined) return <>{custom}</>;\n }\n if (fnRes) {\n if (msg.role === \"bot\") return null;\n const confirmed = fnRes.response?.confirmed;\n return (\n <div key={msg.id} className={styles.wrapper}>\n {confirmed ? (\n <Alert\n message=\"已确认\"\n type=\"success\"\n showIcon\n className={styles.alert}\n />\n ) : (\n <Alert\n message=\"已取消\"\n type=\"error\"\n showIcon\n className={styles.alert}\n />\n )}\n </div>\n );\n }\n const originalFn = msg?.functionCall?.args?.originalFunctionCall;\n return (\n <div\n key={msg.id}\n className={styles.wrapper}\n style={{ justifyContent: \"flex-end\" }}\n >\n <div className={styles.confirm}>\n <div className={styles.confirmText}>\n 请确认是否执行工具:{originalFn?.name}\n </div>\n <Flex justify=\"end\" gap={8}>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={() => onConfirm?.(fnCall, false)}\n >\n 取消\n </Button>\n <Button\n type=\"primary\"\n size=\"small\"\n onClick={() => onConfirm?.(fnCall, true)}\n >\n 确认\n </Button>\n </Flex>\n </div>\n </div>\n );\n }\n if (kind === \"handoff\") {\n if (renderHandoff) {\n const custom = renderHandoff(msg);\n if (custom !== null && custom !== undefined) return <>{custom}</>;\n }\n const agentName = fnCall?.args?.agentName;\n return (\n <div key={msg.id} className={styles.wrapper}>\n <div className={styles.fnCall}>\n <UserSwitchOutlined style={{ color: \"#888\" }} />\n <Typography.Text\n ellipsis={{ tooltip: agentName }}\n style={{ maxWidth: 300, lineHeight: \"16px\" }}\n >\n 任务转交:{agentName}\n </Typography.Text>\n {msg.functionResponse ? (\n <CheckCircleTwoTone twoToneColor=\"#52c41a\" />\n ) : (\n <LoadingOutlined />\n )}\n </div>\n </div>\n );\n }\n const renderItem = (obj: any, text: string) => {\n const str = JSON.stringify(obj, null, 2);\n return (\n <Form.Item\n label={\n <Flex align=\"center\">\n <span className=\"mr-2\">{text}</span>\n <Typography.Text\n copyable={{\n text: str,\n icon: <CopyOutlined />,\n }}\n />\n </Flex>\n }\n style={{ marginBottom: 12 }}\n >\n <JsonView value={str} />\n </Form.Item>\n );\n };\n const renderResponse = () => {\n const res = msg.functionResponse;\n if (res) {\n if (res.response?.error) {\n return (\n <Tooltip title={res.response.error}>\n <InfoCircleOutlined style={{ color: \"#faad14\" }} />\n </Tooltip>\n );\n }\n return <CheckCircleTwoTone twoToneColor=\"#52c41a\" />;\n }\n return <LoadingOutlined />;\n };\n return (\n <div key={msg.id} className={styles.wrapper}>\n {showDetail ? (\n <Popover\n placement=\"left\"\n content={\n <Form style={{ width: 400 }} layout=\"vertical\">\n {renderItem(fnCall?.args, \"工具参数\")}\n {renderItem(msg.functionResponse?.response, \"工具响应\")}\n </Form>\n }\n >\n <div className={styles.fnCall}>\n <ToolOutlined style={{ color: \"#888\" }} />\n <Typography.Text\n ellipsis={{ tooltip: name }}\n style={{ maxWidth: 300, lineHeight: \"16px\" }}\n >\n 调用工具:{name}\n </Typography.Text>\n {renderResponse()}\n </div>\n </Popover>\n ) : (\n <div className={styles.fnCall}>\n <ToolOutlined style={{ color: \"#888\" }} />\n <Typography.Text\n ellipsis={{ tooltip: name }}\n style={{ maxWidth: 300, lineHeight: \"16px\" }}\n >\n 调用工具:{name}\n </Typography.Text>\n {renderResponse()}\n </div>\n )}\n </div>\n );\n};\n\nexport default FunctionCallRender;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import React from \"react\";\nimport { Alert, Button, Flex, Form, Popover, Tooltip, Typography } from \"antd\";\nimport {\n CopyOutlined,\n ToolOutlined,\n CheckCircleTwoTone,\n LoadingOutlined,\n UserSwitchOutlined,\n InfoCircleOutlined,\n} from \"@ant-design/icons\";\nimport type { FunctionCallRenderProps, FunctionCall } from \"@/types\";\nimport { useStyles } from \"./styles\";\nimport { defaultToolKindResolver } from \"@/types/FunctionCallRender\";\nimport JsonView from \"@/components/XAiJsonView\";\n\n// 工具调用组件\nconst FunctionCallRender: React.FC<FunctionCallRenderProps> = ({\n msg,\n showDetail,\n onConfirm,\n kind: kindProp,\n toolKindResolver = defaultToolKindResolver,\n renderApproval,\n renderHandoff,\n}) => {\n const styles = useStyles();\n const fnCall = msg.functionCall as FunctionCall;\n const fnRes = msg.functionResponse;\n const name = fnCall?.name || fnRes?.name;\n const kind = kindProp ?? toolKindResolver(name);\n\n if (kind === \"approval\") {\n if (renderApproval) {\n const custom = renderApproval(msg, onConfirm);\n if (custom !== null && custom !== undefined) return <>{custom}</>;\n }\n if (fnRes) {\n if (msg.role === \"bot\") return null;\n const confirmed = fnRes.response?.confirmed;\n return (\n <div key={msg.id} className={styles.wrapper}>\n {confirmed ? (\n <Alert\n message=\"已确认\"\n type=\"success\"\n showIcon\n className={styles.alert}\n />\n ) : (\n <Alert\n message=\"已取消\"\n type=\"error\"\n showIcon\n className={styles.alert}\n />\n )}\n </div>\n );\n }\n const originalFn = msg?.functionCall?.args?.originalFunctionCall;\n return (\n <div\n key={msg.id}\n className={styles.wrapper}\n style={{ justifyContent: \"flex-end\" }}\n >\n <div className={styles.confirm}>\n <div className={styles.confirmText}>\n 请确认是否执行工具:{originalFn?.name}\n </div>\n <Flex justify=\"end\" gap={8}>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={() => onConfirm?.(fnCall, false)}\n >\n 取消\n </Button>\n <Button\n type=\"primary\"\n size=\"small\"\n onClick={() => onConfirm?.(fnCall, true)}\n >\n 确认\n </Button>\n </Flex>\n </div>\n </div>\n );\n }\n if (kind === \"handoff\") {\n if (renderHandoff) {\n const custom = renderHandoff(msg);\n if (custom !== null && custom !== undefined) return <>{custom}</>;\n }\n const agentName = fnCall?.args?.agentName;\n return (\n <div key={msg.id} className={styles.wrapper}>\n <div className={styles.fnCall}>\n <UserSwitchOutlined style={{ color: \"#888\" }} />\n <Typography.Text\n ellipsis={{ tooltip: agentName }}\n style={{ maxWidth: 300, lineHeight: \"16px\" }}\n >\n 任务转交:{agentName}\n </Typography.Text>\n {msg.functionResponse ? (\n <CheckCircleTwoTone twoToneColor=\"#52c41a\" />\n ) : (\n <LoadingOutlined />\n )}\n </div>\n </div>\n );\n }\n const renderItem = (obj: any, text: string) => {\n const str = JSON.stringify(obj, null, 2);\n return (\n <Form.Item\n label={\n <Flex align=\"center\">\n <span className=\"mr-2\">{text}</span>\n <Typography.Text\n copyable={{\n text: str,\n icon: <CopyOutlined />,\n }}\n />\n </Flex>\n }\n style={{ marginBottom: 12 }}\n >\n <JsonView value={str} />\n </Form.Item>\n );\n };\n const renderResponse = () => {\n const res = msg.functionResponse;\n if (res) {\n if (res.response?.error) {\n return (\n <Tooltip title={res.response.error}>\n <InfoCircleOutlined style={{ color: \"#faad14\" }} />\n </Tooltip>\n );\n }\n return <CheckCircleTwoTone twoToneColor=\"#52c41a\" />;\n }\n return <LoadingOutlined />;\n };\n return (\n <div key={msg.id} className={styles.wrapper}>\n {showDetail ? (\n <Popover\n placement=\"left\"\n content={\n <Form style={{ width: 400 }} layout=\"vertical\">\n {renderItem(fnCall?.args, \"工具参数\")}\n {renderItem(msg.functionResponse?.response, \"工具响应\")}\n </Form>\n }\n >\n <div className={styles.fnCall}>\n <ToolOutlined style={{ color: \"#888\" }} />\n <Typography.Text\n ellipsis={{ tooltip: name }}\n style={{ maxWidth: 300, lineHeight: \"16px\" }}\n >\n 调用工具:{name}\n </Typography.Text>\n {renderResponse()}\n </div>\n </Popover>\n ) : (\n <div className={styles.fnCall}>\n <ToolOutlined style={{ color: \"#888\" }} />\n <Typography.Text\n ellipsis={{ tooltip: name }}\n style={{ maxWidth: 300, lineHeight: \"16px\" }}\n >\n 调用工具:{name}\n </Typography.Text>\n {renderResponse()}\n </div>\n )}\n </div>\n );\n};\n\nexport default FunctionCallRender;\n"],
5
+ "mappings": "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",
6
6
  "names": ["JsonView", "_a"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import { DebugOptions, FunctionCall, SendContent, SessionData, Event, IMessage, Part } from "../types";
3
3
  import { type ChatConfig } from "../services/api";
4
- declare function useADKChat({ url, token, config, type, enabled, // ← 新增: 是否启用 Hook
4
+ declare function useADKChat({ url, token, config, type: _type, enabled, // ← 新增: 是否启用 Hook
5
5
  strategies, onError, onMessage, onSuccess, onStream, }: DebugOptions): {
6
6
  appInfo: ChatConfig | null;
7
7
  startChat: ({ text, files, functionResponse, }: SendContent) => Promise<void>;
@@ -24,7 +24,7 @@ strategies, onError, onMessage, onSuccess, onStream, }: DebugOptions): {
24
24
  sessionLoading: boolean;
25
25
  messages: IMessage[];
26
26
  insertSuggestedQuestions: (suggested_questions?: string[]) => void;
27
- insertPrologue: (prologue: string) => void;
27
+ insertPrologue: (prologueText: string) => void;
28
28
  deleteSession: (sessionId: string) => Promise<void>;
29
29
  updateSession: (sessionId: string, title: string) => Promise<void>;
30
30
  setSuggestedQuestions: import("react").Dispatch<import("react").SetStateAction<string[]>>;
@@ -50,14 +50,46 @@ var combineTextParts = (parts) => {
50
50
  return result;
51
51
  };
52
52
  var DEFAULT_SESSION_EVENTS_POLLING_INTERVAL = 1e4;
53
+ var buildNonTextMessage = (event, part, role = "bot") => {
54
+ const msg = {
55
+ id: (0, import_uuid.v4)(),
56
+ author: event.author,
57
+ invocationId: event.invocationId,
58
+ eventId: event.id,
59
+ timestamp: event.timestamp,
60
+ isLike: event.isLike || 0,
61
+ role,
62
+ modelCode: event.modelCode,
63
+ usageMetadata: event.usageMetadata,
64
+ finishReason: event.finishReason,
65
+ raw: event
66
+ };
67
+ if (part.inlineData) {
68
+ msg.inlineData = {
69
+ displayName: part.inlineData.displayName,
70
+ data: part.inlineData.data,
71
+ mimeType: part.inlineData.mimeType
72
+ };
73
+ } else if (part.fileData) {
74
+ msg.fileData = [part.fileData];
75
+ } else if (part.functionCall) {
76
+ msg.functionCall = part.functionCall;
77
+ } else if (part.functionResponse) {
78
+ msg.functionResponse = part.functionResponse;
79
+ } else if (part.executableCode) {
80
+ msg.executableCode = part.executableCode;
81
+ } else if (part.codeExecutionResult) {
82
+ msg.codeExecutionResult = part.codeExecutionResult;
83
+ } else if (part.text) {
84
+ msg.text = part.text;
85
+ msg.thought = part.thought;
86
+ }
87
+ return msg;
88
+ };
53
89
  var getMessageEventId = (messageItem) => {
54
90
  var _a;
55
91
  return messageItem.eventId || ((_a = messageItem.raw) == null ? void 0 : _a.id);
56
92
  };
57
- var getMessageInvocationId = (messageItem) => {
58
- var _a;
59
- return messageItem.invocationId || ((_a = messageItem.raw) == null ? void 0 : _a.invocationId);
60
- };
61
93
  var deduplicateMessages = (messageItems) => {
62
94
  const seenMessageIds = /* @__PURE__ */ new Set();
63
95
  let hasDuplicate = false;
@@ -71,14 +103,14 @@ var deduplicateMessages = (messageItems) => {
71
103
  });
72
104
  const botTextGroups = /* @__PURE__ */ new Map();
73
105
  uniqueIdMessages.forEach((messageItem) => {
74
- const invocationId = getMessageInvocationId(messageItem);
75
- if (messageItem.role !== "bot" || !invocationId || typeof messageItem.text !== "string")
106
+ const eventId = getMessageEventId(messageItem);
107
+ if (messageItem.role !== "bot" || !eventId || typeof messageItem.text !== "string")
76
108
  return;
77
109
  const normalizedText = messageItem.text.replace(/\s+/g, " ").trim();
78
110
  if (!normalizedText)
79
111
  return;
80
112
  const fileKey = (messageItem.fileData || []).map((file) => file.fileUri).join("|");
81
- const groupKey = `${invocationId}\0${Boolean(
113
+ const groupKey = `${eventId}\0${Boolean(
82
114
  messageItem.thought
83
115
  )}\0${fileKey}`;
84
116
  const group = botTextGroups.get(groupKey) || [];
@@ -110,6 +142,8 @@ var mapSessionMessages = (sessionEvents) => {
110
142
  return;
111
143
  if (item.author === "user" && item.content.parts.some((part) => part.task))
112
144
  return;
145
+ if (item.content.role === "user" && item.content.parts.every((part) => !part || part.functionResponse))
146
+ return;
113
147
  const role = (item.content.role || "").toLowerCase() === "user" ? "user" : "bot";
114
148
  const parts = item.content.parts.filter((part) => {
115
149
  if (!part)
@@ -127,9 +161,10 @@ var mapSessionMessages = (sessionEvents) => {
127
161
  const otherParts = parts.filter(
128
162
  (part) => !part.text && !part.errorMessage && !part.inlineData && !part.fileData
129
163
  );
164
+ let partCounter = 0;
130
165
  if (textParts.length > 0 || fileDataParts.length > 0) {
131
166
  const messageItem = {
132
- id: (0, import_uuid.v4)(),
167
+ id: `session-event:${item.id}:${partCounter++}`,
133
168
  author: item.author,
134
169
  invocationId: item.invocationId,
135
170
  eventId: item.id,
@@ -171,7 +206,7 @@ var mapSessionMessages = (sessionEvents) => {
171
206
  }
172
207
  otherParts.forEach((part) => {
173
208
  const messageItem = {
174
- id: (0, import_uuid.v4)(),
209
+ id: `session-event:${item.id}:${partCounter++}`,
175
210
  author: item.author,
176
211
  invocationId: item.invocationId,
177
212
  eventId: item.id,
@@ -206,64 +241,54 @@ var mapSessionMessages = (sessionEvents) => {
206
241
  });
207
242
  return mapped;
208
243
  };
209
- var getComparableMessageContent = (messageItem) => {
210
- var _a;
211
- return JSON.stringify({
212
- role: messageItem.role,
213
- text: ((_a = messageItem.text) == null ? void 0 : _a.replace(/\r\n/g, "\n").trim()) || "",
214
- thought: Boolean(messageItem.thought),
215
- inlineData: messageItem.inlineData || null,
216
- fileData: messageItem.fileData || null,
217
- functionCall: messageItem.functionCall || null,
218
- functionResponse: messageItem.functionResponse || null,
219
- executableCode: messageItem.executableCode || null,
220
- codeExecutionResult: messageItem.codeExecutionResult || null
221
- });
222
- };
223
- var isStreamMessageWithoutServerEventId = (messageItem) => {
224
- const eventId = getMessageEventId(messageItem);
225
- return Boolean(messageItem.invocationId) && (!eventId || eventId === messageItem.invocationId);
226
- };
227
- var insertMissingSessionEvents = (currentMessages, sessionEvents) => {
244
+ var insertMissingSessionEvents = (currentMessages, sessionEvents, removedInvocationIds) => {
228
245
  const renderedEventIds = new Set(
229
246
  currentMessages.map(getMessageEventId).filter(Boolean)
230
247
  );
231
- const unmatchedStreamMessageIndexes = new Set(
232
- currentMessages.map(
233
- (messageItem, index) => isStreamMessageWithoutServerEventId(messageItem) ? index : -1
234
- ).filter((index) => index >= 0)
235
- );
248
+ let nextMessages = [...currentMessages];
249
+ const fnResMap = /* @__PURE__ */ new Map();
250
+ sessionEvents.forEach((event) => {
251
+ var _a, _b;
252
+ if (((_a = event.content) == null ? void 0 : _a.role) !== "user" || !Array.isArray((_b = event.content) == null ? void 0 : _b.parts))
253
+ return;
254
+ event.content.parts.forEach((p) => {
255
+ var _a2;
256
+ if ((_a2 = p.functionResponse) == null ? void 0 : _a2.id) {
257
+ fnResMap.set(p.functionResponse.id, p.functionResponse);
258
+ }
259
+ });
260
+ });
261
+ if (fnResMap.size > 0) {
262
+ let paired = false;
263
+ nextMessages = nextMessages.map((msg) => {
264
+ if (msg.functionCall && !msg.functionResponse) {
265
+ const callId = msg.functionCall.id;
266
+ if (callId && fnResMap.has(callId)) {
267
+ paired = true;
268
+ return { ...msg, functionResponse: fnResMap.get(callId) };
269
+ }
270
+ }
271
+ return msg;
272
+ });
273
+ if (!paired)
274
+ nextMessages = currentMessages;
275
+ }
236
276
  const missingEvents = sessionEvents.filter((event) => {
237
277
  var _a, _b;
238
278
  const parts = (_a = event.content) == null ? void 0 : _a.parts;
239
279
  const canRender = Boolean(event.id) && ((_b = event.content) == null ? void 0 : _b.role) === "model" && Array.isArray(parts) && parts.length > 0;
240
280
  if (!canRender || renderedEventIds.has(event.id))
241
281
  return false;
242
- const eventMessages = mapSessionMessages([event]);
243
- const matchedIndexes = [];
244
- const isRenderedByStream = eventMessages.length > 0 && eventMessages.every((eventMessage) => {
245
- const comparableContent = getComparableMessageContent(eventMessage);
246
- const matchedIndex = currentMessages.findIndex(
247
- (currentMessage, index) => unmatchedStreamMessageIndexes.has(index) && !matchedIndexes.includes(index) && currentMessage.invocationId === eventMessage.invocationId && getComparableMessageContent(currentMessage) === comparableContent
248
- );
249
- if (matchedIndex < 0)
250
- return false;
251
- matchedIndexes.push(matchedIndex);
252
- return true;
253
- });
254
- if (isRenderedByStream) {
255
- matchedIndexes.forEach(
256
- (index) => unmatchedStreamMessageIndexes.delete(index)
257
- );
282
+ if (removedInvocationIds && removedInvocationIds.size > 0 && event.invocationId && removedInvocationIds.has(event.invocationId)) {
258
283
  return false;
259
284
  }
260
285
  return true;
261
286
  });
262
287
  if (missingEvents.length === 0)
263
- return currentMessages;
288
+ return nextMessages;
264
289
  const missingMessages = mapSessionMessages(missingEvents);
265
290
  if (missingMessages.length === 0)
266
- return currentMessages;
291
+ return nextMessages;
267
292
  const eventOrder = new Map(
268
293
  sessionEvents.map((event, index) => [event.id, index])
269
294
  );
@@ -281,7 +306,6 @@ var insertMissingSessionEvents = (currentMessages, sessionEvents) => {
281
306
  }
282
307
  return Number.POSITIVE_INFINITY;
283
308
  };
284
- const nextMessages = [...currentMessages];
285
309
  missingMessages.forEach((messageItem) => {
286
310
  const targetOrder = getMessageOrder(messageItem);
287
311
  let insertIndex = nextMessages.findIndex((currentMessage) => {
@@ -298,7 +322,7 @@ function useADKChat({
298
322
  url = window.location.origin,
299
323
  token,
300
324
  config = {},
301
- type = "agentDebug",
325
+ type: _type = "agentDebug",
302
326
  enabled = true,
303
327
  // ← 新增: 是否启用 Hook
304
328
  strategies,
@@ -338,10 +362,9 @@ function useADKChat({
338
362
  const [suggestedQuestions, setSuggestedQuestions] = (0, import_react.useState)([]);
339
363
  const [messages, setMessages] = (0, import_react.useState)([]);
340
364
  const pendingSessionEventsRef = (0, import_react.useRef)(null);
341
- const sessionEventsFlushTimerRef = (0, import_react.useRef)(null);
342
- const sessionEventsSyncingRef = (0, import_react.useRef)(false);
343
365
  const sessionDetailLoadingRef = (0, import_react.useRef)(false);
344
366
  const stateDeltaRef = (0, import_react.useRef)(void 0);
367
+ const reChatRemovedInvocationIdsRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
345
368
  const backgroundRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
346
369
  const messagesRef = (0, import_react.useRef)(messages);
347
370
  messagesRef.current = messages;
@@ -369,42 +392,24 @@ function useADKChat({
369
392
  }, [messages]);
370
393
  const textMsgRef = (0, import_react.useRef)(null);
371
394
  const eventDataRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
372
- const cancelSessionEventsFlush = (0, import_react.useCallback)(() => {
373
- if (sessionEventsFlushTimerRef.current === null)
374
- return;
375
- clearTimeout(sessionEventsFlushTimerRef.current);
376
- sessionEventsFlushTimerRef.current = null;
377
- }, []);
378
395
  const flushPendingSessionEvents = (0, import_react.useCallback)(() => {
379
396
  const pending = pendingSessionEventsRef.current;
380
- const replyInProgress = loadingRef.current || sendingRef.current || textMsgRef.current !== null;
397
+ const replyInProgress = sendingRef.current || textMsgRef.current !== null;
381
398
  if (!pending || replyInProgress || pending.sessionId !== currentSessionIdRef.current)
382
399
  return;
383
- const previewMessages = insertMissingSessionEvents(
384
- messagesRef.current,
385
- pending.events
386
- );
387
400
  pendingSessionEventsRef.current = null;
388
- if (previewMessages === messagesRef.current)
389
- return;
390
- sessionEventsSyncingRef.current = true;
391
- setLoading(true);
392
- sessionEventsFlushTimerRef.current = setTimeout(() => {
393
- sessionEventsFlushTimerRef.current = null;
394
- if (pending.sessionId === currentSessionIdRef.current) {
395
- setMessages((prev) => {
396
- const nextMessages = insertMissingSessionEvents(
397
- prev,
398
- pending.events
399
- );
400
- messagesRef.current = nextMessages;
401
- return nextMessages;
402
- });
403
- }
404
- sessionEventsSyncingRef.current = false;
405
- setLoading(false);
406
- }, 0);
407
- }, [setLoading]);
401
+ setMessages((prev) => {
402
+ const nextMessages = insertMissingSessionEvents(
403
+ prev,
404
+ pending.events,
405
+ reChatRemovedInvocationIdsRef.current
406
+ );
407
+ if (nextMessages === prev)
408
+ return prev;
409
+ messagesRef.current = nextMessages;
410
+ return nextMessages;
411
+ });
412
+ }, []);
408
413
  const syncSessionEvents = (0, import_react.useCallback)(
409
414
  (events, targetSessionId) => {
410
415
  if (targetSessionId !== currentSessionIdRef.current)
@@ -419,12 +424,7 @@ function useADKChat({
419
424
  );
420
425
  (0, import_react.useEffect)(() => {
421
426
  pendingSessionEventsRef.current = null;
422
- cancelSessionEventsFlush();
423
- if (sessionEventsSyncingRef.current) {
424
- sessionEventsSyncingRef.current = false;
425
- setLoading(false);
426
- }
427
- }, [cancelSessionEventsFlush, currentSessionId, setLoading]);
427
+ }, [currentSessionId]);
428
428
  (0, import_react.useEffect)(() => {
429
429
  if (!loading)
430
430
  flushPendingSessionEvents();
@@ -438,18 +438,21 @@ function useADKChat({
438
438
  return [...prev, msg];
439
439
  });
440
440
  }, []);
441
- const insertSuggestedQuestions = (suggested_questions = []) => {
442
- if (!(suggested_questions == null ? void 0 : suggested_questions.length))
443
- return;
444
- if (messages.length === 0 && suggested_questions.length) {
445
- setSuggestedQuestions(suggested_questions);
446
- }
447
- };
448
- const insertPrologue = (prologue2) => {
449
- if (prologue2) {
450
- setPrologue(prologue2);
441
+ const insertSuggestedQuestions = (0, import_react.useCallback)(
442
+ (suggested_questions = []) => {
443
+ if (!(suggested_questions == null ? void 0 : suggested_questions.length))
444
+ return;
445
+ setSuggestedQuestions(
446
+ (prev) => messages.length === 0 ? suggested_questions : prev
447
+ );
448
+ },
449
+ [messages.length]
450
+ );
451
+ const insertPrologue = (0, import_react.useCallback)((prologueText) => {
452
+ if (prologueText) {
453
+ setPrologue(prologueText);
451
454
  }
452
- };
455
+ }, []);
453
456
  const updateMessage = (0, import_react.useCallback)((msg) => {
454
457
  setMessages((prev) => {
455
458
  return prev.map((m) => {
@@ -515,47 +518,13 @@ function useADKChat({
515
518
  const storeMessage = (0, import_react.useCallback)(
516
519
  (part, event, role) => {
517
520
  var _a2, _b2;
518
- const msg = {
519
- id: (0, import_uuid.v4)(),
520
- author: event.author,
521
- invocationId: event.invocationId,
522
- eventId: event.id,
523
- timestamp: event.timestamp,
524
- isLike: event.isLike || 0,
525
- role,
526
- modelCode: event.modelCode,
527
- usageMetadata: event.usageMetadata,
528
- finishReason: event.finishReason,
529
- raw: event
530
- };
531
- if (part) {
532
- if (part.inlineData) {
533
- msg.inlineData = {
534
- displayName: part.inlineData.displayName,
535
- data: part.inlineData.data,
536
- mimeType: part.inlineData.mimeType
537
- };
538
- } else if (part.text) {
539
- msg.text = part.text;
540
- msg.thought = part.thought;
541
- if ((_b2 = (_a2 = event == null ? void 0 : event.groundingMetadata) == null ? void 0 : _a2.searchEntryPoint) == null ? void 0 : _b2.renderedContent) {
542
- msg.renderedContent = event.groundingMetadata.searchEntryPoint.renderedContent;
543
- }
544
- } else if (part.fileData) {
545
- msg.fileData = [part.fileData];
546
- } else if (part.functionCall) {
547
- msg.functionCall = part.functionCall;
548
- } else if (part.functionResponse) {
549
- msg.functionResponse = part.functionResponse;
550
- } else if (part.executableCode) {
551
- msg.executableCode = part.executableCode;
552
- } else if (part.codeExecutionResult) {
553
- msg.codeExecutionResult = part.codeExecutionResult;
554
- }
555
- }
556
- if (part && Object.keys(part).length > 0) {
557
- insertMessage(msg);
521
+ if (!part || Object.keys(part).length === 0)
522
+ return;
523
+ const msg = buildNonTextMessage(event, part, role);
524
+ if (part.text && ((_b2 = (_a2 = event == null ? void 0 : event.groundingMetadata) == null ? void 0 : _a2.searchEntryPoint) == null ? void 0 : _b2.renderedContent)) {
525
+ msg.renderedContent = event.groundingMetadata.searchEntryPoint.renderedContent;
558
526
  }
527
+ insertMessage(msg);
559
528
  },
560
529
  [insertMessage]
561
530
  );
@@ -624,7 +593,7 @@ function useADKChat({
624
593
  setSuggestedQuestions((prev) => [...prev, text]);
625
594
  }
626
595
  },
627
- [storeEvents, insertMessage]
596
+ [storeEvents]
628
597
  );
629
598
  const processErrorMessage = (0, import_react.useCallback)(
630
599
  (chunkJson) => {
@@ -750,29 +719,10 @@ function useADKChat({
750
719
  }
751
720
  } else {
752
721
  bgTextMsg = null;
753
- const msg = {
754
- id: (0, import_uuid.v4)(),
755
- author: chunkJson.author,
756
- invocationId: chunkJson.invocationId,
757
- eventId: chunkJson.id,
758
- timestamp: chunkJson.timestamp,
759
- role: "bot"
760
- };
761
- if (part.functionCall)
762
- msg.functionCall = part.functionCall;
763
- else if (part.functionResponse)
764
- msg.functionResponse = part.functionResponse;
765
- else if (part.executableCode)
766
- msg.executableCode = part.executableCode;
767
- else if (part.codeExecutionResult)
768
- msg.codeExecutionResult = part.codeExecutionResult;
769
- else {
770
- msg.text = part.text;
771
- msg.thought = part.thought;
772
- if (part.fileData)
773
- msg.fileData = [part.fileData];
774
- }
775
- bg.messages = [...bg.messages, msg];
722
+ bg.messages = [
723
+ ...bg.messages,
724
+ buildNonTextMessage(chunkJson, part)
725
+ ];
776
726
  }
777
727
  }
778
728
  } else if (chunkJson.errorMessage) {
@@ -809,12 +759,17 @@ function useADKChat({
809
759
  bg.loading = false;
810
760
  bg.textMsgRef = null;
811
761
  }
762
+ if (!backgroundRef.current.has(targetSessionId) && currentSessionIdRef.current === targetSessionId) {
763
+ setLoading(false);
764
+ textMsgRef.current = null;
765
+ }
812
766
  } else {
813
767
  setLoading(false);
814
768
  if (textMsgRef.current) {
815
769
  onMessage == null ? void 0 : onMessage(((_a2 = textMsgRef.current) == null ? void 0 : _a2.text) || "", textMsgRef.current);
816
770
  }
817
771
  textMsgRef.current = null;
772
+ ctrl.current = null;
818
773
  }
819
774
  resolve();
820
775
  },
@@ -824,8 +779,13 @@ function useADKChat({
824
779
  const bg = backgroundRef.current.get(targetSessionId);
825
780
  if (bg)
826
781
  bg.loading = false;
782
+ if (!backgroundRef.current.has(targetSessionId) && currentSessionIdRef.current === targetSessionId) {
783
+ setLoading(false);
784
+ ctrl.current = null;
785
+ }
827
786
  } else {
828
787
  setLoading(false);
788
+ ctrl.current = null;
829
789
  }
830
790
  resolve();
831
791
  console.error("EventSource failed:", error);
@@ -835,8 +795,6 @@ function useADKChat({
835
795
  });
836
796
  },
837
797
  [
838
- type,
839
- currentSessionId,
840
798
  processActionArtifact,
841
799
  processErrorMessage,
842
800
  processPart,
@@ -854,6 +812,7 @@ function useADKChat({
854
812
  return;
855
813
  sendingRef.current = true;
856
814
  setSuggestedQuestions([]);
815
+ reChatRemovedInvocationIdsRef.current = /* @__PURE__ */ new Set();
857
816
  setMessages((prev) => {
858
817
  let temp = [...prev];
859
818
  if (text.trim()) {
@@ -929,6 +888,13 @@ function useADKChat({
929
888
  }
930
889
  const newMessages = messages.slice(0, lastUserIndex + 1);
931
890
  setMessages(newMessages);
891
+ const removedInvocationIds = /* @__PURE__ */ new Set();
892
+ for (let i = lastUserIndex + 1; i < messages.length; i++) {
893
+ const msg = messages[i];
894
+ if (msg.invocationId)
895
+ removedInvocationIds.add(msg.invocationId);
896
+ }
897
+ reChatRemovedInvocationIdsRef.current = removedInvocationIds;
932
898
  const lastUserMessage = newMessages[lastUserIndex];
933
899
  const { text = "", fileData = [] } = lastUserMessage;
934
900
  try {
@@ -976,17 +942,16 @@ function useADKChat({
976
942
  const stopChat = (0, import_react.useCallback)(() => {
977
943
  var _a2;
978
944
  pendingSessionEventsRef.current = null;
979
- cancelSessionEventsFlush();
980
- sessionEventsSyncingRef.current = false;
981
945
  (_a2 = ctrl.current) == null ? void 0 : _a2.abort();
982
946
  ctrl.current = null;
983
947
  setLoading(false);
984
948
  textMsgRef.current = null;
985
- }, [cancelSessionEventsFlush, setLoading]);
949
+ }, [setLoading]);
986
950
  const clearChat = () => {
987
951
  var _a2, _b2;
988
952
  const newSessionId = (0, import_uuid.v4)();
989
953
  setCurrentSessionId(newSessionId);
954
+ reChatRemovedInvocationIdsRef.current = /* @__PURE__ */ new Set();
990
955
  stopChat();
991
956
  setPrologue(((_a2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a2.prologue) || "");
992
957
  setMessages([]);
@@ -1006,11 +971,7 @@ function useADKChat({
1006
971
  return;
1007
972
  }
1008
973
  pendingSessionEventsRef.current = null;
1009
- cancelSessionEventsFlush();
1010
- if (sessionEventsSyncingRef.current) {
1011
- sessionEventsSyncingRef.current = false;
1012
- setLoading(false);
1013
- }
974
+ reChatRemovedInvocationIdsRef.current = /* @__PURE__ */ new Set();
1014
975
  const prevSessionId = currentSessionId;
1015
976
  if (ctrl.current) {
1016
977
  backgroundRef.current.set(prevSessionId, {
@@ -1033,9 +994,11 @@ function useADKChat({
1033
994
  const bg = backgroundRef.current.get(sessionId);
1034
995
  if (bg) {
1035
996
  setMessages(bg.messages);
1036
- setLoading(bg.loading);
997
+ messagesRef.current = bg.messages;
1037
998
  textMsgRef.current = bg.textMsgRef;
1038
- ctrl.current = bg.loading ? bg.ctrl : null;
999
+ const isSseStillActive = bg.loading && !bg.ctrl.signal.aborted;
1000
+ setLoading(isSseStillActive);
1001
+ ctrl.current = isSseStillActive ? bg.ctrl : null;
1039
1002
  setCurrentSessionId(sessionId);
1040
1003
  setInitialized(true);
1041
1004
  backgroundRef.current.delete(sessionId);
@@ -1242,7 +1205,7 @@ function useADKChat({
1242
1205
  let requesting = false;
1243
1206
  const pollingSessionId = currentSessionId;
1244
1207
  const poll = async () => {
1245
- if (requesting || sessionDetailLoadingRef.current)
1208
+ if (disposed || requesting || sessionDetailLoadingRef.current)
1246
1209
  return;
1247
1210
  requesting = true;
1248
1211
  try {
@@ -1260,7 +1223,6 @@ function useADKChat({
1260
1223
  requesting = false;
1261
1224
  }
1262
1225
  };
1263
- void poll();
1264
1226
  const timer = window.setInterval(poll, sessionEventsPollingInterval);
1265
1227
  return () => {
1266
1228
  disposed = true;
@@ -1279,7 +1241,6 @@ function useADKChat({
1279
1241
  (0, import_react.useEffect)(() => {
1280
1242
  return () => {
1281
1243
  var _a2;
1282
- cancelSessionEventsFlush();
1283
1244
  (_a2 = ctrl.current) == null ? void 0 : _a2.abort();
1284
1245
  backgroundRef.current.forEach((bg) => {
1285
1246
  var _a3;
@@ -1287,7 +1248,7 @@ function useADKChat({
1287
1248
  });
1288
1249
  backgroundRef.current.clear();
1289
1250
  };
1290
- }, [cancelSessionEventsFlush]);
1251
+ }, []);
1291
1252
  return {
1292
1253
  appInfo,
1293
1254
  startChat,