react-instantsearch-core 7.39.1 → 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.39.1 | © 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.39.1';
27
+ var version$2 = '7.41.0';
28
28
 
29
29
  function _define_property(obj, key, value) {
30
30
  if (key in obj) {
@@ -7528,6 +7528,9 @@
7528
7528
  current: 0
7529
7529
  },
7530
7530
  waitForResultsRef: null,
7531
+ resolveWaitForResultsRef: {
7532
+ current: null
7533
+ },
7531
7534
  ignoreMultipleHooksWarning: false
7532
7535
  });
7533
7536
 
@@ -7762,7 +7765,10 @@
7762
7765
  useWidget({
7763
7766
  widget: widget,
7764
7767
  parentIndex: parentIndex,
7765
- props: stableProps,
7768
+ props: [
7769
+ stableProps,
7770
+ stableAdditionalWidgetProperties
7771
+ ],
7766
7772
  shouldSsr: Boolean(serverContext),
7767
7773
  skipSuspense: skipSuspense
7768
7774
  });
@@ -8499,13 +8505,47 @@
8499
8505
  ].concat(_to_consumable_array(resolveScopedResultsFromWidgets(current.getWidgets()))));
8500
8506
  }, []);
8501
8507
  }
8508
+ function getWidgetsRequestDependencies(widgets) {
8509
+ return widgets.reduce(function(dependencies, widget) {
8510
+ if (isIndexWidget(widget)) {
8511
+ if (widget._isolated) {
8512
+ return dependencies;
8513
+ }
8514
+ var childDependencies = getWidgetsRequestDependencies(widget.getWidgets());
8515
+ return {
8516
+ hasSearchWidget: dependencies.hasSearchWidget || childDependencies.hasSearchWidget,
8517
+ hasRecommendWidget: dependencies.hasRecommendWidget || childDependencies.hasRecommendWidget
8518
+ };
8519
+ }
8520
+ if (widget.dependsOn === 'recommend') {
8521
+ return _object_spread_props(_object_spread({}, dependencies), {
8522
+ hasRecommendWidget: true
8523
+ });
8524
+ }
8525
+ if (widget.dependsOn === 'none') {
8526
+ return dependencies;
8527
+ }
8528
+ return _object_spread_props(_object_spread({}, dependencies), {
8529
+ hasSearchWidget: true
8530
+ });
8531
+ }, {
8532
+ hasSearchWidget: false,
8533
+ hasRecommendWidget: false
8534
+ });
8535
+ }
8536
+ function recomputeInstantSearchRequestDependencies(instantSearchInstance) {
8537
+ var _getWidgetsRequestDependencies = getWidgetsRequestDependencies(instantSearchInstance.mainIndex.getWidgets()), hasSearchWidget = _getWidgetsRequestDependencies.hasSearchWidget, hasRecommendWidget = _getWidgetsRequestDependencies.hasRecommendWidget;
8538
+ instantSearchInstance._hasSearchWidget = hasSearchWidget;
8539
+ instantSearchInstance._hasRecommendWidget = hasRecommendWidget;
8540
+ }
8502
8541
  var index = function index(widgetParams) {
8503
- 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) {
8504
8544
  throw new Error(withUsage$s('The `indexName` option is required.'));
8505
8545
  }
8506
8546
  // When isolated=true, we use an empty string as the default indexName.
8507
8547
  // This is intentional: isolated indices do not require a real index name.
8508
- 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;
8509
8549
  var localWidgets = [];
8510
8550
  var localUiState = {};
8511
8551
  var localInstantSearchInstance = null;
@@ -8513,8 +8553,11 @@
8513
8553
  var helper = null;
8514
8554
  var derivedHelper = null;
8515
8555
  var lastValidSearchParameters = null;
8516
- var hasRecommendWidget = false;
8517
- var hasSearchWidget = false;
8556
+ var recomputeLocalRequestDependencies = function recomputeLocalRequestDependencies() {
8557
+ if (localInstantSearchInstance) {
8558
+ recomputeInstantSearchRequestDependencies(localInstantSearchInstance);
8559
+ }
8560
+ };
8518
8561
  return {
8519
8562
  $$type: 'ais.index',
8520
8563
  $$widgetType: 'ais.index',
@@ -8605,21 +8648,12 @@
8605
8648
  }
