react-instantsearch-core 7.40.0 → 7.41.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.
@@ -1,4 +1,4 @@
1
- /*! React InstantSearch Core 7.40.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
1
+ /*! React InstantSearch Core 7.41.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
4
4
  typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
@@ -24,7 +24,7 @@
24
24
 
25
25
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
26
26
 
27
- var version$2 = '7.40.0';
27
+ var version$2 = '7.41.0';
28
28
 
29
29
  function _define_property(obj, key, value) {
30
30
  if (key in obj) {
@@ -8539,12 +8539,13 @@
8539
8539
  instantSearchInstance._hasRecommendWidget = hasRecommendWidget;
8540
8540
  }
8541
8541
  var index = function index(widgetParams) {
8542
- if (widgetParams === undefined || widgetParams.indexName === undefined && !widgetParams.EXPERIMENTAL_isolated) {
8542
+ var _widgetParams_EXPERIMENTAL_isolated;
8543
+ if (widgetParams === undefined || widgetParams.indexName === undefined && !widgetParams.isolated && !widgetParams.EXPERIMENTAL_isolated) {
8543
8544
  throw new Error(withUsage$s('The `indexName` option is required.'));
8544
8545
  }
8545
8546
  // When isolated=true, we use an empty string as the default indexName.
8546
8547
  // This is intentional: isolated indices do not require a real index name.
8547
- var _widgetParams_indexName = widgetParams.indexName, indexName = _widgetParams_indexName === void 0 ? '' : _widgetParams_indexName, _widgetParams_indexId = widgetParams.indexId, indexId = _widgetParams_indexId === void 0 ? indexName : _widgetParams_indexId, tmp = widgetParams.EXPERIMENTAL_isolated, isolated = tmp === void 0 ? false : tmp;
8548
+ var _widgetParams_indexName = widgetParams.indexName, indexName = _widgetParams_indexName === void 0 ? '' : _widgetParams_indexName, _widgetParams_indexId = widgetParams.indexId, indexId = _widgetParams_indexId === void 0 ? indexName : _widgetParams_indexId, _widgetParams_isolated = widgetParams.isolated, isolated = _widgetParams_isolated === void 0 ? (_widgetParams_EXPERIMENTAL_isolated = widgetParams.EXPERIMENTAL_isolated) !== null && _widgetParams_EXPERIMENTAL_isolated !== void 0 ? _widgetParams_EXPERIMENTAL_isolated : false : _widgetParams_isolated;
8548
8549
  var localWidgets = [];
8549
8550
  var localUiState = {};
8550
8551
  var localInstantSearchInstance = null;
@@ -9209,7 +9210,7 @@
9209
9210
  });
9210
9211
  }
9211
9212
 
9212
- var version = '4.107.0';
9213
+ var version = '4.108.0';
9213
9214
 
9214
9215
  var ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';
9215
9216
  function getCookie(name) {
@@ -12674,6 +12675,7 @@
12674
12675
  return undefined;
12675
12676
  }
12676
12677
 
12678
+ var _computedKey$1;
12677
12679
  var tryParseJson = function tryParseJson(value) {
12678
12680
  try {
12679
12681
  return JSON.parse(value);
@@ -12744,6 +12746,8 @@
12744
12746
  return fallbackInput;
12745
12747
  };
12746
12748
  var defaultGuardrailFallbackResponse = 'Sorry, we are not able to generate a response at the moment.';
12749
+ _computedKey$1 = /** @internal */ '~addToolResultForMessage';
12750
+ var _computedKey1$1 = _computedKey$1;
12747
12751
  /**
12748
12752
  * Abstract base class for chat implementations.
12749
12753
  */ var AbstractChat = /*#__PURE__*/ function() {
@@ -12763,6 +12767,12 @@
12763
12767
  _define_property(this, "sendAutomaticallyWhen", void 0);
12764
12768
  _define_property(this, "shouldRepairToolInput", void 0);
12765
12769
  _define_property(this, "activeResponse", null);
12770
+ _define_property(this, "latestResponse", null);
12771
+ _define_property(this, "responsesByToolCallId", new Map());
12772
+ _define_property(this, "responseByMessage", new WeakMap());
12773
+ // Once tool ownership is discarded, an identifier-only result cannot prove
12774
+ // which response generation submitted it. Scoped submissions remain safe.
12775
+ _define_property(this, "acceptsIdentifierOnlyToolResults", true);
12766
12776
  _define_property(this, "jobExecutor", new SerialJobExecutor());
12767
12777
  /**
12768
12778
  * Appends or replaces a user message to the chat list. This triggers the API call to fetch
@@ -12848,13 +12858,13 @@
12848
12858
  // Find the message to regenerate from
12849
12859
  var targetIndex = -1;
12850
12860
  if (messageId) {
12851
- targetIndex = _this1.state.messages.findIndex(function(m) {
12861
+ targetIndex = _this1.messages.findIndex(function(m) {
12852
12862
  return m.id === messageId;
12853
12863
  });
12854
12864
  } else {
12855
12865
  // Find the last assistant message
12856
- for(var i = _this1.state.messages.length - 1; i >= 0; i--){
12857
- if (_this1.state.messages[i].role === 'assistant') {
12866
+ for(var i = _this1.messages.length - 1; i >= 0; i--){
12867
+ if (_this1.messages[i].role === 'assistant') {
12858
12868
  targetIndex = i;
12859
12869
  break;
12860
12870
  }
@@ -12862,7 +12872,7 @@
12862
12872
  }
12863
12873
  if (targetIndex >= 0) {
12864
12874
  // Remove the assistant message and all messages after it
12865
- _this1.state.messages = _this1.state.messages.slice(0, targetIndex);
12875
+ _this1.messages = _this1.messages.slice(0, targetIndex);
12866
12876
  }
12867
12877
  return _this1.makeRequest(_object_spread({
12868
12878
  trigger: 'regenerate-message',
@@ -12877,23 +12887,10 @@
12877
12887
  if (!_this.transport) {
12878
12888
  return Promise.reject(new Error('Transport is required for resuming stream. Please provide a transport when initializing the chat.'));
12879
12889
  }
12880
- _this.setStatus({
12881
- status: 'submitted'
12882
- });
12883
- return _this.transport.reconnectToStream(_object_spread({
12884
- chatId: _this.id
12885
- }, options)).then(function(stream) {
12886
- if (stream) {
12887
- return _this.processStreamWithCallbacks(stream);
12888
- } else {
12889
- _this.setStatus({
12890
- status: 'ready'
12891
- });
12892
- return Promise.resolve();
12893
- }
12894
- }, function(error) {
12895
- _this.handleError(error);
12896
- return Promise.resolve();
12890
+ return _this.consume(function() {
12891
+ return _this.transport.reconnectToStream(_object_spread({
12892
+ chatId: _this.id
12893
+ }, options));
12897
12894
  });
12898
12895
  });
12899
12896
  });
@@ -12909,53 +12906,57 @@
12909
12906
  });
12910
12907
  /**
12911
12908
  * Add a tool result for a tool call.
12912
- */ _define_property(this, "addToolResult", function(param) {
12913
- var tool = param.tool, toolCallId = param.toolCallId, output = param.output;
12914
- return _this.jobExecutor.run(function() {
12915
- // Find the message with this tool call
12916
- var messageIndex = _this.state.messages.findIndex(function(m) {
12917
- var _ref;
12918
- var _m_parts;
12919
- return (_ref = (_m_parts = m.parts) === null || _m_parts === void 0 ? void 0 : _m_parts.some(function(p) {
12920
- return 'toolCallId' in p && p.toolCallId === toolCallId || 'type' in p && p.type === "tool-".concat(String(tool));
12921
- })) !== null && _ref !== void 0 ? _ref : false;
12922
- });
12923
- if (messageIndex === -1) return Promise.resolve();
12924
- var message = _this.state.messages[messageIndex];
12925
- var updatedParts = message.parts.map(function(part) {
12926
- if ('toolCallId' in part && part.toolCallId === toolCallId && 'state' in part) {
12927
- return _object_spread_props(_object_spread({}, part), {
12928
- state: 'output-available',
12929
- output: output
12930
- });
12931
- }
12932
- return part;
12933
- });
12934
- _this.state.replaceMessage(messageIndex, _object_spread_props(_object_spread({}, message), {
12935
- parts: updatedParts
12936
- }));
12937
- // Check if we should auto-send based on sendAutomaticallyWhen
12938
- if (_this.sendAutomaticallyWhen) {
12939
- return Promise.resolve(_this.sendAutomaticallyWhen({
12940
- messages: _this.state.messages
12941
- })).then(function(shouldSend) {
12942
- if (shouldSend) {
12943
- return _this.makeRequest({
12944
- trigger: 'submit-message'
12945
- });
12946
- }
12947
- return Promise.resolve();
12909
+ */ _define_property(this, "addToolResult", function(options) {
12910
+ if (!_this.acceptsIdentifierOnlyToolResults) {
12911
+ return Promise.resolve();
12912
+ }
12913
+ var owners = _this.responsesByToolCallId.get(options.toolCallId);
12914
+ var response = (owners === null || owners === void 0 ? void 0 : owners.size) === 1 ? owners.values().next().value : undefined;
12915
+ if (response) return _this.submitToolResult(response, options);
12916
+ var findMatchingMessage = function findMatchingMessage() {
12917
+ var matchingMessages = _this.messages.filter(function(message) {
12918
+ var _message_parts;
12919
+ return (_message_parts = message.parts) === null || _message_parts === void 0 ? void 0 : _message_parts.some(function(part) {
12920
+ return 'toolCallId' in part && part.toolCallId === options.toolCallId;
12948
12921
  });
12922
+ });
12923
+ return matchingMessages.length === 1 ? matchingMessages[0] : undefined;
12924
+ };
12925
+ if (!findMatchingMessage()) return Promise.resolve();
12926
+ return _this.jobExecutor.run(function() {
12927
+ if (!_this.acceptsIdentifierOnlyToolResults) return Promise.resolve();
12928
+ var message = findMatchingMessage();
12929
+ if (!message || !_this.commit(options.toolCallId, options.output, message.id, undefined, message)) {
12930
+ return Promise.resolve();
12949
12931
  }
12950
- return Promise.resolve();
12932
+ return _this.continueResponse();
12951
12933
  });
12952
12934
  });
12935
+ _define_property(this, _computedKey1$1, function(message, options) {
12936
+ var hasToolCall = function hasToolCall(candidate) {
12937
+ var _candidate_parts;
12938
+ return ((_candidate_parts = candidate.parts) === null || _candidate_parts === void 0 ? void 0 : _candidate_parts.some(function(part) {
12939
+ return 'toolCallId' in part && part.toolCallId === options.toolCallId;
12940
+ })) === true;
12941
+ };
12942
+ if (!hasToolCall(message)) {
12943
+ return Promise.resolve();
12944
+ }
12945
+ var response = _this.responseByMessage.get(message);
12946
+ var currentMessage = _this.messages.includes(message) ? message : response && !response.isRetired ? _this.messages.find(function(candidate) {
12947
+ return candidate.id === message.id && _this.responseByMessage.get(candidate) === response && hasToolCall(candidate);
12948
+ }) : undefined;
12949
+ if (!currentMessage) return Promise.resolve();
12950
+ return _this.submitToolResult(response, options, currentMessage.id, currentMessage);
12951
+ });
12953
12952
  /**
12954
12953
  * Abort the current request immediately, keep the generated tokens if any.
12955
12954
  */ _define_property(this, "stop", function() {
12956
12955
  if (_this.activeResponse) {
12957
- _this.activeResponse.abortController.abort();
12956
+ var response = _this.activeResponse;
12957
+ response.outcome = 'aborted';
12958
12958
  _this.activeResponse = null;
12959
+ response.abortController.abort();
12959
12960
  }
12960
12961
  _this.setStatus({
12961
12962
  status: 'ready'
@@ -13017,6 +13018,14 @@
13017
13018
  * context.
13018
13019
  */ key: "resetConversationId",
13019
13020
  value: function resetConversationId() {
13021
+ if (this.responsesByToolCallId.size > 0 || this.messages.some(function(message) {
13022
+ var _message_parts;
13023
+ return (_message_parts = message.parts) === null || _message_parts === void 0 ? void 0 : _message_parts.some(function(part) {
13024
+ return 'toolCallId' in part;
13025
+ });
13026
+ })) {
13027
+ this.acceptsIdentifierOnlyToolResults = false;
13028
+ }
13020
13029
  this.conversationId = this.generateId();
13021
13030
  }
13022
13031
  },
@@ -13026,7 +13035,93 @@
13026
13035
  return this.state.messages;
13027
13036
  },
13028
13037
  set: function set(messages) {
13038
+ var _this = this;
13039
+ var getToolOccurrences = function getToolOccurrences(message) {
13040
+ return message.parts.filter(function(part) {
13041
+ return 'toolCallId' in part;
13042
+ }).map(function(part) {
13043
+ return {
13044
+ type: part.type,
13045
+ toolCallId: part.toolCallId,
13046
+ state: 'state' in part ? part.state : undefined,
13047
+ input: 'input' in part ? part.input : undefined,
13048
+ output: 'output' in part ? part.output : undefined,
13049
+ errorText: 'errorText' in part ? part.errorText : undefined,
13050
+ providerExecuted: 'providerExecuted' in part ? part.providerExecuted : undefined
13051
+ };
13052
+ });
13053
+ };
13054
+ var isEquivalentRehydration = function isEquivalentRehydration(message) {
13055
+ var replacements = messages.filter(function(candidate) {
13056
+ return candidate.id === message.id;
13057
+ });
13058
+ if (replacements.length !== 1) return false;
13059
+ var toolOccurrences = getToolOccurrences(message);
13060
+ var replacementToolOccurrences = getToolOccurrences(replacements[0]);
13061
+ return toolOccurrences.length > 0 || replacementToolOccurrences.length > 0 ? isEqual(toolOccurrences, replacementToolOccurrences) : isEqual(message.parts, replacements[0].parts);
13062
+ };
13063
+ var detachedResponses = new Set();
13064
+ this.state.messages.forEach(function(message) {
13065
+ if (!messages.includes(message)) {
13066
+ var response = _this.responseByMessage.get(message);
13067
+ if (response && !isEquivalentRehydration(message)) {
13068
+ detachedResponses.add(response);
13069
+ }
13070
+ }
13071
+ });
13072
+ var removedToolOwner = this.state.messages.some(function(message) {
13073
+ var _message_parts;
13074
+ return ((_message_parts = message.parts) === null || _message_parts === void 0 ? void 0 : _message_parts.some(function(part) {
13075
+ return 'toolCallId' in part;
13076
+ })) && !messages.includes(message) && !isEquivalentRehydration(message);
13077
+ });
13078
+ var toolCallIds = new Set();
13079
+ var hasDuplicateToolCallId = messages.some(function(message) {
13080
+ var _message_parts;
13081
+ return ((_message_parts = message.parts) === null || _message_parts === void 0 ? void 0 : _message_parts.some(function(part) {
13082
+ if (!('toolCallId' in part)) {
13083
+ return false;
13084
+ }
13085
+ if (toolCallIds.has(part.toolCallId)) {
13086
+ return true;
13087
+ }
13088
+ toolCallIds.add(part.toolCallId);
13089
+ return false;
13090
+ })) === true;
13091
+ });
13092
+ if (removedToolOwner || hasDuplicateToolCallId) {
13093
+ this.acceptsIdentifierOnlyToolResults = false;
13094
+ }
13029
13095
  this.state.messages = messages;
13096
+ var retainedMessageIds = new Set(messages.map(function(message) {
13097
+ return message.id;
13098
+ }));
13099
+ var responses = new Set();
13100
+ this.responsesByToolCallId.forEach(function(owners) {
13101
+ owners.forEach(function(response) {
13102
+ return responses.add(response);
13103
+ });
13104
+ });
13105
+ if (this.activeResponse) {
13106
+ responses.add(this.activeResponse);
13107
+ }
13108
+ detachedResponses.forEach(function(response) {
13109
+ responses.add(response);
13110
+ _this.retireResponse(response);
13111
+ });
13112
+ responses.forEach(function(response) {
13113
+ var message = response.messageId ? messages.find(function(candidate) {
13114
+ return candidate.id === response.messageId;
13115
+ }) : undefined;
13116
+ if (message && !response.isRetired && !detachedResponses.has(response)) {
13117
+ _this.responseByMessage.set(message, response);
13118
+ }
13119
+ });
13120
+ responses.forEach(function(response) {
13121
+ if (detachedResponses.has(response) || response.messageId && !retainedMessageIds.has(response.messageId)) {
13122
+ _this.pruneDetachedResponse(response);
13123
+ }
13124
+ });
13030
13125
  }
13031
13126
  },
13032
13127
  {
@@ -13035,6 +13130,154 @@
13035
13130
  return this.state.messages[this.state.messages.length - 1];
13036
13131
  }
13037
13132
  },
13133
+ {
13134
+ key: "replaceMessage",
13135
+ value: function replaceMessage(index, message, response) {
13136
+ var _this_messages_index;
13137
+ this.state.replaceMessage(index, message);
13138
+ var canonicalMessage = (_this_messages_index = this.messages[index]) !== null && _this_messages_index !== void 0 ? _this_messages_index : message;
13139
+ if (response && this.messages.includes(canonicalMessage)) {
13140
+ this.responseByMessage.set(canonicalMessage, response);
13141
+ }
13142
+ return canonicalMessage;
13143
+ }
13144
+ },
13145
+ {
13146
+ key: "commit",
13147
+ value: function commit(toolCallId, output, messageId, response, expectedMessage) {
13148
+ var isTargetPart = function isTargetPart(part) {
13149
+ return 'toolCallId' in part && part.toolCallId === toolCallId;
13150
+ };
13151
+ var messageIndex = this.messages.findIndex(function(message) {
13152
+ return (!messageId || message.id === messageId) && (!expectedMessage || message === expectedMessage) && message.parts.some(isTargetPart);
13153
+ });
13154
+ if (messageIndex === -1) return false;
13155
+ var message = this.messages[messageIndex];
13156
+ var partIndex = message.parts.findIndex(isTargetPart);
13157
+ var part = message.parts[partIndex];
13158
+ if (!('state' in part) || part.state === 'output-available' && !part.preliminary || part.state === 'output-error') {
13159
+ return false;
13160
+ }
13161
+ // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
13162
+ part.preliminary; // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
13163
+ part.rawOutput;
13164
+ var committedPart = _object_without_properties(part, [
13165
+ "preliminary",
13166
+ "rawOutput"
13167
+ ]);
13168
+ var updatedParts = _to_consumable_array(message.parts);
13169
+ updatedParts[partIndex] = _object_spread_props(_object_spread({}, committedPart), {
13170
+ state: 'output-available',
13171
+ output: output
13172
+ });
13173
+ var updatedMessage = _object_spread_props(_object_spread({}, message), {
13174
+ parts: updatedParts
13175
+ });
13176
+ this.replaceMessage(messageIndex, updatedMessage, response);
13177
+ return true;
13178
+ }
13179
+ },
13180
+ {
13181
+ key: "continueResponse",
13182
+ value: function continueResponse(response) {
13183
+ var _this = this;
13184
+ if (response) {
13185
+ this.pruneDetachedResponse(response);
13186
+ if (response.isRetired || response.outcome !== 'succeeded' || response.requiredToolCallIds.size === 0 || Array.from(response.requiredToolCallIds).some(function(toolCallId) {
13187
+ return !response.resolvedToolCallIds.has(toolCallId);
13188
+ }) || !response.didNotifyFinish || response.didEvaluateContinuation) {
13189
+ return Promise.resolve();
13190
+ }
13191
+ response.didEvaluateContinuation = true;
13192
+ }
13193
+ if (!this.sendAutomaticallyWhen) return Promise.resolve();
13194
+ return Promise.resolve().then(function() {
13195
+ return _this.sendAutomaticallyWhen({
13196
+ messages: _this.messages
13197
+ });
13198
+ }).then(function(shouldSend) {
13199
+ if (response) {
13200
+ _this.pruneDetachedResponse(response);
13201
+ if (response.isRetired) return undefined;
13202
+ }
13203
+ return shouldSend ? _this.makeRequest({
13204
+ trigger: 'submit-message'
13205
+ }) : undefined;
13206
+ }).catch(function(error) {
13207
+ if (response) {
13208
+ _this.pruneDetachedResponse(response);
13209
+ if (response.isRetired) return;
13210
+ _this.handleError(error, {
13211
+ updateState: _this.latestResponse === response
13212
+ });
13213
+ return;
13214
+ }
13215
+ _this.handleError(error);
13216
+ });
13217
+ }
13218
+ },
13219
+ {
13220
+ key: "retireResponse",
13221
+ value: function retireResponse(response) {
13222
+ if (response.isRetired) return;
13223
+ response.isRetired = true;
13224
+ response.didEvaluateContinuation = true;
13225
+ if (this.activeResponse === response) {
13226
+ response.outcome = 'aborted';
13227
+ this.activeResponse = null;
13228
+ response.abortController.abort();
13229
+ this.setStatus({
13230
+ status: 'ready'
13231
+ });
13232
+ }
13233
+ }
13234
+ },
13235
+ {
13236
+ key: "pruneDetachedResponse",
13237
+ value: function pruneDetachedResponse(response) {
13238
+ var _this = this;
13239
+ if (!response.isRetired) {
13240
+ if (!response.messageId || this.messages.some(function(message) {
13241
+ return message.id === response.messageId;
13242
+ })) {
13243
+ return;
13244
+ }
13245
+ this.retireResponse(response);
13246
+ }
13247
+ // Keep a routing tombstone while a callback is running so public
13248
+ // addToolResult calls settle directly instead of entering the executor.
13249
+ if (response.pendingToolCallbacks > 0) return;
13250
+ this.responsesByToolCallId.forEach(function(owners, toolCallId) {
13251
+ owners.delete(response);
13252
+ if (owners.size === 0) {
13253
+ _this.responsesByToolCallId.delete(toolCallId);
13254
+ }
13255
+ });
13256
+ }
13257
+ },
13258
+ {
13259
+ key: "submitToolResult",
13260
+ value: function submitToolResult(response, param) {
13261
+ var _this = this;
13262
+ var toolCallId = param.toolCallId, output = param.output, messageId = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : response === null || response === void 0 ? void 0 : response.messageId, expectedMessage = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : messageId ? this.messages.find(function(message) {
13263
+ return message.id === messageId;
13264
+ }) : undefined;
13265
+ if (response === null || response === void 0 ? void 0 : response.isRetired) return Promise.resolve();
13266
+ var commitResult = function commitResult() {
13267
+ if (!_this.commit(toolCallId, output, messageId, response, expectedMessage)) {
13268
+ return Promise.resolve();
13269
+ }
13270
+ if (response === null || response === void 0 ? void 0 : response.requiredToolCallIds.has(toolCallId)) {
13271
+ response.resolvedToolCallIds.add(toolCallId);
13272
+ }
13273
+ return _this.continueResponse(response);
13274
+ };
13275
+ if (response && (this.activeResponse === response || response.outcome !== 'succeeded' || response.didEvaluateContinuation)) {
13276
+ return commitResult();
13277
+ }
13278
+ return this.jobExecutor.run(commitResult);
13279
+ }
13280
+ },
13038
13281
  {
13039
13282
  key: "makeRequest",
13040
13283
  value: function makeRequest(options) {
@@ -13042,42 +13285,72 @@
13042
13285
  if (!this.transport) {
13043
13286
  return Promise.reject(new Error('Transport is required for sending messages. Please provide a transport when initializing the chat.'));
13044
13287
  }
13045
- // Abort any existing request
13288
+ return this.consume(function(abortSignal) {
13289
+ return _this.transport.sendMessages({
13290
+ chatId: _this.id,
13291
+ messages: _this.messages,
13292
+ abortSignal: abortSignal,
13293
+ trigger: options.trigger,
13294
+ messageId: options.messageId,
13295
+ headers: options.headers,
13296
+ body: options.body,
13297
+ requestMetadata: options.metadata
13298
+ });
13299
+ });
13300
+ }
13301
+ },
13302
+ {
13303
+ key: "consume",
13304
+ value: function consume(createStream) {
13305
+ var _this = this;
13046
13306
  if (this.activeResponse) {
13307
+ this.activeResponse.outcome = 'aborted';
13047
13308
  this.activeResponse.abortController.abort();
13048
13309
  }
13049
- var abortController = new AbortController();
13050
- this.activeResponse = {
13051
- abortController: abortController
13310
+ var response = {
13311
+ abortController: new AbortController(),
13312
+ outcome: 'active',
13313
+ isRetired: false,
13314
+ requiredToolCallIds: new Set(),
13315
+ resolvedToolCallIds: new Set(),
13316
+ returnedToolCallbacks: [],
13317
+ pendingToolCallbacks: 0,
13318
+ didNotifyFinish: false,
13319
+ didEvaluateContinuation: false
13052
13320
  };
13321
+ this.activeResponse = response;
13322
+ this.latestResponse = response;
13053
13323
  this.setStatus({
13054
13324
  status: 'submitted'
13055
13325
  });
13056
- return this.transport.sendMessages({
13057
- chatId: this.id,
13058
- messages: this.state.messages,
13059
- abortSignal: abortController.signal,
13060
- trigger: options.trigger,
13061
- messageId: options.messageId,
13062
- headers: options.headers,
13063
- body: options.body,
13064
- requestMetadata: options.metadata
13065
- }).then(function(stream) {
13066
- _this.activeResponse.stream = stream;
13067
- return _this.processStreamWithCallbacks(stream);
13326
+ return createStream(response.abortController.signal).then(function(stream) {
13327
+ if (_this.activeResponse === response) {
13328
+ if (stream) return _this.processStream(stream, response);
13329
+ response.outcome = 'succeeded';
13330
+ _this.activeResponse = null;
13331
+ _this.setStatus({
13332
+ status: 'ready'
13333
+ });
13334
+ }
13335
+ return undefined;
13068
13336
  }, function(error) {
13337
+ if (_this.activeResponse !== response) return;
13338
+ _this.activeResponse = null;
13069
13339
  if (error.name === 'AbortError') {
13070
- // Request was aborted, don't treat as error
13071
- return Promise.resolve();
13340
+ response.outcome = 'aborted';
13341
+ _this.setStatus({
13342
+ status: 'ready'
13343
+ });
13344
+ } else {
13345
+ response.outcome = 'failed';
13346
+ _this.handleError(error);
13072
13347
  }
13073
- _this.handleError(error);
13074
- return Promise.resolve();
13075
13348
  });
13076
13349
  }
13077
13350
  },
13078
13351
  {
13079
- key: "processStreamWithCallbacks",
13080
- value: function processStreamWithCallbacks(stream) {
13352
+ key: "processStream",
13353
+ value: function processStream1(stream, response) {
13081
13354
  var _this = this;
13082
13355
  this.setStatus({
13083
13356
  status: 'streaming'
@@ -13086,26 +13359,135 @@
13086
13359
  var currentMessage;
13087
13360
  var currentMessageIndex = -1;
13088
13361
  var isAbort = false;
13089
- var isDisconnect = false;
13090
13362
  var isError = false;
13091
- // Track current text/reasoning part state
13092
- var currentTextPartId;
13093
- var currentReasoningPartId;
13094
13363
  var toolRawInputByCallId = {};
13095
13364
  var toolRawOutputByCallId = {};
13096
- // Promise chain for handling tool calls that return promises
13097
- var pendingToolCall = Promise.resolve();
13365
+ var findToolPart = function findToolPart(toolCallId) {
13366
+ return currentMessage.parts.findIndex(function(part) {
13367
+ return 'toolCallId' in part && part.toolCallId === toolCallId;
13368
+ });
13369
+ };
13370
+ var setPart = function setPart(index, part) {
13371
+ var parts = _to_consumable_array(currentMessage.parts);
13372
+ parts[index < 0 ? parts.length : index] = part;
13373
+ currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13374
+ parts: parts
13375
+ });
13376
+ currentMessage = _this.replaceMessage(currentMessageIndex, currentMessage, response);
13377
+ };
13378
+ var mergeCallProviderMetadata = function mergeCallProviderMetadata(toolCallId, metadata) {
13379
+ var toolIndex = findToolPart(toolCallId);
13380
+ if (toolIndex < 0) return;
13381
+ var existingPart = currentMessage.parts[toolIndex];
13382
+ setPart(toolIndex, _object_spread_props(_object_spread({}, existingPart), {
13383
+ callProviderMetadata: metadata !== null && metadata !== void 0 ? metadata : existingPart.callProviderMetadata
13384
+ }));
13385
+ };
13386
+ var getCanonicalMessage = function getCanonicalMessage() {
13387
+ var _this_messages_find;
13388
+ return response.messageId ? (_this_messages_find = _this.messages.find(function(message) {
13389
+ return message.id === response.messageId;
13390
+ })) !== null && _this_messages_find !== void 0 ? _this_messages_find : currentMessage : currentMessage;
13391
+ };
13392
+ var notifyFinish = function notifyFinish(param) {
13393
+ var isAbort = param.isAbort, isDisconnect = param.isDisconnect, isError = param.isError, message = param.message, _param_allowRetired = param.allowRetired, allowRetired = _param_allowRetired === void 0 ? false : _param_allowRetired;
13394
+ _this.pruneDetachedResponse(response);
13395
+ if (response.isRetired && !allowRetired || response.didNotifyFinish) {
13396
+ return;
13397
+ }
13398
+ response.didNotifyFinish = true;
13399
+ var canonicalMessage = message !== null && message !== void 0 ? message : getCanonicalMessage();
13400
+ if (_this.onFinish && canonicalMessage) {
13401
+ _this.onFinish({
13402
+ message: canonicalMessage,
13403
+ messages: _this.messages,
13404
+ isAbort: isAbort,
13405
+ isDisconnect: isDisconnect,
13406
+ isError: isError
13407
+ });
13408
+ }
13409
+ };
13410
+ var failToolCall = function failToolCall(reason) {
13411
+ if (response.outcome !== 'active') return;
13412
+ var message = getCanonicalMessage();
13413
+ var wasRetired = response.isRetired;
13414
+ var error = _instanceof(reason, Error) ? reason : new Error(String(reason));
13415
+ response.outcome = 'failed';
13416
+ response.abortController.abort();
13417
+ if (_this.activeResponse === response) {
13418
+ _this.activeResponse = null;
13419
+ _this.handleError(error);
13420
+ }
13421
+ notifyFinish({
13422
+ isAbort: false,
13423
+ isDisconnect: false,
13424
+ isError: true,
13425
+ message: message,
13426
+ allowRetired: !wasRetired
13427
+ });
13428
+ };
13429
+ var acceptServerToolResult = function acceptServerToolResult(toolCallId) {
13430
+ if (response.requiredToolCallIds.has(toolCallId)) {
13431
+ response.resolvedToolCallIds.add(toolCallId);
13432
+ }
13433
+ };
13098
13434
  return new Promise(function(resolve) {
13435
+ var finish = function finish(error) {
13436
+ if (response.outcome === 'failed') {
13437
+ resolve();
13438
+ return;
13439
+ }
13440
+ isAbort || (isAbort = response.outcome === 'aborted' || !!error && error.name === 'AbortError');
13441
+ response.outcome = isAbort ? 'aborted' : error ? 'failed' : 'succeeded';
13442
+ if (_this.activeResponse === response) {
13443
+ _this.activeResponse = null;
13444
+ if (error && !isAbort) {
13445
+ _this.handleError(error);
13446
+ } else {
13447
+ _this.setStatus({
13448
+ status: 'ready'
13449
+ });
13450
+ }
13451
+ }
13452
+ notifyFinish({
13453
+ isAbort: isAbort,
13454
+ isDisconnect: !!error && !isAbort,
13455
+ isError: isError
13456
+ });
13457
+ resolve(isAbort || error ? undefined : _this.continueResponse(response));
13458
+ };
13099
13459
  processStream(stream, function(chunk) {
13460
+ if (_this.activeResponse !== response || response.isRetired) return;
13461
+ if (currentMessageId) {
13462
+ var canonicalMessageIndex = _this.messages.findIndex(function(message) {
13463
+ return message.id === currentMessageId;
13464
+ });
13465
+ if (canonicalMessageIndex === -1) {
13466
+ _this.pruneDetachedResponse(response);
13467
+ return;
13468
+ }
13469
+ currentMessageIndex = canonicalMessageIndex;
13470
+ currentMessage = _this.messages[canonicalMessageIndex];
13471
+ _this.responseByMessage.set(currentMessage, response);
13472
+ }
13100
13473
  switch(chunk.type){
13101
13474
  case 'start':
13102
13475
  {
13103
13476
  currentMessageId = chunk.messageId || _this.generateId();
13477
+ response.messageId = currentMessageId;
13104
13478
  // Check if we're continuing an existing message or creating a new one
13105
13479
  var lastMessage = _this.lastMessage;
13106
13480
  if (lastMessage && lastMessage.role === 'assistant' && lastMessage.id === currentMessageId) {
13107
- currentMessage = lastMessage;
13108
- currentMessageIndex = _this.state.messages.length - 1;
13481
+ if (lastMessage.parts.some(function(part) {
13482
+ return 'toolCallId' in part;
13483
+ })) {
13484
+ _this.acceptsIdentifierOnlyToolResults = false;
13485
+ }
13486
+ currentMessage = _object_spread_props(_object_spread({}, lastMessage), {
13487
+ parts: _to_consumable_array(lastMessage.parts)
13488
+ });
13489
+ currentMessageIndex = _this.messages.length - 1;
13490
+ currentMessage = _this.replaceMessage(currentMessageIndex, currentMessage, response);
13109
13491
  } else {
13110
13492
  currentMessage = {
13111
13493
  id: currentMessageId,
@@ -13114,123 +13496,60 @@
13114
13496
  metadata: chunk.messageMetadata
13115
13497
  };
13116
13498
  _this.state.pushMessage(currentMessage);
13117
- currentMessageIndex = _this.state.messages.length - 1;
13499
+ currentMessageIndex = _this.messages.length - 1;
13500
+ _this.responseByMessage.set(currentMessage, response);
13118
13501
  }
13119
13502
  break;
13120
13503
  }
13121
13504
  case 'text-start':
13505
+ case 'reasoning-start':
13122
13506
  {
13123
13507
  if (!currentMessage) break;
13124
- currentTextPartId = chunk.id;
13125
- var textPart = {
13126
- type: 'text',
13508
+ var type = chunk.type === 'text-start' ? 'text' : 'reasoning';
13509
+ setPart(-1, {
13510
+ type: type,
13127
13511
  text: '',
13128
13512
  state: 'streaming',
13129
13513
  providerMetadata: chunk.providerMetadata
13130
- };
13131
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13132
- parts: _to_consumable_array(currentMessage.parts).concat([
13133
- textPart
13134
- ])
13135
13514
  });
13136
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13137
13515
  break;
13138
13516
  }
13139
13517
  case 'text-delta':
13518
+ case 'reasoning-delta':
13140
13519
  {
13141
- if (!currentMessage || !currentTextPartId) break;
13142
- var partIndex = currentMessage.parts.findIndex(function(p) {
13143
- return p.type === 'text' && p.state === 'streaming';
13520
+ var type1 = chunk.type === 'text-delta' ? 'text' : 'reasoning';
13521
+ if (!currentMessage) break;
13522
+ var partIndex = currentMessage.parts.findIndex(function(part) {
13523
+ return part.type === type1 && part.state === 'streaming';
13144
13524
  });
13145
13525
  if (partIndex === -1) break;
13146
- var updatedParts = _to_consumable_array(currentMessage.parts);
13147
- var textPart1 = updatedParts[partIndex];
13148
- updatedParts[partIndex] = _object_spread_props(_object_spread({}, textPart1), {
13149
- text: textPart1.text + chunk.delta
13150
- });
13151
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13152
- parts: updatedParts
13153
- });
13154
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13526
+ var part = currentMessage.parts[partIndex];
13527
+ setPart(partIndex, _object_spread_props(_object_spread({}, part), {
13528
+ text: part.text + chunk.delta
13529
+ }));
13155
13530
  break;
13156
13531
  }
13157
13532
  case 'text-end':
13158
- {
13159
- if (!currentMessage) break;
13160
- var partIndex1 = currentMessage.parts.findIndex(function(p) {
13161
- return p.type === 'text' && p.state === 'streaming';
13162
- });
13163
- if (partIndex1 === -1) break;
13164
- var updatedParts1 = _to_consumable_array(currentMessage.parts);
13165
- var textPart2 = updatedParts1[partIndex1];
13166
- updatedParts1[partIndex1] = _object_spread_props(_object_spread({}, textPart2), {
13167
- state: 'done'
13168
- });
13169
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13170
- parts: updatedParts1
13171
- });
13172
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13173
- currentTextPartId = undefined;
13174
- break;
13175
- }
13176
- case 'reasoning-start':
13177
- {
13178
- if (!currentMessage) break;
13179
- currentReasoningPartId = chunk.id;
13180
- var reasoningPart = {
13181
- type: 'reasoning',
13182
- text: '',
13183
- state: 'streaming',
13184
- providerMetadata: chunk.providerMetadata
13185
- };
13186
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13187
- parts: _to_consumable_array(currentMessage.parts).concat([
13188
- reasoningPart
13189
- ])
13190
- });
13191
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13192
- break;
13193
- }
13194
- case 'reasoning-delta':
13195
- {
13196
- if (!currentMessage || !currentReasoningPartId) break;
13197
- var partIndex2 = currentMessage.parts.findIndex(function(p) {
13198
- return p.type === 'reasoning' && p.state === 'streaming';
13199
- });
13200
- if (partIndex2 === -1) break;
13201
- var updatedParts2 = _to_consumable_array(currentMessage.parts);
13202
- var reasoningPart1 = updatedParts2[partIndex2];
13203
- updatedParts2[partIndex2] = _object_spread_props(_object_spread({}, reasoningPart1), {
13204
- text: reasoningPart1.text + chunk.delta
13205
- });
13206
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13207
- parts: updatedParts2
13208
- });
13209
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13210
- break;
13211
- }
13212
13533
  case 'reasoning-end':
13213
13534
  {
13214
13535
  if (!currentMessage) break;
13215
- var partIndex3 = currentMessage.parts.findIndex(function(p) {
13216
- return p.type === 'reasoning' && p.state === 'streaming';
13536
+ var type2 = chunk.type === 'text-end' ? 'text' : 'reasoning';
13537
+ var partIndex1 = currentMessage.parts.findIndex(function(part) {
13538
+ return part.type === type2 && part.state === 'streaming';
13217
13539
  });
13218
- if (partIndex3 === -1) break;
13219
- var updatedParts3 = _to_consumable_array(currentMessage.parts);
13220
- var reasoningPart2 = updatedParts3[partIndex3];
13221
- updatedParts3[partIndex3] = _object_spread_props(_object_spread({}, reasoningPart2), {
13540
+ if (partIndex1 === -1) break;
13541
+ setPart(partIndex1, _object_spread_props(_object_spread({}, currentMessage.parts[partIndex1]), {
13222
13542
  state: 'done'
13223
- });
13224
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13225
- parts: updatedParts3
13226
- });
13227
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13228
- currentReasoningPartId = undefined;
13543
+ }));
13229
13544
  break;
13230
13545
  }
13231
13546
  case 'tool-input-start':
13232
13547
  {
13233
13548
  if (!currentMessage) break;
13549
+ var completedPart = currentMessage.parts.find(function(part) {
13550
+ return 'toolCallId' in part && part.toolCallId === chunk.toolCallId && 'state' in part && (part.state === 'output-available' || part.state === 'output-error');
13551
+ });
13552
+ if (completedPart) break;
13234
13553
  var initialRawInput = typeof chunk.input === 'string' ? chunk.input : chunk.input !== undefined ? JSON.stringify(chunk.input) : '';
13235
13554
  toolRawInputByCallId[chunk.toolCallId] = initialRawInput;
13236
13555
  var toolPart = {
@@ -13241,12 +13560,7 @@
13241
13560
  rawInput: initialRawInput || undefined,
13242
13561
  providerExecuted: chunk.providerExecuted
13243
13562
  };
13244
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13245
- parts: _to_consumable_array(currentMessage.parts).concat([
13246
- toolPart
13247
- ])
13248
- });
13249
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13563
+ setPart(-1, toolPart);
13250
13564
  break;
13251
13565
  }
13252
13566
  case 'tool-input-delta':
@@ -13254,10 +13568,11 @@
13254
13568
  var _ref, _ref1, _chunk_toolName, _ref2;
13255
13569
  var _existingPart_type, _this_shouldRepairToolInput, _this1;
13256
13570
  if (!currentMessage) break;
13257
- var toolIndex = currentMessage.parts.findIndex(function(p) {
13258
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13259
- });
13571
+ var toolIndex = findToolPart(chunk.toolCallId);
13260
13572
  var existingPart = toolIndex >= 0 ? currentMessage.parts[toolIndex] : null;
13573
+ if ((existingPart === null || existingPart === void 0 ? void 0 : existingPart.state) === 'output-available' || (existingPart === null || existingPart === void 0 ? void 0 : existingPart.state) === 'output-error') {
13574
+ break;
13575
+ }
13261
13576
  var previousRawInput = (_ref = (_ref1 = existingPart === null || existingPart === void 0 ? void 0 : existingPart.rawInput) !== null && _ref1 !== void 0 ? _ref1 : toolRawInputByCallId[chunk.toolCallId]) !== null && _ref !== void 0 ? _ref : '';
13262
13577
  var nextRawInput = "".concat(previousRawInput).concat(chunk.inputTextDelta);
13263
13578
  toolRawInputByCallId[chunk.toolCallId] = nextRawInput;
@@ -13272,30 +13587,20 @@
13272
13587
  input: parsedInput,
13273
13588
  rawInput: nextRawInput
13274
13589
  });
13275
- if (toolIndex >= 0) {
13276
- var updatedParts4 = _to_consumable_array(currentMessage.parts);
13277
- updatedParts4[toolIndex] = nextToolPart;
13278
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13279
- parts: updatedParts4
13280
- });
13281
- } else {
13282
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13283
- parts: _to_consumable_array(currentMessage.parts).concat([
13284
- nextToolPart
13285
- ])
13286
- });
13287
- }
13288
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13590
+ setPart(toolIndex, nextToolPart);
13289
13591
  break;
13290
13592
  }
13291
13593
  case 'tool-input-available':
13292
13594
  {
13293
13595
  if (!currentMessage) break;
13596
+ if (response.requiredToolCallIds.has(chunk.toolCallId)) break;
13294
13597
  delete toolRawInputByCallId[chunk.toolCallId];
13295
13598
  // Find existing tool part or create new one
13296
- var existingIndex = currentMessage.parts.findIndex(function(p) {
13297
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13298
- });
13599
+ var existingIndex = findToolPart(chunk.toolCallId);
13600
+ var existingPart1 = existingIndex >= 0 ? currentMessage.parts[existingIndex] : null;
13601
+ if ((existingPart1 === null || existingPart1 === void 0 ? void 0 : existingPart1.state) === 'output-available' || (existingPart1 === null || existingPart1 === void 0 ? void 0 : existingPart1.state) === 'output-error') {
13602
+ break;
13603
+ }
13299
13604
  var toolPart1 = {
13300
13605
  type: "tool-".concat(chunk.toolName),
13301
13606
  toolCallId: chunk.toolCallId,
@@ -13304,35 +13609,63 @@
13304
13609
  callProviderMetadata: chunk.callProviderMetadata,
13305
13610
  providerExecuted: chunk.providerExecuted
13306
13611
  };
13307
- if (existingIndex >= 0) {
13308
- var updatedParts5 = _to_consumable_array(currentMessage.parts);
13309
- updatedParts5[existingIndex] = toolPart1;
13310
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13311
- parts: updatedParts5
13312
- });
13313
- } else {
13314
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13315
- parts: _to_consumable_array(currentMessage.parts).concat([
13316
- toolPart1
13317
- ])
13318
- });
13612
+ setPart(existingIndex, toolPart1);
13613
+ if (_this.messages.some(function(message) {
13614
+ var _message_parts;
13615
+ return message !== currentMessage && ((_message_parts = message.parts) === null || _message_parts === void 0 ? void 0 : _message_parts.some(function(part) {
13616
+ return 'toolCallId' in part && part.toolCallId === chunk.toolCallId;
13617
+ }));
13618
+ })) {
13619
+ _this.acceptsIdentifierOnlyToolResults = false;
13319
13620
  }
13320
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13321
13621
  // Trigger onToolCall callback only for client-executed tools
13322
13622
  // (server-executed tools have providerExecuted: true and don't need client handling)
13323
13623
  if (_this.onToolCall && !chunk.providerExecuted) {
13324
- var result = _this.onToolCall({
13325
- toolCall: {
13326
- toolName: chunk.toolName,
13327
- toolCallId: chunk.toolCallId,
13328
- input: chunk.input,
13329
- dynamic: 'dynamic' in chunk ? chunk.dynamic : undefined
13330
- }
13624
+ var _this_responsesByToolCallId_get;
13625
+ var owners = (_this_responsesByToolCallId_get = _this.responsesByToolCallId.get(chunk.toolCallId)) !== null && _this_responsesByToolCallId_get !== void 0 ? _this_responsesByToolCallId_get : new Set();
13626
+ var existingOwners = Array.from(owners).filter(function(owner) {
13627
+ return owner !== response;
13331
13628
  });
13332
- if (result && typeof result.then === 'function') {
13333
- pendingToolCall = pendingToolCall.then(function() {
13334
- return result;
13629
+ if (existingOwners.length > 0) {
13630
+ _this.acceptsIdentifierOnlyToolResults = false;
13631
+ var conflictingOwner = existingOwners.find(function(owner) {
13632
+ return !owner.isRetired && (owner.outcome === 'active' || owner.outcome === 'succeeded' && (!owner.resolvedToolCallIds.has(chunk.toolCallId) || owner.pendingToolCallbacks > 0));
13335
13633
  });
13634
+ if (conflictingOwner) {
13635
+ // Neither response may continue once ownership is ambiguous.
13636
+ conflictingOwner.didEvaluateContinuation = true;
13637
+ failToolCall(new Error('Tool call "'.concat(chunk.toolCallId, '" is already owned by another response.')));
13638
+ break;
13639
+ }
13640
+ }
13641
+ response.requiredToolCallIds.add(chunk.toolCallId);
13642
+ owners.add(response);
13643
+ _this.responsesByToolCallId.set(chunk.toolCallId, owners);
13644
+ response.pendingToolCallbacks++;
13645
+ try {
13646
+ var result = _this.onToolCall({
13647
+ toolCall: {
13648
+ toolName: chunk.toolName,
13649
+ toolCallId: chunk.toolCallId,
13650
+ input: chunk.input,
13651
+ dynamic: 'dynamic' in chunk ? chunk.dynamic : undefined
13652
+ }
13653
+ }, function(options) {
13654
+ return response.isRetired ? Promise.resolve() : _this.submitToolResult(response, options);
13655
+ });
13656
+ if (result) {
13657
+ response.returnedToolCallbacks.push(Promise.resolve(result).catch(failToolCall).then(function() {
13658
+ response.pendingToolCallbacks--;
13659
+ _this.pruneDetachedResponse(response);
13660
+ }));
13661
+ } else {
13662
+ response.pendingToolCallbacks--;
13663
+ _this.pruneDetachedResponse(response);
13664
+ }
13665
+ } catch (error) {
13666
+ response.pendingToolCallbacks--;
13667
+ failToolCall(error);
13668
+ _this.pruneDetachedResponse(response);
13336
13669
  }
13337
13670
  }
13338
13671
  break;
@@ -13342,15 +13675,14 @@
13342
13675
  var _ref3, _ref4;
13343
13676
  if (!currentMessage) break;
13344
13677
  var _chunk_data = chunk.data, toolCallId = _chunk_data.toolCallId, toolName1 = _chunk_data.toolName, delta = _chunk_data.delta;
13345
- var toolIndex1 = currentMessage.parts.findIndex(function(p) {
13346
- return 'toolCallId' in p && p.toolCallId === toolCallId;
13347
- });
13348
- var existingPart1 = toolIndex1 >= 0 ? currentMessage.parts[toolIndex1] : null;
13349
- var previousRawOutput = (_ref3 = (_ref4 = existingPart1 === null || existingPart1 === void 0 ? void 0 : existingPart1.rawOutput) !== null && _ref4 !== void 0 ? _ref4 : toolRawOutputByCallId[toolCallId]) !== null && _ref3 !== void 0 ? _ref3 : '';
13678
+ if (response.resolvedToolCallIds.has(toolCallId)) break;
13679
+ var toolIndex1 = findToolPart(toolCallId);
13680
+ var existingPart2 = toolIndex1 >= 0 ? currentMessage.parts[toolIndex1] : null;
13681
+ var previousRawOutput = (_ref3 = (_ref4 = existingPart2 === null || existingPart2 === void 0 ? void 0 : existingPart2.rawOutput) !== null && _ref4 !== void 0 ? _ref4 : toolRawOutputByCallId[toolCallId]) !== null && _ref3 !== void 0 ? _ref3 : '';
13350
13682
  var nextRawOutput = "".concat(previousRawOutput).concat(delta);
13351
13683
  toolRawOutputByCallId[toolCallId] = nextRawOutput;
13352
- var parsedOutput = parseToolInputDelta(nextRawOutput, existingPart1 === null || existingPart1 === void 0 ? void 0 : existingPart1.output);
13353
- var nextToolPart1 = _object_spread_props(_object_spread({}, existingPart1 !== null && existingPart1 !== void 0 ? existingPart1 : {
13684
+ var parsedOutput = parseToolInputDelta(nextRawOutput, existingPart2 === null || existingPart2 === void 0 ? void 0 : existingPart2.output);
13685
+ var nextToolPart1 = _object_spread_props(_object_spread({}, existingPart2 !== null && existingPart2 !== void 0 ? existingPart2 : {
13354
13686
  type: "tool-".concat(toolName1),
13355
13687
  toolCallId: toolCallId,
13356
13688
  input: undefined
@@ -13360,47 +13692,34 @@
13360
13692
  rawOutput: nextRawOutput,
13361
13693
  preliminary: true
13362
13694
  });
13363
- if (toolIndex1 >= 0) {
13364
- var updatedParts6 = _to_consumable_array(currentMessage.parts);
13365
- updatedParts6[toolIndex1] = nextToolPart1;
13366
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13367
- parts: updatedParts6
13368
- });
13369
- } else {
13370
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13371
- parts: _to_consumable_array(currentMessage.parts).concat([
13372
- nextToolPart1
13373
- ])
13374
- });
13375
- }
13376
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13695
+ setPart(toolIndex1, nextToolPart1);
13377
13696
  break;
13378
13697
  }
13379
13698
  case 'tool-output-available':
13380
13699
  {
13381
13700
  if (!currentMessage) break;
13382
- var toolIndex2 = currentMessage.parts.findIndex(function(p) {
13383
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13384
- });
13701
+ var toolIndex2 = findToolPart(chunk.toolCallId);
13385
13702
  if (toolIndex2 >= 0) {
13386
13703
  delete toolRawInputByCallId[chunk.toolCallId];
13387
13704
  delete toolRawOutputByCallId[chunk.toolCallId];
13388
- var updatedParts7 = _to_consumable_array(currentMessage.parts);
13389
- var existingPart2 = updatedParts7[toolIndex2];
13705
+ var existingPart3 = currentMessage.parts[toolIndex2];
13706
+ if (response.resolvedToolCallIds.has(chunk.toolCallId)) {
13707
+ mergeCallProviderMetadata(chunk.toolCallId, chunk.callProviderMetadata);
13708
+ break;
13709
+ }
13390
13710
  // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
13391
- var _ignored = existingPart2.rawOutput, rest = _object_without_properties(existingPart2, [
13711
+ var _ignored = existingPart3.rawOutput, rest = _object_without_properties(existingPart3, [
13392
13712
  "rawOutput"
13393
13713
  ]);
13394
- updatedParts7[toolIndex2] = _object_spread_props(_object_spread({}, rest), {
13714
+ setPart(toolIndex2, _object_spread_props(_object_spread({}, rest), {
13395
13715
  state: 'output-available',
13396
13716
  output: chunk.output,
13397
13717
  callProviderMetadata: chunk.callProviderMetadata,
13398
13718
  preliminary: chunk.preliminary
13399
- });
13400
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13401
- parts: updatedParts7
13402
- });
13403
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13719
+ }));
13720
+ if (!chunk.preliminary) {
13721
+ acceptServerToolResult(chunk.toolCallId);
13722
+ }
13404
13723
  }
13405
13724
  break;
13406
13725
  }
@@ -13408,13 +13727,15 @@
13408
13727
  {
13409
13728
  var _chunk_input, _chunk_providerExecuted, _chunk_providerMetadata;
13410
13729
  if (!currentMessage) break;
13730
+ if (response.resolvedToolCallIds.has(chunk.toolCallId)) {
13731
+ mergeCallProviderMetadata(chunk.toolCallId, chunk.providerMetadata);
13732
+ break;
13733
+ }
13411
13734
  delete toolRawInputByCallId[chunk.toolCallId];
13412
13735
  delete toolRawOutputByCallId[chunk.toolCallId];
13413
- var toolIndex3 = currentMessage.parts.findIndex(function(p) {
13414
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13415
- });
13416
- var existingPart3 = toolIndex3 >= 0 ? currentMessage.parts[toolIndex3] : null;
13417
- var _ref5 = existingPart3 !== null && existingPart3 !== void 0 ? existingPart3 : {}, _ignoredOutput = _ref5.output, _ignoredRawOutput = _ref5.rawOutput, _ignoredPreliminary = _ref5.preliminary, carryOver = _object_without_properties(_ref5, [
13736
+ var toolIndex3 = findToolPart(chunk.toolCallId);
13737
+ var existingPart4 = toolIndex3 >= 0 ? currentMessage.parts[toolIndex3] : null;
13738
+ var _ref5 = existingPart4 !== null && existingPart4 !== void 0 ? existingPart4 : {}, _ignoredOutput = _ref5.output, _ignoredRawOutput = _ref5.rawOutput, _ignoredPreliminary = _ref5.preliminary, carryOver = _object_without_properties(_ref5, [
13418
13739
  "output",
13419
13740
  "rawOutput",
13420
13741
  "preliminary"
@@ -13429,49 +13750,35 @@
13429
13750
  providerExecuted: (_chunk_providerExecuted = chunk.providerExecuted) !== null && _chunk_providerExecuted !== void 0 ? _chunk_providerExecuted : carryOver.providerExecuted,
13430
13751
  callProviderMetadata: (_chunk_providerMetadata = chunk.providerMetadata) !== null && _chunk_providerMetadata !== void 0 ? _chunk_providerMetadata : carryOver.callProviderMetadata
13431
13752
  });
13432
- if (toolIndex3 >= 0) {
13433
- var updatedParts8 = _to_consumable_array(currentMessage.parts);
13434
- updatedParts8[toolIndex3] = nextToolPart2;
13435
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13436
- parts: updatedParts8
13437
- });
13438
- } else {
13439
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13440
- parts: _to_consumable_array(currentMessage.parts).concat([
13441
- nextToolPart2
13442
- ])
13443
- });
13444
- }
13445
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13753
+ setPart(toolIndex3, nextToolPart2);
13754
+ acceptServerToolResult(chunk.toolCallId);
13446
13755
  break;
13447
13756
  }
13448
13757
  case 'tool-output-error':
13449
13758
  {
13450
13759
  var _chunk_providerExecuted1, _chunk_providerMetadata1;
13451
13760
  if (!currentMessage) break;
13452
- var toolIndex4 = currentMessage.parts.findIndex(function(p) {
13453
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13454
- });
13761
+ if (response.resolvedToolCallIds.has(chunk.toolCallId)) {
13762
+ mergeCallProviderMetadata(chunk.toolCallId, chunk.providerMetadata);
13763
+ break;
13764
+ }
13765
+ var toolIndex4 = findToolPart(chunk.toolCallId);
13455
13766
  if (toolIndex4 < 0) break;
13456
13767
  delete toolRawInputByCallId[chunk.toolCallId];
13457
13768
  delete toolRawOutputByCallId[chunk.toolCallId];
13458
- var updatedParts9 = _to_consumable_array(currentMessage.parts);
13459
- var existingPart4 = updatedParts9[toolIndex4];
13460
- var _ignoredRawOutput1 = existingPart4.rawOutput, _ignoredPreliminary1 = existingPart4.preliminary, _ignoredOutput1 = existingPart4.output, rest1 = _object_without_properties(existingPart4, [
13769
+ var existingPart5 = currentMessage.parts[toolIndex4];
13770
+ var _ignoredRawOutput1 = existingPart5.rawOutput, _ignoredPreliminary1 = existingPart5.preliminary, _ignoredOutput1 = existingPart5.output, rest1 = _object_without_properties(existingPart5, [
13461
13771
  "rawOutput",
13462
13772
  "preliminary",
13463
13773
  "output"
13464
13774
  ]);
13465
- updatedParts9[toolIndex4] = _object_spread_props(_object_spread({}, rest1), {
13775
+ setPart(toolIndex4, _object_spread_props(_object_spread({}, rest1), {
13466
13776
  state: 'output-error',
13467
13777
  errorText: chunk.errorText,
13468
13778
  providerExecuted: (_chunk_providerExecuted1 = chunk.providerExecuted) !== null && _chunk_providerExecuted1 !== void 0 ? _chunk_providerExecuted1 : rest1.providerExecuted,
13469
13779
  callProviderMetadata: (_chunk_providerMetadata1 = chunk.providerMetadata) !== null && _chunk_providerMetadata1 !== void 0 ? _chunk_providerMetadata1 : rest1.callProviderMetadata
13470
- });
13471
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13472
- parts: updatedParts9
13473
- });
13474
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13780
+ }));
13781
+ acceptServerToolResult(chunk.toolCallId);
13475
13782
  break;
13476
13783
  }
13477
13784
  case 'source-url':
@@ -13483,12 +13790,7 @@
13483
13790
  url: chunk.url,
13484
13791
  title: chunk.title
13485
13792
  };
13486
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13487
- parts: _to_consumable_array(currentMessage.parts).concat([
13488
- sourcePart
13489
- ])
13490
- });
13491
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13793
+ setPart(-1, sourcePart);
13492
13794
  break;
13493
13795
  }
