instantsearch.js 4.86.1 → 4.87.1

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 (82) hide show
  1. package/cjs/connectors/autocomplete/connectAutocomplete.js +13 -5
  2. package/cjs/connectors/chat/connectChat.js +92 -20
  3. package/cjs/connectors/filter-suggestions/connectFilterSuggestions.js +255 -0
  4. package/cjs/connectors/index.js +7 -0
  5. package/cjs/connectors/index.umd.js +7 -0
  6. package/cjs/index.js +2 -2
  7. package/cjs/lib/ai-lite/abstract-chat.js +823 -0
  8. package/cjs/lib/ai-lite/index.js +57 -0
  9. package/cjs/lib/ai-lite/stream-parser.js +138 -0
  10. package/cjs/lib/ai-lite/transport.js +218 -0
  11. package/cjs/lib/ai-lite/types.js +1 -0
  12. package/cjs/lib/ai-lite/utils.js +85 -0
  13. package/cjs/lib/chat/chat.js +6 -6
  14. package/cjs/lib/chat/index.js +5 -2
  15. package/cjs/lib/version.js +1 -1
  16. package/cjs/widgets/autocomplete/autocomplete.js +15 -6
  17. package/cjs/widgets/chat/chat.js +32 -3
  18. package/cjs/widgets/filter-suggestions/filter-suggestions.js +131 -0
  19. package/cjs/widgets/index.js +7 -0
  20. package/cjs/widgets/index.umd.js +7 -0
  21. package/dist/instantsearch.development.d.ts +2551 -346
  22. package/dist/instantsearch.development.js +9408 -4314
  23. package/dist/instantsearch.development.js.map +1 -1
  24. package/dist/instantsearch.production.d.ts +2551 -346
  25. package/dist/instantsearch.production.min.d.ts +2551 -346
  26. package/dist/instantsearch.production.min.js +2 -2
  27. package/dist/instantsearch.production.min.js.map +1 -1
  28. package/es/connectors/autocomplete/connectAutocomplete.d.ts +10 -0
  29. package/es/connectors/autocomplete/connectAutocomplete.js +13 -5
  30. package/es/connectors/chat/connectChat.d.ts +24 -14
  31. package/es/connectors/chat/connectChat.js +90 -18
  32. package/es/connectors/filter-suggestions/connectFilterSuggestions.d.ts +95 -0
  33. package/es/connectors/filter-suggestions/connectFilterSuggestions.js +249 -0
  34. package/es/connectors/frequently-bought-together/connectFrequentlyBoughtTogether.d.ts +2 -2
  35. package/es/connectors/geo-search/connectGeoSearch.d.ts +1 -1
  36. package/es/connectors/hits/connectHits.d.ts +1 -1
  37. package/es/connectors/hits/connectHitsWithInsights.d.ts +1 -1
  38. package/es/connectors/index.d.ts +1 -0
  39. package/es/connectors/index.js +2 -1
  40. package/es/connectors/index.umd.d.ts +1 -0
  41. package/es/connectors/index.umd.js +2 -1
  42. package/es/connectors/infinite-hits/connectInfiniteHits.d.ts +1 -1
  43. package/es/connectors/infinite-hits/connectInfiniteHitsWithInsights.d.ts +1 -1
  44. package/es/connectors/looking-similar/connectLookingSimilar.d.ts +2 -2
  45. package/es/connectors/related-products/connectRelatedProducts.d.ts +2 -2
  46. package/es/connectors/trending-items/connectTrendingItems.d.ts +2 -2
  47. package/es/lib/ai-lite/abstract-chat.d.ts +89 -0
  48. package/es/lib/ai-lite/abstract-chat.js +818 -0
  49. package/es/lib/ai-lite/index.d.ts +11 -0
  50. package/es/lib/ai-lite/index.js +18 -0
  51. package/es/lib/ai-lite/stream-parser.d.ts +18 -0
  52. package/es/lib/ai-lite/stream-parser.js +131 -0
  53. package/es/lib/ai-lite/transport.d.ts +24 -0
  54. package/es/lib/ai-lite/transport.js +214 -0
  55. package/es/lib/ai-lite/types.d.ts +362 -0
  56. package/es/lib/ai-lite/types.js +1 -0
  57. package/es/lib/ai-lite/utils.d.ts +12 -0
  58. package/es/lib/ai-lite/utils.js +76 -0
  59. package/es/lib/chat/chat.d.ts +3 -3
  60. package/es/lib/chat/chat.js +4 -4
  61. package/es/lib/chat/index.d.ts +3 -0
  62. package/es/lib/chat/index.js +4 -1
  63. package/es/lib/version.d.ts +1 -1
  64. package/es/lib/version.js +1 -1
  65. package/es/widgets/autocomplete/autocomplete.d.ts +2 -1
  66. package/es/widgets/autocomplete/autocomplete.js +15 -6
  67. package/es/widgets/chat/chat.d.ts +22 -14
  68. package/es/widgets/chat/chat.js +33 -4
  69. package/es/widgets/filter-suggestions/filter-suggestions.d.ts +689 -0
  70. package/es/widgets/filter-suggestions/filter-suggestions.js +124 -0
  71. package/es/widgets/frequently-bought-together/frequently-bought-together.d.ts +3 -3
  72. package/es/widgets/geo-search/geo-search.d.ts +1 -1
  73. package/es/widgets/hits/hits.d.ts +1 -1
  74. package/es/widgets/index.d.ts +1 -0
  75. package/es/widgets/index.js +2 -1
  76. package/es/widgets/index.umd.d.ts +1 -0
  77. package/es/widgets/index.umd.js +2 -1
  78. package/es/widgets/infinite-hits/infinite-hits.d.ts +1 -1
  79. package/es/widgets/looking-similar/looking-similar.d.ts +3 -3
  80. package/es/widgets/related-products/related-products.d.ts +3 -3
  81. package/es/widgets/trending-items/trending-items.d.ts +3 -3
  82. package/package.json +6 -7