8606
8649
  flatWidgets.forEach(function(widget) {
8607
8650
  widget.parent = _this;
8608
- if (isIndexWidget(widget)) {
8609
- return;
8610
- }
8611
- if (localInstantSearchInstance && widget.dependsOn === 'recommend') {
8612
- localInstantSearchInstance._hasRecommendWidget = true;
8613
- } else if (localInstantSearchInstance) {
8614
- localInstantSearchInstance._hasSearchWidget = true;
8615
- } else if (widget.dependsOn === 'recommend') {
8616
- hasRecommendWidget = true;
8617
- } else {
8618
- hasSearchWidget = true;
8651
+ if (!isIndexWidget(widget)) {
8652
+ addWidgetId(widget);
8619
8653
  }
8620
- addWidgetId(widget);
8621
8654
  });
8622
8655
  localWidgets = localWidgets.concat(flatWidgets);
8656
+ recomputeLocalRequestDependencies();
8623
8657
  if (localInstantSearchInstance && Boolean(flatWidgets.length)) {
8624
8658
  privateHelperSetState(helper, {
8625
8659
  state: getLocalWidgetsSearchParameters(localWidgets, {
@@ -8676,21 +8710,10 @@
8676
8710
  localWidgets = localWidgets.filter(function(widget) {
8677
8711
  return flatWidgets.indexOf(widget) === -1;
8678
8712
  });
8679
- localWidgets.forEach(function(widget) {
8713
+ flatWidgets.forEach(function(widget) {
8680
8714
  widget.parent = undefined;
8681
- if (isIndexWidget(widget)) {
8682
- return;
8683
- }
8684
- if (localInstantSearchInstance && widget.dependsOn === 'recommend') {
8685
- localInstantSearchInstance._hasRecommendWidget = true;
8686
- } else if (localInstantSearchInstance) {
8687
- localInstantSearchInstance._hasSearchWidget = true;
8688
- } else if (widget.dependsOn === 'recommend') {
8689
- hasRecommendWidget = true;
8690
- } else {
8691
- hasSearchWidget = true;
8692
- }
8693
8715
  });
8716
+ recomputeLocalRequestDependencies();
8694
8717
  if (localInstantSearchInstance && Boolean(flatWidgets.length)) {
8695
8718
  var _flatWidgets_reduce = flatWidgets.reduce(function(states, widget) {
8696
8719
  // the `dispose` method exists at this point we already assert it
@@ -8913,12 +8936,7 @@
8913
8936
  // schedule a render that will render the results injected on the helper.
8914
8937
  instantSearchInstance.scheduleRender();
8915
8938
  }
8916
- if (hasRecommendWidget) {
8917
- instantSearchInstance._hasRecommendWidget = true;
8918
- }
8919
- if (hasSearchWidget) {
8920
- instantSearchInstance._hasSearchWidget = true;
8921
- }
8939
+ recomputeLocalRequestDependencies();
8922
8940
  },
8923
8941
  render: function render(param) {
8924
8942
  var _this = this;
@@ -9192,7 +9210,7 @@
9192
9210
  });
9193
9211
  }
9194
9212
 
9195
- var version = '4.106.0';
9213
+ var version = '4.108.0';
9196
9214
 
9197
9215
  var ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';
9198
9216
  function getCookie(name) {
@@ -11333,8 +11351,11 @@
11333
11351
  mainHelper.searchForFacetValues = mainHelper.searchForCompositionFacetValues.bind(mainHelper);
11334
11352
  }
11335
11353
  mainHelper.search = function() {
11336
- _this.status = 'loading';
11337
- _this.scheduleRender(false);
11354
+ var hasSearchOrRecommendWidget = _this._hasSearchWidget || _this._hasRecommendWidget;
11355
+ if (hasSearchOrRecommendWidget) {
11356
+ _this.status = 'loading';
11357
+ }
11358
+ _this.scheduleRender(!hasSearchOrRecommendWidget);
11338
11359
  // This solution allows us to keep the exact same API for the users but
11339
11360
  // under the hood, we have a different implementation. It should be
11340
11361
  // completely transparent for the rest of the codebase. Only this module
@@ -11398,7 +11419,7 @@
11398
11419
  error.error = error;
11399
11420
  _this.error = error;
11400
11421
  _this.status = 'error';
11401
- _this.scheduleRender(false);
11422
+ _this.scheduleRender(!_this._hasSearchWidget && !_this._hasRecommendWidget);
11402
11423
  // This needs to execute last because it throws the error.
11403
11424
  _this.emit('error', error);
11404
11425
  });
@@ -12106,10 +12127,14 @@
12106
12127
  return function(widgetParams) {
12107
12128
  var _ref = widgetParams || {}, _ref_escapeHTML = _ref.escapeHTML, escapeHTML = _ref_escapeHTML === void 0 ? true : _ref_escapeHTML, _ref_transformItems = _ref.transformItems, transformItems = _ref_transformItems === void 0 ? function(indices) {
12108
12129
  return indices;
12109
- } : _ref_transformItems, tmp = _ref.future, _ref1 = tmp === void 0 ? {} : tmp, _ref_undefinedEmptyQuery = _ref1.undefinedEmptyQuery, undefinedEmptyQuery = _ref_undefinedEmptyQuery === void 0 ? false : _ref_undefinedEmptyQuery;
12130
+ } : _ref_transformItems, _ref_requiresSearch = _ref.requiresSearch, requiresSearch = _ref_requiresSearch === void 0 ? true : _ref_requiresSearch, tmp = _ref.future, _ref1 = tmp === void 0 ? {} : tmp, _ref_undefinedEmptyQuery = _ref1.undefinedEmptyQuery, undefinedEmptyQuery = _ref_undefinedEmptyQuery === void 0 ? false : _ref_undefinedEmptyQuery;
12110
12131
  var connectorState = {};
12111
12132
  return {
12112
12133
  $$type: 'ais.autocomplete',
12134
+ dependsOn: requiresSearch ? 'search' : 'none',
12135
+ shouldRender: requiresSearch ? undefined : function() {
12136
+ return true;
12137
+ },
12113
12138
  init: function init(initOptions) {
12114
12139
  var instantSearchInstance = initOptions.instantSearchInstance;
12115
12140
  renderFn(_object_spread_props(_object_spread({}, this.getWidgetRenderState(initOptions)), {
@@ -12650,6 +12675,7 @@
12650
12675
  return undefined;
12651
12676
  }
12652
12677
 
12678
+ var _computedKey$1;
12653
12679
  var tryParseJson = function tryParseJson(value) {
12654
12680
  try {
12655
12681
  return JSON.parse(value);
@@ -12720,6 +12746,8 @@
12720
12746
  return fallbackInput;
12721
12747
  };
12722
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;
12723
12751
  /**
12724
12752
  * Abstract base class for chat implementations.
12725
12753
  */ var AbstractChat = /*#__PURE__*/ function() {
@@ -12739,6 +12767,12 @@
12739
12767
  _define_property(this, "sendAutomaticallyWhen", void 0);
12740
12768
  _define_property(this, "shouldRepairToolInput", void 0);
12741
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);
12742
12776
  _define_property(this, "jobExecutor", new SerialJobExecutor());
12743
12777
  /**
12744
12778
  * Appends or replaces a user message to the chat list. This triggers the API call to fetch
@@ -12824,13 +12858,13 @@
12824
12858
  // Find the message to regenerate from
12825
12859
  var targetIndex = -1;
12826
12860
  if (messageId) {
12827
- targetIndex = _this1.state.messages.findIndex(function(m) {
12861
+ targetIndex = _this1.messages.findIndex(function(m) {
12828
12862
  return m.id === messageId;
12829
12863
  });
12830
12864
  } else {
12831
12865
  // Find the last assistant message
12832
- for(var i = _this1.state.messages.length - 1; i >= 0; i--){
12833
- 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') {
12834
12868
  targetIndex = i;
12835
12869
  break;
12836
12870
  }
@@ -12838,7 +12872,7 @@
12838
12872
  }
12839
12873
  if (targetIndex >= 0) {
12840
12874
  // Remove the assistant message and all messages after it
12841
- _this1.state.messages = _this1.state.messages.slice(0, targetIndex);
12875
+ _this1.messages = _this1.messages.slice(0, targetIndex);
12842
12876
  }
12843
12877
  return _this1.makeRequest(_object_spread({
12844
12878
  trigger: 'regenerate-message',
@@ -12853,23 +12887,10 @@
12853
12887
  if (!_this.transport) {
12854
12888
  return Promise.reject(new Error('Transport is required for resuming stream. Please provide a transport when initializing the chat.'));
12855
12889
  }
12856
- _this.setStatus({
12857
- status: 'submitted'
12858
- });
12859
- return _this.transport.reconnectToStream(_object_spread({
12860
- chatId: _this.id
12861
- }, options)).then(function(stream) {
12862
- if (stream) {
12863
- return _this.processStreamWithCallbacks(stream);
12864
- } else {
12865
- _this.setStatus({
12866
- status: 'ready'
12867
- });
12868
- return Promise.resolve();
12869
- }
12870
- }, function(error) {
12871
- _this.handleError(error);
12872
- return Promise.resolve();
12890
+ return _this.consume(function() {
12891
+ return _this.transport.reconnectToStream(_object_spread({
12892
+ chatId: _this.id
12893
+ }, options));
12873
12894
  });
12874
12895
  });
12875
12896
  });
@@ -12885,53 +12906,57 @@
12885
12906
  });
12886
12907
  /**
12887
12908
  * Add a tool result for a tool call.
12888
- */ _define_property(this, "addToolResult", function(param) {
12889
- var tool = param.tool, toolCallId = param.toolCallId, output = param.output;
12890
- return _this.jobExecutor.run(function() {
12891
- // Find the message with this tool call
12892
- var messageIndex = _this.state.messages.findIndex(function(m) {
12893
- var _ref;
12894
- var _m_parts;
12895
- return (_ref = (_m_parts = m.parts) === null || _m_parts === void 0 ? void 0 : _m_parts.some(function(p) {
12896
- return 'toolCallId' in p && p.toolCallId === toolCallId || 'type' in p && p.type === "tool-".concat(String(tool));
12897
- })) !== null && _ref !== void 0 ? _ref : false;
12898
- });
12899
- if (messageIndex === -1) return Promise.resolve();
12900
- var message = _this.state.messages[messageIndex];
12901
- var updatedParts = message.parts.map(function(part) {
12902
- if ('toolCallId' in part && part.toolCallId === toolCallId && 'state' in part) {
12903
- return _object_spread_props(_object_spread({}, part), {
12904
- state: 'output-available',
12905
- output: output
12906
- });
12907
- }
12908
- return part;
12909
- });
12910
- _this.state.replaceMessage(messageIndex, _object_spread_props(_object_spread({}, message), {
12911
- parts: updatedParts
12912
- }));
12913
- // Check if we should auto-send based on sendAutomaticallyWhen
12914
- if (_this.sendAutomaticallyWhen) {
12915
- return Promise.resolve(_this.sendAutomaticallyWhen({
12916
- messages: _this.state.messages
12917
- })).then(function(shouldSend) {
12918
- if (shouldSend) {
12919
- return _this.makeRequest({
12920
- trigger: 'submit-message'
12921
- });
12922
- }
12923
- 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;
12924
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();
12925
12931
  }
12926
- return Promise.resolve();
12932
+ return _this.continueResponse();
12927
12933
  });
12928
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
+ });
12929
12952
  /**
12930
12953
  * Abort the current request immediately, keep the generated tokens if any.
12931
12954
  */ _define_property(this, "stop", function() {
12932
12955
  if (_this.activeResponse) {
12933
- _this.activeResponse.abortController.abort();
12956
+ var response = _this.activeResponse;
12957
+ response.outcome = 'aborted';
12934
12958
  _this.activeResponse = null;
12959
+ response.abortController.abort();
12935
12960
  }
12936
12961
  _this.setStatus({
12937
12962
  status: 'ready'
@@ -12993,6 +13018,14 @@
12993
13018
  * context.
12994
13019
  */ key: "resetConversationId",
12995
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
+ }
12996
13029
  this.conversationId = this.generateId();
12997
13030
  }
12998
13031
  },
@@ -13002,7 +13035,93 @@
13002
13035
  return this.state.messages;
13003
13036
  },
13004
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
+ }
13005
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
+ });
13006
13125
  }
13007
13126
  },
13008
13127
  {
@@ -13011,6 +13130,154 @@
13011
13130
  return this.state.messages[this.state.messages.length - 1];
13012
13131
  }
13013
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
+ },
13014
13281
  {
13015
13282
  key: "makeRequest",
13016
13283
  value: function makeRequest(options) {
@@ -13018,42 +13285,72 @@
13018
13285
  if (!this.transport) {
13019
13286
  return Promise.reject(new Error('Transport is required for sending messages. Please provide a transport when initializing the chat.'));
13020
13287
  }
13021
- // 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;
13022
13306
  if (this.activeResponse) {
13307
+ this.activeResponse.outcome = 'aborted';
13023
13308
  this.activeResponse.abortController.abort();
13024
13309
  }
13025
- var abortController = new AbortController();
13026
- this.activeResponse = {
13027
- 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
13028
13320
  };
13321
+ this.activeResponse = response;
13322
+ this.latestResponse = response;
13029
13323
  this.setStatus({
13030
13324
  status: 'submitted'
13031
13325
  });
13032
- return this.transport.sendMessages({
13033
- chatId: this.id,
13034
- messages: this.state.messages,
13035
- abortSignal: abortController.signal,
13036
- trigger: options.trigger,
13037
- messageId: options.messageId,
13038
- headers: options.headers,
13039
- body: options.body,
13040
- requestMetadata: options.metadata
13041
- }).then(function(stream) {
13042
- _this.activeResponse.stream = stream;
13043
- 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;
13044
13336
  }, function(error) {
13337
+ if (_this.activeResponse !== response) return;
13338
+ _this.activeResponse = null;
13045
13339
  if (error.name === 'AbortError') {
13046
- // Request was aborted, don't treat as error
13047
- return Promise.resolve();
13340
+ response.outcome = 'aborted';
13341
+ _this.setStatus({
13342
+ status: 'ready'
13343
+ });
13344
+ } else {
13345
+ response.outcome = 'failed';
13346
+ _this.handleError(error);
13048
13347
  }
13049
- _this.handleError(error);
13050
- return Promise.resolve();
13051
13348
  });
13052
13349
  }
13053
13350
  },
13054
13351
  {
13055
- key: "processStreamWithCallbacks",
13056
- value: function processStreamWithCallbacks(stream) {
13352
+ key: "processStream",
13353
+ value: function processStream1(stream, response) {
13057
13354
  var _this = this;
13058
13355
  this.setStatus({
13059
13356
  status: 'streaming'
@@ -13062,26 +13359,135 @@
13062
13359
  var currentMessage;
13063
13360
  var currentMessageIndex = -1;
13064
13361
  var isAbort = false;
13065
- var isDisconnect = false;
13066
13362
  var isError = false;
13067
- // Track current text/reasoning part state
13068
- var currentTextPartId;
13069
- var currentReasoningPartId;
13070
13363
  var toolRawInputByCallId = {};
13071
13364
  var toolRawOutputByCallId = {};
13072
- // Promise chain for handling tool calls that return promises
13073
- 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
+ };
13074
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
+ };
13075
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
+ }
13076
13473
  switch(chunk.type){
13077
13474
  case 'start':
13078
13475
  {
13079
13476
  currentMessageId = chunk.messageId || _this.generateId();
13477
+ response.messageId = currentMessageId;
13080
13478
  // Check if we're continuing an existing message or creating a new one
13081
13479
  var lastMessage = _this.lastMessage;
13082
13480
  if (lastMessage && lastMessage.role === 'assistant' && lastMessage.id === currentMessageId) {
13083
- currentMessage = lastMessage;
13084
- 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);
13085
13491
  } else {
13086
13492
  currentMessage = {
13087
13493
  id: currentMessageId,
@@ -13090,123 +13496,60 @@
13090
13496
  metadata: chunk.messageMetadata
13091
13497
  };
13092
13498
  _this.state.pushMessage(currentMessage);
13093
- currentMessageIndex = _this.state.messages.length - 1;
13499
+ currentMessageIndex = _this.messages.length - 1;
13500
+ _this.responseByMessage.set(currentMessage, response);
13094
13501
  }
13095
13502
  break;
13096
13503
  }
13097
13504
  case 'text-start':
13505
+ case 'reasoning-start':
13098
13506
  {
13099
13507
  if (!currentMessage) break;
13100
- currentTextPartId = chunk.id;
13101
- var textPart = {
13102
- type: 'text',
13508
+ var type = chunk.type === 'text-start' ? 'text' : 'reasoning';
13509
+ setPart(-1, {
13510
+ type: type,
13103
13511
  text: '',
13104
13512
  state: 'streaming',
13105
13513
  providerMetadata: chunk.providerMetadata
13106
- };
13107
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13108
- parts: _to_consumable_array(currentMessage.parts).concat([
13109
- textPart
13110
- ])
13111
13514
  });
13112
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13113
13515
  break;
13114
13516
  }
13115
13517
  case 'text-delta':
13518
+ case 'reasoning-delta':
13116
13519
  {
13117
- if (!currentMessage || !currentTextPartId) break;
13118
- var partIndex = currentMessage.parts.findIndex(function(p) {
13119
- 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';
13120
13524
  });
13121
13525
  if (partIndex === -1) break;
13122
- var updatedParts = _to_consumable_array(currentMessage.parts);
13123
- var textPart1 = updatedParts[partIndex];
13124
- updatedParts[partIndex] = _object_spread_props(_object_spread({}, textPart1), {
13125
- text: textPart1.text + chunk.delta
13126
- });
13127
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13128
- parts: updatedParts
13129
- });
13130
- _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
+ }));
13131
13530
  break;
13132
13531
  }
13133
13532
  case 'text-end':
13134
- {
13135
- if (!currentMessage) break;
13136
- var partIndex1 = currentMessage.parts.findIndex(function(p) {
13137
- return p.type === 'text' && p.state === 'streaming';
13138
- });
13139
- if (partIndex1 === -1) break;
13140
- var updatedParts1 = _to_consumable_array(currentMessage.parts);
13141
- var textPart2 = updatedParts1[partIndex1];
13142
- updatedParts1[partIndex1] = _object_spread_props(_object_spread({}, textPart2), {
13143
- state: 'done'
13144
- });
13145
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13146
- parts: updatedParts1
13147
- });
13148
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13149
- currentTextPartId = undefined;
13150
- break;
13151
- }
13152
- case 'reasoning-start':
13153
- {
13154
- if (!currentMessage) break;
13155
- currentReasoningPartId = chunk.id;
13156
- var reasoningPart = {
13157
- type: 'reasoning',
13158
- text: '',
13159
- state: 'streaming',
13160
- providerMetadata: chunk.providerMetadata
13161
- };
13162
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13163
- parts: _to_consumable_array(currentMessage.parts).concat([
13164
- reasoningPart
13165
- ])
13166
- });
13167
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13168
- break;
13169
- }
13170
- case 'reasoning-delta':
13171
- {
13172
- if (!currentMessage || !currentReasoningPartId) break;
13173
- var partIndex2 = currentMessage.parts.findIndex(function(p) {
13174
- return p.type === 'reasoning' && p.state === 'streaming';
13175
- });
13176
- if (partIndex2 === -1) break;
13177
- var updatedParts2 = _to_consumable_array(currentMessage.parts);
13178
- var reasoningPart1 = updatedParts2[partIndex2];
13179
- updatedParts2[partIndex2] = _object_spread_props(_object_spread({}, reasoningPart1), {
13180
- text: reasoningPart1.text + chunk.delta
13181
- });
13182
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13183
- parts: updatedParts2
13184
- });
13185
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13186
- break;
13187
- }
13188
13533
  case 'reasoning-end':