13494
13796
  case 'source-document':
@@ -13502,12 +13804,7 @@
13502
13804
  filename: chunk.filename,
13503
13805
  providerMetadata: chunk.providerMetadata
13504
13806
  };
13505
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13506
- parts: _to_consumable_array(currentMessage.parts).concat([
13507
- docPart
13508
- ])
13509
- });
13510
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13807
+ setPart(-1, docPart);
13511
13808
  break;
13512
13809
  }
13513
13810
  case 'file':
@@ -13518,26 +13815,15 @@
13518
13815
  url: chunk.url,
13519
13816
  mediaType: chunk.mediaType
13520
13817
  };
13521
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13522
- parts: _to_consumable_array(currentMessage.parts).concat([
13523
- filePart
13524
- ])
13525
- });
13526
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13818
+ setPart(-1, filePart);
13527
13819
  break;
13528
13820
  }
13529
13821
  case 'start-step':
13530
13822
  {
13531
13823
  if (!currentMessage) break;
13532
- var stepPart = {
13824
+ setPart(-1, {
13533
13825
  type: 'step-start'
13534
- };
13535
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13536
- parts: _to_consumable_array(currentMessage.parts).concat([
13537
- stepPart
13538
- ])
13539
13826
  });
13540
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13541
13827
  break;
13542
13828
  }
