@ai-group/chat-sdk 3.6.7 → 3.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/XAdkChatbot/components/FunctionCallRender/index.js.map +2 -2
- package/dist/cjs/hooks/useADKChat.d.ts +2 -2
- package/dist/cjs/hooks/useADKChat.js +145 -179
- package/dist/cjs/hooks/useADKChat.js.map +3 -3
- package/dist/esm/components/XAdkChatbot/components/FunctionCallRender/index.js +2 -0
- package/dist/esm/components/XAdkChatbot/components/FunctionCallRender/index.js.map +1 -1
- package/dist/esm/hooks/useADKChat.d.ts +2 -2
- package/dist/esm/hooks/useADKChat.js +209 -199
- package/dist/esm/hooks/useADKChat.js.map +1 -1
- package/dist/umd/chat-sdk.min.js +1 -1
- package/package.json +1 -1
|
@@ -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": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAwE;AACxE,mBAOO;AAEP,oBAA0B;AAC1B,gCAAwC;AACxC,yBAAqB;
|
|
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: (
|
|
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,6 +50,42 @@ 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);
|
|
@@ -67,14 +103,13 @@ var deduplicateMessages = (messageItems) => {
|
|
|
67
103
|
});
|
|
68
104
|
const botTextGroups = /* @__PURE__ */ new Map();
|
|
69
105
|
uniqueIdMessages.forEach((messageItem) => {
|
|
70
|
-
|
|
71
|
-
if (messageItem.role !== "bot" || !eventId || typeof messageItem.text !== "string")
|
|
106
|
+
if (messageItem.role !== "bot" || !messageItem.invocationId || typeof messageItem.text !== "string")
|
|
72
107
|
return;
|
|
73
108
|
const normalizedText = messageItem.text.replace(/\s+/g, " ").trim();
|
|
74
109
|
if (!normalizedText)
|
|
75
110
|
return;
|
|
76
111
|
const fileKey = (messageItem.fileData || []).map((file) => file.fileUri).join("|");
|
|
77
|
-
const groupKey = `${
|
|
112
|
+
const groupKey = `${messageItem.invocationId}\0${Boolean(
|
|
78
113
|
messageItem.thought
|
|
79
114
|
)}\0${fileKey}`;
|
|
80
115
|
const group = botTextGroups.get(groupKey) || [];
|
|
@@ -83,6 +118,8 @@ var deduplicateMessages = (messageItems) => {
|
|
|
83
118
|
});
|
|
84
119
|
const redundantMessageIds = /* @__PURE__ */ new Set();
|
|
85
120
|
botTextGroups.forEach((group) => {
|
|
121
|
+
if (group.length <= 1)
|
|
122
|
+
return;
|
|
86
123
|
const completeTexts = [];
|
|
87
124
|
[...group].sort((a, b) => b.normalizedText.length - a.normalizedText.length).forEach(({ messageItem, normalizedText }) => {
|
|
88
125
|
if (completeTexts.some(
|
|
@@ -106,6 +143,8 @@ var mapSessionMessages = (sessionEvents) => {
|
|
|
106
143
|
return;
|
|
107
144
|
if (item.author === "user" && item.content.parts.some((part) => part.task))
|
|
108
145
|
return;
|
|
146
|
+
if (item.content.role === "user" && item.content.parts.every((part) => !part || part.functionResponse))
|
|
147
|
+
return;
|
|
109
148
|
const role = (item.content.role || "").toLowerCase() === "user" ? "user" : "bot";
|
|
110
149
|
const parts = item.content.parts.filter((part) => {
|
|
111
150
|
if (!part)
|
|
@@ -123,9 +162,10 @@ var mapSessionMessages = (sessionEvents) => {
|
|
|
123
162
|
const otherParts = parts.filter(
|
|
124
163
|
(part) => !part.text && !part.errorMessage && !part.inlineData && !part.fileData
|
|
125
164
|
);
|
|
165
|
+
let partCounter = 0;
|
|
126
166
|
if (textParts.length > 0 || fileDataParts.length > 0) {
|
|
127
167
|
const messageItem = {
|
|
128
|
-
id:
|
|
168
|
+
id: `session-event:${item.id}:${partCounter++}`,
|
|
129
169
|
author: item.author,
|
|
130
170
|
invocationId: item.invocationId,
|
|
131
171
|
eventId: item.id,
|
|
@@ -167,7 +207,7 @@ var mapSessionMessages = (sessionEvents) => {
|
|
|
167
207
|
}
|
|
168
208
|
otherParts.forEach((part) => {
|
|
169
209
|
const messageItem = {
|
|
170
|
-
id:
|
|
210
|
+
id: `session-event:${item.id}:${partCounter++}`,
|
|
171
211
|
author: item.author,
|
|
172
212
|
invocationId: item.invocationId,
|
|
173
213
|
eventId: item.id,
|
|
@@ -202,64 +242,54 @@ var mapSessionMessages = (sessionEvents) => {
|
|
|
202
242
|
});
|
|
203
243
|
return mapped;
|
|
204
244
|
};
|
|
205
|
-
var
|
|
206
|
-
var _a;
|
|
207
|
-
return JSON.stringify({
|
|
208
|
-
role: messageItem.role,
|
|
209
|
-
text: ((_a = messageItem.text) == null ? void 0 : _a.replace(/\r\n/g, "\n").trim()) || "",
|
|
210
|
-
thought: Boolean(messageItem.thought),
|
|
211
|
-
inlineData: messageItem.inlineData || null,
|
|
212
|
-
fileData: messageItem.fileData || null,
|
|
213
|
-
functionCall: messageItem.functionCall || null,
|
|
214
|
-
functionResponse: messageItem.functionResponse || null,
|
|
215
|
-
executableCode: messageItem.executableCode || null,
|
|
216
|
-
codeExecutionResult: messageItem.codeExecutionResult || null
|
|
217
|
-
});
|
|
218
|
-
};
|
|
219
|
-
var isStreamMessageWithoutServerEventId = (messageItem) => {
|
|
220
|
-
const eventId = getMessageEventId(messageItem);
|
|
221
|
-
return Boolean(messageItem.invocationId) && (!eventId || eventId === messageItem.invocationId);
|
|
222
|
-
};
|
|
223
|
-
var insertMissingSessionEvents = (currentMessages, sessionEvents) => {
|
|
245
|
+
var insertMissingSessionEvents = (currentMessages, sessionEvents, removedInvocationIds) => {
|
|
224
246
|
const renderedEventIds = new Set(
|
|
225
247
|
currentMessages.map(getMessageEventId).filter(Boolean)
|
|
226
248
|
);
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
249
|
+
let nextMessages = [...currentMessages];
|
|
250
|
+
const fnResMap = /* @__PURE__ */ new Map();
|
|
251
|
+
sessionEvents.forEach((event) => {
|
|
252
|
+
var _a, _b;
|
|
253
|
+
if (((_a = event.content) == null ? void 0 : _a.role) !== "user" || !Array.isArray((_b = event.content) == null ? void 0 : _b.parts))
|
|
254
|
+
return;
|
|
255
|
+
event.content.parts.forEach((p) => {
|
|
256
|
+
var _a2;
|
|
257
|
+
if ((_a2 = p.functionResponse) == null ? void 0 : _a2.id) {
|
|
258
|
+
fnResMap.set(p.functionResponse.id, p.functionResponse);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
if (fnResMap.size > 0) {
|
|
263
|
+
let paired = false;
|
|
264
|
+
nextMessages = nextMessages.map((msg) => {
|
|
265
|
+
if (msg.functionCall && !msg.functionResponse) {
|
|
266
|
+
const callId = msg.functionCall.id;
|
|
267
|
+
if (callId && fnResMap.has(callId)) {
|
|
268
|
+
paired = true;
|
|
269
|
+
return { ...msg, functionResponse: fnResMap.get(callId) };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return msg;
|
|
273
|
+
});
|
|
274
|
+
if (!paired)
|
|
275
|
+
nextMessages = currentMessages;
|
|
276
|
+
}
|
|
232
277
|
const missingEvents = sessionEvents.filter((event) => {
|
|
233
278
|
var _a, _b;
|
|
234
279
|
const parts = (_a = event.content) == null ? void 0 : _a.parts;
|
|
235
280
|
const canRender = Boolean(event.id) && ((_b = event.content) == null ? void 0 : _b.role) === "model" && Array.isArray(parts) && parts.length > 0;
|
|
236
281
|
if (!canRender || renderedEventIds.has(event.id))
|
|
237
282
|
return false;
|
|
238
|
-
|
|
239
|
-
const matchedIndexes = [];
|
|
240
|
-
const isRenderedByStream = eventMessages.length > 0 && eventMessages.every((eventMessage) => {
|
|
241
|
-
const comparableContent = getComparableMessageContent(eventMessage);
|
|
242
|
-
const matchedIndex = currentMessages.findIndex(
|
|
243
|
-
(currentMessage, index) => unmatchedStreamMessageIndexes.has(index) && !matchedIndexes.includes(index) && currentMessage.invocationId === eventMessage.invocationId && getComparableMessageContent(currentMessage) === comparableContent
|
|
244
|
-
);
|
|
245
|
-
if (matchedIndex < 0)
|
|
246
|
-
return false;
|
|
247
|
-
matchedIndexes.push(matchedIndex);
|
|
248
|
-
return true;
|
|
249
|
-
});
|
|
250
|
-
if (isRenderedByStream) {
|
|
251
|
-
matchedIndexes.forEach(
|
|
252
|
-
(index) => unmatchedStreamMessageIndexes.delete(index)
|
|
253
|
-
);
|
|
283
|
+
if (removedInvocationIds && removedInvocationIds.size > 0 && event.invocationId && removedInvocationIds.has(event.invocationId)) {
|
|
254
284
|
return false;
|
|
255
285
|
}
|
|
256
286
|
return true;
|
|
257
287
|
});
|
|
258
288
|
if (missingEvents.length === 0)
|
|
259
|
-
return
|
|
289
|
+
return nextMessages;
|
|
260
290
|
const missingMessages = mapSessionMessages(missingEvents);
|
|
261
291
|
if (missingMessages.length === 0)
|
|
262
|
-
return
|
|
292
|
+
return nextMessages;
|
|
263
293
|
const eventOrder = new Map(
|
|
264
294
|
sessionEvents.map((event, index) => [event.id, index])
|
|
265
295
|
);
|
|
@@ -277,7 +307,6 @@ var insertMissingSessionEvents = (currentMessages, sessionEvents) => {
|
|
|
277
307
|
}
|
|
278
308
|
return Number.POSITIVE_INFINITY;
|
|
279
309
|
};
|
|
280
|
-
const nextMessages = [...currentMessages];
|
|
281
310
|
missingMessages.forEach((messageItem) => {
|
|
282
311
|
const targetOrder = getMessageOrder(messageItem);
|
|
283
312
|
let insertIndex = nextMessages.findIndex((currentMessage) => {
|
|
@@ -294,7 +323,7 @@ function useADKChat({
|
|
|
294
323
|
url = window.location.origin,
|
|
295
324
|
token,
|
|
296
325
|
config = {},
|
|
297
|
-
type = "agentDebug",
|
|
326
|
+
type: _type = "agentDebug",
|
|
298
327
|
enabled = true,
|
|
299
328
|
// ← 新增: 是否启用 Hook
|
|
300
329
|
strategies,
|
|
@@ -334,10 +363,9 @@ function useADKChat({
|
|
|
334
363
|
const [suggestedQuestions, setSuggestedQuestions] = (0, import_react.useState)([]);
|
|
335
364
|
const [messages, setMessages] = (0, import_react.useState)([]);
|
|
336
365
|
const pendingSessionEventsRef = (0, import_react.useRef)(null);
|
|
337
|
-
const sessionEventsFlushTimerRef = (0, import_react.useRef)(null);
|
|
338
|
-
const sessionEventsSyncingRef = (0, import_react.useRef)(false);
|
|
339
366
|
const sessionDetailLoadingRef = (0, import_react.useRef)(false);
|
|
340
367
|
const stateDeltaRef = (0, import_react.useRef)(void 0);
|
|
368
|
+
const reChatRemovedInvocationIdsRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
341
369
|
const backgroundRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
342
370
|
const messagesRef = (0, import_react.useRef)(messages);
|
|
343
371
|
messagesRef.current = messages;
|
|
@@ -365,42 +393,24 @@ function useADKChat({
|
|
|
365
393
|
}, [messages]);
|
|
366
394
|
const textMsgRef = (0, import_react.useRef)(null);
|
|
367
395
|
const eventDataRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
368
|
-
const cancelSessionEventsFlush = (0, import_react.useCallback)(() => {
|
|
369
|
-
if (sessionEventsFlushTimerRef.current === null)
|
|
370
|
-
return;
|
|
371
|
-
clearTimeout(sessionEventsFlushTimerRef.current);
|
|
372
|
-
sessionEventsFlushTimerRef.current = null;
|
|
373
|
-
}, []);
|
|
374
396
|
const flushPendingSessionEvents = (0, import_react.useCallback)(() => {
|
|
375
397
|
const pending = pendingSessionEventsRef.current;
|
|
376
|
-
const replyInProgress =
|
|
398
|
+
const replyInProgress = sendingRef.current || textMsgRef.current !== null;
|
|
377
399
|
if (!pending || replyInProgress || pending.sessionId !== currentSessionIdRef.current)
|
|
378
400
|
return;
|
|
379
|
-
const previewMessages = insertMissingSessionEvents(
|
|
380
|
-
messagesRef.current,
|
|
381
|
-
pending.events
|
|
382
|
-
);
|
|
383
401
|
pendingSessionEventsRef.current = null;
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
if (
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
messagesRef.current = nextMessages;
|
|
397
|
-
return nextMessages;
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
sessionEventsSyncingRef.current = false;
|
|
401
|
-
setLoading(false);
|
|
402
|
-
}, 0);
|
|
403
|
-
}, [setLoading]);
|
|
402
|
+
setMessages((prev) => {
|
|
403
|
+
const nextMessages = insertMissingSessionEvents(
|
|
404
|
+
prev,
|
|
405
|
+
pending.events,
|
|
406
|
+
reChatRemovedInvocationIdsRef.current
|
|
407
|
+
);
|
|
408
|
+
if (nextMessages === prev)
|
|
409
|
+
return prev;
|
|
410
|
+
messagesRef.current = nextMessages;
|
|
411
|
+
return nextMessages;
|
|
412
|
+
});
|
|
413
|
+
}, []);
|
|
404
414
|
const syncSessionEvents = (0, import_react.useCallback)(
|
|
405
415
|
(events, targetSessionId) => {
|
|
406
416
|
if (targetSessionId !== currentSessionIdRef.current)
|
|
@@ -415,12 +425,7 @@ function useADKChat({
|
|
|
415
425
|
);
|
|
416
426
|
(0, import_react.useEffect)(() => {
|
|
417
427
|
pendingSessionEventsRef.current = null;
|
|
418
|
-
|
|
419
|
-
if (sessionEventsSyncingRef.current) {
|
|
420
|
-
sessionEventsSyncingRef.current = false;
|
|
421
|
-
setLoading(false);
|
|
422
|
-
}
|
|
423
|
-
}, [cancelSessionEventsFlush, currentSessionId, setLoading]);
|
|
428
|
+
}, [currentSessionId]);
|
|
424
429
|
(0, import_react.useEffect)(() => {
|
|
425
430
|
if (!loading)
|
|
426
431
|
flushPendingSessionEvents();
|
|
@@ -434,18 +439,21 @@ function useADKChat({
|
|
|
434
439
|
return [...prev, msg];
|
|
435
440
|
});
|
|
436
441
|
}, []);
|
|
437
|
-
const insertSuggestedQuestions = (
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
setSuggestedQuestions(
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
442
|
+
const insertSuggestedQuestions = (0, import_react.useCallback)(
|
|
443
|
+
(suggested_questions = []) => {
|
|
444
|
+
if (!(suggested_questions == null ? void 0 : suggested_questions.length))
|
|
445
|
+
return;
|
|
446
|
+
setSuggestedQuestions(
|
|
447
|
+
(prev) => messages.length === 0 ? suggested_questions : prev
|
|
448
|
+
);
|
|
449
|
+
},
|
|
450
|
+
[messages.length]
|
|
451
|
+
);
|
|
452
|
+
const insertPrologue = (0, import_react.useCallback)((prologueText) => {
|
|
453
|
+
if (prologueText) {
|
|
454
|
+
setPrologue(prologueText);
|
|
447
455
|
}
|
|
448
|
-
};
|
|
456
|
+
}, []);
|
|
449
457
|
const updateMessage = (0, import_react.useCallback)((msg) => {
|
|
450
458
|
setMessages((prev) => {
|
|
451
459
|
return prev.map((m) => {
|
|
@@ -511,47 +519,13 @@ function useADKChat({
|
|
|
511
519
|
const storeMessage = (0, import_react.useCallback)(
|
|
512
520
|
(part, event, role) => {
|
|
513
521
|
var _a2, _b2;
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
timestamp: event.timestamp,
|
|
520
|
-
isLike: event.isLike || 0,
|
|
521
|
-
role,
|
|
522
|
-
modelCode: event.modelCode,
|
|
523
|
-
usageMetadata: event.usageMetadata,
|
|
524
|
-
finishReason: event.finishReason,
|
|
525
|
-
raw: event
|
|
526
|
-
};
|
|
527
|
-
if (part) {
|
|
528
|
-
if (part.inlineData) {
|
|
529
|
-
msg.inlineData = {
|
|
530
|
-
displayName: part.inlineData.displayName,
|
|
531
|
-
data: part.inlineData.data,
|
|
532
|
-
mimeType: part.inlineData.mimeType
|
|
533
|
-
};
|
|
534
|
-
} else if (part.text) {
|
|
535
|
-
msg.text = part.text;
|
|
536
|
-
msg.thought = part.thought;
|
|
537
|
-
if ((_b2 = (_a2 = event == null ? void 0 : event.groundingMetadata) == null ? void 0 : _a2.searchEntryPoint) == null ? void 0 : _b2.renderedContent) {
|
|
538
|
-
msg.renderedContent = event.groundingMetadata.searchEntryPoint.renderedContent;
|
|
539
|
-
}
|
|
540
|
-
} else if (part.fileData) {
|
|
541
|
-
msg.fileData = [part.fileData];
|
|
542
|
-
} else if (part.functionCall) {
|
|
543
|
-
msg.functionCall = part.functionCall;
|
|
544
|
-
} else if (part.functionResponse) {
|
|
545
|
-
msg.functionResponse = part.functionResponse;
|
|
546
|
-
} else if (part.executableCode) {
|
|
547
|
-
msg.executableCode = part.executableCode;
|
|
548
|
-
} else if (part.codeExecutionResult) {
|
|
549
|
-
msg.codeExecutionResult = part.codeExecutionResult;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
if (part && Object.keys(part).length > 0) {
|
|
553
|
-
insertMessage(msg);
|
|
522
|
+
if (!part || Object.keys(part).length === 0)
|
|
523
|
+
return;
|
|
524
|
+
const msg = buildNonTextMessage(event, part, role);
|
|
525
|
+
if (part.text && ((_b2 = (_a2 = event == null ? void 0 : event.groundingMetadata) == null ? void 0 : _a2.searchEntryPoint) == null ? void 0 : _b2.renderedContent)) {
|
|
526
|
+
msg.renderedContent = event.groundingMetadata.searchEntryPoint.renderedContent;
|
|
554
527
|
}
|
|
528
|
+
insertMessage(msg);
|
|
555
529
|
},
|
|
556
530
|
[insertMessage]
|
|
557
531
|
);
|
|
@@ -620,7 +594,7 @@ function useADKChat({
|
|
|
620
594
|
setSuggestedQuestions((prev) => [...prev, text]);
|
|
621
595
|
}
|
|
622
596
|
},
|
|
623
|
-
[storeEvents
|
|
597
|
+
[storeEvents]
|
|
624
598
|
);
|
|
625
599
|
const processErrorMessage = (0, import_react.useCallback)(
|
|
626
600
|
(chunkJson) => {
|
|
@@ -746,29 +720,10 @@ function useADKChat({
|
|
|
746
720
|
}
|
|
747
721
|
} else {
|
|
748
722
|
bgTextMsg = null;
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
eventId: chunkJson.id,
|
|
754
|
-
timestamp: chunkJson.timestamp,
|
|
755
|
-
role: "bot"
|
|
756
|
-
};
|
|
757
|
-
if (part.functionCall)
|
|
758
|
-
msg.functionCall = part.functionCall;
|
|
759
|
-
else if (part.functionResponse)
|
|
760
|
-
msg.functionResponse = part.functionResponse;
|
|
761
|
-
else if (part.executableCode)
|
|
762
|
-
msg.executableCode = part.executableCode;
|
|
763
|
-
else if (part.codeExecutionResult)
|
|
764
|
-
msg.codeExecutionResult = part.codeExecutionResult;
|
|
765
|
-
else {
|
|
766
|
-
msg.text = part.text;
|
|
767
|
-
msg.thought = part.thought;
|
|
768
|
-
if (part.fileData)
|
|
769
|
-
msg.fileData = [part.fileData];
|
|
770
|
-
}
|
|
771
|
-
bg.messages = [...bg.messages, msg];
|
|
723
|
+
bg.messages = [
|
|
724
|
+
...bg.messages,
|
|
725
|
+
buildNonTextMessage(chunkJson, part)
|
|
726
|
+
];
|
|
772
727
|
}
|
|
773
728
|
}
|
|
774
729
|
} else if (chunkJson.errorMessage) {
|
|
@@ -805,12 +760,17 @@ function useADKChat({
|
|
|
805
760
|
bg.loading = false;
|
|
806
761
|
bg.textMsgRef = null;
|
|
807
762
|
}
|
|
763
|
+
if (!backgroundRef.current.has(targetSessionId) && currentSessionIdRef.current === targetSessionId) {
|
|
764
|
+
setLoading(false);
|
|
765
|
+
textMsgRef.current = null;
|
|
766
|
+
}
|
|
808
767
|
} else {
|
|
809
768
|
setLoading(false);
|
|
810
769
|
if (textMsgRef.current) {
|
|
811
770
|
onMessage == null ? void 0 : onMessage(((_a2 = textMsgRef.current) == null ? void 0 : _a2.text) || "", textMsgRef.current);
|
|
812
771
|
}
|
|
813
772
|
textMsgRef.current = null;
|
|
773
|
+
ctrl.current = null;
|
|
814
774
|
}
|
|
815
775
|
resolve();
|
|
816
776
|
},
|
|
@@ -820,8 +780,13 @@ function useADKChat({
|
|
|
820
780
|
const bg = backgroundRef.current.get(targetSessionId);
|
|
821
781
|
if (bg)
|
|
822
782
|
bg.loading = false;
|
|
783
|
+
if (!backgroundRef.current.has(targetSessionId) && currentSessionIdRef.current === targetSessionId) {
|
|
784
|
+
setLoading(false);
|
|
785
|
+
ctrl.current = null;
|
|
786
|
+
}
|
|
823
787
|
} else {
|
|
824
788
|
setLoading(false);
|
|
789
|
+
ctrl.current = null;
|
|
825
790
|
}
|
|
826
791
|
resolve();
|
|
827
792
|
console.error("EventSource failed:", error);
|
|
@@ -831,8 +796,6 @@ function useADKChat({
|
|
|
831
796
|
});
|
|
832
797
|
},
|
|
833
798
|
[
|
|
834
|
-
type,
|
|
835
|
-
currentSessionId,
|
|
836
799
|
processActionArtifact,
|
|
837
800
|
processErrorMessage,
|
|
838
801
|
processPart,
|
|
@@ -850,6 +813,7 @@ function useADKChat({
|
|
|
850
813
|
return;
|
|
851
814
|
sendingRef.current = true;
|
|
852
815
|
setSuggestedQuestions([]);
|
|
816
|
+
reChatRemovedInvocationIdsRef.current = /* @__PURE__ */ new Set();
|
|
853
817
|
setMessages((prev) => {
|
|
854
818
|
let temp = [...prev];
|
|
855
819
|
if (text.trim()) {
|
|
@@ -925,6 +889,13 @@ function useADKChat({
|
|
|
925
889
|
}
|
|
926
890
|
const newMessages = messages.slice(0, lastUserIndex + 1);
|
|
927
891
|
setMessages(newMessages);
|
|
892
|
+
const removedInvocationIds = /* @__PURE__ */ new Set();
|
|
893
|
+
for (let i = lastUserIndex + 1; i < messages.length; i++) {
|
|
894
|
+
const msg = messages[i];
|
|
895
|
+
if (msg.invocationId)
|
|
896
|
+
removedInvocationIds.add(msg.invocationId);
|
|
897
|
+
}
|
|
898
|
+
reChatRemovedInvocationIdsRef.current = removedInvocationIds;
|
|
928
899
|
const lastUserMessage = newMessages[lastUserIndex];
|
|
929
900
|
const { text = "", fileData = [] } = lastUserMessage;
|
|
930
901
|
try {
|
|
@@ -972,17 +943,16 @@ function useADKChat({
|
|
|
972
943
|
const stopChat = (0, import_react.useCallback)(() => {
|
|
973
944
|
var _a2;
|
|
974
945
|
pendingSessionEventsRef.current = null;
|
|
975
|
-
cancelSessionEventsFlush();
|
|
976
|
-
sessionEventsSyncingRef.current = false;
|
|
977
946
|
(_a2 = ctrl.current) == null ? void 0 : _a2.abort();
|
|
978
947
|
ctrl.current = null;
|
|
979
948
|
setLoading(false);
|
|
980
949
|
textMsgRef.current = null;
|
|
981
|
-
}, [
|
|
950
|
+
}, [setLoading]);
|
|
982
951
|
const clearChat = () => {
|
|
983
952
|
var _a2, _b2;
|
|
984
953
|
const newSessionId = (0, import_uuid.v4)();
|
|
985
954
|
setCurrentSessionId(newSessionId);
|
|
955
|
+
reChatRemovedInvocationIdsRef.current = /* @__PURE__ */ new Set();
|
|
986
956
|
stopChat();
|
|
987
957
|
setPrologue(((_a2 = appInfo == null ? void 0 : appInfo.onboardingInfo) == null ? void 0 : _a2.prologue) || "");
|
|
988
958
|
setMessages([]);
|
|
@@ -1002,11 +972,7 @@ function useADKChat({
|
|
|
1002
972
|
return;
|
|
1003
973
|
}
|
|
1004
974
|
pendingSessionEventsRef.current = null;
|
|
1005
|
-
|
|
1006
|
-
if (sessionEventsSyncingRef.current) {
|
|
1007
|
-
sessionEventsSyncingRef.current = false;
|
|
1008
|
-
setLoading(false);
|
|
1009
|
-
}
|
|
975
|
+
reChatRemovedInvocationIdsRef.current = /* @__PURE__ */ new Set();
|
|
1010
976
|
const prevSessionId = currentSessionId;
|
|
1011
977
|
if (ctrl.current) {
|
|
1012
978
|
backgroundRef.current.set(prevSessionId, {
|
|
@@ -1029,9 +995,11 @@ function useADKChat({
|
|
|
1029
995
|
const bg = backgroundRef.current.get(sessionId);
|
|
1030
996
|
if (bg) {
|
|
1031
997
|
setMessages(bg.messages);
|
|
1032
|
-
|
|
998
|
+
messagesRef.current = bg.messages;
|
|
1033
999
|
textMsgRef.current = bg.textMsgRef;
|
|
1034
|
-
|
|
1000
|
+
const isSseStillActive = bg.loading && !bg.ctrl.signal.aborted;
|
|
1001
|
+
setLoading(isSseStillActive);
|
|
1002
|
+
ctrl.current = isSseStillActive ? bg.ctrl : null;
|
|
1035
1003
|
setCurrentSessionId(sessionId);
|
|
1036
1004
|
setInitialized(true);
|
|
1037
1005
|
backgroundRef.current.delete(sessionId);
|
|
@@ -1238,7 +1206,7 @@ function useADKChat({
|
|
|
1238
1206
|
let requesting = false;
|
|
1239
1207
|
const pollingSessionId = currentSessionId;
|
|
1240
1208
|
const poll = async () => {
|
|
1241
|
-
if (requesting || sessionDetailLoadingRef.current)
|
|
1209
|
+
if (disposed || requesting || sessionDetailLoadingRef.current)
|
|
1242
1210
|
return;
|
|
1243
1211
|
requesting = true;
|
|
1244
1212
|
try {
|
|
@@ -1256,7 +1224,6 @@ function useADKChat({
|
|
|
1256
1224
|
requesting = false;
|
|
1257
1225
|
}
|
|
1258
1226
|
};
|
|
1259
|
-
void poll();
|
|
1260
1227
|
const timer = window.setInterval(poll, sessionEventsPollingInterval);
|
|
1261
1228
|
return () => {
|
|
1262
1229
|
disposed = true;
|
|
@@ -1275,7 +1242,6 @@ function useADKChat({
|
|
|
1275
1242
|
(0, import_react.useEffect)(() => {
|
|
1276
1243
|
return () => {
|
|
1277
1244
|
var _a2;
|
|
1278
|
-
cancelSessionEventsFlush();
|
|
1279
1245
|
(_a2 = ctrl.current) == null ? void 0 : _a2.abort();
|
|
1280
1246
|
backgroundRef.current.forEach((bg) => {
|
|
1281
1247
|
var _a3;
|
|
@@ -1283,7 +1249,7 @@ function useADKChat({
|
|
|
1283
1249
|
});
|
|
1284
1250
|
backgroundRef.current.clear();
|
|
1285
1251
|
};
|
|
1286
|
-
}, [
|
|
1252
|
+
}, []);
|
|
1287
1253
|
return {
|
|
1288
1254
|
appInfo,
|
|
1289
1255
|
startChat,
|