13189
13534
  {
13190
13535
  if (!currentMessage) break;
13191
- var partIndex3 = currentMessage.parts.findIndex(function(p) {
13192
- 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';
13193
13539
  });
13194
- if (partIndex3 === -1) break;
13195
- var updatedParts3 = _to_consumable_array(currentMessage.parts);
13196
- var reasoningPart2 = updatedParts3[partIndex3];
13197
- updatedParts3[partIndex3] = _object_spread_props(_object_spread({}, reasoningPart2), {
13540
+ if (partIndex1 === -1) break;
13541
+ setPart(partIndex1, _object_spread_props(_object_spread({}, currentMessage.parts[partIndex1]), {
13198
13542
  state: 'done'
13199
- });
13200
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13201
- parts: updatedParts3
13202
- });
13203
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13204
- currentReasoningPartId = undefined;
13543
+ }));
13205
13544
  break;
13206
13545
  }
13207
13546
  case 'tool-input-start':
13208
13547
  {
13209
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;
13210
13553
  var initialRawInput = typeof chunk.input === 'string' ? chunk.input : chunk.input !== undefined ? JSON.stringify(chunk.input) : '';
13211
13554
  toolRawInputByCallId[chunk.toolCallId] = initialRawInput;
13212
13555
  var toolPart = {
@@ -13217,12 +13560,7 @@
13217
13560
  rawInput: initialRawInput || undefined,
13218
13561
  providerExecuted: chunk.providerExecuted
13219
13562
  };
13220
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13221
- parts: _to_consumable_array(currentMessage.parts).concat([
13222
- toolPart
13223
- ])
13224
- });
13225
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13563
+ setPart(-1, toolPart);
13226
13564
  break;