13543
13829
  case 'message-metadata':
@@ -13546,7 +13832,7 @@
13546
13832
  currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13547
13833
  metadata: chunk.messageMetadata
13548
13834
  });
13549
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13835
+ currentMessage = _this.replaceMessage(currentMessageIndex, currentMessage, response);
13550
13836
  break;
13551
13837
  }
13552
13838
  case 'error':
@@ -13566,7 +13852,7 @@
13566
13852
  currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13567
13853
  metadata: chunk.messageMetadata
13568
13854
  });
13569
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13855
+ currentMessage = _this.replaceMessage(currentMessageIndex, currentMessage, response);
13570
13856
  }
13571
13857
  break;
13572
13858
  }
@@ -13592,14 +13878,13 @@
13592
13878
  ]
13593
13879
  };
13594
13880
  if (currentMessageIndex >= 0) {
13595
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13881
+ currentMessage = _this.replaceMessage(currentMessageIndex, currentMessage, response);
13596
13882
  } else {
13597
13883
  _this.state.pushMessage(currentMessage);
13598
- currentMessageIndex = _this.state.messages.length - 1;
13884
+ currentMessageIndex = _this.messages.length - 1;
13885
+ _this.responseByMessage.set(currentMessage, response);
13599
13886
  }
13600
13887
  currentMessageId = currentMessage.id;
