@ai-group/chat-sdk 3.6.11 → 3.7.0

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 (149) hide show
  1. package/dist/cjs/components/XAdkChatbot/index.js +27 -15
  2. package/dist/cjs/components/XAdkChatbot/index.js.map +2 -2
  3. package/dist/cjs/components/XAdkProvider/compound/Sender.d.ts +2 -2
  4. package/dist/cjs/components/XAdkProvider/compound/Sender.js +20 -17
  5. package/dist/cjs/components/XAdkProvider/compound/Sender.js.map +2 -2
  6. package/dist/cjs/components/XAdkProvider/compound/Sidebar.js +6 -2
  7. package/dist/cjs/components/XAdkProvider/compound/Sidebar.js.map +2 -2
  8. package/dist/cjs/components/XAdkProvider/context/ChatSenderStateContext.d.ts +6 -2
  9. package/dist/cjs/components/XAdkProvider/context/ChatSenderStateContext.js.map +2 -2
  10. package/dist/cjs/components/XAdkProvider/index.js +8 -5
  11. package/dist/cjs/components/XAdkProvider/index.js.map +2 -2
  12. package/dist/cjs/components/XAdkSender/index.js +502 -496
  13. package/dist/cjs/components/XAdkSender/index.js.map +2 -2
  14. package/dist/cjs/components/XAdkSender/styles.js +0 -13
  15. package/dist/cjs/components/XAdkSender/styles.js.map +2 -2
  16. package/dist/cjs/core/index.d.ts +2 -0
  17. package/dist/cjs/core/index.js +26 -0
  18. package/dist/cjs/core/index.js.map +7 -0
  19. package/dist/cjs/core/protocol/index.d.ts +3 -0
  20. package/dist/cjs/core/protocol/index.js +28 -0
  21. package/dist/cjs/core/protocol/index.js.map +7 -0
  22. package/dist/cjs/core/protocol/messages.d.ts +55 -0
  23. package/dist/cjs/core/protocol/messages.js +307 -0
  24. package/dist/cjs/core/protocol/messages.js.map +7 -0
  25. package/dist/cjs/core/protocol/parts.d.ts +24 -0
  26. package/dist/cjs/core/protocol/parts.js +106 -0
  27. package/dist/cjs/core/protocol/parts.js.map +7 -0
  28. package/dist/cjs/core/protocol/types.d.ts +57 -0
  29. package/dist/cjs/core/protocol/types.js +18 -0
  30. package/dist/cjs/core/protocol/types.js.map +7 -0
  31. package/dist/cjs/core/runtime/createAdkConversationController.d.ts +8 -0
  32. package/dist/cjs/core/runtime/createAdkConversationController.js +424 -0
  33. package/dist/cjs/core/runtime/createAdkConversationController.js.map +7 -0
  34. package/dist/cjs/core/runtime/index.d.ts +2 -0
  35. package/dist/cjs/core/runtime/index.js +26 -0
  36. package/dist/cjs/core/runtime/index.js.map +7 -0
  37. package/dist/cjs/core/runtime/types.d.ts +130 -0
  38. package/dist/cjs/core/runtime/types.js +18 -0
  39. package/dist/cjs/core/runtime/types.js.map +7 -0
  40. package/dist/{esm/utils/umdEntry.d.ts → cjs/entries/umd.d.ts} +7 -0
  41. package/dist/cjs/{utils/umdEntry.js → entries/umd.js} +19 -9
  42. package/dist/cjs/entries/umd.js.map +7 -0
  43. package/dist/cjs/hooks/useADKChat.js +1 -0
  44. package/dist/cjs/hooks/useADKChat.js.map +2 -2
  45. package/dist/cjs/index.d.ts +6 -1
  46. package/dist/cjs/index.js +19 -11
  47. package/dist/cjs/index.js.map +3 -3
  48. package/dist/cjs/presets/xgroup/index.d.ts +4 -0
  49. package/dist/cjs/presets/xgroup/index.js +30 -0
  50. package/dist/cjs/presets/xgroup/index.js.map +7 -0
  51. package/dist/cjs/presets/xgroup/preset.d.ts +15 -0
  52. package/dist/cjs/presets/xgroup/preset.js +69 -0
  53. package/dist/cjs/presets/xgroup/preset.js.map +7 -0
  54. package/dist/cjs/presets/xgroup/strategies.d.ts +8 -0
  55. package/dist/cjs/presets/xgroup/strategies.js +53 -0
  56. package/dist/cjs/presets/xgroup/strategies.js.map +7 -0
  57. package/dist/cjs/presets/xgroup/transport.d.ts +15 -0
  58. package/dist/cjs/presets/xgroup/transport.js +183 -0
  59. package/dist/cjs/presets/xgroup/transport.js.map +7 -0
  60. package/dist/cjs/presets/xgroup/upload.d.ts +8 -0
  61. package/dist/cjs/presets/xgroup/upload.js +65 -0
  62. package/dist/cjs/presets/xgroup/upload.js.map +7 -0
  63. package/dist/cjs/react/index.d.ts +6 -0
  64. package/dist/cjs/react/index.js +53 -0
  65. package/dist/cjs/react/index.js.map +7 -0
  66. package/dist/cjs/react/useAdkConversation.d.ts +27 -0
  67. package/dist/cjs/react/useAdkConversation.js +69 -0
  68. package/dist/cjs/react/useAdkConversation.js.map +7 -0
  69. package/dist/cjs/types/XAdkSender.d.ts +0 -2
  70. package/dist/cjs/types/XAdkSender.js.map +1 -1
  71. package/dist/esm/components/XAdkChatbot/index.js +1 -1
  72. package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
  73. package/dist/esm/components/XAdkProvider/compound/Sender.d.ts +2 -2
  74. package/dist/esm/components/XAdkProvider/compound/Sender.js +7 -4
  75. package/dist/esm/components/XAdkProvider/compound/Sender.js.map +1 -1
  76. package/dist/esm/components/XAdkProvider/compound/Sidebar.js +7 -2
  77. package/dist/esm/components/XAdkProvider/compound/Sidebar.js.map +1 -1
  78. package/dist/esm/components/XAdkProvider/context/ChatSenderStateContext.d.ts +6 -2
  79. package/dist/esm/components/XAdkProvider/context/ChatSenderStateContext.js.map +1 -1
  80. package/dist/esm/components/XAdkProvider/index.js +13 -4
  81. package/dist/esm/components/XAdkProvider/index.js.map +1 -1
  82. package/dist/esm/components/XAdkSender/index.js +2 -5
  83. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  84. package/dist/esm/components/XAdkSender/styles.js +1 -1
  85. package/dist/esm/components/XAdkSender/styles.js.map +1 -1
  86. package/dist/esm/core/index.d.ts +2 -0
  87. package/dist/esm/core/index.js +3 -0
  88. package/dist/esm/core/index.js.map +1 -0
  89. package/dist/esm/core/protocol/index.d.ts +3 -0
  90. package/dist/esm/core/protocol/index.js +4 -0
  91. package/dist/esm/core/protocol/index.js.map +1 -0
  92. package/dist/esm/core/protocol/messages.d.ts +55 -0
  93. package/dist/esm/core/protocol/messages.js +315 -0
  94. package/dist/esm/core/protocol/messages.js.map +1 -0
  95. package/dist/esm/core/protocol/parts.d.ts +24 -0
  96. package/dist/esm/core/protocol/parts.js +100 -0
  97. package/dist/esm/core/protocol/parts.js.map +1 -0
  98. package/dist/esm/core/protocol/types.d.ts +57 -0
  99. package/dist/esm/core/protocol/types.js +2 -0
  100. package/dist/esm/core/protocol/types.js.map +1 -0
  101. package/dist/esm/core/runtime/createAdkConversationController.d.ts +8 -0
  102. package/dist/esm/core/runtime/createAdkConversationController.js +742 -0
  103. package/dist/esm/core/runtime/createAdkConversationController.js.map +1 -0
  104. package/dist/esm/core/runtime/index.d.ts +2 -0
  105. package/dist/esm/core/runtime/index.js +3 -0
  106. package/dist/esm/core/runtime/index.js.map +1 -0
  107. package/dist/esm/core/runtime/types.d.ts +130 -0
  108. package/dist/esm/core/runtime/types.js +2 -0
  109. package/dist/esm/core/runtime/types.js.map +1 -0
  110. package/dist/{cjs/utils/umdEntry.d.ts → esm/entries/umd.d.ts} +7 -0
  111. package/dist/esm/{utils/umdEntry.js → entries/umd.js} +10 -1
  112. package/dist/esm/entries/umd.js.map +1 -0
  113. package/dist/esm/hooks/useADKChat.js +2 -1
  114. package/dist/esm/hooks/useADKChat.js.map +1 -1
  115. package/dist/esm/index.d.ts +6 -1
  116. package/dist/esm/index.js +6 -1
  117. package/dist/esm/index.js.map +1 -1
  118. package/dist/esm/presets/xgroup/index.d.ts +4 -0
  119. package/dist/esm/presets/xgroup/index.js +5 -0
  120. package/dist/esm/presets/xgroup/index.js.map +1 -0
  121. package/dist/esm/presets/xgroup/preset.d.ts +15 -0
  122. package/dist/esm/presets/xgroup/preset.js +44 -0
  123. package/dist/esm/presets/xgroup/preset.js.map +1 -0
  124. package/dist/esm/presets/xgroup/strategies.d.ts +8 -0
  125. package/dist/esm/presets/xgroup/strategies.js +30 -0
  126. package/dist/esm/presets/xgroup/strategies.js.map +1 -0
  127. package/dist/esm/presets/xgroup/transport.d.ts +15 -0
  128. package/dist/esm/presets/xgroup/transport.js +322 -0
  129. package/dist/esm/presets/xgroup/transport.js.map +1 -0
  130. package/dist/esm/presets/xgroup/upload.d.ts +8 -0
  131. package/dist/esm/presets/{xGroupAdk.js → xgroup/upload.js} +9 -63
  132. package/dist/esm/presets/xgroup/upload.js.map +1 -0
  133. package/dist/esm/react/index.d.ts +6 -0
  134. package/dist/esm/react/index.js +5 -0
  135. package/dist/esm/react/index.js.map +1 -0
  136. package/dist/esm/react/useAdkConversation.d.ts +27 -0
  137. package/dist/esm/react/useAdkConversation.js +53 -0
  138. package/dist/esm/react/useAdkConversation.js.map +1 -0
  139. package/dist/esm/types/XAdkSender.d.ts +0 -2
  140. package/dist/esm/types/XAdkSender.js.map +1 -1
  141. package/dist/umd/chat-sdk.min.js +1 -1
  142. package/package.json +36 -2
  143. package/dist/cjs/presets/xGroupAdk.d.ts +0 -20
  144. package/dist/cjs/presets/xGroupAdk.js +0 -130
  145. package/dist/cjs/presets/xGroupAdk.js.map +0 -7
  146. package/dist/cjs/utils/umdEntry.js.map +0 -7
  147. package/dist/esm/presets/xGroupAdk.d.ts +0 -20
  148. package/dist/esm/presets/xGroupAdk.js.map +0 -1
  149. package/dist/esm/utils/umdEntry.js.map +0 -1