13227
13565
  }
13228
13566
  case 'tool-input-delta':
@@ -13230,10 +13568,11 @@
13230
13568
  var _ref, _ref1, _chunk_toolName, _ref2;
13231
13569
  var _existingPart_type, _this_shouldRepairToolInput, _this1;
13232
13570
  if (!currentMessage) break;
13233
- var toolIndex = currentMessage.parts.findIndex(function(p) {
13234
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13235
- });
13571
+ var toolIndex = findToolPart(chunk.toolCallId);
13236
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
+ }
13237
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 : '';
13238
13577
  var nextRawInput = "".concat(previousRawInput).concat(chunk.inputTextDelta);
13239
13578
  toolRawInputByCallId[chunk.toolCallId] = nextRawInput;
@@ -13248,30 +13587,20 @@
13248
13587
  input: parsedInput,
13249
13588
  rawInput: nextRawInput
13250
13589
  });
13251
- if (toolIndex >= 0) {
13252
- var updatedParts4 = _to_consumable_array(currentMessage.parts);
13253
- updatedParts4[toolIndex] = nextToolPart;
13254
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13255
- parts: updatedParts4
13256
- });
13257
- } else {
13258
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13259
- parts: _to_consumable_array(currentMessage.parts).concat([
13260
- nextToolPart
13261
- ])
13262
- });
13263
- }
13264
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13590
+ setPart(toolIndex, nextToolPart);
13265
13591
  break;