13601
- currentTextPartId = undefined;
13602
- currentReasoningPartId = undefined;
13603
13888
  break;
13604
13889
  }
13605
13890
  default:
@@ -13612,12 +13897,7 @@
13612
13897
  id: chunk.id,
13613
13898
  data: chunk.data
13614
13899
  };
13615
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13616
- parts: _to_consumable_array(currentMessage.parts).concat([
13617
- dataPart
13618
- ])
13619
- });
13620
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13900
+ setPart(-1, dataPart);
13621
13901
  // Trigger onData callback
13622
13902
  if (_this.onData) {
13623
13903
  _this.onData(dataPart);
@@ -13626,49 +13906,11 @@
13626
13906
  }
13627
13907
  }
13628
13908
  }, function() {
13629
- // Wait for any pending tool calls to complete
13630
- pendingToolCall.then(function() {
13631
- // Stream finished successfully
13632
- _this.setStatus({
13633
- status: 'ready'
13634
- });
13635
- _this.activeResponse = null;
13636
- // Trigger onFinish callback
13637
- if (_this.onFinish && currentMessage) {
13638
- _this.onFinish({
13639
- message: currentMessage,
13640
- messages: _this.state.messages,
13641
- isAbort: isAbort,
13642
- isDisconnect: isDisconnect,
13643
- isError: isError
13644
- });
13645
- }
13646
- // Note: sendAutomaticallyWhen is only checked in addToolResult,
13647
- // not here. For server-executed tools, the server continues the
13648
- // conversation. For client-executed tools, addToolResult handles it.
13649
- resolve();
13909
+ return Promise.all(response.returnedToolCallbacks).then(function() {
13910
+ return finish();
13650
13911
  });
13651
13912
  }, function(error) {
13652
- if (error.name === 'AbortError') {
13653
- isAbort = true;
13654
- _this.setStatus({
13655
- status: 'ready'
13656
- });
13657
- } else {
13658
- isDisconnect = true;
13659
- _this.handleError(error);
13660
- }
13661
- // Still call onFinish even on error/abort
13662
- if (_this.onFinish && currentMessage) {
13663
- _this.onFinish({
13664
- message: currentMessage,
13665
- messages: _this.state.messages,
13666
- isAbort: isAbort,
13667
- isDisconnect: isDisconnect,
13668
- isError: isError
13669
- });
13670
- }
13671
- resolve();
13913
+ return finish(error);
13672
13914
  });
13673
13915
  });