@@ -0,0 +1,307 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/core/protocol/messages.ts
20
+ var messages_exports = {};
21
+ __export(messages_exports, {
22
+ buildAdkUserMessage: () => buildAdkUserMessage,
23
+ buildAdkUserParts: () => import_parts.buildAdkUserParts,
24
+ collectFunctionResponses: () => collectFunctionResponses,
25
+ createAdkMessage: () => createAdkMessage,
26
+ dedupeAdkMessages: () => dedupeAdkMessages,
27
+ getAdkEventMeta: () => getAdkEventMeta,
28
+ getAdkMessageEventId: () => getAdkMessageEventId,
29
+ getAdkMessageInvocationId: () => getAdkMessageInvocationId,
30
+ insertMissingAdkSessionEvents: () => insertMissingAdkSessionEvents,
31
+ isAdkAsyncTaskEvent: () => isAdkAsyncTaskEvent,
32
+ isUserFunctionResponseEvent: () => isUserFunctionResponseEvent,
33
+ mapAdkEventToMessages: () => mapAdkEventToMessages,
34
+ mapAdkSessionEventsToMessages: () => mapAdkSessionEventsToMessages,
35
+ pairFunctionResponses: () => pairFunctionResponses
36
+ });
37
+ module.exports = __toCommonJS(messages_exports);
38
+ var import_uuid = require("uuid");
39
+ var import_parts = require("./parts");
40
+ var defaultProtocolOptions = {
41
+ hideAsyncTaskEvents: true,
42
+ pairFunctionResponses: true
43
+ };
44
+ var getAdkMessageEventId = (message) => {
45
+ var _a;
46
+ return message.eventId || ((_a = message.raw) == null ? void 0 : _a.id) || message.id;
47
+ };
48
+ var getAdkMessageInvocationId = (message) => {
49
+ var _a;
50
+ return message.invocationId || ((_a = message.raw) == null ? void 0 : _a.invocationId);
51
+ };
52
+ var isAdkAsyncTaskEvent = (event) => {
53
+ var _a, _b;
54
+ return event.author === "user" && ((_b = (_a = event.content) == null ? void 0 : _a.parts) == null ? void 0 : _b.some((part) => Boolean(part == null ? void 0 : part.task)));
55
+ };
56
+ var isUserFunctionResponseEvent = (event) => {
57
+ var _a;
58
+ return ((_a = event.content) == null ? void 0 : _a.role) === "user" && Array.isArray(event.content.parts) && event.content.parts.length > 0 && event.content.parts.every((part) => Boolean(part == null ? void 0 : part.functionResponse));
59
+ };
60
+ var getAdkEventMeta = (event) => ({
61
+ eventId: event.id,
62
+ invocationId: event.invocationId,
63
+ sessionId: event.sessionId,
64
+ timestamp: event.timestamp,
65
+ author: event.author,
66
+ modelCode: event.modelCode,
67
+ usageMetadata: event.usageMetadata,
68
+ finishReason: event.finishReason,
69
+ isLike: event.isLike
70
+ });
71
+ var createAdkMessage = (event, part, role = "bot") => {
72
+ var _a, _b;
73
+ return {
74
+ id: (0, import_uuid.v4)(),
75
+ role,
76
+ ...getAdkEventMeta(event),
77
+ thought: part.thought,
78
+ functionCall: part.functionCall,
79
+ functionResponse: part.functionResponse,
80
+ fileData: part.fileDataList || (part.fileData ? [part.fileData] : void 0),
81
+ inlineData: part.inlineData,
82
+ executableCode: part.executableCode,
83
+ codeExecutionResult: part.codeExecutionResult,
84
+ text: part.errorMessage || part.text,
85
+ renderedContent: (_b = (_a = event.groundingMetadata) == null ? void 0 : _a.searchEntryPoint) == null ? void 0 : _b.renderedContent,
86
+ raw: event
87
+ };
88
+ };
89
+ var mapAdkEventToMessages = (event, options) => {
90
+ var _a, _b, _c, _d;
91
+ const mergedOptions = { ...defaultProtocolOptions, ...options };
92
+ if (mergedOptions.hideAsyncTaskEvents && isAdkAsyncTaskEvent(event))
93
+ return [];
94
+ if (mergedOptions.pairFunctionResponses && isUserFunctionResponseEvent(event))
95
+ return [];
96
+ if (((_a = event.content) == null ? void 0 : _a.role) === "followup")
97
+ return [];
98
+ if ((_c = (_b = event.content) == null ? void 0 : _b.parts) == null ? void 0 : _c.length) {
99
+ const role = event.content.role === "user" ? "user" : "bot";
100
+ return (0, import_parts.normalizeAdkParts)(event.content.parts).map(
101
+ (part) => createAdkMessage(event, part, role)
102
+ );
103
+ }
104
+ if (event.errorMessage) {
105
+ return [
106
+ {
107
+ id: (0, import_uuid.v4)(),
108
+ role: "bot",
109
+ text: event.errorMessage,
110
+ ...getAdkEventMeta(event),
111
+ raw: event
112
+ }
113
+ ];
114
+ }
115
+ if ((_d = event.actions) == null ? void 0 : _d.artifactDelta) {
116
+ return [
117
+ {
118
+ id: (0, import_uuid.v4)(),
119
+ role: "bot",
120
+ ...getAdkEventMeta(event),
121
+ raw: event
122
+ }
123
+ ];
124
+ }
125
+ return [];
126
+ };
127
+ var mapAdkSessionEventsToMessages = (events = [], options) => pairFunctionResponses(events.flatMap(
128
+ (event) => mapAdkEventToMessages(event, options)
129
+ ));
130
+ var dedupeAdkMessages = (messages) => {
131
+ const seenMessageIds = /* @__PURE__ */ new Set();
132
+ let hasDuplicate = false;
133
+ const uniqueIdMessages = messages.filter((message) => {
134
+ if (seenMessageIds.has(message.id)) {
135
+ hasDuplicate = true;
136
+ return false;
137
+ }
138
+ seenMessageIds.add(message.id);
139
+ return true;
140
+ });
141
+ const botTextGroups = /* @__PURE__ */ new Map();
142
+ uniqueIdMessages.forEach((message) => {
143
+ const invocationId = getAdkMessageInvocationId(message);
144
+ if (message.role !== "bot" || !invocationId || typeof message.text !== "string")
145
+ return;
146
+ const normalizedText = message.text.replace(/\s+/g, " ").trim();
147
+ if (!normalizedText)
148
+ return;
149
+ const fileKey = (message.fileData || []).map((file) => file.fileUri).join("|");
150
+ const groupKey = `${invocationId}\0${Boolean(
151
+ message.thought
152
+ )}\0${fileKey}`;
153
+ const group = botTextGroups.get(groupKey) || [];
154
+ group.push({ message, normalizedText });
155
+ botTextGroups.set(groupKey, group);
156
+ });
157
+ const redundantIds = /* @__PURE__ */ new Set();
158
+ botTextGroups.forEach((group) => {
159
+ const completeTexts = [];
160
+ [...group].sort((a, b) => b.normalizedText.length - a.normalizedText.length).forEach(({ message, normalizedText }) => {
161
+ if (completeTexts.some(
162
+ (completeText) => completeText.includes(normalizedText)
163
+ )) {
164
+ redundantIds.add(message.id);
165
+ hasDuplicate = true;
166
+ return;
167
+ }
168
+ completeTexts.push(normalizedText);
169
+ });
170
+ });
171
+ return hasDuplicate ? uniqueIdMessages.filter((message) => !redundantIds.has(message.id)) : messages;
172
+ };
173
+ var insertMissingAdkSessionEvents = (currentMessages, sessionEvents, options) => {
174
+ let nextMessages = pairFunctionResponses(currentMessages);
175
+ const functionResponses = collectFunctionResponses(sessionEvents);
176
+ if (functionResponses.size) {
177
+ nextMessages = pairFunctionResponses(nextMessages, functionResponses);
178
+ }
179
+ const renderedEventIds = new Set(
180
+ nextMessages.map(getAdkMessageEventId).filter(Boolean)
181
+ );
182
+ const missingMessages = sessionEvents.filter((event) => {
183
+ var _a, _b, _c;
184
+ if ((_a = options == null ? void 0 : options.removedInvocationIds) == null ? void 0 : _a.has(event.invocationId || ""))
185
+ return false;
186
+ const parts = (_b = event.content) == null ? void 0 : _b.parts;
187
+ return Boolean(event.id) && ((_c = event.content) == null ? void 0 : _c.role) === "model" && Array.isArray(parts) && parts.length > 0 && !renderedEventIds.has(event.id);
188
+ }).flatMap((event) => mapAdkEventToMessages(event, options));
189
+ if (!missingMessages.length)
190
+ return nextMessages;
191
+ const eventOrder = new Map(
192
+ sessionEvents.map((event, index) => [event.id, index])
193
+ );
194
+ const getMessageOrder = (message) => {
195
+ var _a;
196
+ const eventId = getAdkMessageEventId(message);
197
+ if (eventId && eventOrder.has(eventId))
198
+ return eventOrder.get(eventId);
199
+ const timestamp = message.timestamp ?? ((_a = message.raw) == null ? void 0 : _a.timestamp);
200
+ if (timestamp !== void 0) {
201
+ const nextEventIndex = sessionEvents.findIndex(
202
+ (event) => (event.timestamp || 0) > timestamp
203
+ );
204
+ return nextEventIndex < 0 ? sessionEvents.length + 0.5 : nextEventIndex - 0.5;
205
+ }
206
+ return Number.POSITIVE_INFINITY;
207
+ };
208
+ missingMessages.forEach((message) => {
209
+ const targetOrder = getMessageOrder(message);
210
+ let insertIndex = nextMessages.findIndex((current) => {
211
+ const currentOrder = getMessageOrder(current);
212
+ return Number.isFinite(currentOrder) && currentOrder > targetOrder;
213
+ });
214
+ if (insertIndex < 0)
215
+ insertIndex = nextMessages.length;
216
+ nextMessages.splice(insertIndex, 0, message);
217
+ });
218
+ return dedupeAdkMessages(pairFunctionResponses(nextMessages));
219
+ };
220
+ var collectFunctionResponses = (events) => {
221
+ const functionResponses = /* @__PURE__ */ new Map();
222
+ events.forEach((event) => {
223
+ var _a, _b;
224
+ (_b = (_a = event.content) == null ? void 0 : _a.parts) == null ? void 0 : _b.forEach((part) => {
225
+ var _a2;
226
+ if ((_a2 = part.functionResponse) == null ? void 0 : _a2.id) {
227
+ functionResponses.set(part.functionResponse.id, part.functionResponse);
228
+ }
229
+ });
230
+ });
231
+ return functionResponses;
232
+ };
233
+ var pairFunctionResponses = (messages, responses) => {
234
+ const responseMap = responses || new Map(
235
+ messages.filter((message) => {
236
+ var _a;
237
+ return (_a = message.functionResponse) == null ? void 0 : _a.id;
238
+ }).map((message) => [
239
+ message.functionResponse.id,
240
+ message.functionResponse
241
+ ])
242
+ );
243
+ if (!responseMap.size)
244
+ return messages;
245
+ return messages.map((message) => {
246
+ var _a;
247
+ const callId = (_a = message.functionCall) == null ? void 0 : _a.id;
248
+ if (!callId || message.functionResponse || !responseMap.has(callId)) {
249
+ return message;
250
+ }
251
+ return {
252
+ ...message,
253
+ functionResponse: responseMap.get(callId)
254
+ };
255
+ });
256
+ };
257
+ var buildAdkUserMessage = ({
258
+ text = "",
259
+ files = [],
260
+ functionResponse
261
+ }) => {
262
+ const timestamp = Date.now();
263
+ const messages = [];
264
+ if (files.length) {
265
+ messages.push({
266
+ id: (0, import_uuid.v4)(),
267
+ role: "user",
268
+ timestamp,
269
+ fileData: files.map((file) => {
270
+ var _a, _b, _c, _d;
271
+ const fileUri = file.tempUrl || file.fileUrl || ((_a = file.response) == null ? void 0 : _a.fileUrl) || ((_b = file.response) == null ? void 0 : _b.tempUrl);
272
+ if (!fileUri)
273
+ return null;
274
+ return {
275
+ displayName: file.fileName || file.name || ((_c = file.response) == null ? void 0 : _c.fileName) || "",
276
+ mimeType: file.mimeType || ((_d = file.response) == null ? void 0 : _d.mimeType) || "",
277
+ fileUri
278
+ };
279
+ }).filter(Boolean)
280
+ });
281
+ }
282
+ if (text.trim()) {
283
+ messages.push({ id: (0, import_uuid.v4)(), role: "user", text, timestamp });
284
+ }
285
+ if (functionResponse) {
286
+ messages.push({ id: (0, import_uuid.v4)(), role: "user", functionResponse, timestamp });
287
+ }
288
+ return messages;
289
+ };
290
+ // Annotate the CommonJS export names for ESM import in node:
291
+ 0 && (module.exports = {
292
+ buildAdkUserMessage,
293
+ buildAdkUserParts,
294
+ collectFunctionResponses,
295
+ createAdkMessage,
296
+ dedupeAdkMessages,
297
+ getAdkEventMeta,
298
+ getAdkMessageEventId,
299
+ getAdkMessageInvocationId,
300
+ insertMissingAdkSessionEvents,
301
+ isAdkAsyncTaskEvent,
302
+ isUserFunctionResponseEvent,
303
+ mapAdkEventToMessages,
304
+ mapAdkSessionEventsToMessages,
305
+ pairFunctionResponses
306
+ });
307
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/core/protocol/messages.ts"],
4
+ "sourcesContent": ["import { v4 } from \"uuid\";\nimport type { Event, IMessage } from \"@/types\";\nimport { buildAdkUserParts, normalizeAdkParts } from \"./parts\";\nimport type {\n AdkProtocolOptions,\n BuildAdkUserPartsInput,\n MessageEventMeta,\n NormalizedAdkPart,\n} from \"./types\";\n\nconst defaultProtocolOptions: Required<AdkProtocolOptions> = {\n hideAsyncTaskEvents: true,\n pairFunctionResponses: true,\n};\n\n/**\n * 获取消息对应的服务端 eventId。\n * session events 补偿和去重会优先用服务端 id,避免前端临时 id 导致重复插入。\n */\nexport const getAdkMessageEventId = (message: IMessage) =>\n message.eventId || message.raw?.id || message.id;\n\n/**\n * 获取单次模型调用 id。流式分片与 sessionDetails 完整消息通常共享 invocationId,\n * 可用它判断哪些文本属于同一轮回复。\n */\nexport const getAdkMessageInvocationId = (message: IMessage) =>\n message.invocationId || message.raw?.invocationId;\n\n/**\n * 后端为异步任务补链路时可能插入 user task 事件,这类事件用于关联任务,\n * 默认不作为用户可见消息展示。\n */\nexport const isAdkAsyncTaskEvent = (event: Event) =>\n event.author === \"user\" &&\n event.content?.parts?.some((part) => Boolean((part as any)?.task));\n\nexport const isUserFunctionResponseEvent = (event: Event) =>\n event.content?.role === \"user\" &&\n Array.isArray(event.content.parts) &&\n event.content.parts.length > 0 &&\n event.content.parts.every((part) => Boolean(part?.functionResponse));\n\n/**\n * 提取 event 级元信息,保证 stream 最后一条里的 modelCode / usageMetadata\n * 能透传到 IMessage,业务侧可据此展示 token 消耗等信息。\n */\nexport const getAdkEventMeta = (event: Event): MessageEventMeta => ({\n eventId: event.id,\n invocationId: event.invocationId,\n sessionId: event.sessionId,\n timestamp: event.timestamp,\n author: event.author,\n modelCode: event.modelCode,\n usageMetadata: event.usageMetadata,\n finishReason: event.finishReason,\n isLike: event.isLike,\n});\n\nexport const createAdkMessage = (\n event: Event,\n part: NormalizedAdkPart,\n role: IMessage[\"role\"] = \"bot\",\n): IMessage => ({\n id: v4(),\n role,\n ...getAdkEventMeta(event),\n thought: part.thought,\n functionCall: part.functionCall,\n functionResponse: part.functionResponse,\n fileData: part.fileDataList || (part.fileData ? [part.fileData] : undefined),\n inlineData: part.inlineData,\n executableCode: part.executableCode,\n codeExecutionResult: part.codeExecutionResult,\n text: part.errorMessage || part.text,\n renderedContent: event.groundingMetadata?.searchEntryPoint?.renderedContent,\n raw: event,\n});\n\n/**\n * 将单个 ADK event 转换为 SDK 消息。\n *\n * followup 事件由上层作为 suggestedQuestions 处理;user functionResponse\n * 默认只用于回填对应 functionCall,不单独展示成一条用户消息。\n */\nexport const mapAdkEventToMessages = (\n event: Event,\n options?: AdkProtocolOptions,\n): IMessage[] => {\n const mergedOptions = { ...defaultProtocolOptions, ...options };\n if (mergedOptions.hideAsyncTaskEvents && isAdkAsyncTaskEvent(event)) return [];\n if (mergedOptions.pairFunctionResponses && isUserFunctionResponseEvent(event))\n return [];\n if (event.content?.role === \"followup\") return [];\n\n if (event.content?.parts?.length) {\n const role = event.content.role === \"user\" ? \"user\" : \"bot\";\n return normalizeAdkParts(event.content.parts).map((part) =>\n createAdkMessage(event, part, role),\n );\n }\n\n if (event.errorMessage) {\n return [\n {\n id: v4(),\n role: \"bot\",\n text: event.errorMessage,\n ...getAdkEventMeta(event),\n raw: event,\n },\n ];\n }\n\n if (event.actions?.artifactDelta) {\n return [\n {\n id: v4(),\n role: \"bot\",\n ...getAdkEventMeta(event),\n raw: event,\n },\n ];\n }\n\n return [];\n};\n\nexport const mapAdkSessionEventsToMessages = (\n events: Event[] = [],\n options?: AdkProtocolOptions,\n): IMessage[] => pairFunctionResponses(events.flatMap((event) =>\n mapAdkEventToMessages(event, options),\n));\n\n/**\n * 消息去重分两层:\n * - 先按前端 id 去重。\n * - 再按 invocationId + thought + fileUri 聚合同一轮 bot 文本,保留更完整的长文本。\n *\n * 第二层主要解决 SSE 增量文本和 sessionDetails 完整文本同时存在时重复展示的问题。\n */\nexport const dedupeAdkMessages = (messages: IMessage[]): IMessage[] => {\n const seenMessageIds = new Set<string>();\n let hasDuplicate = false;\n\n const uniqueIdMessages = messages.filter((message) => {\n if (seenMessageIds.has(message.id)) {\n hasDuplicate = true;\n return false;\n }\n seenMessageIds.add(message.id);\n return true;\n });\n\n const botTextGroups = new Map<\n string,\n Array<{ message: IMessage; normalizedText: string }>\n >();\n\n uniqueIdMessages.forEach((message) => {\n const invocationId = getAdkMessageInvocationId(message);\n if (\n message.role !== \"bot\" ||\n !invocationId ||\n typeof message.text !== \"string\"\n )\n return;\n\n const normalizedText = message.text.replace(/\\s+/g, \" \").trim();\n if (!normalizedText) return;\n\n const fileKey = (message.fileData || [])\n .map((file) => file.fileUri)\n .join(\"|\");\n const groupKey = `${invocationId}\\u0000${Boolean(\n message.thought,\n )}\\u0000${fileKey}`;\n const group = botTextGroups.get(groupKey) || [];\n group.push({ message, normalizedText });\n botTextGroups.set(groupKey, group);\n });\n\n const redundantIds = new Set<string>();\n botTextGroups.forEach((group) => {\n const completeTexts: string[] = [];\n [...group]\n .sort((a, b) => b.normalizedText.length - a.normalizedText.length)\n .forEach(({ message, normalizedText }) => {\n if (\n completeTexts.some((completeText) =>\n completeText.includes(normalizedText),\n )\n ) {\n redundantIds.add(message.id);\n hasDuplicate = true;\n return;\n }\n completeTexts.push(normalizedText);\n });\n });\n\n return hasDuplicate\n ? uniqueIdMessages.filter((message) => !redundantIds.has(message.id))\n : messages;\n};\n\nexport const insertMissingAdkSessionEvents = (\n currentMessages: IMessage[],\n sessionEvents: Event[],\n options?: AdkProtocolOptions & { removedInvocationIds?: Set<string> },\n): IMessage[] => {\n // 先用 sessionEvents 里的 functionResponse 回填已有 functionCall,避免工具状态丢失。\n let nextMessages = pairFunctionResponses(currentMessages);\n const functionResponses = collectFunctionResponses(sessionEvents);\n if (functionResponses.size) {\n nextMessages = pairFunctionResponses(nextMessages, functionResponses);\n }\n\n const renderedEventIds = new Set(\n nextMessages.map(getAdkMessageEventId).filter(Boolean),\n );\n\n const missingMessages = sessionEvents\n .filter((event) => {\n if (options?.removedInvocationIds?.has(event.invocationId || \"\"))\n return false;\n const parts = event.content?.parts;\n return (\n Boolean(event.id) &&\n event.content?.role === \"model\" &&\n Array.isArray(parts) &&\n parts.length > 0 &&\n !renderedEventIds.has(event.id)\n );\n })\n .flatMap((event) => mapAdkEventToMessages(event, options));\n\n if (!missingMessages.length) return nextMessages;\n\n // 按服务端事件顺序插入缺失消息,尽量保持历史消息和流式消息的时间线一致。\n const eventOrder = new Map(\n sessionEvents.map((event, index) => [event.id, index]),\n );\n const getMessageOrder = (message: IMessage) => {\n const eventId = getAdkMessageEventId(message);\n if (eventId && eventOrder.has(eventId)) return eventOrder.get(eventId)!;\n\n const timestamp = message.timestamp ?? message.raw?.timestamp;\n if (timestamp !== undefined) {\n const nextEventIndex = sessionEvents.findIndex(\n (event) => (event.timestamp || 0) > timestamp,\n );\n return nextEventIndex < 0\n ? sessionEvents.length + 0.5\n : nextEventIndex - 0.5;\n }\n return Number.POSITIVE_INFINITY;\n };\n\n missingMessages.forEach((message) => {\n const targetOrder = getMessageOrder(message);\n let insertIndex = nextMessages.findIndex((current) => {\n const currentOrder = getMessageOrder(current);\n return Number.isFinite(currentOrder) && currentOrder > targetOrder;\n });\n if (insertIndex < 0) insertIndex = nextMessages.length;\n nextMessages.splice(insertIndex, 0, message);\n });\n\n return dedupeAdkMessages(pairFunctionResponses(nextMessages));\n};\n\n/**\n * 从 session events 中收集工具响应,用于回填前面已经渲染出来的 functionCall。\n */\nexport const collectFunctionResponses = (events: Event[]) => {\n const functionResponses = new Map<\n string,\n NonNullable<IMessage[\"functionResponse\"]>\n >();\n events.forEach((event) => {\n event.content?.parts?.forEach((part) => {\n if (part.functionResponse?.id) {\n functionResponses.set(part.functionResponse.id, part.functionResponse);\n }\n });\n });\n return functionResponses;\n};\n\nexport const pairFunctionResponses = (\n messages: IMessage[],\n responses?: Map<string, NonNullable<IMessage[\"functionResponse\"]>>,\n): IMessage[] => {\n const responseMap =\n responses ||\n new Map(\n messages\n .filter((message) => message.functionResponse?.id)\n .map((message) => [\n message.functionResponse!.id!,\n message.functionResponse!,\n ]),\n );\n\n if (!responseMap.size) return messages;\n\n return messages.map((message) => {\n const callId = message.functionCall?.id;\n if (!callId || message.functionResponse || !responseMap.has(callId)) {\n return message;\n }\n return {\n ...message,\n functionResponse: responseMap.get(callId),\n };\n });\n};\n\n/**\n * 构造本地乐观用户消息。\n * controller 在真正发请求前会先插入这些消息,让 UI 立即响应用户输入。\n */\nexport const buildAdkUserMessage = ({\n text = \"\",\n files = [],\n functionResponse,\n}: BuildAdkUserPartsInput): IMessage[] => {\n const timestamp = Date.now();\n const messages: IMessage[] = [];\n\n if (files.length) {\n messages.push({\n id: v4(),\n role: \"user\",\n timestamp,\n fileData: files\n .map((file) => {\n const fileUri =\n file.tempUrl ||\n file.fileUrl ||\n file.response?.fileUrl ||\n file.response?.tempUrl;\n if (!fileUri) return null;\n return {\n displayName:\n file.fileName || file.name || file.response?.fileName || \"\",\n mimeType: file.mimeType || file.response?.mimeType || \"\",\n fileUri,\n };\n })\n .filter(Boolean) as IMessage[\"fileData\"],\n });\n }\n\n if (text.trim()) {\n messages.push({ id: v4(), role: \"user\", text, timestamp });\n }\n\n if (functionResponse) {\n messages.push({ id: v4(), role: \"user\", functionResponse, timestamp });\n }\n\n return messages;\n};\n\nexport { buildAdkUserParts };\n"],
5
+ "mappings": "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",
6
+ "names": ["_a"]
7
+ }
@@ -0,0 +1,24 @@
1
+ import type { Part } from "../../types";
2
+ import type { BuildAdkUserPartsInput } from "./types";
3
+ import type { NormalizedAdkPart } from "./types";
4
+ /**
5
+ * 将后端 ADK parts 归一化成更适合 UI 渲染的片段。
6
+ *
7
+ * 设计目标:
8
+ * - 连续 text 会被合并,减少流式分片直接渲染带来的碎片化。
9
+ * - fileData 会合并到 fileDataList,支持“文件 + 文本”作为一条消息展示。
10
+ * - functionCall、functionResponse、代码执行等特殊 part 保持独立,避免影响工具渲染。
11
+ * - thought 发生切换时会结算当前缓冲,保证思考内容和普通回答不误合并。
12
+ */
13
+ export declare const normalizeAdkParts: (parts?: Part[]) => NormalizedAdkPart[];
14
+ /**
15
+ * 兼容早期只关注文本合并的调用方,语义上等同于 normalizeAdkParts。
16
+ */
17
+ export declare const combineAdkParts: (parts?: Part[]) => NormalizedAdkPart[];
18
+ /**
19
+ * 将 SDK Sender 的输入内容转换为 ADK 请求体里的 user parts。
20
+ *
21
+ * 这里保持“附件 part 在前、文本 part 在后”的顺序,和业务项目 useDebug
22
+ * 当前对后端协议的使用方式一致;functionResponse 场景只提交工具响应。
23
+ */
24
+ export declare const buildAdkUserParts: ({ text, files, functionResponse, }: BuildAdkUserPartsInput) => Part[];
@@ -0,0 +1,106 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/core/protocol/parts.ts
20
+ var parts_exports = {};
21
+ __export(parts_exports, {
22
+ buildAdkUserParts: () => buildAdkUserParts,
23
+ combineAdkParts: () => combineAdkParts,
24
+ normalizeAdkParts: () => normalizeAdkParts
25
+ });
26
+ module.exports = __toCommonJS(parts_exports);
27
+ var hasContent = (text, files) => Boolean(text) || Boolean(files == null ? void 0 : files.length);
28
+ var isSpecialPart = (part) => Boolean(
29
+ part.functionCall || part.functionResponse || part.executableCode || part.codeExecutionResult || part.actions
30
+ );
31
+ var normalizeAdkParts = (parts = []) => {
32
+ const normalized = [];
33
+ let currentFiles = [];
34
+ let currentText = "";
35
+ let currentThought;
36
+ parts.forEach((part) => {
37
+ const thoughtChanged = part.thought !== currentThought && hasContent(currentText, currentFiles);
38
+ if (isSpecialPart(part) || thoughtChanged) {
39
+ if (hasContent(currentText, currentFiles)) {
40
+ normalized.push({
41
+ text: currentText || void 0,
42
+ fileDataList: currentFiles.length ? currentFiles : void 0,
43
+ thought: currentThought
44
+ });
45
+ currentText = "";
46
+ currentFiles = [];
47
+ }
48
+ if (typeof part.thought !== "undefined") {
49
+ currentThought = part.thought;
50
+ }
51
+ }
52
+ if (isSpecialPart(part)) {
53
+ normalized.push({ ...part });
54
+ return;
55
+ }
56
+ if (part.fileData)
57
+ currentFiles.push(part.fileData);
58
+ if (part.text)
59
+ currentText += part.text;
60
+ if (typeof part.thought !== "undefined")
61
+ currentThought = part.thought;
62
+ });
63
+ if (hasContent(currentText, currentFiles)) {
64
+ normalized.push({
65
+ text: currentText || void 0,
66
+ fileDataList: currentFiles.length ? currentFiles : void 0,
67
+ thought: currentThought
68
+ });
69
+ } else if (!normalized.length && parts.length > 0) {
70
+ return parts.map((part) => ({ ...part }));
71
+ }
72
+ return normalized;
73
+ };
74
+ var combineAdkParts = normalizeAdkParts;
75
+ var buildAdkUserParts = ({
76
+ text = "",
77
+ files = [],
78
+ functionResponse
79
+ }) => {
80
+ if (functionResponse)
81
+ return [{ functionResponse }];
82
+ const parts = [];
83
+ files.forEach((file) => {
84
+ var _a, _b, _c, _d;
85
+ const fileUri = file.tempUrl || file.fileUrl || ((_a = file.response) == null ? void 0 : _a.fileUrl) || ((_b = file.response) == null ? void 0 : _b.tempUrl);
86
+ if (!fileUri)
87
+ return;
88
+ parts.push({
89
+ fileData: {
90
+ fileUri,
91
+ displayName: file.fileName || file.name || ((_c = file.response) == null ? void 0 : _c.fileName) || "",
92
+ mimeType: file.mimeType || ((_d = file.response) == null ? void 0 : _d.mimeType) || ""
93
+ }
94
+ });
95
+ });
96
+ if (text.trim())
97
+ parts.push({ text });
98
+ return parts;
99
+ };
100
+ // Annotate the CommonJS export names for ESM import in node:
101
+ 0 && (module.exports = {
102
+ buildAdkUserParts,
103
+ combineAdkParts,
104
+ normalizeAdkParts
105
+ });
106
+ //# sourceMappingURL=parts.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/core/protocol/parts.ts"],
4
+ "sourcesContent": ["import type { FileData, Part } from \"@/types\";\nimport type { BuildAdkUserPartsInput } from \"./types\";\nimport type { NormalizedAdkPart } from \"./types\";\n\nconst hasContent = (text?: string, files?: FileData[]) =>\n Boolean(text) || Boolean(files?.length);\n\nconst isSpecialPart = (part: Part) =>\n Boolean(\n part.functionCall ||\n part.functionResponse ||\n part.executableCode ||\n part.codeExecutionResult ||\n (part as any).actions,\n );\n\n/**\n * 将后端 ADK parts 归一化成更适合 UI 渲染的片段。\n *\n * 设计目标:\n * - 连续 text 会被合并,减少流式分片直接渲染带来的碎片化。\n * - fileData 会合并到 fileDataList,支持“文件 + 文本”作为一条消息展示。\n * - functionCall、functionResponse、代码执行等特殊 part 保持独立,避免影响工具渲染。\n * - thought 发生切换时会结算当前缓冲,保证思考内容和普通回答不误合并。\n */\nexport const normalizeAdkParts = (parts: Part[] = []): NormalizedAdkPart[] => {\n const normalized: NormalizedAdkPart[] = [];\n let currentFiles: FileData[] = [];\n let currentText = \"\";\n let currentThought: boolean | undefined;\n\n parts.forEach((part) => {\n const thoughtChanged =\n part.thought !== currentThought && hasContent(currentText, currentFiles);\n\n if (isSpecialPart(part) || thoughtChanged) {\n if (hasContent(currentText, currentFiles)) {\n normalized.push({\n text: currentText || undefined,\n fileDataList: currentFiles.length ? currentFiles : undefined,\n thought: currentThought,\n });\n currentText = \"\";\n currentFiles = [];\n }\n if (typeof part.thought !== \"undefined\") {\n currentThought = part.thought;\n }\n }\n\n if (isSpecialPart(part)) {\n normalized.push({ ...part });\n return;\n }\n\n if (part.fileData) currentFiles.push(part.fileData as FileData);\n if (part.text) currentText += part.text;\n if (typeof part.thought !== \"undefined\") currentThought = part.thought;\n });\n\n if (hasContent(currentText, currentFiles)) {\n normalized.push({\n text: currentText || undefined,\n fileDataList: currentFiles.length ? currentFiles : undefined,\n thought: currentThought,\n });\n } else if (!normalized.length && parts.length > 0) {\n return parts.map((part) => ({ ...part }));\n }\n\n return normalized;\n};\n\n/**\n * 兼容早期只关注文本合并的调用方,语义上等同于 normalizeAdkParts。\n */\nexport const combineAdkParts = normalizeAdkParts;\n\n/**\n * 将 SDK Sender 的输入内容转换为 ADK 请求体里的 user parts。\n *\n * 这里保持“附件 part 在前、文本 part 在后”的顺序,和业务项目 useDebug\n * 当前对后端协议的使用方式一致;functionResponse 场景只提交工具响应。\n */\nexport const buildAdkUserParts = ({\n text = \"\",\n files = [],\n functionResponse,\n}: BuildAdkUserPartsInput): Part[] => {\n if (functionResponse) return [{ functionResponse }];\n\n const parts: Part[] = [];\n files.forEach((file) => {\n const fileUri =\n file.tempUrl ||\n file.fileUrl ||\n file.response?.fileUrl ||\n file.response?.tempUrl;\n if (!fileUri) return;\n\n parts.push({\n fileData: {\n fileUri,\n displayName:\n file.fileName || file.name || file.response?.fileName || \"\",\n mimeType: file.mimeType || file.response?.mimeType || \"\",\n },\n });\n });\n\n if (text.trim()) parts.push({ text });\n return parts;\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,IAAM,aAAa,CAAC,MAAe,UACjC,QAAQ,IAAI,KAAK,QAAQ,+BAAO,MAAM;AAExC,IAAM,gBAAgB,CAAC,SACrB;AAAA,EACE,KAAK,gBACH,KAAK,oBACL,KAAK,kBACL,KAAK,uBACJ,KAAa;AAClB;AAWK,IAAM,oBAAoB,CAAC,QAAgB,CAAC,MAA2B;AAC5E,QAAM,aAAkC,CAAC;AACzC,MAAI,eAA2B,CAAC;AAChC,MAAI,cAAc;AAClB,MAAI;AAEJ,QAAM,QAAQ,CAAC,SAAS;AACtB,UAAM,iBACJ,KAAK,YAAY,kBAAkB,WAAW,aAAa,YAAY;AAEzE,QAAI,cAAc,IAAI,KAAK,gBAAgB;AACzC,UAAI,WAAW,aAAa,YAAY,GAAG;AACzC,mBAAW,KAAK;AAAA,UACd,MAAM,eAAe;AAAA,UACrB,cAAc,aAAa,SAAS,eAAe;AAAA,UACnD,SAAS;AAAA,QACX,CAAC;AACD,sBAAc;AACd,uBAAe,CAAC;AAAA,MAClB;AACA,UAAI,OAAO,KAAK,YAAY,aAAa;AACvC,yBAAiB,KAAK;AAAA,MACxB;AAAA,IACF;AAEA,QAAI,cAAc,IAAI,GAAG;AACvB,iBAAW,KAAK,EAAE,GAAG,KAAK,CAAC;AAC3B;AAAA,IACF;AAEA,QAAI,KAAK;AAAU,mBAAa,KAAK,KAAK,QAAoB;AAC9D,QAAI,KAAK;AAAM,qBAAe,KAAK;AACnC,QAAI,OAAO,KAAK,YAAY;AAAa,uBAAiB,KAAK;AAAA,EACjE,CAAC;AAED,MAAI,WAAW,aAAa,YAAY,GAAG;AACzC,eAAW,KAAK;AAAA,MACd,MAAM,eAAe;AAAA,MACrB,cAAc,aAAa,SAAS,eAAe;AAAA,MACnD,SAAS;AAAA,IACX,CAAC;AAAA,EACH,WAAW,CAAC,WAAW,UAAU,MAAM,SAAS,GAAG;AACjD,WAAO,MAAM,IAAI,CAAC,UAAU,EAAE,GAAG,KAAK,EAAE;AAAA,EAC1C;AAEA,SAAO;AACT;AAKO,IAAM,kBAAkB;AAQxB,IAAM,oBAAoB,CAAC;AAAA,EAChC,OAAO;AAAA,EACP,QAAQ,CAAC;AAAA,EACT;AACF,MAAsC;AACpC,MAAI;AAAkB,WAAO,CAAC,EAAE,iBAAiB,CAAC;AAElD,QAAM,QAAgB,CAAC;AACvB,QAAM,QAAQ,CAAC,SAAS;AA5F1B;AA6FI,UAAM,UACJ,KAAK,WACL,KAAK,aACL,UAAK,aAAL,mBAAe,cACf,UAAK,aAAL,mBAAe;AACjB,QAAI,CAAC;AAAS;AAEd,UAAM,KAAK;AAAA,MACT,UAAU;AAAA,QACR;AAAA,QACA,aACE,KAAK,YAAY,KAAK,UAAQ,UAAK,aAAL,mBAAe,aAAY;AAAA,QAC3D,UAAU,KAAK,cAAY,UAAK,aAAL,mBAAe,aAAY;AAAA,MACxD;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,MAAI,KAAK,KAAK;AAAG,UAAM,KAAK,EAAE,KAAK,CAAC;AACpC,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,57 @@
1
+ import type { AgentRunRequest, Event, FileData, FunctionCall, FunctionResponse, IMessage, Part, SendContent } from "../../types";
2
+ export type AdkEvent = Event;
3
+ export type AdkPart = Part;
4
+ export type AdkFileData = FileData;
5
+ export type AdkFunctionCall = FunctionCall;
6
+ export type AdkFunctionResponse = FunctionResponse;
7
+ export type AdkMessage = IMessage;
8
+ export type AdkSendContent = SendContent;
9
+ export type AdkRunRequest = AgentRunRequest;
10
+ export interface NormalizedAdkPart extends Partial<Part> {
11
+ text?: string;
12
+ fileDataList?: FileData[];
13
+ thought?: boolean;
14
+ }
15
+ export interface MessageEventMeta {
16
+ eventId?: string;
17
+ invocationId?: string;
18
+ sessionId?: string;
19
+ timestamp?: number;
20
+ author?: string;
21
+ modelCode?: string;
22
+ usageMetadata?: AdkEvent["usageMetadata"];
23
+ finishReason?: string;
24
+ isLike?: number;
25
+ }
26
+ export interface AdkProtocolOptions {
27
+ /**
28
+ * Hide user events inserted by backend async tasks.
29
+ * @default true
30
+ */
31
+ hideAsyncTaskEvents?: boolean;
32
+ /**
33
+ * Treat user-only functionResponse events as tool-call status updates instead
34
+ * of standalone messages.
35
+ * @default true
36
+ */
37
+ pairFunctionResponses?: boolean;
38
+ }
39
+ export interface BuildAdkUserPartsInput {
40
+ text?: string;
41
+ files?: Array<{
42
+ fileName?: string;
43
+ name?: string;
44
+ tempUrl?: string;
45
+ fileUrl?: string;
46
+ mimeType?: string;
47
+ type?: string;
48
+ response?: {
49
+ fileName?: string;
50
+ fileUrl?: string;
51
+ tempUrl?: string;
52
+ mimeType?: string;
53
+ fileType?: string;
54
+ };
55
+ }>;
56
+ functionResponse?: FunctionResponse | null;
57
+ }
@@ -0,0 +1,18 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __copyProps = (to, from, except, desc) => {
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from))
8
+ if (!__hasOwnProp.call(to, key) && key !== except)
9
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
+ }
11
+ return to;
12
+ };
13
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
14
+
15
+ // src/core/protocol/types.ts
16
+ var types_exports = {};
17
+ module.exports = __toCommonJS(types_exports);
18
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/core/protocol/types.ts"],
4
+ "sourcesContent": ["import type {\n AgentRunRequest,\n Event,\n FileData,\n FunctionCall,\n FunctionResponse,\n IMessage,\n Part,\n SendContent,\n} from \"@/types\";\n\nexport type AdkEvent = Event;\nexport type AdkPart = Part;\nexport type AdkFileData = FileData;\nexport type AdkFunctionCall = FunctionCall;\nexport type AdkFunctionResponse = FunctionResponse;\nexport type AdkMessage = IMessage;\nexport type AdkSendContent = SendContent;\nexport type AdkRunRequest = AgentRunRequest;\n\nexport interface NormalizedAdkPart extends Partial<Part> {\n text?: string;\n fileDataList?: FileData[];\n thought?: boolean;\n}\n\nexport interface MessageEventMeta {\n eventId?: string;\n invocationId?: string;\n sessionId?: string;\n timestamp?: number;\n author?: string;\n modelCode?: string;\n usageMetadata?: AdkEvent[\"usageMetadata\"];\n finishReason?: string;\n isLike?: number;\n}\n\nexport interface AdkProtocolOptions {\n /**\n * Hide user events inserted by backend async tasks.\n * @default true\n */\n hideAsyncTaskEvents?: boolean;\n /**\n * Treat user-only functionResponse events as tool-call status updates instead\n * of standalone messages.\n * @default true\n */\n pairFunctionResponses?: boolean;\n}\n\nexport interface BuildAdkUserPartsInput {\n text?: string;\n files?: Array<{\n fileName?: string;\n name?: string;\n tempUrl?: string;\n fileUrl?: string;\n mimeType?: string;\n type?: string;\n response?: {\n fileName?: string;\n fileUrl?: string;\n tempUrl?: string;\n mimeType?: string;\n fileType?: string;\n };\n }>;\n functionResponse?: FunctionResponse | null;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;",
6
+ "names": []
7
+ }
@@ -0,0 +1,8 @@
1
+ import type { AdkConversationController, AdkConversationOptions } from "./types";
2
+ /**
3
+ * 创建无 React 依赖的 ADK 对话数据流控制器。
4
+ *
5
+ * controller 只管理状态和数据流编排;所有请求细节都交给 transport,
6
+ * 所有 UI 提示都通过 callbacks 抛给调用方。
7
+ */
8
+ export declare const createAdkConversationController: (options: AdkConversationOptions) => AdkConversationController;