13266
13592
  }
13267
13593
  case 'tool-input-available':
13268
13594
  {
13269
13595
  if (!currentMessage) break;
13596
+ if (response.requiredToolCallIds.has(chunk.toolCallId)) break;
13270
13597
  delete toolRawInputByCallId[chunk.toolCallId];
13271
13598
  // Find existing tool part or create new one
13272
- var existingIndex = currentMessage.parts.findIndex(function(p) {
13273
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13274
- });
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
+ }
13275
13604
  var toolPart1 = {
13276
13605
  type: "tool-".concat(chunk.toolName),
13277
13606
  toolCallId: chunk.toolCallId,
@@ -13280,35 +13609,63 @@
13280
13609
  callProviderMetadata: chunk.callProviderMetadata,
13281
13610
  providerExecuted: chunk.providerExecuted
13282
13611
  };
13283
- if (existingIndex >= 0) {
13284
- var updatedParts5 = _to_consumable_array(currentMessage.parts);
13285
- updatedParts5[existingIndex] = toolPart1;
13286
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13287
- parts: updatedParts5
13288
- });
13289
- } else {
13290
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13291
- parts: _to_consumable_array(currentMessage.parts).concat([
13292
- toolPart1
13293
- ])
13294
- });
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;
13295
13620
  }
13296
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13297
13621
  // Trigger onToolCall callback only for client-executed tools
13298
13622
  // (server-executed tools have providerExecuted: true and don't need client handling)
13299
13623
  if (_this.onToolCall && !chunk.providerExecuted) {
13300
- var result = _this.onToolCall({
13301
- toolCall: {
13302
- toolName: chunk.toolName,
13303
- toolCallId: chunk.toolCallId,
13304
- input: chunk.input,
13305
- dynamic: 'dynamic' in chunk ? chunk.dynamic : undefined
13306
- }
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;
13307
13628
  });
13308
- if (result && typeof result.then === 'function') {
13309
- pendingToolCall = pendingToolCall.then(function() {
13310
- 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));
13311
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);
13312
13669
  }
13313
13670
  }
13314
13671
  break;
@@ -13318,15 +13675,14 @@
13318
13675
  var _ref3, _ref4;
13319
13676
  if (!currentMessage) break;
13320
13677
  var _chunk_data = chunk.data, toolCallId = _chunk_data.toolCallId, toolName1 = _chunk_data.toolName, delta = _chunk_data.delta;
13321
- var toolIndex1 = currentMessage.parts.findIndex(function(p) {
13322
- return 'toolCallId' in p && p.toolCallId === toolCallId;
13323
- });
13324
- var existingPart1 = toolIndex1 >= 0 ? currentMessage.parts[toolIndex1] : null;
13325
- 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 : '';
13326
13682
  var nextRawOutput = "".concat(previousRawOutput).concat(delta);
13327
13683
  toolRawOutputByCallId[toolCallId] = nextRawOutput;
13328
- var parsedOutput = parseToolInputDelta(nextRawOutput, existingPart1 === null || existingPart1 === void 0 ? void 0 : existingPart1.output);
13329
- 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 : {
13330
13686
  type: "tool-".concat(toolName1),
13331
13687
  toolCallId: toolCallId,
13332
13688
  input: undefined
@@ -13336,47 +13692,34 @@
13336
13692
  rawOutput: nextRawOutput,
13337
13693
  preliminary: true
13338
13694
  });
13339
- if (toolIndex1 >= 0) {
13340
- var updatedParts6 = _to_consumable_array(currentMessage.parts);
13341
- updatedParts6[toolIndex1] = nextToolPart1;
13342
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13343
- parts: updatedParts6
13344
- });
13345
- } else {
13346
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13347
- parts: _to_consumable_array(currentMessage.parts).concat([
13348
- nextToolPart1
13349
- ])
13350
- });
13351
- }
13352
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13695
+ setPart(toolIndex1, nextToolPart1);
13353
13696
  break;
13354
13697
  }
13355
13698
  case 'tool-output-available':
13356
13699
  {
13357
13700
  if (!currentMessage) break;
13358
- var toolIndex2 = currentMessage.parts.findIndex(function(p) {
13359
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13360
- });
13701
+ var toolIndex2 = findToolPart(chunk.toolCallId);
13361
13702
  if (toolIndex2 >= 0) {
13362
13703
  delete toolRawInputByCallId[chunk.toolCallId];
13363
13704
  delete toolRawOutputByCallId[chunk.toolCallId];
13364
- var updatedParts7 = _to_consumable_array(currentMessage.parts);
13365
- 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
+ }
13366
13710
  // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
13367
- var _ignored = existingPart2.rawOutput, rest = _object_without_properties(existingPart2, [
13711
+ var _ignored = existingPart3.rawOutput, rest = _object_without_properties(existingPart3, [
13368
13712
  "rawOutput"
13369
13713
  ]);
13370
- updatedParts7[toolIndex2] = _object_spread_props(_object_spread({}, rest), {
13714
+ setPart(toolIndex2, _object_spread_props(_object_spread({}, rest), {
13371
13715
  state: 'output-available',
13372
13716
  output: chunk.output,
13373
13717
  callProviderMetadata: chunk.callProviderMetadata,
13374
13718
  preliminary: chunk.preliminary
13375
- });
13376
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13377
- parts: updatedParts7
13378
- });
13379
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13719
+ }));
13720
+ if (!chunk.preliminary) {
13721
+ acceptServerToolResult(chunk.toolCallId);
13722
+ }
13380
13723
  }
13381
13724
  break;