13674
13916
  }
@@ -13676,10 +13918,13 @@
13676
13918
  {
13677
13919
  key: "handleError",
13678
13920
  value: function handleError(error) {
13679
- this.setStatus({
13680
- status: 'error',
13681
- error: error
13682
- });
13921
+ var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, _ref_updateState = _ref.updateState, updateState = _ref_updateState === void 0 ? true : _ref_updateState;
13922
+ if (updateState) {
13923
+ this.setStatus({
13924
+ status: 'error',
13925
+ error: error
13926
+ });
13927
+ }
13683
13928
  if (this.onError) {
13684
13929
  this.onError(error);
13685
13930
  }
@@ -14347,7 +14592,7 @@
14347
14592
  if (!tool) return true;
14348
14593
  return Boolean(tool.streamInput);
14349
14594
  },
14350
- onToolCall: function onToolCall(param) {
14595
+ onToolCall: function onToolCall(param, submitToolResult) {
14351
14596
  var toolCall = param.toolCall;
14352
14597
  var tool = tools[toolCall.toolName];
14353
14598
  // Compatibility shim with Algolia MCP Server search tool
@@ -14355,7 +14600,7 @@
14355
14600
  tool = tools[SearchIndexToolType];
14356
14601
  }
14357
14602
  if (!tool) {
14358
- return _chatInstance.addToolResult({
14603
+ return submitToolResult({
14359
14604
  output: 'No tool implemented for "'.concat(toolCall.toolName, '".'),
14360
14605
  tool: toolCall.toolName,
14361
14606
  toolCallId: toolCall.toolCallId
@@ -14364,7 +14609,7 @@
14364
14609
  if (tool.onToolCall) {
14365
14610
  var addToolResult = function addToolResult(param) {
14366
14611
  var output = param.output;
14367
- return _chatInstance.addToolResult({
14612
+ return submitToolResult({
14368
14613
  output: output,
14369
14614
  tool: toolCall.toolName,
14370
14615
  toolCallId: toolCall.toolCallId
@@ -14486,6 +14731,7 @@
14486
14731
  var _param = _sliced_to_array(param, 2), key = _param[0], tool = _param[1];
14487
14732
  var toolWithAddToolResult = _object_spread_props(_object_spread({}, tool), {
14488
14733
  addToolResult: _chatInstance.addToolResult,
14734
+ '~addToolResultForMessage': _chatInstance['~addToolResultForMessage'],
14489
14735
  applyFilters: applyFilters,
14490
14736
  sendEvent: sendEvent
14491
14737
  });