@@ -0,0 +1,818 @@
1
+ var _excluded = ["messageId"];
2
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
3
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
4
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
5
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
6
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
8
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
9
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
10
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
11
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
12
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
13
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
14
+ function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
15
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
16
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
17
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
18
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
19
+ /* eslint-disable @typescript-eslint/consistent-type-assertions */
20
+ import { processStream } from "./stream-parser.js";
21
+ import { generateId as defaultGenerateId, SerialJobExecutor } from "./utils.js";
22
+ /**
23
+ * Abstract base class for chat implementations.
24
+ */
25
+ export var AbstractChat = /*#__PURE__*/function () {
26
+ function AbstractChat(_ref) {
27
+ var _this = this;
28
+ var _ref$generateId = _ref.generateId,
29
+ generateId = _ref$generateId === void 0 ? defaultGenerateId : _ref$generateId,
30
+ _ref$id = _ref.id,
31
+ id = _ref$id === void 0 ? generateId() : _ref$id,
32
+ transport = _ref.transport,
33
+ state = _ref.state,
34
+ onError = _ref.onError,
35
+ onToolCall = _ref.onToolCall,
36
+ onFinish = _ref.onFinish,
37
+ onData = _ref.onData,
38
+ sendAutomaticallyWhen = _ref.sendAutomaticallyWhen;
39
+ _classCallCheck(this, AbstractChat);
40
+ _defineProperty(this, "id", void 0);
41
+ _defineProperty(this, "generateId", void 0);
42
+ _defineProperty(this, "state", void 0);
43
+ _defineProperty(this, "transport", void 0);
44
+ _defineProperty(this, "onError", void 0);
45
+ _defineProperty(this, "onToolCall", void 0);
46
+ _defineProperty(this, "onFinish", void 0);
47
+ _defineProperty(this, "onData", void 0);
48
+ _defineProperty(this, "sendAutomaticallyWhen", void 0);
49
+ _defineProperty(this, "activeResponse", null);
50
+ _defineProperty(this, "jobExecutor", new SerialJobExecutor());
51
+ /**
52
+ * Appends or replaces a user message to the chat list. This triggers the API call to fetch
53
+ * the assistant's response.
54
+ */
55
+ _defineProperty(this, "sendMessage", function (message, options) {
56
+ return _this.jobExecutor.run(function () {
57
+ // Build the user message
58
+ var userMessagePromise;
59
+ if (message) {
60
+ var messageId = message.messageId || _this.generateId();
61
+ if ('parts' in message && message.parts) {
62
+ // Full message with parts provided
63
+ userMessagePromise = Promise.resolve(_objectSpread({
64
+ id: messageId,
65
+ role: 'user'
66
+ }, message));
67
+ } else if ('text' in message && message.text) {
68
+ // Build from text
69
+ var parts = [{
70
+ type: 'text',
71
+ text: message.text
72
+ }];
73
+
74
+ // Add file parts if provided
75
+ if (message.files) {
76
+ userMessagePromise = _this.convertFilesToParts(message.files).then(function (fileParts) {
77
+ parts.push.apply(parts, _toConsumableArray(fileParts));
78
+ return {
79
+ id: messageId,
80
+ role: 'user',
81
+ parts: parts,
82
+ metadata: message.metadata
83
+ };
84
+ });
85
+ } else {
86
+ userMessagePromise = Promise.resolve({
87
+ id: messageId,
88
+ role: 'user',
89
+ parts: parts,
90
+ metadata: message.metadata
91
+ });
92
+ }
93
+ } else if ('files' in message && message.files) {
94
+ // Files only
95
+ userMessagePromise = _this.convertFilesToParts(message.files).then(function (fileParts) {
96
+ return {
97
+ id: messageId,
98
+ role: 'user',
99
+ parts: fileParts,
100
+ metadata: message.metadata
101
+ };
102
+ });
103
+ } else {
104
+ userMessagePromise = Promise.resolve(undefined);
105
+ }
106
+ } else {
107
+ userMessagePromise = Promise.resolve(undefined);
108
+ }
109
+ return userMessagePromise.then(function (userMessage) {
110
+ if (userMessage) {
111
+ _this.state.pushMessage(userMessage);
112
+ }
113
+ return _this.makeRequest(_objectSpread({
114
+ trigger: 'submit-message',
115
+ messageId: userMessage === null || userMessage === void 0 ? void 0 : userMessage.id
116
+ }, options));
117
+ });
118
+ });
119
+ });
120
+ /**
121
+ * Regenerate the assistant message with the provided message id.
122
+ * If no message id is provided, the last assistant message will be regenerated.
123
+ */
124
+ _defineProperty(this, "regenerate", function () {
125
+ var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
126
+ messageId = _ref2.messageId,
127
+ options = _objectWithoutProperties(_ref2, _excluded);
128
+ return _this.jobExecutor.run(function () {
129
+ // Find the message to regenerate from
130
+ var targetIndex = -1;
131
+ if (messageId) {
132
+ targetIndex = _this.state.messages.findIndex(function (m) {
133
+ return m.id === messageId;
134
+ });
135
+ } else {
136
+ // Find the last assistant message
137
+ for (var i = _this.state.messages.length - 1; i >= 0; i--) {
138
+ if (_this.state.messages[i].role === 'assistant') {
139
+ targetIndex = i;
140
+ break;
141
+ }
142
+ }
143
+ }
144
+ if (targetIndex >= 0) {
145
+ // Remove the assistant message and all messages after it
146
+ _this.state.messages = _this.state.messages.slice(0, targetIndex);
147
+ }
148
+ return _this.makeRequest(_objectSpread({
149
+ trigger: 'regenerate-message',
150
+ messageId: messageId
151
+ }, options));
152
+ });
153
+ });
154
+ /**
155
+ * Attempt to resume an ongoing streaming response.
156
+ */
157
+ _defineProperty(this, "resumeStream", function (options) {
158
+ return _this.jobExecutor.run(function () {
159
+ if (!_this.transport) {
160
+ return Promise.reject(new Error('Transport is required for resuming stream. Please provide a transport when initializing the chat.'));
161
+ }
162
+ _this.setStatus({
163
+ status: 'submitted'
164
+ });
165
+ return _this.transport.reconnectToStream(_objectSpread({
166
+ chatId: _this.id
167
+ }, options)).then(function (stream) {
168
+ if (stream) {
169
+ return _this.processStreamWithCallbacks(stream);
170
+ } else {
171
+ _this.setStatus({
172
+ status: 'ready'
173
+ });
174
+ return Promise.resolve();
175
+ }
176
+ }, function (error) {
177
+ _this.handleError(error);
178
+ return Promise.resolve();
179
+ });
180
+ });
181
+ });
182
+ /**
183
+ * Clear the error state and set the status to ready if the chat is in an error state.
184
+ */
185
+ _defineProperty(this, "clearError", function () {
186
+ if (_this.state.status === 'error') {
187
+ _this.setStatus({
188
+ status: 'ready',
189
+ error: undefined
190
+ });
191
+ }
192
+ });
193
+ /**
194
+ * Add a tool result for a tool call.
195
+ */
196
+ _defineProperty(this, "addToolResult", function (_ref3) {
197
+ var tool = _ref3.tool,
198
+ toolCallId = _ref3.toolCallId,
199
+ output = _ref3.output;
200
+ return _this.jobExecutor.run(function () {
201
+ // Find the message with this tool call
202
+ var messageIndex = _this.state.messages.findIndex(function (m) {
203
+ var _m$parts$some, _m$parts;
204
+ return (_m$parts$some = (_m$parts = m.parts) === null || _m$parts === void 0 ? void 0 : _m$parts.some(function (p) {
205
+ return 'toolCallId' in p && p.toolCallId === toolCallId || 'type' in p && p.type === "tool-".concat(String(tool));
206
+ })) !== null && _m$parts$some !== void 0 ? _m$parts$some : false;
207
+ });
208
+ if (messageIndex === -1) return Promise.resolve();
209
+ var message = _this.state.messages[messageIndex];
210
+ var updatedParts = message.parts.map(function (part) {
211
+ if ('toolCallId' in part && part.toolCallId === toolCallId && 'state' in part) {
212
+ return _objectSpread(_objectSpread({}, part), {}, {
213
+ state: 'output-available',
214
+ output: output
215
+ });
216
+ }
217
+ return part;
218
+ });
219
+ _this.state.replaceMessage(messageIndex, _objectSpread(_objectSpread({}, message), {}, {
220
+ parts: updatedParts
221
+ }));
222
+
223
+ // Check if we should auto-send based on sendAutomaticallyWhen
224
+ if (_this.sendAutomaticallyWhen) {
225
+ return Promise.resolve(_this.sendAutomaticallyWhen({
226
+ messages: _this.state.messages
227
+ })).then(function (shouldSend) {
228
+ if (shouldSend) {
229
+ return _this.makeRequest({
230
+ trigger: 'submit-message'
231
+ });
232
+ }
233
+ return Promise.resolve();
234
+ });
235
+ }
236
+ return Promise.resolve();
237
+ });
238
+ });
239
+ /**
240
+ * Abort the current request immediately, keep the generated tokens if any.
241
+ */
242
+ _defineProperty(this, "stop", function () {
243
+ if (_this.activeResponse) {
244
+ _this.activeResponse.abortController.abort();
245
+ _this.activeResponse = null;
246
+ }
247
+ _this.setStatus({
248
+ status: 'ready'
249
+ });
250
+ return Promise.resolve();
251
+ });
252
+ this.id = id;
253
+ this.generateId = generateId;
254
+ this.state = state;
255
+ this.transport = transport;
256
+ this.onError = onError;
257
+ this.onToolCall = onToolCall;
258
+ this.onFinish = onFinish;
259
+ this.onData = onData;
260
+ this.sendAutomaticallyWhen = sendAutomaticallyWhen;
261
+ }
262
+
263
+ /**
264
+ * Hook status:
265
+ *
266
+ * - `submitted`: The message has been sent to the API and we're awaiting the start of the response stream.
267
+ * - `streaming`: The response is actively streaming in from the API, receiving chunks of data.
268
+ * - `ready`: The full response has been received and processed; a new user message can be submitted.
269
+ * - `error`: An error occurred during the API request, preventing successful completion.
270
+ */
271
+ _createClass(AbstractChat, [{
272
+ key: "status",
273
+ get: function get() {
274
+ return this.state.status;
275
+ }
276
+ }, {
277
+ key: "setStatus",
278
+ value: function setStatus(_ref4) {
279
+ var status = _ref4.status,
280
+ error = _ref4.error;
281
+ this.state.status = status;
282
+ if (error !== undefined) {
283
+ this.state.error = error;
284
+ }
285
+ }
286
+ }, {
287
+ key: "error",
288
+ get: function get() {
289
+ return this.state.error;
290
+ }
291
+ }, {
292
+ key: "messages",
293
+ get: function get() {
294
+ return this.state.messages;
295
+ },
296
+ set: function set(messages) {
297
+ this.state.messages = messages;
298
+ }
299
+ }, {
300
+ key: "lastMessage",
301
+ get: function get() {
302
+ return this.state.messages[this.state.messages.length - 1];
303
+ }
304
+ }, {
305
+ key: "makeRequest",
306
+ value: function makeRequest(options) {
307
+ var _this2 = this;
308
+ if (!this.transport) {
309
+ return Promise.reject(new Error('Transport is required for sending messages. Please provide a transport when initializing the chat.'));
310
+ }
311
+
312
+ // Abort any existing request
313
+ if (this.activeResponse) {
314
+ this.activeResponse.abortController.abort();
315
+ }
316
+ var abortController = new AbortController();
317
+ this.activeResponse = {
318
+ abortController: abortController
319
+ };
320
+ this.setStatus({
321
+ status: 'submitted'
322
+ });
323
+ return this.transport.sendMessages({
324
+ chatId: this.id,
325
+ messages: this.state.messages,
326
+ abortSignal: abortController.signal,
327
+ trigger: options.trigger,
328
+ messageId: options.messageId,
329
+ headers: options.headers,
330
+ body: options.body,
331
+ requestMetadata: options.metadata
332
+ }).then(function (stream) {
333
+ _this2.activeResponse.stream = stream;
334
+ return _this2.processStreamWithCallbacks(stream);
335
+ }, function (error) {
336
+ if (error.name === 'AbortError') {
337
+ // Request was aborted, don't treat as error
338
+ return Promise.resolve();
339
+ }
340
+ _this2.handleError(error);
341
+ return Promise.resolve();
342
+ });
343
+ }
344
+ }, {
345
+ key: "processStreamWithCallbacks",
346
+ value: function processStreamWithCallbacks(stream) {
347
+ var _this3 = this;
348
+ this.setStatus({
349
+ status: 'streaming'
350
+ });
351
+ var currentMessageId;
352
+ var currentMessage;
353
+ var currentMessageIndex = -1;
354
+ var isAbort = false;
355
+ var isDisconnect = false;
356
+ var isError = false;
357
+
358
+ // Track current text/reasoning part state
359
+ var currentTextPartId;
360
+ var currentReasoningPartId;
361
+
362
+ // Promise chain for handling tool calls that return promises
363
+ var pendingToolCall = Promise.resolve();
364
+ return new Promise(function (resolve) {
365
+ processStream(stream,
366
+ // eslint-disable-next-line complexity
367
+ function (chunk) {
368
+ switch (chunk.type) {
369
+ case 'start':
370
+ {
371
+ currentMessageId = chunk.messageId || _this3.generateId();
372
+
373
+ // Check if we're continuing an existing message or creating a new one
374
+ var lastMessage = _this3.lastMessage;
375
+ if (lastMessage && lastMessage.role === 'assistant' && lastMessage.id === currentMessageId) {
376
+ currentMessage = lastMessage;
377
+ currentMessageIndex = _this3.state.messages.length - 1;
378
+ } else {
379
+ currentMessage = {
380
+ id: currentMessageId,
381
+ role: 'assistant',
382
+ parts: [],
383
+ metadata: chunk.messageMetadata
384
+ };
385
+ _this3.state.pushMessage(currentMessage);
386
+ currentMessageIndex = _this3.state.messages.length - 1;
387
+ }
388
+ break;
389
+ }
390
+ case 'text-start':
391
+ {
392
+ if (!currentMessage) break;
393
+ currentTextPartId = chunk.id;
394
+ var textPart = {
395
+ type: 'text',
396
+ text: '',
397
+ state: 'streaming',
398
+ providerMetadata: chunk.providerMetadata
399
+ };
400
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
401
+ parts: [].concat(_toConsumableArray(currentMessage.parts), [textPart])
402
+ });
403
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
404
+ break;
405
+ }
406
+ case 'text-delta':
407
+ {
408
+ if (!currentMessage || !currentTextPartId) break;
409
+ var partIndex = currentMessage.parts.findIndex(function (p) {
410
+ return p.type === 'text' && p.state === 'streaming';
411
+ });
412
+ if (partIndex === -1) break;
413
+ var updatedParts = _toConsumableArray(currentMessage.parts);
414
+ var _textPart = updatedParts[partIndex];
415
+ updatedParts[partIndex] = _objectSpread(_objectSpread({}, _textPart), {}, {
416
+ text: _textPart.text + chunk.delta
417
+ });
418
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
419
+ parts: updatedParts
420
+ });
421
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
422
+ break;
423
+ }
424
+ case 'text-end':
425
+ {
426
+ if (!currentMessage) break;
427
+ var _partIndex = currentMessage.parts.findIndex(function (p) {
428
+ return p.type === 'text' && p.state === 'streaming';
429
+ });
430
+ if (_partIndex === -1) break;
431
+ var _updatedParts = _toConsumableArray(currentMessage.parts);
432
+ var _textPart2 = _updatedParts[_partIndex];
433
+ _updatedParts[_partIndex] = _objectSpread(_objectSpread({}, _textPart2), {}, {
434
+ state: 'done'
435
+ });
436
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
437
+ parts: _updatedParts
438
+ });
439
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
440
+ currentTextPartId = undefined;
441
+ break;
442
+ }
443
+ case 'reasoning-start':
444
+ {
445
+ if (!currentMessage) break;
446
+ currentReasoningPartId = chunk.id;
447
+ var reasoningPart = {
448
+ type: 'reasoning',
449
+ text: '',
450
+ state: 'streaming',
451
+ providerMetadata: chunk.providerMetadata
452
+ };
453
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
454
+ parts: [].concat(_toConsumableArray(currentMessage.parts), [reasoningPart])
455
+ });
456
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
457
+ break;
458
+ }
459
+ case 'reasoning-delta':
460
+ {
461
+ if (!currentMessage || !currentReasoningPartId) break;
462
+ var _partIndex2 = currentMessage.parts.findIndex(function (p) {
463
+ return p.type === 'reasoning' && p.state === 'streaming';
464
+ });
465
+ if (_partIndex2 === -1) break;
466
+ var _updatedParts2 = _toConsumableArray(currentMessage.parts);
467
+ var _reasoningPart = _updatedParts2[_partIndex2];
468
+ _updatedParts2[_partIndex2] = _objectSpread(_objectSpread({}, _reasoningPart), {}, {
469
+ text: _reasoningPart.text + chunk.delta
470
+ });
471
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
472
+ parts: _updatedParts2
473
+ });
474
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
475
+ break;
476
+ }
477
+ case 'reasoning-end':
478
+ {
479
+ if (!currentMessage) break;
480
+ var _partIndex3 = currentMessage.parts.findIndex(function (p) {
481
+ return p.type === 'reasoning' && p.state === 'streaming';
482
+ });
483
+ if (_partIndex3 === -1) break;
484
+ var _updatedParts3 = _toConsumableArray(currentMessage.parts);
485
+ var _reasoningPart2 = _updatedParts3[_partIndex3];
486
+ _updatedParts3[_partIndex3] = _objectSpread(_objectSpread({}, _reasoningPart2), {}, {
487
+ state: 'done'
488
+ });
489
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
490
+ parts: _updatedParts3
491
+ });
492
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
493
+ currentReasoningPartId = undefined;
494
+ break;
495
+ }
496
+ case 'tool-input-start':
497
+ {
498
+ if (!currentMessage) break;
499
+ var toolPart = {
500
+ type: "tool-".concat(chunk.toolName),
501
+ toolCallId: chunk.toolCallId,
502
+ state: 'input-streaming',
503
+ input: chunk.input,
504
+ providerExecuted: chunk.providerExecuted
505
+ };
506
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
507
+ parts: [].concat(_toConsumableArray(currentMessage.parts), [toolPart])
508
+ });
509
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
510
+ break;
511
+ }
512
+ case 'tool-input-delta':
513
+ {
514
+ // Tool input streaming - we'd need to parse partial JSON
515
+ // For now, we'll wait for tool-input-available
516
+ break;
517
+ }
518
+ case 'tool-input-available':
519
+ {
520
+ if (!currentMessage) break;
521
+
522
+ // Find existing tool part or create new one
523
+ var existingIndex = currentMessage.parts.findIndex(function (p) {
524
+ return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
525
+ });
526
+ var _toolPart = {
527
+ type: "tool-".concat(chunk.toolName),
528
+ toolCallId: chunk.toolCallId,
529
+ state: 'input-available',
530
+ input: chunk.input,
531
+ callProviderMetadata: chunk.callProviderMetadata,
532
+ providerExecuted: chunk.providerExecuted
533
+ };
534
+ if (existingIndex >= 0) {
535
+ var _updatedParts4 = _toConsumableArray(currentMessage.parts);
536
+ _updatedParts4[existingIndex] = _toolPart;
537
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
538
+ parts: _updatedParts4
539
+ });
540
+ } else {
541
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
542
+ parts: [].concat(_toConsumableArray(currentMessage.parts), [_toolPart])
543
+ });
544
+ }
545
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
546
+
547
+ // Trigger onToolCall callback only for client-executed tools
548
+ // (server-executed tools have providerExecuted: true and don't need client handling)
549
+ if (_this3.onToolCall && !chunk.providerExecuted) {
550
+ var result = _this3.onToolCall({
551
+ toolCall: {
552
+ toolName: chunk.toolName,
553
+ toolCallId: chunk.toolCallId,
554
+ input: chunk.input
555
+ }
556
+ });
557
+ if (result && typeof result.then === 'function') {
558
+ pendingToolCall = pendingToolCall.then(function () {
559
+ return result;
560
+ });
561
+ }
562
+ }
563
+ break;
564
+ }
565
+ case 'tool-output-available':
566
+ {
567
+ if (!currentMessage) break;
568
+ var toolIndex = currentMessage.parts.findIndex(function (p) {
569
+ return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
570
+ });
571
+ if (toolIndex >= 0) {
572
+ var _updatedParts5 = _toConsumableArray(currentMessage.parts);
573
+ var existingPart = _updatedParts5[toolIndex];
574
+ _updatedParts5[toolIndex] = _objectSpread(_objectSpread({}, existingPart), {}, {
575
+ state: 'output-available',
576
+ output: chunk.output,
577
+ callProviderMetadata: chunk.callProviderMetadata,
578
+ preliminary: chunk.preliminary
579
+ });
580
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
581
+ parts: _updatedParts5
582
+ });
583
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
584
+ }
585
+ break;
586
+ }
587
+ case 'tool-error':
588
+ {
589
+ if (!currentMessage) break;
590
+ var _toolIndex = currentMessage.parts.findIndex(function (p) {
591
+ return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
592
+ });
593
+ if (_toolIndex >= 0) {
594
+ var _chunk$input;
595
+ var _updatedParts6 = _toConsumableArray(currentMessage.parts);
596
+ var _existingPart = _updatedParts6[_toolIndex];
597
+ _updatedParts6[_toolIndex] = _objectSpread(_objectSpread({}, _existingPart), {}, {
598
+ state: 'output-error',
599
+ errorText: chunk.errorText,
600
+ input: (_chunk$input = chunk.input) !== null && _chunk$input !== void 0 ? _chunk$input : _existingPart.input,
601
+ callProviderMetadata: chunk.callProviderMetadata
602
+ });
603
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
604
+ parts: _updatedParts6
605
+ });
606
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
607
+ }
608
+ break;
609
+ }
610
+ case 'source-url':
611
+ {
612
+ if (!currentMessage) break;
613
+ var sourcePart = {
614
+ type: 'source-url',
615
+ sourceId: chunk.sourceId,
616
+ url: chunk.url,
617
+ title: chunk.title
618
+ };
619
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
620
+ parts: [].concat(_toConsumableArray(currentMessage.parts), [sourcePart])
621
+ });
622
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
623
+ break;
624
+ }
625
+ case 'source-document':
626
+ {
627
+ if (!currentMessage) break;
628
+ var docPart = {
629
+ type: 'source-document',
630
+ sourceId: chunk.sourceId,
631
+ mediaType: chunk.mediaType,
632
+ title: chunk.title,
633
+ filename: chunk.filename,
634
+ providerMetadata: chunk.providerMetadata
635
+ };
636
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
637
+ parts: [].concat(_toConsumableArray(currentMessage.parts), [docPart])
638
+ });
639
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
640
+ break;
641
+ }
642
+ case 'file':
643
+ {
644
+ if (!currentMessage) break;
645
+ var filePart = {
646
+ type: 'file',
647
+ url: chunk.url,
648
+ mediaType: chunk.mediaType
649
+ };
650
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
651
+ parts: [].concat(_toConsumableArray(currentMessage.parts), [filePart])
652
+ });
653
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
654
+ break;
655
+ }
656
+ case 'start-step':
657
+ {
658
+ if (!currentMessage) break;
659
+ var stepPart = {
660
+ type: 'step-start'
661
+ };
662
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
663
+ parts: [].concat(_toConsumableArray(currentMessage.parts), [stepPart])
664
+ });
665
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
666
+ break;
667
+ }
668
+ case 'message-metadata':
669
+ {
670
+ if (!currentMessage) break;
671
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
672
+ metadata: chunk.messageMetadata
673
+ });
674
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
675
+ break;
676
+ }
677
+ case 'error':
678
+ {
679
+ isError = true;
680
+ throw new Error(chunk.errorText);
681
+ }
682
+ case 'abort':
683
+ {
684
+ isAbort = true;
685
+ break;
686
+ }
687
+ case 'finish':
688
+ {
689
+ if (currentMessage && chunk.messageMetadata !== undefined) {
690
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
691
+ metadata: chunk.messageMetadata
692
+ });
693
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
694
+ }
695
+ break;
696
+ }
697
+ default:
698
+ {
699
+ // Handle data parts (data-*)
700
+ var chunkType = chunk.type;
701
+ if (chunkType !== null && chunkType !== void 0 && chunkType.startsWith('data-') && currentMessage) {
702
+ var dataPart = {
703
+ type: chunkType,
704
+ id: chunk.id,
705
+ data: chunk.data
706
+ };
707
+ currentMessage = _objectSpread(_objectSpread({}, currentMessage), {}, {
708
+ parts: [].concat(_toConsumableArray(currentMessage.parts), [dataPart])
709
+ });
710
+ _this3.state.replaceMessage(currentMessageIndex, currentMessage);
711
+
712
+ // Trigger onData callback
713
+ if (_this3.onData) {
714
+ _this3.onData(dataPart);
715
+ }
716
+ }
717
+ }
718
+ }
719
+ }, function () {
720
+ // Wait for any pending tool calls to complete
721
+ pendingToolCall.then(function () {
722
+ // Stream finished successfully
723
+ _this3.setStatus({
724
+ status: 'ready'
725
+ });
726
+ _this3.activeResponse = null;
727
+
728
+ // Trigger onFinish callback
729
+ if (_this3.onFinish && currentMessage) {
730
+ _this3.onFinish({
731
+ message: currentMessage,
732
+ messages: _this3.state.messages,
733
+ isAbort: isAbort,
734
+ isDisconnect: isDisconnect,
735
+ isError: isError
736
+ });
737
+ }
738
+
739
+ // Note: sendAutomaticallyWhen is only checked in addToolResult,
740
+ // not here. For server-executed tools, the server continues the
741
+ // conversation. For client-executed tools, addToolResult handles it.
742
+ resolve();
743
+ });
744
+ }, function (error) {
745
+ if (error.name === 'AbortError') {
746
+ isAbort = true;
747
+ _this3.setStatus({
748
+ status: 'ready'
749
+ });
750
+ } else {
751
+ isDisconnect = true;
752
+ _this3.handleError(error);
753
+ }
754
+
755
+ // Still call onFinish even on error/abort
756
+ if (_this3.onFinish && currentMessage) {
757
+ _this3.onFinish({
758
+ message: currentMessage,
759
+ messages: _this3.state.messages,
760
+ isAbort: isAbort,
761
+ isDisconnect: isDisconnect,
762
+ isError: isError
763
+ });
764
+ }
765
+ resolve();
766
+ });
767
+ });
768
+ }
769
+ }, {
770
+ key: "handleError",
771
+ value: function handleError(error) {
772
+ this.setStatus({
773
+ status: 'error',
774
+ error: error
775
+ });
776
+ if (this.onError) {
777
+ this.onError(error);
778
+ }
779
+ }
780
+ }, {
781
+ key: "convertFilesToParts",
782
+ value: function convertFilesToParts(files) {
783
+ var _this4 = this;
784
+ if (Array.isArray(files)) {
785
+ return Promise.resolve(files);
786
+ }
787
+ var promises = [];
788
+ var _loop = function _loop() {
789
+ var file = files[i];
790
+ promises.push(_this4.fileToDataUrl(file).then(function (dataUrl) {
791
+ return {
792
+ type: 'file',
793
+ mediaType: file.type,
794
+ filename: file.name,
795
+ url: dataUrl
796
+ };
797
+ }));
798
+ };
799
+ for (var i = 0; i < files.length; i++) {
800
+ _loop();
801
+ }
802
+ return Promise.all(promises);
803
+ }
804
+ }, {
805
+ key: "fileToDataUrl",
806
+ value: function fileToDataUrl(file) {
807
+ return new Promise(function (resolve, reject) {
808
+ var reader = new FileReader();
809
+ reader.onload = function () {
810
+ return resolve(reader.result);
811
+ };
812
+ reader.onerror = reject;
813
+ reader.readAsDataURL(file);
814
+ });
815
+ }
816
+ }]);
817
+ return AbstractChat;
818
+ }();