13382
13725
  }
@@ -13384,13 +13727,15 @@
13384
13727
  {
13385
13728
  var _chunk_input, _chunk_providerExecuted, _chunk_providerMetadata;
13386
13729
  if (!currentMessage) break;
13730
+ if (response.resolvedToolCallIds.has(chunk.toolCallId)) {
13731
+ mergeCallProviderMetadata(chunk.toolCallId, chunk.providerMetadata);
13732
+ break;
13733
+ }
13387
13734
  delete toolRawInputByCallId[chunk.toolCallId];
13388
13735
  delete toolRawOutputByCallId[chunk.toolCallId];
13389
- var toolIndex3 = currentMessage.parts.findIndex(function(p) {
13390
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13391
- });
13392
- var existingPart3 = toolIndex3 >= 0 ? currentMessage.parts[toolIndex3] : null;
13393
- 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, [
13394
13739
  "output",
13395
13740
  "rawOutput",
13396
13741
  "preliminary"
@@ -13405,49 +13750,35 @@
13405
13750
  providerExecuted: (_chunk_providerExecuted = chunk.providerExecuted) !== null && _chunk_providerExecuted !== void 0 ? _chunk_providerExecuted : carryOver.providerExecuted,
13406
13751
  callProviderMetadata: (_chunk_providerMetadata = chunk.providerMetadata) !== null && _chunk_providerMetadata !== void 0 ? _chunk_providerMetadata : carryOver.callProviderMetadata
13407
13752
  });
13408
- if (toolIndex3 >= 0) {
13409
- var updatedParts8 = _to_consumable_array(currentMessage.parts);
13410
- updatedParts8[toolIndex3] = nextToolPart2;
13411
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13412
- parts: updatedParts8
13413
- });
13414
- } else {
13415
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13416
- parts: _to_consumable_array(currentMessage.parts).concat([
13417
- nextToolPart2
13418
- ])
13419
- });
13420
- }
13421
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13753
+ setPart(toolIndex3, nextToolPart2);
13754
+ acceptServerToolResult(chunk.toolCallId);
13422
13755
  break;
13423
13756
  }
13424
13757
  case 'tool-output-error':
13425
13758
  {
13426
13759
  var _chunk_providerExecuted1, _chunk_providerMetadata1;
13427
13760
  if (!currentMessage) break;
13428
- var toolIndex4 = currentMessage.parts.findIndex(function(p) {
13429
- return 'toolCallId' in p && p.toolCallId === chunk.toolCallId;
13430
- });
13761
+ if (response.resolvedToolCallIds.has(chunk.toolCallId)) {
13762
+ mergeCallProviderMetadata(chunk.toolCallId, chunk.providerMetadata);
13763
+ break;
13764
+ }
13765
+ var toolIndex4 = findToolPart(chunk.toolCallId);
13431
13766
  if (toolIndex4 < 0) break;
13432
13767
  delete toolRawInputByCallId[chunk.toolCallId];
13433
13768
  delete toolRawOutputByCallId[chunk.toolCallId];
13434
- var updatedParts9 = _to_consumable_array(currentMessage.parts);
13435
- var existingPart4 = updatedParts9[toolIndex4];
13436
- 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, [
13437
13771
  "rawOutput",
13438
13772
  "preliminary",
13439
13773
  "output"
13440
13774
  ]);
13441
- updatedParts9[toolIndex4] = _object_spread_props(_object_spread({}, rest1), {
13775
+ setPart(toolIndex4, _object_spread_props(_object_spread({}, rest1), {
13442
13776
  state: 'output-error',
13443
13777
  errorText: chunk.errorText,
13444
13778
  providerExecuted: (_chunk_providerExecuted1 = chunk.providerExecuted) !== null && _chunk_providerExecuted1 !== void 0 ? _chunk_providerExecuted1 : rest1.providerExecuted,
13445
13779
  callProviderMetadata: (_chunk_providerMetadata1 = chunk.providerMetadata) !== null && _chunk_providerMetadata1 !== void 0 ? _chunk_providerMetadata1 : rest1.callProviderMetadata
13446
- });
13447
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13448
- parts: updatedParts9
13449
- });
13450
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13780
+ }));
13781
+ acceptServerToolResult(chunk.toolCallId);
13451
13782
  break;
13452
13783
  }
13453
13784
  case 'source-url':
@@ -13459,12 +13790,7 @@
13459
13790
  url: chunk.url,
13460
13791
  title: chunk.title
13461
13792
  };
13462
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13463
- parts: _to_consumable_array(currentMessage.parts).concat([
13464
- sourcePart
13465
- ])
13466
- });
13467
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13793
+ setPart(-1, sourcePart);
13468
13794
  break;
13469
13795
  }
13470
13796
  case 'source-document':
@@ -13478,12 +13804,7 @@
13478
13804
  filename: chunk.filename,
13479
13805
  providerMetadata: chunk.providerMetadata
13480
13806
  };
13481
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13482
- parts: _to_consumable_array(currentMessage.parts).concat([
13483
- docPart
13484
- ])
13485
- });
13486
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13807
+ setPart(-1, docPart);
13487
13808
  break;
13488
13809
  }
13489
13810
  case 'file':
@@ -13494,26 +13815,15 @@
13494
13815
  url: chunk.url,
13495
13816
  mediaType: chunk.mediaType
13496
13817
  };
13497
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13498
- parts: _to_consumable_array(currentMessage.parts).concat([
13499
- filePart
13500
- ])
13501
- });
13502
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13818
+ setPart(-1, filePart);
13503
13819
  break;
13504
13820
  }
13505
13821
  case 'start-step':
13506
13822
  {
13507
13823
  if (!currentMessage) break;
13508
- var stepPart = {
13824
+ setPart(-1, {
13509
13825
  type: 'step-start'
13510
- };
13511
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13512
- parts: _to_consumable_array(currentMessage.parts).concat([
13513
- stepPart
13514
- ])
13515
13826
  });
13516
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13517
13827
  break;
13518
13828
  }
13519
13829
  case 'message-metadata':
@@ -13522,7 +13832,7 @@
13522
13832
  currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13523
13833
  metadata: chunk.messageMetadata
13524
13834
  });
13525
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13835
+ currentMessage = _this.replaceMessage(currentMessageIndex, currentMessage, response);
13526
13836
  break;
13527
13837
  }
13528
13838
  case 'error':
@@ -13542,7 +13852,7 @@
13542
13852
  currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13543
13853
  metadata: chunk.messageMetadata
13544
13854
  });
13545
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13855
+ currentMessage = _this.replaceMessage(currentMessageIndex, currentMessage, response);
13546
13856
  }
13547
13857
  break;
13548
13858
  }
@@ -13568,14 +13878,13 @@
13568
13878
  ]
13569
13879
  };
13570
13880
  if (currentMessageIndex >= 0) {
13571
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13881
+ currentMessage = _this.replaceMessage(currentMessageIndex, currentMessage, response);
13572
13882
  } else {
13573
13883
  _this.state.pushMessage(currentMessage);
13574
- currentMessageIndex = _this.state.messages.length - 1;
13884
+ currentMessageIndex = _this.messages.length - 1;
13885
+ _this.responseByMessage.set(currentMessage, response);
13575
13886
  }
13576
13887
  currentMessageId = currentMessage.id;
13577
- currentTextPartId = undefined;
13578
- currentReasoningPartId = undefined;
13579
13888
  break;
13580
13889
  }
13581
13890
  default:
@@ -13588,12 +13897,7 @@
13588
13897
  id: chunk.id,
13589
13898
  data: chunk.data
13590
13899
  };
13591
- currentMessage = _object_spread_props(_object_spread({}, currentMessage), {
13592
- parts: _to_consumable_array(currentMessage.parts).concat([
13593
- dataPart
13594
- ])
13595
- });
13596
- _this.state.replaceMessage(currentMessageIndex, currentMessage);
13900
+ setPart(-1, dataPart);
13597
13901
  // Trigger onData callback
13598
13902
  if (_this.onData) {
13599
13903
  _this.onData(dataPart);
@@ -13602,49 +13906,11 @@
13602
13906
  }
13603
13907
  }
13604
13908
  }, function() {
13605
- // Wait for any pending tool calls to complete
13606
- pendingToolCall.then(function() {
13607
- // Stream finished successfully
13608
- _this.setStatus({
13609
- status: 'ready'
13610
- });
13611
- _this.activeResponse = null;
13612
- // Trigger onFinish callback
13613
- if (_this.onFinish && currentMessage) {
13614
- _this.onFinish({
13615
- message: currentMessage,
13616
- messages: _this.state.messages,
13617
- isAbort: isAbort,
13618
- isDisconnect: isDisconnect,
13619
- isError: isError
13620
- });
13621
- }
13622
- // Note: sendAutomaticallyWhen is only checked in addToolResult,
13623
- // not here. For server-executed tools, the server continues the
13624
- // conversation. For client-executed tools, addToolResult handles it.
13625
- resolve();
13909
+ return Promise.all(response.returnedToolCallbacks).then(function() {
13910
+ return finish();
13626
13911
  });
13627
13912
  }, function(error) {
13628
- if (error.name === 'AbortError') {
13629
- isAbort = true;
13630
- _this.setStatus({
13631
- status: 'ready'
13632
- });
13633
- } else {
13634
- isDisconnect = true;
13635
- _this.handleError(error);
13636
- }
13637
- // Still call onFinish even on error/abort
13638
- if (_this.onFinish && currentMessage) {
13639
- _this.onFinish({
13640
- message: currentMessage,
13641
- messages: _this.state.messages,
13642
- isAbort: isAbort,
13643
- isDisconnect: isDisconnect,
13644
- isError: isError
13645
- });
13646
- }
13647
- resolve();
13913
+ return finish(error);
13648
13914
  });
13649
13915
  });
13650
13916
  }
@@ -13652,10 +13918,13 @@
13652
13918
  {
13653
13919
  key: "handleError",
13654
13920
  value: function handleError(error) {
13655
- this.setStatus({
13656
- status: 'error',
13657
- error: error
13658
- });
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
+ }
13659
13928
  if (this.onError) {
13660
13929
  this.onError(error);
13661
13930
  }
@@ -14143,14 +14412,16 @@
14143
14412
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
14144
14413
  checkRendering(renderFn, withUsage$o());
14145
14414
  return function(widgetParams) {
14146
- var _ref = widgetParams || {}, _ref_resume = _ref.resume, resume = _ref_resume === void 0 ? false : _ref_resume, _ref_tools = _ref.tools, tools = _ref_tools === void 0 ? {} : _ref_tools, _ref_type = _ref.type, type = _ref_type === void 0 ? 'chat' : _ref_type, context = _ref.context, initialUserMessage = _ref.initialUserMessage, initialMessages = _ref.initialMessages, _ref_disableTriggerValidation = _ref.disableTriggerValidation, disableTriggerValidation = _ref_disableTriggerValidation === void 0 ? false : _ref_disableTriggerValidation, options = _object_without_properties(_ref, [
14415
+ var _ref = widgetParams || {}, _ref_resume = _ref.resume, resume = _ref_resume === void 0 ? false : _ref_resume, _ref_tools = _ref.tools, tools = _ref_tools === void 0 ? {} : _ref_tools, _ref_type = _ref.type, type = _ref_type === void 0 ? 'chat' : _ref_type, context = _ref.context, initialUserMessage = _ref.initialUserMessage, initialMessages = _ref.initialMessages, _ref_disableTriggerValidation = _ref.disableTriggerValidation, disableTriggerValidation = _ref_disableTriggerValidation === void 0 ? false : _ref_disableTriggerValidation, _ref_sendAutomaticallyWhen = _ref.sendAutomaticallyWhen, sendAutomaticallyWhen = _ref_sendAutomaticallyWhen === void 0 ? lastAssistantMessageIsCompleteWithToolCalls : _ref_sendAutomaticallyWhen, _ref_requiresSearch = _ref.requiresSearch, requiresSearch = _ref_requiresSearch === void 0 ? true : _ref_requiresSearch, options = _object_without_properties(_ref, [
14147
14416
  "resume",
14148
14417
  "tools",
14149
14418
  "type",
14150
14419
  "context",
14151
14420
  "initialUserMessage",
14152
14421
  "initialMessages",
14153
- "disableTriggerValidation"
14422
+ "disableTriggerValidation",
14423
+ "sendAutomaticallyWhen",
14424
+ "requiresSearch"
14154
14425
  ]);
14155
14426
  var _chatInstance;
14156
14427
  var input = '';
@@ -14311,8 +14582,8 @@
14311
14582
  return options.chat;
14312
14583
  }
14313
14584
  return new Chat(_object_spread_props(_object_spread({}, options), {
14585
+ sendAutomaticallyWhen: sendAutomaticallyWhen,
14314
14586
  transport: transport,
14315
- sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
14316
14587
  shouldRepairToolInput: function shouldRepairToolInput(toolName) {
14317
14588
  var tool = tools[toolName];
14318
14589
  if (!tool && toolName.startsWith("".concat(SearchIndexToolType, "_"))) {
@@ -14321,7 +14592,7 @@
14321
14592
  if (!tool) return true;
14322
14593
  return Boolean(tool.streamInput);
14323
14594
  },
14324
- onToolCall: function onToolCall(param) {
14595
+ onToolCall: function onToolCall(param, submitToolResult) {
14325
14596
  var toolCall = param.toolCall;
14326
14597
  var tool = tools[toolCall.toolName];
14327
14598
  // Compatibility shim with Algolia MCP Server search tool
@@ -14329,7 +14600,7 @@
14329
14600
  tool = tools[SearchIndexToolType];
14330
14601
  }
14331
14602
  if (!tool) {
14332
- return _chatInstance.addToolResult({
14603
+ return submitToolResult({
14333
14604
  output: 'No tool implemented for "'.concat(toolCall.toolName, '".'),
14334
14605
  tool: toolCall.toolName,
14335
14606
  toolCallId: toolCall.toolCallId
@@ -14338,7 +14609,7 @@
14338
14609
  if (tool.onToolCall) {
14339
14610
  var addToolResult = function addToolResult(param) {
14340
14611
  var output = param.output;
14341
- return _chatInstance.addToolResult({
14612
+ return submitToolResult({
14342
14613
  output: output,
14343
14614
  tool: toolCall.toolName,
14344
14615
  toolCallId: toolCall.toolCallId
@@ -14354,6 +14625,7 @@
14354
14625
  };
14355
14626
  return {
14356
14627
  $$type: 'ais.chat',
14628
+ dependsOn: requiresSearch ? 'search' : 'none',
14357
14629
  init: function init(initOptions) {
14358
14630
  var _this = this;
14359
14631
  var instantSearchInstance = initOptions.instantSearchInstance;
@@ -14459,6 +14731,7 @@
14459
14731
  var _param = _sliced_to_array(param, 2), key = _param[0], tool = _param[1];
14460
14732
  var toolWithAddToolResult = _object_spread_props(_object_spread({}, tool), {
14461
14733
  addToolResult: _chatInstance.addToolResult,
14734
+ '~addToolResultForMessage': _chatInstance['~addToolResultForMessage'],
14462
14735
  applyFilters: applyFilters,
14463
14736
  sendEvent: sendEvent
14464
14737
  });
@@ -14566,6 +14839,7 @@
14566
14839
  return {
14567
14840
  $$type: 'ais.chatTrigger',
14568
14841
  opensChat: true,
14842
+ dependsOn: 'none',
14569
14843
  init: function init(initOptions) {
14570
14844
  lastOptions = initOptions;
14571
14845
  renderFn(_object_spread_props(_object_spread({}, this.getWidgetRenderState(initOptions)), {
@@ -14594,6 +14868,9 @@
14594
14868
  return _object_spread_props(_object_spread({}, renderState), {
14595
14869
  chatTrigger: this.getWidgetRenderState(renderOptions)
14596
14870
  });
14871
+ },
14872
+ shouldRender: function shouldRender() {
14873
+ return true;
14597
14874
  }
14598
14875
  };
14599
14876
  };
@@ -18534,6 +18811,8 @@
18534
18811
  // later during hydration.
18535
18812
  var requestParamsList;
18536
18813
  var client = helper.getClient();
18814
+ var waitsForSearch = search._hasSearchWidget;
18815
+ var waitsForRecommend = !skipRecommend && search._hasRecommendWidget;
18537
18816
  if (search.compositionID) {
18538
18817
  helper.setClient(_object_spread_props(_object_spread({}, client), {
18539
18818
  search: function search(query) {
@@ -18554,17 +18833,22 @@
18554
18833
  }
18555
18834
  }));
18556
18835
  }
18557
- if (search._hasSearchWidget) {
18836
+ if (waitsForSearch) {
18558
18837
  if (search.compositionID) {
18559
18838
  helper.searchWithComposition();
18560
18839
  } else {
18561
18840
  helper.searchOnlyWithDerivedHelpers();
18562
18841
  }
18563
18842
  }
18564
- !skipRecommend && search._hasRecommendWidget && helper.recommend();
18843
+ if (waitsForRecommend) {
18844
+ helper.recommend();
18845
+ }
18846
+ if (!waitsForSearch && !waitsForRecommend) {
18847
+ return Promise.resolve([]);
18848
+ }
18565
18849
  return new Promise(function(resolve, reject) {
18566
- var searchResultsReceived = !search._hasSearchWidget;
18567
- var recommendResultsReceived = !search._hasRecommendWidget || skipRecommend;
18850
+ var searchResultsReceived = !waitsForSearch;
18851
+ var recommendResultsReceived = !waitsForRecommend;
18568
18852
  // All derived helpers resolve in the same tick so we're safe only relying
18569
18853
  // on the first one.
18570
18854
  helper.derivedHelpers[0].on('result', function() {
@@ -18604,6 +18888,13 @@
18604
18888
  var requestParamsIndex = 0;
18605
18889
  walkIndex(rootIndex, function(widget) {
18606
18890
  var _widget_getHelper;
18891
+ var currentIndex = widget;
18892
+ while(currentIndex){
18893
+ if (currentIndex._isolated) {
18894
+ return;
18895
+ }
18896
+ currentIndex = currentIndex.getParent();
18897
+ }
18607
18898
  var searchResults = widget.getResults();
18608
18899
  var recommendResults = (_widget_getHelper = widget.getHelper()) === null || _widget_getHelper === void 0 ? void 0 : _widget_getHelper.lastRecommendResults;
18609
18900
  if (searchResults || recommendResults) {
@@ -18634,7 +18925,7 @@
18634
18925
  });
18635
18926
  }
18636
18927
  });
18637
- if (Object.keys(initialResults).length === 0) {
18928
+ if (Object.keys(initialResults).length === 0 && (requestParamsList === null || requestParamsList === void 0 ? void 0 : requestParamsList.length) !== 0) {
18638
18929
  throw new Error('The root index does not have any results. Make sure you have at least one widget that provides results.');
18639
18930
  }
18640
18931
  return initialResults;
@@ -18669,6 +18960,13 @@
18669
18960
  var shouldRefetch = false;
18670
18961
  // Two-pass widgets require another query to discover and mount child widgets.
18671
18962
  walkIndex(searchRef.current.mainIndex, function(index) {
18963
+ var current = index;
18964
+ while(current){
18965
+ if (current._isolated) {
18966
+ return;
18967
+ }
18968
+ current = current.getParent();
18969
+ }
18672
18970
  shouldRefetch = shouldRefetch || index.getWidgets().some(isTwoPassWidget);
18673
18971
  });
18674
18972
  if (shouldRefetch) {