react-instantsearch 7.41.0 → 7.43.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 7.41.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
1
+ /*! React InstantSearch 7.43.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.41.0';
27
+ var version$2 = '7.43.0';
28
28
 
29
29
  function _define_property(obj, key, value) {
30
30
  if (key in obj) {
@@ -3919,7 +3919,7 @@
3919
3919
  function requireVersion() {
3920
3920
  if (hasRequiredVersion) return version$1;
3921
3921
  hasRequiredVersion = 1;
3922
- version$1 = '3.29.2';
3922
+ version$1 = '3.29.3';
3923
3923
  return version$1;
3924
3924
  }
3925
3925
 
@@ -5980,7 +5980,7 @@
5980
5980
  }
5981
5981
  }
5982
5982
 
5983
- var withUsage$v = createDocumentationMessageGenerator({
5983
+ var withUsage$x = createDocumentationMessageGenerator({
5984
5984
  name: 'configure',
5985
5985
  connector: true
5986
5986
  });
@@ -5996,7 +5996,7 @@
5996
5996
  var renderFn = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : noop, unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
5997
5997
  return function(widgetParams) {
5998
5998
  if (!widgetParams || !isPlainObject(widgetParams.searchParameters)) {
5999
- throw new Error(withUsage$v('The `searchParameters` option expects an object.'));
5999
+ throw new Error(withUsage$x('The `searchParameters` option expects an object.'));
6000
6000
  }
6001
6001
  var connectorState = {};
6002
6002
  function refine(helper) {
@@ -6267,6 +6267,45 @@
6267
6267
  return stableValue;
6268
6268
  }
6269
6269
 
6270
+ /**
6271
+ * Forwards the insights-related search parameters to every Recommend query.
6272
+ *
6273
+ * The insights middleware writes `userToken` and `clickAnalytics` on the main
6274
+ * helper's search state, which only feeds search queries: Recommend queries are
6275
+ * built from their own parameters and never read the search state. Without this,
6276
+ * recommendations can't be personalized, and their responses carry no `queryID`
6277
+ * for the connectors to attribute click and conversion events with.
6278
+ *
6279
+ * Parameters set on a widget win, so an explicit `queryParameters.userToken`
6280
+ * keeps overriding the middleware.
6281
+ *
6282
+ * The fallback query is a regular search, so it gets the same treatment — but
6283
+ * only merged into a `fallbackParameters` the widget already set. See below.
6284
+ */ function addInsightsToRecommendParameters(recommendParameters, param) {
6285
+ var userToken = param.userToken, clickAnalytics = param.clickAnalytics;
6286
+ if (userToken === undefined && clickAnalytics === undefined) {
6287
+ return recommendParameters;
6288
+ }
6289
+ var insightsParameters = _object_spread({}, clickAnalytics === undefined ? {} : {
6290
+ clickAnalytics: clickAnalytics
6291
+ }, userToken === undefined ? {} : {
6292
+ userToken: userToken
6293
+ });
6294
+ return new algoliasearchHelper.RecommendParameters({
6295
+ params: recommendParameters.params.map(function(params) {
6296
+ // v4 `TrendingFacetsQuery` doesn't include `queryParameters` or
6297
+ // `fallbackParameters`, but the v5 API and the helper support them, like
6298
+ // `connectTrendingFacets` does.
6299
+ var queryParameters = params.queryParameters, fallbackParameters = params.fallbackParameters;
6300
+ return _object_spread(_object_spread_props(_object_spread({}, params), {
6301
+ queryParameters: _object_spread({}, insightsParameters, queryParameters)
6302
+ }), fallbackParameters && {
6303
+ fallbackParameters: _object_spread({}, insightsParameters, fallbackParameters)
6304
+ });
6305
+ })
6306
+ });
6307
+ }
6308
+
6270
6309
  var id$1 = 0;
6271
6310
  function addWidgetId(widget) {
6272
6311
  if (widget.dependsOn !== 'recommend') {
@@ -7763,13 +7802,13 @@
7763
7802
  return null;
7764
7803
  }
7765
7804
 
7766
- var withUsage$u = createDocumentationMessageGenerator({
7805
+ var withUsage$w = createDocumentationMessageGenerator({
7767
7806
  name: 'dynamic-widgets',
7768
7807
  connector: true
7769
7808
  });
7770
7809
  var connectDynamicWidgets = function connectDynamicWidgets(renderFn) {
7771
7810
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
7772
- checkRendering(renderFn, withUsage$u());
7811
+ checkRendering(renderFn, withUsage$w());
7773
7812
  return function(widgetParams) {
7774
7813
  var widgets = widgetParams.widgets, _widgetParams_maxValuesPerFacet = widgetParams.maxValuesPerFacet, maxValuesPerFacet = _widgetParams_maxValuesPerFacet === void 0 ? 20 : _widgetParams_maxValuesPerFacet, _widgetParams_facets = widgetParams.facets, facets = _widgetParams_facets === void 0 ? [
7775
7814
  '*'
@@ -7779,10 +7818,10 @@
7779
7818
  if (!(widgets && Array.isArray(widgets) && widgets.every(function(widget) {
7780
7819
  return (typeof widget === "undefined" ? "undefined" : _type_of(widget)) === 'object';
7781
7820
  }))) {
7782
- throw new Error(withUsage$u('The `widgets` option expects an array of widgets.'));
7821
+ throw new Error(withUsage$w('The `widgets` option expects an array of widgets.'));
7783
7822
  }
7784
7823
  if (!Array.isArray(facets)) {
7785
- throw new Error(withUsage$u("The `facets` option only accepts an array of facets, you passed ".concat(JSON.stringify(facets))));
7824
+ throw new Error(withUsage$w("The `facets` option only accepts an array of facets, you passed ".concat(JSON.stringify(facets))));
7786
7825
  }
7787
7826
  var localWidgets = new Map();
7788
7827
  return {
@@ -7884,7 +7923,7 @@
7884
7923
  results: results
7885
7924
  });
7886
7925
  if (!Array.isArray(attributesToRender)) {
7887
- throw new Error(withUsage$u('The `transformItems` option expects a function that returns an Array.'));
7926
+ throw new Error(withUsage$w('The `transformItems` option expects a function that returns an Array.'));
7888
7927
  }
7889
7928
  return {
7890
7929
  attributesToRender: attributesToRender,
@@ -8205,19 +8244,19 @@
8205
8244
  return toFeedSearchResults(lastResults._state, raw);
8206
8245
  });
8207
8246
  }
8208
- var withUsage$t = createDocumentationMessageGenerator({
8247
+ var withUsage$v = createDocumentationMessageGenerator({
8209
8248
  name: 'feeds',
8210
8249
  connector: true
8211
8250
  });
8212
8251
  var connectFeeds = function connectFeeds(renderFn) {
8213
8252
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
8214
- checkRendering(renderFn, withUsage$t());
8253
+ checkRendering(renderFn, withUsage$v());
8215
8254
  return function(widgetParams) {
8216
8255
  var isolated = widgetParams.isolated, _widgetParams_transformFeeds = widgetParams.transformFeeds, transformFeeds = _widgetParams_transformFeeds === void 0 ? function(feeds) {
8217
8256
  return feeds;
8218
8257
  } : _widgetParams_transformFeeds;
8219
8258
  if (isolated !== false) {
8220
- throw new Error(withUsage$t('The `isolated` option currently only supports `false`.'));
8259
+ throw new Error(withUsage$v('The `isolated` option currently only supports `false`.'));
8221
8260
  }
8222
8261
  return {
8223
8262
  $$type: 'ais.feeds',
@@ -8225,7 +8264,7 @@
8225
8264
  init: function init(initOptions) {
8226
8265
  var instantSearchInstance = initOptions.instantSearchInstance;
8227
8266
  if (!instantSearchInstance.compositionID) {
8228
- throw new Error(withUsage$t('The `feeds` widget requires a composition-based InstantSearch instance (compositionID must be set).'));
8267
+ throw new Error(withUsage$v('The `feeds` widget requires a composition-based InstantSearch instance (compositionID must be set).'));
8229
8268
  }
8230
8269
  hydrateFeedsFromInitialResultsIfNeeded(instantSearchInstance, initOptions.parent);
8231
8270
  renderFn(_object_spread_props(_object_spread({}, this.getWidgetRenderState(initOptions)), {
@@ -8271,12 +8310,12 @@
8271
8310
  ];
8272
8311
  feedIDs = transformFeeds(feedIDs);
8273
8312
  if (!Array.isArray(feedIDs)) {
8274
- throw new Error(withUsage$t('The `transformFeeds` option expects a function that returns an Array.'));
8313
+ throw new Error(withUsage$v('The `transformFeeds` option expects a function that returns an Array.'));
8275
8314
  }
8276
8315
  if (!feedIDs.every(function(feedID) {
8277
8316
  return typeof feedID === 'string';
8278
8317
  })) {
8279
- throw new Error(withUsage$t('The `transformFeeds` option expects a function that returns an array of feed IDs (strings).'));
8318
+ throw new Error(withUsage$v('The `transformFeeds` option expects a function that returns an array of feed IDs (strings).'));
8280
8319
  }
8281
8320
  return {
8282
8321
  feedIDs: feedIDs,
@@ -8387,7 +8426,7 @@
8387
8426
  }));
8388
8427
  }
8389
8428
 
8390
- var withUsage$s = createDocumentationMessageGenerator({
8429
+ var withUsage$u = createDocumentationMessageGenerator({
8391
8430
  name: 'index-widget'
8392
8431
  });
8393
8432
  /**
@@ -8515,7 +8554,7 @@
8515
8554
  var index = function index(widgetParams) {
8516
8555
  var _widgetParams_EXPERIMENTAL_isolated;
8517
8556
  if (widgetParams === undefined || widgetParams.indexName === undefined && !widgetParams.isolated && !widgetParams.EXPERIMENTAL_isolated) {
8518
- throw new Error(withUsage$s('The `indexName` option is required.'));
8557
+ throw new Error(withUsage$u('The `indexName` option is required.'));
8519
8558
  }
8520
8559
  // When isolated=true, we use an empty string as the default indexName.
8521
8560
  // This is intentional: isolated indices do not require a real index name.
@@ -8608,7 +8647,7 @@
8608
8647
  addWidgets: function addWidgets(widgets) {
8609
8648
  var _this = this;
8610
8649
  if (!Array.isArray(widgets)) {
8611
- throw new Error(withUsage$s('The `addWidgets` method expects an array of widgets.'));
8650
+ throw new Error(withUsage$u('The `addWidgets` method expects an array of widgets.'));
8612
8651
  }
8613
8652
  var flatWidgets = widgets.reduce(function(acc, w) {
8614
8653
  return acc.concat(Array.isArray(w) ? w : [
@@ -8618,7 +8657,7 @@
8618
8657
  if (flatWidgets.some(function(widget) {
8619
8658
  return typeof widget.init !== 'function' && typeof widget.render !== 'function';
8620
8659
  })) {
8621
- throw new Error(withUsage$s('The widget definition expects a `render` and/or an `init` method.'));
8660
+ throw new Error(withUsage$u('The widget definition expects a `render` and/or an `init` method.'));
8622
8661
  }
8623
8662
  flatWidgets.forEach(function(widget) {
8624
8663
  widget.parent = _this;
@@ -8669,7 +8708,7 @@
8669
8708
  removeWidgets: function removeWidgets(widgets) {
8670
8709
  var _this = this;
8671
8710
  if (!Array.isArray(widgets)) {
8672
- throw new Error(withUsage$s('The `removeWidgets` method expects an array of widgets.'));
8711
+ throw new Error(withUsage$u('The `removeWidgets` method expects an array of widgets.'));
8673
8712
  }
8674
8713
  var flatWidgets = widgets.reduce(function(acc, w) {
8675
8714
  return acc.concat(Array.isArray(w) ? w : [
@@ -8679,7 +8718,7 @@
8679
8718
  if (flatWidgets.some(function(widget) {
8680
8719
  return typeof widget.dispose !== 'function';
8681
8720
  })) {
8682
- throw new Error(withUsage$s('The widget definition expects a `dispose` method.'));
8721
+ throw new Error(withUsage$u('The widget definition expects a `dispose` method.'));
8683
8722
  }
8684
8723
  localWidgets = localWidgets.filter(function(widget) {
8685
8724
  return flatWidgets.indexOf(widget) === -1;
@@ -8807,7 +8846,7 @@
8807
8846
  mainHelper.state
8808
8847
  ].concat(_to_consumable_array(resolveSearchParameters(_this))));
8809
8848
  }, function() {
8810
- return _this.getHelper().recommendState;
8849
+ return addInsightsToRecommendParameters(_this.getHelper().recommendState, mainHelper.state);
8811
8850
  });
8812
8851
  var indexInitialResults = (_instantSearchInstance__initialResults = instantSearchInstance._initialResults) === null || _instantSearchInstance__initialResults === void 0 ? void 0 : _instantSearchInstance__initialResults[this.getIndexId()];
8813
8852
  if (indexInitialResults === null || indexInitialResults === void 0 ? void 0 : indexInitialResults.results) {
@@ -9184,7 +9223,7 @@
9184
9223
  });
9185
9224
  }
9186
9225
 
9187
- var version = '4.108.0';
9226
+ var version = '4.110.0';
9188
9227
 
9189
9228
  var ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';
9190
9229
  function getCookie(name) {
@@ -9414,7 +9453,8 @@
9414
9453
  helper.overrideStateWithoutTriggeringChangeEvent(_object_spread_props(_object_spread({}, helper.state), {
9415
9454
  userToken: normalizedUserToken
9416
9455
  }));
9417
- if (existingToken && existingToken !== userToken) {
9456
+ if (existingToken && existingToken !== normalizedUserToken) {
9457
+ helper._recommendCache = {};
9418
9458
  instantSearchInstance.scheduleSearch();
9419
9459
  }
9420
9460
  }
@@ -9503,14 +9543,17 @@
9503
9543
  } else if (event.insightsMethod) {
9504
9544
  if (event.insightsMethod === 'viewedObjectIDs') {
9505
9545
  var payload = event.payload;
9546
+ var getViewEventKey = function getViewEventKey(objectID) {
9547
+ return payload.queryID ? "".concat(payload.queryID, ":").concat(objectID) : objectID;
9548
+ };
9506
9549
  var difference = payload.objectIDs.filter(function(objectID) {
9507
- return !viewedObjectIDs.has(objectID);
9550
+ return !viewedObjectIDs.has(getViewEventKey(objectID));
9508
9551
  });
9509
9552
  if (difference.length === 0) {
9510
9553
  return;
9511
9554
  }
9512
9555
  difference.forEach(function(objectID) {
9513
- return viewedObjectIDs.add(objectID);
9556
+ return viewedObjectIDs.add(getViewEventKey(objectID));
9514
9557
  });
9515
9558
  payload.objectIDs = difference;
9516
9559
  }
@@ -9618,10 +9661,10 @@
9618
9661
  * and the ability to set credentials via extra parameters when sending events.
9619
9662
  */ function isModernInsightsClient(client) {
9620
9663
  var _split_map = _sliced_to_array((client.version || '').split('.').map(Number), 2), major = _split_map[0], minor = _split_map[1];
9621
- /* eslint-disable instantsearch/naming-convention */ var v3 = major >= 3;
9664
+ /* oxlint-disable instantsearch/naming-convention */ var v3 = major >= 3;
9622
9665
  var v2_6 = major === 2 && minor >= 6;
9623
9666
  var v1_10 = major === 1 && minor >= 10;
9624
- /* eslint-enable instantsearch/naming-convention */ return v3 || v2_6 || v1_10;
9667
+ /* oxlint-enable instantsearch/naming-convention */ return v3 || v2_6 || v1_10;
9625
9668
  }
9626
9669
  /**
9627
9670
  * While `search-insights` supports both string and number user tokens,
@@ -11042,7 +11085,7 @@
11042
11085
  };
11043
11086
  }
11044
11087
 
11045
- var withUsage$r = createDocumentationMessageGenerator({
11088
+ var withUsage$t = createDocumentationMessageGenerator({
11046
11089
  name: 'instantsearch'
11047
11090
  });
11048
11091
  function defaultCreateURL() {
@@ -11105,7 +11148,7 @@
11105
11148
  _this.setMaxListeners(100);
11106
11149
  var _options_indexName = options.indexName, indexName = _options_indexName === void 0 ? '' : _options_indexName, compositionID = options.compositionID, numberLocale = options.numberLocale, _options_initialUiState = options.initialUiState, initialUiState = _options_initialUiState === void 0 ? {} : _options_initialUiState, _options_routing = options.routing, routing = _options_routing === void 0 ? null : _options_routing, _options_insights = options.insights, insights = _options_insights === void 0 ? undefined : _options_insights, searchFunction = options.searchFunction, _options_stalledSearchDelay = options.stalledSearchDelay, stalledSearchDelay = _options_stalledSearchDelay === void 0 ? 200 : _options_stalledSearchDelay, _options_searchClient = options.searchClient, searchClient = _options_searchClient === void 0 ? null : _options_searchClient, _options_insightsClient = options.insightsClient, insightsClient = _options_insightsClient === void 0 ? null : _options_insightsClient, _options_onStateChange = options.onStateChange, onStateChange = _options_onStateChange === void 0 ? null : _options_onStateChange, _options_future1 = options.future, future = _options_future1 === void 0 ? _object_spread({}, INSTANTSEARCH_FUTURE_DEFAULTS, options.future || {}) : _options_future1;
11107
11150
  if (searchClient === null) {
11108
- throw new Error(withUsage$r('The `searchClient` option is required.'));
11151
+ throw new Error(withUsage$t('The `searchClient` option is required.'));
11109
11152
  }
11110
11153
  if (typeof searchClient.search !== 'function') {
11111
11154
  throw new Error("The `searchClient` must implement a `search` method.\n\nSee: https://www.algolia.com/doc/guides/building-search-ui/going-further/backend-search/in-depth/backend-instantsearch/js/");
@@ -11114,7 +11157,7 @@
11114
11157
  searchClient.addAlgoliaAgent("instantsearch.js (".concat(version, ")"));
11115
11158
  }
11116
11159
  if (insightsClient && typeof insightsClient !== 'function') {
11117
- throw new Error(withUsage$r('The `insightsClient` option should be a function.'));
11160
+ throw new Error(withUsage$t('The `insightsClient` option should be a function.'));
11118
11161
  }
11119
11162
  _this._initialOptions = options;
11120
11163
  _this.client = searchClient;
@@ -11263,12 +11306,12 @@
11263
11306
  * @param widgets The array of widgets to add to InstantSearch.
11264
11307
  */ function addWidgets(widgets) {
11265
11308
  if (!Array.isArray(widgets)) {
11266
- throw new Error(withUsage$r('The `addWidgets` method expects an array of widgets. Please use `addWidget`.'));
11309
+ throw new Error(withUsage$t('The `addWidgets` method expects an array of widgets. Please use `addWidget`.'));
11267
11310
  }
11268
11311
  if (this.compositionID && widgets.some(function(w) {
11269
11312
  return !Array.isArray(w) && isIndexWidget(w) && !w._isolated;
11270
11313
  })) {
11271
- throw new Error(withUsage$r('The `index` widget cannot be used with a composition-based InstantSearch implementation.'));
11314
+ throw new Error(withUsage$t('The `index` widget cannot be used with a composition-based InstantSearch implementation.'));
11272
11315
  }
11273
11316
  this.mainIndex.addWidgets(widgets);
11274
11317
  return this;
@@ -11297,7 +11340,7 @@
11297
11340
  * The widgets must implement a `dispose()` method to clear their states.
11298
11341
  */ function removeWidgets(widgets) {
11299
11342
  if (!Array.isArray(widgets)) {
11300
- throw new Error(withUsage$r('The `removeWidgets` method expects an array of widgets. Please use `removeWidget`.'));
11343
+ throw new Error(withUsage$t('The `removeWidgets` method expects an array of widgets. Please use `removeWidget`.'));
11301
11344
  }
11302
11345
  this.mainIndex.removeWidgets(widgets);
11303
11346
  return this;
@@ -11311,7 +11354,7 @@
11311
11354
  */ function start() {
11312
11355
  var _this = this;
11313
11356
  if (this.started) {
11314
- throw new Error(withUsage$r('The `start` method has already been called once.'));
11357
+ throw new Error(withUsage$t('The `start` method has already been called once.'));
11315
11358
  }
11316
11359
  // This Helper is used for the queries, we don't care about its state. The
11317
11360
  // states are managed at the `index` level. We use this Helper to create
@@ -11519,7 +11562,7 @@
11519
11562
  var _this = this;
11520
11563
  var callOnStateChange = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
11521
11564
  if (!this.mainHelper) {
11522
- throw new Error(withUsage$r('The `start` method needs to be called before `setUiState`.'));
11565
+ throw new Error(withUsage$t('The `start` method needs to be called before `setUiState`.'));
11523
11566
  }
11524
11567
  // We refresh the index UI state to update the local UI state that the
11525
11568
  // main index passes to the function form of `setUiState`.
@@ -11556,7 +11599,7 @@
11556
11599
  value: function createURL() {
11557
11600
  var nextState = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
11558
11601
  if (!this.started) {
11559
- throw new Error(withUsage$r('The `start` method needs to be called before `createURL`.'));
11602
+ throw new Error(withUsage$t('The `start` method needs to be called before `createURL`.'));
11560
11603
  }
11561
11604
  return this._createURL(nextState);
11562
11605
  }
@@ -11565,7 +11608,7 @@
11565
11608
  key: "refresh",
11566
11609
  value: function refresh() {
11567
11610
  if (!this.mainHelper) {
11568
- throw new Error(withUsage$r('The `start` method needs to be called before `refresh`.'));
11611
+ throw new Error(withUsage$t('The `start` method needs to be called before `refresh`.'));
11569
11612
  }
11570
11613
  this.mainHelper.clearCache().search();
11571
11614
  }
@@ -12057,6 +12100,10 @@
12057
12100
  var ssrSearchRef = React.useRef(null);
12058
12101
  // This is used to re-map the result index to the requesting widget
12059
12102
  var recommendIdx = React.useRef(0);
12103
+ var hydrationCompleteRef = React.useRef(false);
12104
+ React.useEffect(function() {
12105
+ hydrationCompleteRef.current = true;
12106
+ }, []);
12060
12107
  // When <DynamicWidgets> is mounted, a second provider is used above the user-land
12061
12108
  // <InstantSearchSSRProvider> in `getServerState()`.
12062
12109
  // To avoid the user's provider overriding the context value with an empty object,
@@ -12064,21 +12111,23 @@
12064
12111
  if (Object.keys(props).length === 0) {
12065
12112
  return /*#__PURE__*/ React.createElement(React.Fragment, null, children);
12066
12113
  }
12114
+ var contextValue = _object_spread_props(_object_spread({}, props), {
12115
+ ssrSearchRef: ssrSearchRef,
12116
+ recommendIdx: recommendIdx,
12117
+ hydrationCompleteRef: hydrationCompleteRef
12118
+ });
12067
12119
  return /*#__PURE__*/ React.createElement(InstantSearchSSRContext.Provider, {
12068
- value: _object_spread_props(_object_spread({}, props), {
12069
- ssrSearchRef: ssrSearchRef,
12070
- recommendIdx: recommendIdx
12071
- })
12120
+ value: contextValue
12072
12121
  }, children);
12073
12122
  }
12074
12123
 
12075
- var withUsage$q = createDocumentationMessageGenerator({
12124
+ var withUsage$s = createDocumentationMessageGenerator({
12076
12125
  name: 'autocomplete',
12077
12126
  connector: true
12078
12127
  });
12079
12128
  var connectAutocomplete = function connectAutocomplete(renderFn) {
12080
12129
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
12081
- checkRendering(renderFn, withUsage$q());
12130
+ checkRendering(renderFn, withUsage$s());
12082
12131
  return function(widgetParams) {
12083
12132
  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) {
12084
12133
  return indices;
@@ -12191,20 +12240,20 @@
12191
12240
  return useConnector(connectAutocomplete, props, additionalWidgetProperties);
12192
12241
  }
12193
12242
 
12194
- var withUsage$p = createDocumentationMessageGenerator({
12243
+ var withUsage$r = createDocumentationMessageGenerator({
12195
12244
  name: 'breadcrumb',
12196
12245
  connector: true
12197
12246
  });
12198
12247
  var connectBreadcrumb = function connectBreadcrumb(renderFn) {
12199
12248
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
12200
- checkRendering(renderFn, withUsage$p());
12249
+ checkRendering(renderFn, withUsage$r());
12201
12250
  var connectorState = {};
12202
12251
  return function(widgetParams) {
12203
12252
  var _ref = widgetParams || {}, attributes = _ref.attributes, _ref_separator = _ref.separator, separator = _ref_separator === void 0 ? ' > ' : _ref_separator, _ref_rootPath = _ref.rootPath, rootPath = _ref_rootPath === void 0 ? null : _ref_rootPath, _ref_transformItems = _ref.transformItems, transformItems = _ref_transformItems === void 0 ? function(items) {
12204
12253
  return items;
12205
12254
  } : _ref_transformItems;
12206
12255
  if (!attributes || !Array.isArray(attributes) || attributes.length === 0) {
12207
- throw new Error(withUsage$p('The `attributes` option expects an array of strings.'));
12256
+ throw new Error(withUsage$r('The `attributes` option expects an array of strings.'));
12208
12257
  }
12209
12258
  var _attributes = _sliced_to_array(attributes, 1), hierarchicalFacetName = _attributes[0];
12210
12259
  function getRefinedState(state, facetValue) {
@@ -12350,6 +12399,76 @@
12350
12399
  return useConnector(connectBreadcrumb, props, additionalWidgetProperties);
12351
12400
  }
12352
12401
 
12402
+ var tryParseJson = function tryParseJson(value) {
12403
+ try {
12404
+ return JSON.parse(value);
12405
+ } catch (unused) {
12406
+ return undefined;
12407
+ }
12408
+ };
12409
+ var repairPartialJson = function repairPartialJson(value) {
12410
+ var repaired = value.trim();
12411
+ if (!repaired) {
12412
+ return repaired;
12413
+ }
12414
+ var inString = false;
12415
+ var isEscaped = false;
12416
+ var stack = [];
12417
+ for(var index = 0; index < repaired.length; index++){
12418
+ var char = repaired[index];
12419
+ if (inString) {
12420
+ if (isEscaped) {
12421
+ isEscaped = false;
12422
+ } else if (char === '\\') {
12423
+ isEscaped = true;
12424
+ } else if (char === '"') {
12425
+ inString = false;
12426
+ }
12427
+ continue;
12428
+ }
12429
+ if (char === '"') {
12430
+ inString = true;
12431
+ continue;
12432
+ }
12433
+ if (char === '{' || char === '[') {
12434
+ stack.push(char);
12435
+ continue;
12436
+ }
12437
+ if (char === '}' && stack[stack.length - 1] === '{') {
12438
+ stack.pop();
12439
+ continue;
12440
+ }
12441
+ if (char === ']' && stack[stack.length - 1] === '[') {
12442
+ stack.pop();
12443
+ }
12444
+ }
12445
+ if (inString && !isEscaped) {
12446
+ repaired += '"';
12447
+ }
12448
+ repaired = repaired.replace(RegExp(",\\s*$", "u"), '');
12449
+ if (stack.length > 0) {
12450
+ repaired += stack.reverse().map(function(opening) {
12451
+ return opening === '{' ? '}' : ']';
12452
+ }).join('');
12453
+ }
12454
+ return repaired.replace(RegExp(",\\s*([}\\]])", "gu"), '$1');
12455
+ };
12456
+ var parsePartialJson = function parsePartialJson(accumulatedRawJson, fallbackValue) {
12457
+ var normalized = accumulatedRawJson.trim();
12458
+ if (!normalized) {
12459
+ return fallbackValue;
12460
+ }
12461
+ var directParsed = tryParseJson(normalized);
12462
+ if (directParsed !== undefined) {
12463
+ return directParsed;
12464
+ }
12465
+ var repairedParsed = tryParseJson(repairPartialJson(normalized));
12466
+ if (repairedParsed !== undefined) {
12467
+ return repairedParsed;
12468
+ }
12469
+ return fallbackValue;
12470
+ };
12471
+
12353
12472
  /**
12354
12473
  * Stream parser for parsing SSE (Server-Sent Events) streams.
12355
12474
  * The AI SDK 5 format uses SSE with JSON payloads prefixed by "data: ".
@@ -12631,75 +12750,6 @@
12631
12750
  }
12632
12751
 
12633
12752
  var _computedKey$1;
12634
- var tryParseJson = function tryParseJson(value) {
12635
- try {
12636
- return JSON.parse(value);
12637
- } catch (unused) {
12638
- return undefined;
12639
- }
12640
- };
12641
- var repairPartialJson = function repairPartialJson(value) {
12642
- var repaired = value.trim();
12643
- if (!repaired) {
12644
- return repaired;
12645
- }
12646
- var inString = false;
12647
- var isEscaped = false;
12648
- var stack = [];
12649
- for(var index = 0; index < repaired.length; index++){
12650
- var char = repaired[index];
12651
- if (inString) {
12652
- if (isEscaped) {
12653
- isEscaped = false;
12654
- } else if (char === '\\') {
12655
- isEscaped = true;
12656
- } else if (char === '"') {
12657
- inString = false;
12658
- }
12659
- continue;
12660
- }
12661
- if (char === '"') {
12662
- inString = true;
12663
- continue;
12664
- }
12665
- if (char === '{' || char === '[') {
12666
- stack.push(char);
12667
- continue;
12668
- }
12669
- if (char === '}' && stack[stack.length - 1] === '{') {
12670
- stack.pop();
12671
- continue;
12672
- }
12673
- if (char === ']' && stack[stack.length - 1] === '[') {
12674
- stack.pop();
12675
- }
12676
- }
12677
- if (inString && !isEscaped) {
12678
- repaired += '"';
12679
- }
12680
- repaired = repaired.replace(RegExp(",\\s*$", "u"), '');
12681
- if (stack.length > 0) {
12682
- repaired += stack.reverse().map(function(opening) {
12683
- return opening === '{' ? '}' : ']';
12684
- }).join('');
12685
- }
12686
- return repaired.replace(RegExp(",\\s*([}\\]])", "gu"), '$1');
12687
- };
12688
- var parseToolInputDelta = function parseToolInputDelta(accumulatedRawInput, fallbackInput) {
12689
- var normalized = accumulatedRawInput.trim();
12690
- if (!normalized) {
12691
- return fallbackInput;
12692
- }
12693
- var directParsed = tryParseJson(normalized);
12694
- if (directParsed !== undefined) {
12695
- return directParsed;
12696
- }
12697
- var repairedParsed = tryParseJson(repairPartialJson(normalized));
12698
- if (repairedParsed !== undefined) {
12699
- return repairedParsed;
12700
- }
12701
- return fallbackInput;
12702
- };
12703
12753
  var defaultGuardrailFallbackResponse = 'Sorry, we are not able to generate a response at the moment.';
12704
12754
  _computedKey$1 = /** @internal */ '~addToolResultForMessage';
12705
12755
  var _computedKey1$1 = _computedKey$1;
@@ -13533,7 +13583,7 @@
13533
13583
  toolRawInputByCallId[chunk.toolCallId] = nextRawInput;
13534
13584
  var toolName = (_chunk_toolName = chunk.toolName) !== null && _chunk_toolName !== void 0 ? _chunk_toolName : existingPart === null || existingPart === void 0 ? void 0 : (_existingPart_type = existingPart.type) === null || _existingPart_type === void 0 ? void 0 : _existingPart_type.replace('tool-', '');
13535
13585
  var shouldRepair = toolName ? (_ref2 = (_this_shouldRepairToolInput = (_this1 = _this).shouldRepairToolInput) === null || _this_shouldRepairToolInput === void 0 ? void 0 : _this_shouldRepairToolInput.call(_this1, toolName)) !== null && _ref2 !== void 0 ? _ref2 : true : true;
13536
- var parsedInput = shouldRepair ? parseToolInputDelta(nextRawInput, existingPart === null || existingPart === void 0 ? void 0 : existingPart.input) : existingPart === null || existingPart === void 0 ? void 0 : existingPart.input;
13586
+ var parsedInput = shouldRepair ? parsePartialJson(nextRawInput, existingPart === null || existingPart === void 0 ? void 0 : existingPart.input) : existingPart === null || existingPart === void 0 ? void 0 : existingPart.input;
13537
13587
  var nextToolPart = _object_spread_props(_object_spread({}, existingPart !== null && existingPart !== void 0 ? existingPart : {
13538
13588
  type: "tool-".concat(chunk.toolName),
13539
13589
  toolCallId: chunk.toolCallId
@@ -13636,7 +13686,7 @@
13636
13686
  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 : '';
13637
13687
  var nextRawOutput = "".concat(previousRawOutput).concat(delta);
13638
13688
  toolRawOutputByCallId[toolCallId] = nextRawOutput;
13639
- var parsedOutput = parseToolInputDelta(nextRawOutput, existingPart2 === null || existingPart2 === void 0 ? void 0 : existingPart2.output);
13689
+ var parsedOutput = parsePartialJson(nextRawOutput, existingPart2 === null || existingPart2 === void 0 ? void 0 : existingPart2.output);
13640
13690
  var nextToolPart1 = _object_spread_props(_object_spread({}, existingPart2 !== null && existingPart2 !== void 0 ? existingPart2 : {
13641
13691
  type: "tool-".concat(toolName1),
13642
13692
  toolCallId: toolCallId,
@@ -13926,9 +13976,25 @@
13926
13976
 
13927
13977
  var _computedKey, _computedKey1, _computedKey2, _computedKey3, _computedKey4, _computedKey5;
13928
13978
  var CACHE_KEY = 'instantsearch-chat-initial-messages';
13979
+ // Message history is a browser concern, and a server render constructs a Chat
13980
+ // too. Reading storage there throws during rendering; the write below only
13981
+ // throws into its own `catch`, so gating it just stops a pointless attempt.
13929
13982
  function getDefaultInitialMessages(id) {
13930
- var initialMessages = sessionStorage.getItem(CACHE_KEY + (id ? "-".concat(id) : ''));
13931
- return initialMessages ? JSON.parse(initialMessages) : [];
13983
+ return safelyRunOnBrowser(function() {
13984
+ try {
13985
+ // `sessionStorage` is not available in every environment with a
13986
+ // `window` (e.g. React Native), and some browsers throw on access
13987
+ // when storage is disabled.
13988
+ var initialMessages = sessionStorage.getItem(CACHE_KEY + (id ? "-".concat(id) : ''));
13989
+ return initialMessages ? JSON.parse(initialMessages) : [];
13990
+ } catch (e) {
13991
+ return [];
13992
+ }
13993
+ }, {
13994
+ fallback: function fallback() {
13995
+ return [];
13996
+ }
13997
+ });
13932
13998
  }
13933
13999
  _computedKey = '~registerMessagesCallback', _computedKey1 = '~registerStatusCallback', _computedKey2 = '~registerErrorCallback';
13934
14000
  var _computedKey6 = _computedKey, _computedKey7 = _computedKey1, _computedKey8 = _computedKey2;
@@ -14007,11 +14073,13 @@
14007
14073
  }
14008
14074
  var saveMessagesInLocalStorage = function saveMessagesInLocalStorage() {
14009
14075
  if (_this.status === 'ready') {
14010
- try {
14011
- sessionStorage.setItem(CACHE_KEY + (id ? "-".concat(id) : ''), JSON.stringify(_this.messages));
14012
- } catch (e) {
14013
- // Do nothing if sessionStorage is not available or full
14014
- }
14076
+ safelyRunOnBrowser(function() {
14077
+ try {
14078
+ sessionStorage.setItem(CACHE_KEY + (id ? "-".concat(id) : ''), JSON.stringify(_this.messages));
14079
+ } catch (e) {
14080
+ // Do nothing if sessionStorage is not available or full
14081
+ }
14082
+ });
14015
14083
  }
14016
14084
  };
14017
14085
  this['~registerMessagesCallback'](saveMessagesInLocalStorage);
@@ -14087,25 +14155,33 @@
14087
14155
  // it is non-empty and the chat is not already processing a message.
14088
14156
  // Returns true when a message was submitted, so callers can clear their input.
14089
14157
  function openChat(chatRenderState) {
14090
- var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, message = _ref.message, referer = _ref.referer;
14158
+ var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, message = _ref.message, referer = _ref.referer, turnContext = _ref.turnContext;
14091
14159
  var _ref1;
14092
14160
  var _chatRenderState_setOpen;
14093
14161
  if (!chatRenderState) {
14094
14162
  return false;
14095
14163
  }
14096
- (_chatRenderState_setOpen = chatRenderState.setOpen) === null || _chatRenderState_setOpen === void 0 ? void 0 : _chatRenderState_setOpen.call(chatRenderState, true);
14097
14164
  var trimmed = (_ref1 = message === null || message === void 0 ? void 0 : message.trim()) !== null && _ref1 !== void 0 ? _ref1 : '';
14098
14165
  if (!trimmed) {
14099
- var _chatRenderState_focusInput;
14100
- (_chatRenderState_focusInput = chatRenderState.focusInput) === null || _chatRenderState_focusInput === void 0 ? void 0 : _chatRenderState_focusInput.call(chatRenderState);
14166
+ if (chatRenderState.focusInput) {
14167
+ chatRenderState.focusInput();
14168
+ } else {
14169
+ var _chatRenderState_setOpen1;
14170
+ (_chatRenderState_setOpen1 = chatRenderState.setOpen) === null || _chatRenderState_setOpen1 === void 0 ? void 0 : _chatRenderState_setOpen1.call(chatRenderState, true);
14171
+ }
14101
14172
  return false;
14102
14173
  }
14174
+ (_chatRenderState_setOpen = chatRenderState.setOpen) === null || _chatRenderState_setOpen === void 0 ? void 0 : _chatRenderState_setOpen.call(chatRenderState, true);
14103
14175
  if (isChatBusy(chatRenderState) || !chatRenderState.sendMessage) {
14104
14176
  return false;
14105
14177
  }
14106
- chatRenderState.sendMessage({
14178
+ chatRenderState.sendMessage(_object_spread({
14107
14179
  text: trimmed
14108
- }, referer ? {
14180
+ }, turnContext ? {
14181
+ metadata: {
14182
+ turnContext: turnContext
14183
+ }
14184
+ } : {}), referer ? {
14109
14185
  headers: {
14110
14186
  'x-algolia-referer': referer
14111
14187
  }
@@ -14319,10 +14395,62 @@
14319
14395
  return DefaultChatTransport;
14320
14396
  }(HttpChatTransport);
14321
14397
 
14322
- var withUsage$o = createDocumentationMessageGenerator({
14398
+ var withUsage$q = createDocumentationMessageGenerator({
14323
14399
  name: 'chat',
14324
14400
  connector: true
14325
14401
  });
14402
+ var OPEN_STATE_CACHE_KEY = 'instantsearch-chat-open-state';
14403
+ function normalizePersistence(persistence, hasCustomChat) {
14404
+ if (hasCustomChat) {
14405
+ return {
14406
+ messages: false,
14407
+ open: persistence === undefined || (typeof persistence === "undefined" ? "undefined" : _type_of(persistence)) === 'object' && persistence.open === true
14408
+ };
14409
+ }
14410
+ if (persistence === undefined || persistence === true) {
14411
+ return {
14412
+ messages: true,
14413
+ open: true
14414
+ };
14415
+ }
14416
+ if (persistence === false) {
14417
+ return {
14418
+ messages: false,
14419
+ open: false
14420
+ };
14421
+ }
14422
+ return {
14423
+ messages: persistence.messages === true,
14424
+ open: persistence.open === true
14425
+ };
14426
+ }
14427
+ function getOpenStateCacheKey(type) {
14428
+ return "".concat(OPEN_STATE_CACHE_KEY, "-").concat(type);
14429
+ }
14430
+ function readPersistedOpen(type) {
14431
+ try {
14432
+ return safelyRunOnBrowser(function(param) {
14433
+ var browserWindow = param.window;
14434
+ return browserWindow.sessionStorage.getItem(getOpenStateCacheKey(type)) === 'true';
14435
+ }, {
14436
+ fallback: function fallback() {
14437
+ return false;
14438
+ }
14439
+ });
14440
+ } catch (unused) {
14441
+ return false;
14442
+ }
14443
+ }
14444
+ function writePersistedOpen(type, open) {
14445
+ try {
14446
+ safelyRunOnBrowser(function(param) {
14447
+ var browserWindow = param.window;
14448
+ browserWindow.sessionStorage.setItem(getOpenStateCacheKey(type), String(open));
14449
+ });
14450
+ } catch (unused) {
14451
+ // Storage availability must not block the visible state change.
14452
+ }
14453
+ }
14326
14454
  function getAttributesToClear$1(param) {
14327
14455
  var results = param.results, helper = param.helper;
14328
14456
  return uniq(getRefinements(results, helper.state, true).map(function(refinement) {
@@ -14340,26 +14468,36 @@
14340
14468
  attributesToClear: attributesToClear
14341
14469
  }));
14342
14470
  if (params.facetFilters) {
14343
- var attributes = flat(params.facetFilters).map(function(filter) {
14344
- var _filter_split = _sliced_to_array(filter.split(':'), 2), attribute = _filter_split[0], value = _filter_split[1];
14345
- return {
14346
- attribute: attribute,
14347
- value: value
14348
- };
14349
- });
14350
- attributes.forEach(function(param) {
14471
+ var refinements = flat(params.facetFilters).reduce(function(acc, filter) {
14472
+ var separatorIndex = filter.indexOf(':');
14473
+ if (separatorIndex > 0) {
14474
+ acc.push({
14475
+ attribute: filter.slice(0, separatorIndex),
14476
+ value: filter.slice(separatorIndex + 1)
14477
+ });
14478
+ }
14479
+ return acc;
14480
+ }, []);
14481
+ var hierarchicalRefinements = new Map();
14482
+ refinements.forEach(function(param) {
14351
14483
  var attribute = param.attribute, value = param.value;
14352
- if (!helper.state.isConjunctiveFacet(attribute) && !helper.state.isHierarchicalFacet(attribute) && !helper.state.isDisjunctiveFacet(attribute)) {
14353
- var s = helper.state.addDisjunctiveFacet(attribute);
14354
- helper.setState(s);
14355
- helper.toggleFacetRefinement(attribute, value);
14356
- } else {
14357
- var _helper_state_hierarchicalFacets_find;
14358
- var attr = ((_helper_state_hierarchicalFacets_find = helper.state.hierarchicalFacets.find(function(facet) {
14359
- return facet.name === attribute;
14360
- })) === null || _helper_state_hierarchicalFacets_find === void 0 ? void 0 : _helper_state_hierarchicalFacets_find.name) || attribute;
14361
- helper.toggleFacetRefinement(attr, value);
14484
+ var hierarchicalFacet = helper.state.hierarchicalFacets.find(function(facet) {
14485
+ return facet.name === attribute || facet.attributes.includes(attribute);
14486
+ });
14487
+ if (hierarchicalFacet) {
14488
+ var currentValue = hierarchicalRefinements.get(hierarchicalFacet.name);
14489
+ if (currentValue === undefined || value.length > currentValue.length) {
14490
+ hierarchicalRefinements.set(hierarchicalFacet.name, value);
14491
+ }
14492
+ return;
14493
+ }
14494
+ if (!helper.state.isConjunctiveFacet(attribute) && !helper.state.isDisjunctiveFacet(attribute)) {
14495
+ helper.setState(helper.state.addDisjunctiveFacet(attribute));
14362
14496
  }
14497
+ helper.toggleFacetRefinement(attribute, value);
14498
+ });
14499
+ hierarchicalRefinements.forEach(function(value, name) {
14500
+ helper.toggleFacetRefinement(name, value);
14363
14501
  });
14364
14502
  }
14365
14503
  if (params.query) {
@@ -14370,12 +14508,13 @@
14370
14508
  }
14371
14509
  var connectChat = function connectChat(renderFn) {
14372
14510
  var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
14373
- checkRendering(renderFn, withUsage$o());
14511
+ checkRendering(renderFn, withUsage$q());
14374
14512
  return function(widgetParams) {
14375
- 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, [
14513
+ 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, persistence = _ref.persistence, 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, [
14376
14514
  "resume",
14377
14515
  "tools",
14378
14516
  "type",
14517
+ "persistence",
14379
14518
  "context",
14380
14519
  "initialUserMessage",
14381
14520
  "initialMessages",
@@ -14383,6 +14522,7 @@
14383
14522
  "sendAutomaticallyWhen",
14384
14523
  "requiresSearch"
14385
14524
  ]);
14525
+ var normalizedPersistence = normalizePersistence(persistence, 'chat' in options);
14386
14526
  var _chatInstance;
14387
14527
  var input = '';
14388
14528
  var open = false;
@@ -14390,12 +14530,19 @@
14390
14530
  var setInput;
14391
14531
  var setOpen;
14392
14532
  var focusInput;
14533
+ var inputFocusRequested = false;
14393
14534
  var setFeedbackState;
14394
14535
  var hasValidatedEntryPoints = false;
14395
14536
  var agentId = 'agentId' in options ? options.agentId : undefined;
14396
14537
  var feedbackState = {};
14397
14538
  var _sendChatMessageFeedback;
14398
14539
  var feedbackAbortController;
14540
+ var chatSubscriptionUnsubscribers = [];
14541
+ var unsubscribeChatCallbacks = function unsubscribeChatCallbacks() {
14542
+ chatSubscriptionUnsubscribers.splice(0).forEach(function(unsubscribe) {
14543
+ return unsubscribe();
14544
+ });
14545
+ };
14399
14546
  // Extract suggestions from the last assistant message's data-suggestions part
14400
14547
  var getSuggestionsFromMessages = function getSuggestionsFromMessages(messages) {
14401
14548
  // Find the last assistant message (iterate from end)
@@ -14448,6 +14595,11 @@
14448
14595
  hasValidatedEntryPoints = true;
14449
14596
  };
14450
14597
  var makeChatInstance = function makeChatInstance(instantSearchInstance) {
14598
+ // A caller supplied `chat` already owns its transport, so it bypasses the
14599
+ // connector's transport construction and validation below.
14600
+ if ('chat' in options) {
14601
+ return options.chat;
14602
+ }
14451
14603
  var transport;
14452
14604
  var client = instantSearchInstance.client;
14453
14605
  var _getAppIdAndApiKey = _sliced_to_array(getAppIdAndApiKey(client), 2), appId = _getAppIdAndApiKey[0], apiKey = _getAppIdAndApiKey[1];
@@ -14497,7 +14649,7 @@
14497
14649
  if ('agentId' in options && options.agentId) {
14498
14650
  var _options_requestOptions, _options_requestOptions1;
14499
14651
  if (!appId || !apiKey) {
14500
- throw new Error(withUsage$o('Could not extract Algolia credentials from the search client.'));
14652
+ throw new Error(withUsage$q('Could not extract Algolia credentials from the search client.'));
14501
14653
  }
14502
14654
  var createApi = function createApi() {
14503
14655
  var bypassCache = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : false;
@@ -14514,7 +14666,7 @@
14514
14666
  var baseApi = createApi();
14515
14667
  transport = new DefaultChatTransport({
14516
14668
  api: baseApi,
14517
- headers: _object_spread_props(_object_spread({}, _instanceof((_options_requestOptions = options.requestOptions) === null || _options_requestOptions === void 0 ? void 0 : _options_requestOptions.headers, Headers) ? Object.fromEntries(options.requestOptions.headers.entries()) : (_options_requestOptions1 = options.requestOptions) === null || _options_requestOptions1 === void 0 ? void 0 : _options_requestOptions1.headers), {
14669
+ headers: _object_spread_props(_object_spread({}, typeof Headers !== 'undefined' && _instanceof((_options_requestOptions = options.requestOptions) === null || _options_requestOptions === void 0 ? void 0 : _options_requestOptions.headers, Headers) ? Object.fromEntries(options.requestOptions.headers.entries()) : (_options_requestOptions1 = options.requestOptions) === null || _options_requestOptions1 === void 0 ? void 0 : _options_requestOptions1.headers), {
14518
14670
  // Preserve the required Algolia identity headers and chat agent
14519
14671
  // marker, even when requestOptions.headers contains the same keys.
14520
14672
  'x-algolia-application-id': appId,
@@ -14536,12 +14688,10 @@
14536
14688
  });
14537
14689
  }
14538
14690
  if (!transport) {
14539
- throw new Error(withUsage$o('You need to provide either an `agentId` or a `transport`.'));
14540
- }
14541
- if ('chat' in options) {
14542
- return options.chat;
14691
+ throw new Error(withUsage$q('You need to provide either an `agentId` or a `transport`.'));
14543
14692
  }
14544
14693
  return new Chat$1(_object_spread_props(_object_spread({}, options), {
14694
+ persistence: normalizedPersistence.messages,
14545
14695
  sendAutomaticallyWhen: sendAutomaticallyWhen,
14546
14696
  transport: transport,
14547
14697
  shouldRepairToolInput: function shouldRepairToolInput(toolName) {
@@ -14590,22 +14740,30 @@
14590
14740
  var _this = this;
14591
14741
  var instantSearchInstance = initOptions.instantSearchInstance;
14592
14742
  validateEntryPoints(instantSearchInstance);
14743
+ open = normalizedPersistence.open ? readPersistedOpen(type) : false;
14593
14744
  _chatInstance = makeChatInstance(instantSearchInstance);
14594
14745
  var render = function render() {
14595
14746
  renderFn(_object_spread_props(_object_spread({}, _this.getWidgetRenderState(initOptions)), {
14596
14747
  instantSearchInstance: initOptions.instantSearchInstance
14597
14748
  }), false);
14598
14749
  };
14599
- setOpen = function setOpen(o) {
14600
- open = o;
14750
+ var updateOpen = function updateOpen(nextOpen, requestFocus) {
14751
+ open = nextOpen;
14752
+ inputFocusRequested = nextOpen && (inputFocusRequested || requestFocus);
14753
+ if (normalizedPersistence.open) {
14754
+ writePersistedOpen(type, open);
14755
+ }
14601
14756
  render();
14602
14757
  // `open` is read by sibling widgets (e.g. `chatTrigger`) via the
14603
14758
  // shared `renderState`. Schedule a full re-render so they pick up
14604
14759
  // the new value instead of staying frozen on their initial state.
14605
14760
  initOptions.instantSearchInstance.scheduleRender();
14606
14761
  };
14762
+ setOpen = function setOpen(nextOpen) {
14763
+ updateOpen(nextOpen, nextOpen && !open);
14764
+ };
14607
14765
  focusInput = function focusInput() {
14608
- setOpen(true);
14766
+ updateOpen(true, true);
14609
14767
  };
14610
14768
  setInput = function setInput(i) {
14611
14769
  input = i;
@@ -14619,7 +14777,7 @@
14619
14777
  if (agentId && feedback) {
14620
14778
  var _getAppIdAndApiKey = _sliced_to_array(getAppIdAndApiKey(initOptions.instantSearchInstance.client), 2), appId = _getAppIdAndApiKey[0], apiKey = _getAppIdAndApiKey[1];
14621
14779
  if (!appId || !apiKey) {
14622
- throw new Error(withUsage$o('Could not extract Algolia credentials from the search client.'));
14780
+ throw new Error(withUsage$q('Could not extract Algolia credentials from the search client.'));
14623
14781
  }
14624
14782
  feedbackAbortController = new AbortController();
14625
14783
  _sendChatMessageFeedback = function _sendChatMessageFeedback(messageId, vote) {
@@ -14639,25 +14797,42 @@
14639
14797
  };
14640
14798
  }
14641
14799
  var hasExistingMessages = _chatInstance.messages.length > 0;
14642
- // Set initialMessages before registering callbacks to avoid
14643
- // triggering re-renders during init
14644
- if ((initialMessages === null || initialMessages === void 0 ? void 0 : initialMessages.length) && !resume && !hasExistingMessages) {
14645
- _chatInstance.messages = initialMessages;
14646
- }
14647
- _chatInstance['~registerErrorCallback'](render);
14648
- _chatInstance['~registerMessagesCallback'](render);
14649
- _chatInstance['~registerStatusCallback'](render);
14650
- if (resume) {
14651
- _chatInstance.resumeStream();
14652
- }
14653
- if (initialUserMessage && !resume && !hasExistingMessages) {
14654
- _chatInstance.sendMessage({
14655
- text: initialUserMessage
14656
- });
14657
- }
14800
+ // Unsubscribe previous callbacks before setting initialMessages, then
14801
+ // register the current callbacks after to avoid re-renders during init.
14802
+ // A server render owns no conversation, so it leaves the instance empty.
14803
+ safelyRunOnBrowser(function() {
14804
+ unsubscribeChatCallbacks();
14805
+ if ((initialMessages === null || initialMessages === void 0 ? void 0 : initialMessages.length) && !resume && !hasExistingMessages) {
14806
+ _chatInstance.messages = initialMessages;
14807
+ }
14808
+ });
14809
+ safelyRunOnBrowser(function() {
14810
+ chatSubscriptionUnsubscribers = [
14811
+ _chatInstance['~registerErrorCallback'](render),
14812
+ _chatInstance['~registerMessagesCallback'](render),
14813
+ _chatInstance['~registerStatusCallback'](render)
14814
+ ];
14815
+ });
14816
+ // Resuming and sending reach the network, which a server render must
14817
+ // not: the HTML pass repeats what `getServerState` already rendered, so
14818
+ // each send happens at least twice, and each failure resolves into chat
14819
+ // state well after the render that started it has finished.
14820
+ safelyRunOnBrowser(function() {
14821
+ if (resume) {
14822
+ _chatInstance.resumeStream();
14823
+ }
14824
+ if (initialUserMessage && !resume && !hasExistingMessages) {
14825
+ _chatInstance.sendMessage({
14826
+ text: initialUserMessage
14827
+ });
14828
+ }
14829
+ });
14658
14830
  renderFn(_object_spread_props(_object_spread({}, this.getWidgetRenderState(initOptions)), {
14659
14831
  instantSearchInstance: instantSearchInstance
14660
14832
  }), true);
14833
+ if (open) {
14834
+ instantSearchInstance.scheduleRender();
14835
+ }
14661
14836
  },
14662
14837
  render: function render(renderOptions) {
14663
14838
  validateEntryPoints(renderOptions.instantSearchInstance);
@@ -14686,6 +14861,10 @@
14686
14861
  function applyFilters(params) {
14687
14862
  return updateStateFromSearchToolInput(params, helper);
14688
14863
  }
14864
+ var insightsEventContext = {
14865
+ agentId: agentId,
14866
+ instantSearchStatus: instantSearchInstance.status
14867
+ };
14689
14868
  var toolsWithAddToolResult = {};
14690
14869
  Object.entries(tools).forEach(function(param) {
14691
14870
  var _param = _sliced_to_array(param, 2), key = _param[0], tool = _param[1];
@@ -14693,7 +14872,8 @@
14693
14872
  addToolResult: _chatInstance.addToolResult,
14694
14873
  '~addToolResultForMessage': _chatInstance['~addToolResultForMessage'],
14695
14874
  applyFilters: applyFilters,
14696
- sendEvent: sendEvent
14875
+ sendEvent: sendEvent,
14876
+ insightsEventContext: insightsEventContext
14697
14877
  });
14698
14878
  toolsWithAddToolResult[key] = toolWithAddToolResult;
14699
14879
  });
@@ -14719,7 +14899,7 @@
14719
14899
  })
14720
14900
  ].concat(_to_consumable_array(rest)));
14721
14901
  };
14722
- return {
14902
+ var renderState = {
14723
14903
  indexUiState: instantSearchInstance.getUiState()[parent.getIndexId()],
14724
14904
  input: input,
14725
14905
  open: open,
@@ -14728,6 +14908,12 @@
14728
14908
  setInput: setInput,
14729
14909
  setOpen: setOpen,
14730
14910
  focusInput: focusInput,
14911
+ '~consumeInputFocus': function() {
14912
+ var shouldFocus = inputFocusRequested;
14913
+ inputFocusRequested = false;
14914
+ return shouldFocus;
14915
+ },
14916
+ '~isOpenStatePersistenceEnabled': normalizedPersistence.open,
14731
14917
  setMessages: setMessages,
14732
14918
  suggestions: getSuggestionsFromMessages(_chatInstance.messages),
14733
14919
  clearMessages: clearMessages,
@@ -14747,9 +14933,11 @@
14747
14933
  status: _chatInstance.status,
14748
14934
  stop: _chatInstance.stop
14749
14935
  };
14936
+ return renderState;
14750
14937
  },
14751
14938
  dispose: function dispose() {
14752
14939
  feedbackAbortController === null || feedbackAbortController === void 0 ? void 0 : feedbackAbortController.abort();
14940
+ unsubscribeChatCallbacks();
14753
14941
  unmountFn();
14754
14942
  },
14755
14943
  shouldRender: function shouldRender() {
@@ -14762,8 +14950,624 @@
14762
14950
  };
14763
14951
  };
14764
14952
 
14953
+ var subscribe = function subscribe() {
14954
+ return function() {};
14955
+ };
14956
+ var getClientSnapshot = function getClientSnapshot() {
14957
+ return true;
14958
+ };
14959
+ var getServerSnapshot = function getServerSnapshot() {
14960
+ return false;
14961
+ };
14962
+ function useNativeIsHydrated() {
14963
+ return React__namespace.useSyncExternalStore(subscribe, getClientSnapshot, getServerSnapshot);
14964
+ }
14965
+ // React 16 and 17 have no `useSyncExternalStore`, so the flip waits for an
14966
+ // effect and the render itself cannot tell hydration from a plain mount. These
14967
+ // contexts provide that signal for the supported `getServerState` and
14968
+ // `InstantSearchSSRProvider` flow: the server context covers state collection,
14969
+ // and the SSR context covers HTML rendering and hydration.
14970
+ //
14971
+ // The shim's React 16 and 17 fallback ignores the server snapshot, so using it
14972
+ // here would not distinguish initial hydration from later provider children.
14973
+ function useLegacyIsHydrated() {
14974
+ var _ssrContext_hydrationCompleteRef;
14975
+ var serverContext = useInstantSearchServerContext();
14976
+ var ssrContext = useInstantSearchSSRContext();
14977
+ var isServerRendered = serverContext !== null || ssrContext !== null;
14978
+ var isProviderHydrated = (ssrContext === null || ssrContext === void 0 ? void 0 : (_ssrContext_hydrationCompleteRef = ssrContext.hydrationCompleteRef) === null || _ssrContext_hydrationCompleteRef === void 0 ? void 0 : _ssrContext_hydrationCompleteRef.current) === true;
14979
+ var _React_useState = _sliced_to_array(React__namespace.useState(!isServerRendered || isProviderHydrated), 2), isHydrated = _React_useState[0], setIsHydrated = _React_useState[1];
14980
+ React__namespace.useEffect(function() {
14981
+ setIsHydrated(true);
14982
+ }, []);
14983
+ return isHydrated;
14984
+ }
14985
+ /**
14986
+ * Whether this render can use browser state, or has to reproduce the markup a
14987
+ * server produced without it.
14988
+ *
14989
+ * @internal
14990
+ */ var useIsHydrated = typeof React__namespace.useSyncExternalStore === 'function' ? useNativeIsHydrated : useLegacyIsHydrated;
14991
+
14765
14992
  function useChat(props, additionalWidgetProperties) {
14766
- return useConnector(connectChat, props, additionalWidgetProperties);
14993
+ var isHydrated = useIsHydrated();
14994
+ var chatState = useConnector(connectChat, props, additionalWidgetProperties);
14995
+ if (isHydrated) {
14996
+ return chatState;
14997
+ }
14998
+ // Server rendering only promises the closed Chat shell, so a render that has
14999
+ // to reproduce that markup shows no conversation either. `status` is pinned
15000
+ // with `messages` because it diverges two ways: a server render suppresses
15001
+ // `resumeStream()`, which the browser runs synchronously while initialising,
15002
+ // and a caller-owned chat can already be streaming. `error` is pinned because
15003
+ // a caller-owned chat can already have failed, which a connector-built one
15004
+ // cannot, since its failures arrive in a microtask. `suggestions` is pinned
15005
+ // because the connector derives them from those messages. Only an `id` given
15006
+ // as a connector option passes through, because that value is the same on
15007
+ // both sides. Anything else is withheld: the default is random per Chat, and
15008
+ // an `id` carried by a caller-owned instance is no safer, since the server and
15009
+ // the browser each construct their own.
15010
+ return _object_spread_props(_object_spread({}, chatState), {
15011
+ error: undefined,
15012
+ id: 'id' in props && props.id || '',
15013
+ messages: [],
15014
+ open: false,
15015
+ status: 'ready',
15016
+ suggestions: undefined
15017
+ });
15018
+ }
15019
+
15020
+ function buildEndpoint(param) {
15021
+ var appId = param.appId, agentId = param.agentId;
15022
+ return "https://".concat(appId, ".algolia.net/agent-studio/1/agents/").concat(agentId, "/tasks");
15023
+ }
15024
+ function resolveEndpoint(params) {
15025
+ if (params.transport) {
15026
+ return {
15027
+ endpoint: params.transport.api,
15028
+ headers: params.transport.headers || {},
15029
+ prepareSendMessagesRequest: params.transport.prepareSendMessagesRequest
15030
+ };
15031
+ }
15032
+ if (!params.appId || !params.apiKey || !params.agentId) {
15033
+ throw new Error('[tasks] Either `transport` or `{ appId, apiKey, agentId }` is required.');
15034
+ }
15035
+ var headers = {
15036
+ 'x-algolia-application-id': params.appId,
15037
+ 'x-algolia-api-key': params.apiKey
15038
+ };
15039
+ if (params.algoliaAgent) {
15040
+ headers['x-algolia-agent'] = "".concat(params.algoliaAgent, "; tasks");
15041
+ }
15042
+ return {
15043
+ endpoint: buildEndpoint({
15044
+ appId: params.appId,
15045
+ agentId: params.agentId
15046
+ }),
15047
+ headers: headers
15048
+ };
15049
+ }
15050
+
15051
+ function buildTaskPayload(param) {
15052
+ var task = param.task, input = param.input, prepareRequest = param.prepareRequest;
15053
+ var payload = {
15054
+ task: task,
15055
+ input: input
15056
+ };
15057
+ return prepareRequest ? prepareRequest(payload).body : payload;
15058
+ }
15059
+ function withStreamParam(url) {
15060
+ return url.includes('?') ? "".concat(url, "&stream=true") : "".concat(url, "?stream=true");
15061
+ }
15062
+ function resolveStreamedOutput(data, previous) {
15063
+ return typeof data === 'string' ? parsePartialJson(data, previous) : data;
15064
+ }
15065
+ function consumeTaskStream(body, onData) {
15066
+ return new Promise(function(resolve, reject) {
15067
+ var chunkStream = parseJsonEventStream(body);
15068
+ var latest;
15069
+ processStream(chunkStream, function(chunk) {
15070
+ if (!chunk) {
15071
+ return;
15072
+ }
15073
+ // A terminal `error` event aborts the task: reject rather than let the
15074
+ // stream close and resolve the last partial snapshot as a success.
15075
+ // Throwing here lets `processStream` release the reader and stop
15076
+ // consuming; the rejection propagates to the caller's `.catch`.
15077
+ if (chunk.type === 'error') {
15078
+ throw new Error(chunk.errorText || 'Task stream error');
15079
+ }
15080
+ if (chunk.type !== 'data-task-output') {
15081
+ return;
15082
+ }
15083
+ latest = resolveStreamedOutput(chunk.data, latest);
15084
+ if (onData) {
15085
+ onData(latest);
15086
+ }
15087
+ }, function() {
15088
+ return resolve(latest);
15089
+ }, reject);
15090
+ });
15091
+ }
15092
+ function fetchTask(param) {
15093
+ var endpoint = param.endpoint, headers = param.headers, payload = param.payload, onData = param.onData, _param_stream = param.stream, stream = _param_stream === void 0 ? true : _param_stream;
15094
+ return fetch(stream ? withStreamParam(endpoint) : endpoint, {
15095
+ method: 'POST',
15096
+ headers: _object_spread_props(_object_spread({}, headers), {
15097
+ 'Content-Type': 'application/json'
15098
+ }),
15099
+ body: JSON.stringify(payload)
15100
+ }).then(function(response) {
15101
+ var _response_headers_get, _response_headers;
15102
+ if (!response.ok) {
15103
+ throw new Error("HTTP error ".concat(response.status));
15104
+ }
15105
+ var contentType = ((_response_headers = response.headers) === null || _response_headers === void 0 ? void 0 : (_response_headers_get = _response_headers.get) === null || _response_headers_get === void 0 ? void 0 : _response_headers_get.call(_response_headers, 'content-type')) || '';
15106
+ if (stream && response.body && contentType.includes('text/event-stream')) {
15107
+ return consumeTaskStream(response.body, onData);
15108
+ }
15109
+ return response.json();
15110
+ });
15111
+ }
15112
+ function unwrap(envelope) {
15113
+ return envelope === null || envelope === void 0 ? void 0 : envelope.output;
15114
+ }
15115
+ function createTaskRunner(param) {
15116
+ var endpoint = param.endpoint, headers = param.headers, task = param.task, _param_stream = param.stream, stream = _param_stream === void 0 ? true : _param_stream, prepareRequest = param.prepareRequest;
15117
+ return {
15118
+ submit: function submit(variables) {
15119
+ var onData = (arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}).onData;
15120
+ var payload = buildTaskPayload({
15121
+ task: task,
15122
+ input: variables,
15123
+ prepareRequest: prepareRequest
15124
+ });
15125
+ return fetchTask({
15126
+ endpoint: endpoint,
15127
+ headers: headers,
15128
+ payload: payload,
15129
+ stream: stream,
15130
+ onData: onData ? function(partial) {
15131
+ return onData(unwrap(partial));
15132
+ } : undefined
15133
+ }).then(unwrap);
15134
+ }
15135
+ };
15136
+ }
15137
+
15138
+ var withUsage$p = createDocumentationMessageGenerator({
15139
+ name: 'tasks',
15140
+ connector: true
15141
+ });
15142
+ var connectTasks = function connectTasks(renderFn) {
15143
+ var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
15144
+ checkRendering(renderFn, withUsage$p());
15145
+ return function(widgetParams) {
15146
+ var agentId = widgetParams.agentId, transport = widgetParams.transport, task = widgetParams.task, _widgetParams_stream = widgetParams.stream, stream = _widgetParams_stream === void 0 ? true : _widgetParams_stream;
15147
+ if (!agentId && !transport) {
15148
+ throw new Error(withUsage$p('The `agentId` option is required unless a custom `transport` is provided.'));
15149
+ }
15150
+ if (!task) {
15151
+ throw new Error(withUsage$p('The `task` option is required.'));
15152
+ }
15153
+ var runner;
15154
+ var output;
15155
+ var isLoading = false;
15156
+ var error;
15157
+ var disposed = false;
15158
+ var triggerRender = noop;
15159
+ var requestId = 0;
15160
+ var submit = function submit(variables) {
15161
+ if (disposed) return Promise.resolve(undefined);
15162
+ var currentRequestId = requestId += 1;
15163
+ var isStale = function isStale() {
15164
+ return disposed || currentRequestId !== requestId;
15165
+ };
15166
+ // Clear the previous output so consumers can show a loading state
15167
+ // rather than stale data while the new request is in flight.
15168
+ output = undefined;
15169
+ error = undefined;
15170
+ isLoading = true;
15171
+ triggerRender();
15172
+ return Promise.resolve().then(function() {
15173
+ return runner.submit(variables, {
15174
+ onData: stream ? function(partial) {
15175
+ if (isStale()) return;
15176
+ output = partial;
15177
+ triggerRender();
15178
+ } : undefined
15179
+ });
15180
+ }).then(function(next) {
15181
+ var result = next;
15182
+ if (!isStale()) {
15183
+ output = result;
15184
+ }
15185
+ return result;
15186
+ }).catch(function(err) {
15187
+ if (!isStale()) {
15188
+ output = undefined;
15189
+ error = _instanceof(err, Error) ? err : new Error(String(err));
15190
+ }
15191
+ return undefined;
15192
+ }).finally(function() {
15193
+ if (isStale()) return;
15194
+ isLoading = false;
15195
+ triggerRender();
15196
+ });
15197
+ };
15198
+ var invalidate = function invalidate() {
15199
+ if (disposed) return;
15200
+ // Bump the request id so any in-flight request's callbacks see
15201
+ // `isStale()` and are ignored. The fetch itself is left to complete.
15202
+ requestId += 1;
15203
+ isLoading = false;
15204
+ triggerRender();
15205
+ };
15206
+ var getWidgetRenderState = function getWidgetRenderState() {
15207
+ return {
15208
+ output: output,
15209
+ isLoading: isLoading,
15210
+ error: error,
15211
+ submit: submit,
15212
+ invalidate: invalidate,
15213
+ widgetParams: widgetParams
15214
+ };
15215
+ };
15216
+ return {
15217
+ $$type: 'ais.tasks',
15218
+ init: function init(initOptions) {
15219
+ var instantSearchInstance = initOptions.instantSearchInstance;
15220
+ if (transport) {
15221
+ var resolved = resolveEndpoint({
15222
+ transport: transport
15223
+ });
15224
+ runner = createTaskRunner({
15225
+ endpoint: resolved.endpoint,
15226
+ headers: resolved.headers,
15227
+ task: task,
15228
+ stream: stream,
15229
+ prepareRequest: resolved.prepareSendMessagesRequest
15230
+ });
15231
+ } else {
15232
+ var _getAppIdAndApiKey = _sliced_to_array(getAppIdAndApiKey(instantSearchInstance.client), 2), appId = _getAppIdAndApiKey[0], apiKey = _getAppIdAndApiKey[1];
15233
+ if (!appId || !apiKey) {
15234
+ throw new Error(withUsage$p('Could not extract Algolia credentials from the search client.'));
15235
+ }
15236
+ var resolved1 = resolveEndpoint({
15237
+ appId: appId,
15238
+ apiKey: apiKey,
15239
+ agentId: agentId,
15240
+ algoliaAgent: getAlgoliaAgent(instantSearchInstance.client)
15241
+ });
15242
+ runner = createTaskRunner({
15243
+ endpoint: resolved1.endpoint,
15244
+ headers: resolved1.headers,
15245
+ task: task,
15246
+ stream: stream
15247
+ });
15248
+ }
15249
+ triggerRender = function triggerRender() {
15250
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState()), {
15251
+ instantSearchInstance: instantSearchInstance
15252
+ }), false);
15253
+ };
15254
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState()), {
15255
+ instantSearchInstance: instantSearchInstance
15256
+ }), true);
15257
+ },
15258
+ render: function render(renderOptions) {
15259
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState()), {
15260
+ instantSearchInstance: renderOptions.instantSearchInstance
15261
+ }), false);
15262
+ },
15263
+ dispose: function dispose() {
15264
+ disposed = true;
15265
+ unmountFn();
15266
+ }
15267
+ };
15268
+ };
15269
+ };
15270
+
15271
+ var withUsage$o = createDocumentationMessageGenerator({
15272
+ name: 'prompt-suggestions',
15273
+ connector: true
15274
+ });
15275
+ var RENDER_STATE_KEY = 'promptSuggestions';
15276
+ var CHAT_RENDER_STATE_KEY = 'chat';
15277
+ var DEBOUNCE_MS = 300;
15278
+ function parseSuggestions(data) {
15279
+ var suggestions = data === null || data === void 0 ? void 0 : data.suggestions;
15280
+ if (!Array.isArray(suggestions)) {
15281
+ return [];
15282
+ }
15283
+ return suggestions.filter(function(s) {
15284
+ return typeof s === 'string';
15285
+ });
15286
+ }
15287
+ function buildSuggestionMessage(suggestion) {
15288
+ return "The user clicked this on-page suggestion. Use the current page context first, then search only if needed.\n\nSuggestion: ".concat(suggestion);
15289
+ }
15290
+ function stripInternalHitMetadata(hit) {
15291
+ var clean = {};
15292
+ Object.keys(hit).forEach(function(key) {
15293
+ // Strip internal metadata, which is `_`-prefixed
15294
+ // (`_highlightResult`, `_rankingInfo`, `__position`, …).
15295
+ if (!key.startsWith('_')) {
15296
+ clean[key] = hit[key];
15297
+ }
15298
+ });
15299
+ return clean;
15300
+ }
15301
+ var DEFAULT_TRANSFORM_HITS = function DEFAULT_TRANSFORM_HITS(hits) {
15302
+ return hits.slice(0, 5).map(stripInternalHitMetadata);
15303
+ };
15304
+ function buildFilters(results) {
15305
+ var state = results._state;
15306
+ if (!state) {
15307
+ return undefined;
15308
+ }
15309
+ var groups = [];
15310
+ var disjunctiveGroups = {};
15311
+ getRefinements(results, state).forEach(function(refinement) {
15312
+ if (refinement.type === 'numeric') {
15313
+ groups.push([
15314
+ "".concat(refinement.attribute).concat(refinement.operator).concat(refinement.numericValue)
15315
+ ]);
15316
+ return;
15317
+ }
15318
+ var value = refinement.type === 'exclude' ? "".concat(refinement.attribute, ":-").concat(refinement.name) : "".concat(refinement.attribute, ":").concat(refinement.name);
15319
+ if (refinement.type === 'disjunctive') {
15320
+ var group = disjunctiveGroups[refinement.attribute];
15321
+ if (group) {
15322
+ group.push(value);
15323
+ } else {
15324
+ var newGroup = [
15325
+ value
15326
+ ];
15327
+ disjunctiveGroups[refinement.attribute] = newGroup;
15328
+ groups.push(newGroup);
15329
+ }
15330
+ return;
15331
+ }
15332
+ groups.push([
15333
+ value
15334
+ ]);
15335
+ });
15336
+ return groups.length > 0 ? groups : undefined;
15337
+ }
15338
+ var connectPromptSuggestions = function connectPromptSuggestions(renderFn) {
15339
+ var unmountFn = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : noop;
15340
+ checkRendering(renderFn, withUsage$o());
15341
+ return function(widgetParams) {
15342
+ var agentId = widgetParams.agentId, configurationId = widgetParams.configurationId, _widgetParams_transformHits = widgetParams.transformHits, transformHits = _widgetParams_transformHits === void 0 ? DEFAULT_TRANSFORM_HITS : _widgetParams_transformHits, context = widgetParams.context, _widgetParams_transformItems = widgetParams.transformItems, transformItems = _widgetParams_transformItems === void 0 ? function(items) {
15343
+ return items;
15344
+ } : _widgetParams_transformItems, transport = widgetParams.transport;
15345
+ if (!agentId && !transport) {
15346
+ throw new Error(withUsage$o('The `agentId` option is required unless a custom `transport` is provided.'));
15347
+ }
15348
+ if (!configurationId) {
15349
+ throw new Error(withUsage$o('The `configurationId` option is required.'));
15350
+ }
15351
+ var tasksState;
15352
+ var suggestions = [];
15353
+ var isLoading = false;
15354
+ var debounceTimer;
15355
+ var lastStateSignature = null;
15356
+ var latestRenderOptions = null;
15357
+ // Set in `dispose()`. A debounced or in-flight `fetch()` can resolve after
15358
+ // the widget is unmounted; this guard stops those late callbacks from
15359
+ // calling `renderFn` into a torn-down container.
15360
+ var disposed = false;
15361
+ // True between a state-signature change and the debounced refetch that
15362
+ // follows it. While pending, the search state has already moved on, so a
15363
+ // still-in-flight request from the previous state must not paint its
15364
+ // suggestions, its inner render is ignored until the new `submit` starts.
15365
+ var refetchPending = false;
15366
+ var getStateSignature = function getStateSignature(results) {
15367
+ var _buildFilters;
15368
+ if (results.queryID) {
15369
+ return results.queryID;
15370
+ }
15371
+ var query = results.query || '';
15372
+ var filters = JSON.stringify((_buildFilters = buildFilters(results)) !== null && _buildFilters !== void 0 ? _buildFilters : []);
15373
+ var hitIds = (results.hits || []).map(function(hit) {
15374
+ return hit.objectID;
15375
+ }).join(',');
15376
+ return "".concat(query, "|").concat(filters, "|").concat(hitIds);
15377
+ };
15378
+ var getChatRenderState = function getChatRenderState(renderOptions) {
15379
+ var _instantSearchInstance_renderState;
15380
+ var instantSearchInstance = renderOptions.instantSearchInstance, parent = renderOptions.parent;
15381
+ var indexId = parent ? parent.getIndexId() : '';
15382
+ if (!indexId || !((_instantSearchInstance_renderState = instantSearchInstance.renderState) === null || _instantSearchInstance_renderState === void 0 ? void 0 : _instantSearchInstance_renderState[indexId])) {
15383
+ return undefined;
15384
+ }
15385
+ return instantSearchInstance.renderState[indexId][CHAT_RENDER_STATE_KEY];
15386
+ };
15387
+ var sendToChat = function sendToChat(renderOptions) {
15388
+ return function(prompt) {
15389
+ var _ref, _ref1;
15390
+ var chatRenderState = getChatRenderState(renderOptions);
15391
+ if (!chatRenderState || !chatRenderState.sendMessage) {
15392
+ return false;
15393
+ }
15394
+ var results = (_ref = (_ref1 = latestRenderOptions === null || latestRenderOptions === void 0 ? void 0 : latestRenderOptions.results) !== null && _ref1 !== void 0 ? _ref1 : 'results' in renderOptions ? renderOptions.results : null) !== null && _ref !== void 0 ? _ref : null;
15395
+ return openChat(chatRenderState, {
15396
+ message: buildSuggestionMessage(prompt),
15397
+ referer: 'prompt-suggestions-widget',
15398
+ turnContext: buildTurnContext(results)
15399
+ });
15400
+ };
15401
+ };
15402
+ var resolvePageContext = function resolvePageContext(results) {
15403
+ var resolvedContext = typeof context === 'function' ? context() : context;
15404
+ // Explicit context replaces auto-extraction; otherwise derive it from
15405
+ // the current search state. The task's server-owned instructions decide
15406
+ // how to interpret the shape — the client doesn't label it.
15407
+ if (resolvedContext) {
15408
+ return _object_spread({}, resolvedContext);
15409
+ }
15410
+ if (!results) {
15411
+ return undefined;
15412
+ }
15413
+ var filters = buildFilters(results);
15414
+ return _object_spread_props(_object_spread({
15415
+ query: results.query || ''
15416
+ }, filters ? {
15417
+ filters: filters
15418
+ } : {}), {
15419
+ hitsSample: transformHits(results.hits)
15420
+ });
15421
+ };
15422
+ var buildInput = function buildInput(results) {
15423
+ var _resolvePageContext;
15424
+ return (_resolvePageContext = resolvePageContext(results)) !== null && _resolvePageContext !== void 0 ? _resolvePageContext : {};
15425
+ };
15426
+ // The same page context, flattened for the chat handoff: `turnContext` is
15427
+ // a flat `Record<string, string>` per the Agent Studio contract, so
15428
+ // non-string values (e.g. `hitsSample`) are serialized.
15429
+ var buildTurnContext = function buildTurnContext(results) {
15430
+ var pageContext = resolvePageContext(results);
15431
+ if (!pageContext) {
15432
+ return undefined;
15433
+ }
15434
+ var entries = Object.entries(pageContext).map(function(param) {
15435
+ var _param = _sliced_to_array(param, 2), key = _param[0], value = _param[1];
15436
+ return [
15437
+ key,
15438
+ typeof value === 'string' ? value : JSON.stringify(value)
15439
+ ];
15440
+ }).filter(function(param) {
15441
+ var _param = _sliced_to_array(param, 2), value = _param[1];
15442
+ return value.trim() !== '';
15443
+ });
15444
+ return entries.length > 0 ? Object.fromEntries(entries) : undefined;
15445
+ };
15446
+ var renderOutward = function renderOutward(renderOptions) {
15447
+ if (disposed) return;
15448
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState(renderOptions)), {
15449
+ instantSearchInstance: renderOptions.instantSearchInstance
15450
+ }), false);
15451
+ };
15452
+ var fetchAndRender = function fetchAndRender(results, renderOptions) {
15453
+ var _results_hits;
15454
+ if (disposed || !tasksState) return;
15455
+ refetchPending = false;
15456
+ var hasContext = context !== undefined;
15457
+ if (!hasContext && !(results === null || results === void 0 ? void 0 : (_results_hits = results.hits) === null || _results_hits === void 0 ? void 0 : _results_hits.length)) {
15458
+ tasksState.invalidate();
15459
+ suggestions = [];
15460
+ isLoading = false;
15461
+ renderOutward(renderOptions);
15462
+ return;
15463
+ }
15464
+ tasksState.submit(buildInput(results));
15465
+ };
15466
+ var refresh = function refresh() {
15467
+ if (isLoading) return;
15468
+ var results = latestRenderOptions === null || latestRenderOptions === void 0 ? void 0 : latestRenderOptions.results;
15469
+ if (!results || !latestRenderOptions) return;
15470
+ clearTimeout(debounceTimer);
15471
+ lastStateSignature = getStateSignature(results);
15472
+ fetchAndRender(results, latestRenderOptions);
15473
+ };
15474
+ var getWidgetRenderState = function getWidgetRenderState(renderOptions) {
15475
+ var results = 'results' in renderOptions ? renderOptions.results : undefined;
15476
+ var transformed = transformItems(suggestions, {
15477
+ query: (results === null || results === void 0 ? void 0 : results.query) || '',
15478
+ results: results || null
15479
+ });
15480
+ var chatRenderState = getChatRenderState(renderOptions);
15481
+ var isChatBusy$1 = chatRenderState ? !chatRenderState.sendMessage || isChatBusy(chatRenderState) : false;
15482
+ var send = sendToChat(renderOptions);
15483
+ return {
15484
+ suggestions: transformed,
15485
+ isLoading: isLoading,
15486
+ onSuggestionClick: send,
15487
+ sendToChat: send,
15488
+ refresh: refresh,
15489
+ isChatBusy: isChatBusy$1,
15490
+ widgetParams: widgetParams
15491
+ };
15492
+ };
15493
+ // Mirrors each inner render (submit start → skeleton, stream partials,
15494
+ // resolve/error) into this widget's state and re-renders on the client.
15495
+ var handleInnerRender = function handleInnerRender(renderState) {
15496
+ tasksState = renderState;
15497
+ if (refetchPending) return;
15498
+ if (renderState.error) {
15499
+ // A failed task (including a mid-stream `error` event) must not leave
15500
+ // any streamed partial visible. There's no error UI for now, so fall
15501
+ // back to a blank suggestions state.
15502
+ suggestions = [];
15503
+ } else if (renderState.isLoading || renderState.output !== undefined) {
15504
+ // Only adopt the inner output once a request is loading or has
15505
+ // produced one, so the initial no-op render doesn't clobber pills.
15506
+ suggestions = parseSuggestions(renderState.output);
15507
+ }
15508
+ isLoading = renderState.isLoading;
15509
+ if (!latestRenderOptions) return;
15510
+ renderOutward(latestRenderOptions);
15511
+ };
15512
+ var tasksWidget = connectTasks(handleInnerRender, noop)(_object_spread_props(_object_spread({}, transport ? {
15513
+ transport: transport
15514
+ } : {
15515
+ agentId: agentId
15516
+ }), {
15517
+ task: configurationId,
15518
+ stream: true
15519
+ }));
15520
+ return {
15521
+ $$type: 'ais.promptSuggestions',
15522
+ init: function init(initOptions) {
15523
+ var instantSearchInstance = initOptions.instantSearchInstance;
15524
+ tasksWidget.init(initOptions);
15525
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState(initOptions)), {
15526
+ instantSearchInstance: instantSearchInstance
15527
+ }), true);
15528
+ },
15529
+ render: function render(renderOptions) {
15530
+ var results = renderOptions.results, instantSearchInstance = renderOptions.instantSearchInstance;
15531
+ latestRenderOptions = renderOptions;
15532
+ if (!results) {
15533
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState(renderOptions)), {
15534
+ instantSearchInstance: instantSearchInstance
15535
+ }), false);
15536
+ return;
15537
+ }
15538
+ var stateSignature = getStateSignature(results);
15539
+ if (stateSignature !== lastStateSignature) {
15540
+ lastStateSignature = stateSignature;
15541
+ refetchPending = true;
15542
+ clearTimeout(debounceTimer);
15543
+ debounceTimer = setTimeout(function() {
15544
+ if (latestRenderOptions === null || latestRenderOptions === void 0 ? void 0 : latestRenderOptions.results) {
15545
+ fetchAndRender(latestRenderOptions.results, latestRenderOptions);
15546
+ }
15547
+ }, DEBOUNCE_MS);
15548
+ }
15549
+ renderFn(_object_spread_props(_object_spread({}, getWidgetRenderState(renderOptions)), {
15550
+ instantSearchInstance: instantSearchInstance
15551
+ }), false);
15552
+ },
15553
+ dispose: function dispose(disposeOptions) {
15554
+ disposed = true;
15555
+ clearTimeout(debounceTimer);
15556
+ tasksWidget.dispose(disposeOptions);
15557
+ unmountFn();
15558
+ },
15559
+ getRenderState: function getRenderState(renderState, renderOptions) {
15560
+ return _object_spread_props(_object_spread({}, renderState), _define_property({}, RENDER_STATE_KEY, this.getWidgetRenderState(renderOptions)));
15561
+ },
15562
+ getWidgetRenderState: function getWidgetRenderState1(renderOptions) {
15563
+ return getWidgetRenderState(renderOptions);
15564
+ }
15565
+ };
15566
+ };
15567
+ };
15568
+
15569
+ function usePromptSuggestions(props, additionalWidgetProperties) {
15570
+ return useConnector(connectPromptSuggestions, props, additionalWidgetProperties);
14767
15571
  }
14768
15572
 
14769
15573
  var withUsage$n = createDocumentationMessageGenerator({
@@ -19543,6 +20347,34 @@
19543
20347
  d: "M17 14V2"
19544
20348
  }));
19545
20349
  }
20350
+ function BrainIcon(param) {
20351
+ var createElement = param.createElement;
20352
+ return /*#__PURE__*/ createElement("svg", {
20353
+ xmlns: "http://www.w3.org/2000/svg",
20354
+ viewBox: "0 0 24 24",
20355
+ fill: "none",
20356
+ stroke: "currentColor",
20357
+ strokeLinecap: "round",
20358
+ strokeLinejoin: "round",
20359
+ "aria-hidden": "true"
20360
+ }, /*#__PURE__*/ createElement("path", {
20361
+ d: "M12 18V5"
20362
+ }), /*#__PURE__*/ createElement("path", {
20363
+ d: "M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4"
20364
+ }), /*#__PURE__*/ createElement("path", {
20365
+ d: "M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5"
20366
+ }), /*#__PURE__*/ createElement("path", {
20367
+ d: "M17.997 5.125a4 4 0 0 1 2.526 5.77"
20368
+ }), /*#__PURE__*/ createElement("path", {
20369
+ d: "M18 18a4 4 0 0 0 2-7.464"
20370
+ }), /*#__PURE__*/ createElement("path", {
20371
+ d: "M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517"
20372
+ }), /*#__PURE__*/ createElement("path", {
20373
+ d: "M6 18a4 4 0 0 1-2-7.464"
20374
+ }), /*#__PURE__*/ createElement("path", {
20375
+ d: "M6.003 5.125a4 4 0 0 0-2.526 5.77"
20376
+ }));
20377
+ }
19546
20378
  function ChevronLeftIcon(param) {
19547
20379
  var createElement = param.createElement;
19548
20380
  return /*#__PURE__*/ createElement("svg", {
@@ -20196,6 +21028,22 @@
20196
21028
  };
20197
21029
  }
20198
21030
 
21031
+ function updateNavigationButtonsProps(param) {
21032
+ var listRef = param.listRef, nextButtonRef = param.nextButtonRef, previousButtonRef = param.previousButtonRef, setCanScrollLeft = param.setCanScrollLeft, setCanScrollRight = param.setCanScrollRight;
21033
+ if (!listRef.current) {
21034
+ return;
21035
+ }
21036
+ var isLeftHidden = listRef.current.scrollLeft <= 0;
21037
+ var isRightHidden = listRef.current.scrollLeft + listRef.current.clientWidth >= listRef.current.scrollWidth;
21038
+ setCanScrollLeft(!isLeftHidden);
21039
+ setCanScrollRight(!isRightHidden);
21040
+ if (previousButtonRef.current) {
21041
+ previousButtonRef.current.hidden = isLeftHidden;
21042
+ }
21043
+ if (nextButtonRef.current) {
21044
+ nextButtonRef.current.hidden = isRightHidden;
21045
+ }
21046
+ }
20199
21047
  var lastCarouselId = 0;
20200
21048
  function generateCarouselId() {
20201
21049
  return "ais-Carousel-".concat(lastCarouselId++);
@@ -20229,7 +21077,7 @@
20229
21077
  }));
20230
21078
  }
20231
21079
  function createCarouselComponent(param) {
20232
- var createElement = param.createElement, Fragment = param.Fragment;
21080
+ var createElement = param.createElement, Fragment = param.Fragment, useEffect = param.useEffect, useRef = param.useRef;
20233
21081
  return function Carousel(userProps) {
20234
21082
  var listRef = userProps.listRef, nextButtonRef = userProps.nextButtonRef, previousButtonRef = userProps.previousButtonRef, carouselIdRef = userProps.carouselIdRef, canScrollLeft = userProps.canScrollLeft, canScrollRight = userProps.canScrollRight, setCanScrollLeft = userProps.setCanScrollLeft, setCanScrollRight = userProps.setCanScrollRight, _userProps_classNames = userProps.classNames, classNames = _userProps_classNames === void 0 ? {} : _userProps_classNames, tmp = userProps.itemComponent, ItemComponent = tmp === void 0 ? createDefaultItemComponent({
20235
21083
  createElement: createElement,
@@ -20260,6 +21108,7 @@
20260
21108
  previousButtonLabel: 'Previous',
20261
21109
  previousButtonTitle: 'Previous'
20262
21110
  }, userTranslations);
21111
+ var previousItemsLengthRef = useRef(items.length);
20263
21112
  var cssClasses = {
20264
21113
  root: cx('ais-Carousel', classNames.root),
20265
21114
  list: cx('ais-Carousel-list', classNames.list),
@@ -20278,27 +21127,33 @@
20278
21127
  listRef.current.scrollLeft += listRef.current.offsetWidth * 0.75;
20279
21128
  }
20280
21129
  }
20281
- function updateNavigationButtonsProps() {
20282
- if (!listRef.current) {
20283
- return;
20284
- }
20285
- var isLeftHidden = listRef.current.scrollLeft <= 0;
20286
- var isRightHidden = listRef.current.scrollLeft + listRef.current.clientWidth >= listRef.current.scrollWidth;
20287
- setCanScrollLeft(!isLeftHidden);
20288
- setCanScrollRight(!isRightHidden);
20289
- if (previousButtonRef.current) {
20290
- previousButtonRef.current.hidden = isLeftHidden;
20291
- }
20292
- if (nextButtonRef.current) {
20293
- nextButtonRef.current.hidden = isRightHidden;
21130
+ useEffect(function() {
21131
+ if (previousItemsLengthRef.current !== items.length) {
21132
+ updateNavigationButtonsProps({
21133
+ listRef: listRef,
21134
+ nextButtonRef: nextButtonRef,
21135
+ previousButtonRef: previousButtonRef,
21136
+ setCanScrollLeft: setCanScrollLeft,
21137
+ setCanScrollRight: setCanScrollRight
21138
+ });
21139
+ previousItemsLengthRef.current = items.length;
20294
21140
  }
20295
- }
21141
+ }, [
21142
+ items.length,
21143
+ listRef,
21144
+ nextButtonRef,
21145
+ previousButtonRef,
21146
+ setCanScrollLeft,
21147
+ setCanScrollRight
21148
+ ]);
20296
21149
  if (items.length === 0) {
20297
21150
  return null;
20298
21151
  }
21152
+ var itemOccurrences = new Map();
20299
21153
  return /*#__PURE__*/ createElement("div", _object_spread_props(_object_spread({}, props), {
20300
21154
  className: cx(cssClasses.root)
20301
21155
  }), HeaderComponent && /*#__PURE__*/ createElement(HeaderComponent, {
21156
+ nbItems: items.length,
20302
21157
  canScrollLeft: canScrollLeft,
20303
21158
  canScrollRight: canScrollRight,
20304
21159
  scrollLeft: scrollLeft,
@@ -20324,7 +21179,15 @@
20324
21179
  "aria-roledescription": "carousel",
20325
21180
  "aria-label": translations.listLabel,
20326
21181
  "aria-live": "polite",
20327
- onScroll: updateNavigationButtonsProps,
21182
+ onScroll: function onScroll() {
21183
+ return updateNavigationButtonsProps({
21184
+ listRef: listRef,
21185
+ nextButtonRef: nextButtonRef,
21186
+ previousButtonRef: previousButtonRef,
21187
+ setCanScrollLeft: setCanScrollLeft,
21188
+ setCanScrollRight: setCanScrollRight
21189
+ });
21190
+ },
20328
21191
  onKeyDown: function onKeyDown(event) {
20329
21192
  if (event.key === 'ArrowLeft') {
20330
21193
  event.preventDefault();
@@ -20335,8 +21198,14 @@
20335
21198
  }
20336
21199
  }
20337
21200
  }, items.map(function(item, index) {
21201
+ var _itemOccurrences_get;
21202
+ var occurrence = (_itemOccurrences_get = itemOccurrences.get(item.objectID)) !== null && _itemOccurrences_get !== void 0 ? _itemOccurrences_get : 0;
21203
+ itemOccurrences.set(item.objectID, occurrence + 1);
20338
21204
  return /*#__PURE__*/ createElement("li", {
20339
- key: item.objectID,
21205
+ key: JSON.stringify([
21206
+ item.objectID,
21207
+ occurrence
21208
+ ]),
20340
21209
  className: cx(cssClasses.item),
20341
21210
  "aria-roledescription": "slide",
20342
21211
  "aria-label": "".concat(index + 1, " of ").concat(items.length),
@@ -20446,7 +21315,7 @@
20446
21315
  var SearchIndexToolType$1 = 'algolia_search_index';
20447
21316
  var getTextContent = function getTextContent(message) {
20448
21317
  return message.parts.map(function(part) {
20449
- return 'text' in part ? part.text : '';
21318
+ return part.type === 'text' ? part.text : '';
20450
21319
  }).join('');
20451
21320
  };
20452
21321
  var hasTextContent = function hasTextContent(message) {
@@ -20458,6 +21327,12 @@
20458
21327
  var isPartTool = function isPartTool(part) {
20459
21328
  return startsWith(part.type, 'tool-');
20460
21329
  };
21330
+ function isReasoningPartActive(parts, index) {
21331
+ var part = parts[index];
21332
+ return (part === null || part === void 0 ? void 0 : part.type) === 'reasoning' && part.state === 'streaming' && !parts.slice(index + 1).some(function(laterPart) {
21333
+ return laterPart.type !== 'reasoning' || laterPart.state === 'streaming';
21334
+ });
21335
+ }
20461
21336
  var findTool = function findTool(partType, tools) {
20462
21337
  var toolName = partType.replace('tool-', '');
20463
21338
  var tool = tools[toolName];
@@ -20471,22 +21346,23 @@
20471
21346
  return tool;
20472
21347
  };
20473
21348
  var FACET_KEY_PREFIX = 'facet_';
20474
- /**
20475
- * Extracts the `facetFilters` from a search tool input.
20476
- *
20477
- * The default search tool provides a ready-to-use `facet_filters` array. The
20478
- * Algolia MCP Server search tool instead expresses refinements as individual
20479
- * `facet_<attribute>` keys (e.g. `facet_categories: ['Books', 'Toys']`), which
20480
- * are converted here into the `[['attribute:value']]` shape `applyFilters`
20481
- * expects.
20482
- */ var getFacetFiltersFromToolInput = function getFacetFiltersFromToolInput(input) {
21349
+ var hasQueries = function hasQueries(input) {
21350
+ return Array.isArray(input.queries);
21351
+ };
21352
+ var getSearchToolQuery = function getSearchToolQuery(input) {
20483
21353
  if (!input) {
20484
21354
  return undefined;
20485
21355
  }
20486
- if (Array.isArray(input.facet_filters)) {
20487
- return input.facet_filters;
21356
+ return hasQueries(input) ? input.queries[0] : input;
21357
+ };
21358
+ var getFacetFilters = function getFacetFilters(query) {
21359
+ if (!query) {
21360
+ return undefined;
21361
+ }
21362
+ if (Array.isArray(query.facet_filters)) {
21363
+ return query.facet_filters;
20488
21364
  }
20489
- var facetFilters = Object.entries(input).reduce(function(acc, param) {
21365
+ var facetFilters = Object.entries(query).reduce(function(acc, param) {
20490
21366
  var _param = _sliced_to_array(param, 2), key = _param[0], value = _param[1];
20491
21367
  if (!startsWith(key, FACET_KEY_PREFIX) || !Array.isArray(value)) {
20492
21368
  return acc;
@@ -20504,6 +21380,21 @@
20504
21380
  }, []);
20505
21381
  return facetFilters.length > 0 ? facetFilters : undefined;
20506
21382
  };
21383
+ /**
21384
+ * Extracts the refinements a search tool searched with, in the shape
21385
+ * `applyFilters` expects.
21386
+ *
21387
+ * The default search tool provides a ready-to-use `facet_filters` array. The
21388
+ * Algolia MCP Server search tool instead expresses refinements as individual
21389
+ * `facet_<attribute>` keys (e.g. `facet_categories: ['Books', 'Toys']`), which
21390
+ * are converted here into `[['attribute:value']]`.
21391
+ */ var getApplyFiltersParamsFromToolInput = function getApplyFiltersParamsFromToolInput(input) {
21392
+ var query = getSearchToolQuery(input);
21393
+ return {
21394
+ query: query === null || query === void 0 ? void 0 : query.query,
21395
+ facetFilters: getFacetFilters(query)
21396
+ };
21397
+ };
20507
21398
  var isSearchToolPart = function isSearchToolPart(part) {
20508
21399
  return part.type === "tool-".concat(SearchIndexToolType$1) || // Compatibility shim with Algolia MCP Server search tool
20509
21400
  startsWith(part.type, "tool-".concat(SearchIndexToolType$1, "_"));
@@ -20531,59 +21422,72 @@
20531
21422
  * relies on this map to hydrate each result with the full record that the
20532
21423
  * preceding search tool already fetched.
20533
21424
  *
20534
- * Pass `untilToolCallId` (the display tool's own `toolCallId`) to scope
20535
- * collection to the turn that produced it: hits are only gathered up to and
20536
- * including the message that contains that tool call. This prevents a later
20537
- * turn's search from overwriting an earlier display tool's records (and their
20538
- * per-query metadata like `__queryID`).
20539
- */ var getHitsByObjectID = function getHitsByObjectID(messages, untilToolCallId) {
20540
- var hitsByObjectID = {};
20541
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
20542
- try {
20543
- var _loop = function _loop() {
20544
- var message = _step.value;
20545
- var reachedBoundary = false;
20546
- message.parts.forEach(function(part) {
20547
- if (!isPartTool(part)) {
20548
- return;
20549
- }
20550
- // Note the boundary but keep processing the rest of this message's parts:
20551
- // the search tool that fed this display tool lives in the same message,
20552
- // so its hits must still be collected before we stop.
20553
- if (untilToolCallId && part.toolCallId === untilToolCallId) {
20554
- reachedBoundary = true;
20555
- }
20556
- if (isSearchToolPart(part)) {
20557
- collectHitsFromPart(part, hitsByObjectID);
20558
- }
20559
- });
20560
- if (reachedBoundary) {
20561
- return "break";
21425
+ * Pass the display tool's own message part to scope collection to that exact
21426
+ * occurrence. This prevents reused tool call IDs and later searches from
21427
+ * changing another display tool's records or per-query metadata like
21428
+ * `__queryID`.
21429
+ */ var getHitsByObjectID = function getHitsByObjectID(messages, untilToolPart) {
21430
+ var hitsByObjectID = Object.create(null);
21431
+ var reachedBoundary = messages.some(function(message) {
21432
+ return message.parts.some(function(part) {
21433
+ if (!isPartTool(part)) {
21434
+ return false;
20562
21435
  }
20563
- };
20564
- for(var _iterator = messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
20565
- var _ret = _loop();
20566
- if (_ret === "break") break;
20567
- }
20568
- } catch (err) {
20569
- _didIteratorError = true;
20570
- _iteratorError = err;
20571
- } finally{
20572
- try {
20573
- if (!_iteratorNormalCompletion && _iterator.return != null) {
20574
- _iterator.return();
21436
+ if (untilToolPart && part === untilToolPart) {
21437
+ return true;
20575
21438
  }
20576
- } finally{
20577
- if (_didIteratorError) {
20578
- throw _iteratorError;
21439
+ if (isSearchToolPart(part)) {
21440
+ collectHitsFromPart(part, hitsByObjectID);
20579
21441
  }
20580
- }
21442
+ return false;
21443
+ });
21444
+ });
21445
+ if (untilToolPart && !reachedBoundary) {
21446
+ return Object.create(null);
20581
21447
  }
20582
21448
  return hitsByObjectID;
20583
21449
  };
20584
21450
 
20585
21451
  function n(){return n=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var t in r)Object.prototype.hasOwnProperty.call(r,t)&&(e[t]=r[t]);}return e},n.apply(this,arguments)}const o=["allowFullScreen","allowTransparency","autoComplete","autoFocus","autoPlay","cellPadding","cellSpacing","charSet","classId","colSpan","contentEditable","contextMenu","crossOrigin","encType","formAction","formEncType","formMethod","formNoValidate","formTarget","frameBorder","hrefLang","inputMode","keyParams","keyType","marginHeight","marginWidth","maxLength","mediaGroup","minLength","noValidate","radioGroup","readOnly","rowSpan","spellCheck","srcDoc","srcLang","srcSet","tabIndex","useMap"].reduce((e,n)=>(e[n.toLowerCase()]=n,e),{class:"className",for:"htmlFor"}),a={amp:"&",apos:"'",gt:">",lt:"<",nbsp:" ",quot:"“"},c=["style","script","pre"],i=["src","href","data","formAction","srcDoc","action"],u=/([-A-Z0-9_:]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|(?:\{((?:\\.|{[^}]*?}|[^}])*)\})))?/gi,l=/\n{2,}$/,s=/^(\s*>[\s\S]*?)(?=\n\n|$)/,f=/^ *> ?/gm,_=/^(?:\[!([^\]]*)\]\n)?([\s\S]*)/,d=/^ {2,}\n/,p=/^(?:([-*_])( *\1){2,}) *(?:\n *)+\n/,y=/^(?: {1,3})?(`{3,}|~{3,}) *(\S+)? *([^\n]*?)?\n([\s\S]*?)(?:\1\n?|$)/,h=/^(?: {4}[^\n]+\n*)+(?:\n *)+\n?/,g=/^(`+)((?:\\`|(?!\1)`|[^`])+)\1/,m=/^(?:\n *)*\n/,k=/\r\n?/g,x=/^\[\^([^\]]+)](:(.*)((\n+ {4,}.*)|(\n(?!\[\^).+))*)/,q=/^\[\^([^\]]+)]/,v=/\f/g,b=/^---[ \t]*\n(.|\n)*\n---[ \t]*\n/,$=/^\s*?\[(x|\s)\]/,S=/^ *(#{1,6}) *([^\n]+?)(?: +#*)?(?:\n *)*(?:\n|$)/,z=/^ *(#{1,6}) +([^\n]+?)(?: +#*)?(?:\n *)*(?:\n|$)/,E=/^([^\n]+)\n *(=|-)\2{2,} *\n/,A=/^ *(?!<[a-z][^ >/]* ?\/>)<([a-z][^ >/]*) ?((?:[^>]*[^/])?)>\n?(\s*(?:<\1[^>]*?>[\s\S]*?<\/\1>|(?!<\1\b)[\s\S])*?)<\/\1>(?!<\/\1>)\n*/i,R=/&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-fA-F]{1,6});/gi,B=/^<!--[\s\S]*?(?:-->)/,L=/^(data|aria|x)-[a-z_][a-z\d_.-]*$/,O=/^ *<([a-z][a-z0-9:]*)(?:\s+((?:<.*?>|[^>])*))?\/?>(?!<\/\1>)(\s*\n)?/i,j=/^\{.*\}$/,C=/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,I=/^<([^ >]+[:@\/][^ >]+)>/,T=/-([a-z])?/gi,M=/^(\|.*)\n(?: *(\|? *[-:]+ *\|[-| :]*)\n((?:.*\|.*\n)*))?\n?/,w=/^[^\n]+(?: \n|\n{2,})/,D=/^\[([^\]]*)\]:\s+<?([^\s>]+)>?\s*("([^"]*)")?/,F=/^!\[([^\]]*)\] ?\[([^\]]*)\]/,P=/^\[([^\]]*)\] ?\[([^\]]*)\]/,Z=/(\n|^[-*]\s|^#|^ {2,}|^-{2,}|^>\s)/,N=/\t/g,G=/(^ *\||\| *$)/g,U=/^ *:-+: *$/,V=/^ *:-+ *$/,H=/^ *-+: *$/,Q=e=>`(?=[\\s\\S]+?\\1${e?"\\1":""})`,W="((?:\\[.*?\\][([].*?[)\\]]|<.*?>(?:.*?<.*?>)?|`.*?`|\\\\\\1|[\\s\\S])+?)",J=RegExp(`^([*_])\\1${Q(1)}${W}\\1\\1(?!\\1)`),K=RegExp(`^([*_])${Q(0)}${W}\\1(?!\\1)`),X=RegExp(`^(==)${Q(0)}${W}\\1`),Y=RegExp(`^(~~)${Q(0)}${W}\\1`),ee=/^(:[a-zA-Z0-9-_]+:)/,ne=/^\\([^0-9A-Za-z\s])/,re=/\\([^0-9A-Za-z\s])/g,te=/^[\s\S](?:(?! \n|[0-9]\.|http)[^=*_~\-\n:<`\\\[!])*/,oe=/^\n+/,ae=/^([ \t]*)/,ce=/(?:^|\n)( *)$/,ie="(?:\\d+\\.)",ue="(?:[*+-])";function le(e){return "( *)("+(1===e?ie:ue)+") +"}const se=le(1),fe=le(2);function _e(e){return RegExp("^"+(1===e?se:fe))}const de=_e(1),pe=_e(2);function ye(e){return RegExp("^"+(1===e?se:fe)+"[^\\n]*(?:\\n(?!\\1"+(1===e?ie:ue)+" )[^\\n]*)*(\\n|$)","gm")}const he=ye(1),ge=ye(2);function me(e){const n=1===e?ie:ue;return RegExp("^( *)("+n+") [\\s\\S]+?(?:\\n{2,}(?! )(?!\\1"+n+" (?!"+n+" ))\\n*|\\s*\\n*$)")}const ke=me(1),xe=me(2);function qe(e,n){const r=1===n,t=r?ke:xe,o=r?he:ge,a=r?de:pe;return {t:e=>a.test(e),o:je(function(e,n){const r=ce.exec(n.prevCapture);return r&&(n.list||!n.inline&&!n.simple)?t.exec(e=r[1]+e):null}),i:1,u(e,n,t){const c=r?+e[2]:void 0,i=e[0].replace(l,"\n").match(o);let u=!1;return {items:i.map(function(e,r){const o=a.exec(e)[0].length,c=RegExp("^ {1,"+o+"}","gm"),l=e.replace(c,"").replace(a,""),s=r===i.length-1,f=-1!==l.indexOf("\n\n")||s&&u;u=f;const _=t.inline,d=t.list;let p;t.list=!0,f?(t.inline=!1,p=Se(l)+"\n\n"):(t.inline=!0,p=Se(l));const y=n(p,t);return t.inline=_,t.list=d,y}),ordered:r,start:c}},l:(n,r,t)=>e(n.ordered?"ol":"ul",{key:t.key,start:"20"===n.type?n.start:void 0},n.items.map(function(n,o){return e("li",{key:o},r(n,t))}))}}const ve=RegExp("^\\[((?:\\[[^\\[\\]]*(?:\\[[^\\[\\]]*\\][^\\[\\]]*)*\\]|[^\\[\\]])*)\\]\\(\\s*<?((?:\\([^)]*\\)|[^\\s\\\\]|\\\\.)*?)>?(?:\\s+['\"]([\\s\\S]*?)['\"])?\\s*\\)"),be=/^!\[(.*?)\]\( *((?:\([^)]*\)|[^() ])*) *"?([^)"]*)?"?\)/;function $e(e){return "string"==typeof e}function Se(e){let n=e.length;for(;n>0&&e[n-1]<=" ";)n--;return e.slice(0,n)}function ze(e,n){return e.startsWith(n)}function Ee(e,n,r){if(Array.isArray(r)){for(let n=0;n<r.length;n++)if(ze(e,r[n]))return !0;return !1}return r(e,n)}function Ae(e){return e.replace(/[ÀÁÂÃÄÅàáâãä忯]/g,"a").replace(/[çÇ]/g,"c").replace(/[ðÐ]/g,"d").replace(/[ÈÉÊËéèêë]/g,"e").replace(/[ÏïÎîÍíÌì]/g,"i").replace(/[Ññ]/g,"n").replace(/[øØœŒÕõÔôÓóÒò]/g,"o").replace(/[ÜüÛûÚúÙù]/g,"u").replace(/[ŸÿÝý]/g,"y").replace(/[^a-z0-9- ]/gi,"").replace(/ /gi,"-").toLowerCase()}function Re(e){return H.test(e)?"right":U.test(e)?"center":V.test(e)?"left":null}function Be(e,n,r,t){const o=r.inTable;r.inTable=!0;let a=[[]],c="";function i(){if(!c)return;const e=a[a.length-1];e.push.apply(e,n(c,r)),c="";}return e.trim().split(/(`[^`]*`|\\\||\|)/).filter(Boolean).forEach((e,n,r)=>{"|"===e.trim()&&(i(),t)?0!==n&&n!==r.length-1&&a.push([]):c+=e;}),i(),r.inTable=o,a}function Le(e,n,r){r.inline=!0;const t=e[2]?e[2].replace(G,"").split("|").map(Re):[],o=e[3]?function(e,n,r){return e.trim().split("\n").map(function(e){return Be(e,n,r,!0)})}(e[3],n,r):[],a=Be(e[1],n,r,!!o.length);return r.inline=!1,o.length?{align:t,cells:o,header:a,type:"25"}:{children:a,type:"21"}}function Oe(e,n){return null==e.align[n]?{}:{textAlign:e.align[n]}}function je(e){return e.inline=1,e}function Ce(e){return je(function(n,r){return r.inline?e.exec(n):null})}function Ie(e){return je(function(n,r){return r.inline||r.simple?e.exec(n):null})}function Te(e){return function(n,r){return r.inline||r.simple?null:e.exec(n)}}function Me(e){return je(function(n){return e.exec(n)})}const we=/(javascript|vbscript|data(?!:image)):/i;function De(e){try{const n=decodeURIComponent(e).replace(/[^A-Za-z0-9/:]/g,"");if(we.test(n))return null}catch(e){return null}return e}function Fe(e){return e?e.replace(re,"$1"):e}function Pe(e,n,r){const t=r.inline||!1,o=r.simple||!1;r.inline=!0,r.simple=!0;const a=e(n,r);return r.inline=t,r.simple=o,a}function Ze(e,n,r){const t=r.inline||!1,o=r.simple||!1;r.inline=!1,r.simple=!0;const a=e(n,r);return r.inline=t,r.simple=o,a}function Ne(e,n,r){const t=r.inline||!1;r.inline=!1;const o=e(n,r);return r.inline=t,o}const Ge=(e,n,r)=>({children:Pe(n,e[2],r)});function Ue(){return {}}function Ve(){return null}function He(...e){return e.filter(Boolean).join(" ")}function Qe(e,n,r){let t=e;const o=n.split(".");for(;o.length&&(t=t[o[0]],void 0!==t);)o.shift();return t||r}function We(r="",t={}){t.overrides=t.overrides||{},t.namedCodesToUnicode=t.namedCodesToUnicode?n({},a,t.namedCodesToUnicode):a;const l=t.slugify||Ae,G=t.sanitizer||De,U=t.createElement||React__namespace.createElement,V=[s,y,h,t.enforceAtxHeadings?z:S,E,M,ke,xe],H=[...V,w,A,B,O];function Q(e,n){for(let r=0;r<e.length;r++)if(e[r].test(n))return !0;return !1}function W(e,r,...o){const a=Qe(t.overrides,e+".props",{});return U(function(e,n){const r=Qe(n,e);return r?"function"==typeof r||"object"==typeof r&&"render"in r?r:Qe(n,e+".component",e):e}(e,t.overrides),n({},r,a,{className:He(null==r?void 0:r.className,a.className)||void 0}),...o)}function re(e){e=e.replace(b,"");let n=!1;t.forceInline?n=!0:t.forceBlock||(n=!1===Z.test(e));const r=fe(se(n?e:Se(e).replace(oe,"")+"\n\n",{inline:n}));for(;$e(r[r.length-1])&&!r[r.length-1].trim();)r.pop();if(null===t.wrapper)return r;const o=t.wrapper||(n?"span":"div");let a;if(r.length>1||t.forceWrapper)a=r;else {if(1===r.length)return a=r[0],"string"==typeof a?W("span",{key:"outer"},a):a;a=null;}return U(o,{key:"outer"},a)}function ce(e,n){if(!n||!n.trim())return null;const r=n.match(u);return r?r.reduce(function(n,r){const t=r.indexOf("=");if(-1!==t){const a=function(e){return -1!==e.indexOf("-")&&null===e.match(L)&&(e=e.replace(T,function(e,n){return n.toUpperCase()})),e}(r.slice(0,t)).trim(),c=function(e){const n=e[0];return ('"'===n||"'"===n)&&e.length>=2&&e[e.length-1]===n?e.slice(1,-1):e}(r.slice(t+1).trim()),u=o[a]||a;if("ref"===u)return n;const l=n[u]=function(e,n,r,t){return "style"===n?function(e){const n=[];let r="",t=!1,o=!1,a="";if(!e)return n;for(let c=0;c<e.length;c++){const i=e[c];if('"'!==i&&"'"!==i||t||(o?i===a&&(o=!1,a=""):(o=!0,a=i)),"("===i&&r.endsWith("url")?t=!0:")"===i&&t&&(t=!1),";"!==i||o||t)r+=i;else {const e=r.trim();if(e){const r=e.indexOf(":");if(r>0){const t=e.slice(0,r).trim(),o=e.slice(r+1).trim();n.push([t,o]);}}r="";}}const c=r.trim();if(c){const e=c.indexOf(":");if(e>0){const r=c.slice(0,e).trim(),t=c.slice(e+1).trim();n.push([r,t]);}}return n}(r).reduce(function(n,[r,o]){return n[r.replace(/(-[a-z])/g,e=>e[1].toUpperCase())]=t(o,e,r),n},{}):-1!==i.indexOf(n)?t(Fe(r),e,n):(r.match(j)&&(r=Fe(r.slice(1,r.length-1))),"true"===r||"false"!==r&&r)}(e,a,c,G);"string"==typeof l&&(A.test(l)||O.test(l))&&(n[u]=re(l.trim()));}else "style"!==r&&(n[o[r]||r]=!0);return n},{}):null}const ie=[],ue={},le={0:{t:[">"],o:Te(s),i:1,u(e,n,r){const[,t,o]=e[0].replace(f,"").match(_);return {alert:t,children:n(o,r)}},l(e,n,r){const t={key:r.key};return e.alert&&(t.className="markdown-alert-"+l(e.alert.toLowerCase(),Ae),e.children.unshift({attrs:{},children:[{type:"27",text:e.alert}],noInnerParse:!0,type:"11",tag:"header"})),W("blockquote",t,n(e.children,r))}},1:{t:[" "],o:Me(d),i:1,u:Ue,l:(e,n,r)=>W("br",{key:r.key})},2:{t:["--","__","**","- ","* ","_ "],o:Te(p),i:1,u:Ue,l:(e,n,r)=>W("hr",{key:r.key})},3:{t:[" "],o:Te(h),i:0,u:e=>({lang:void 0,text:Fe(Se(e[0].replace(/^ {4}/gm,"")))}),l:(e,r,t)=>W("pre",{key:t.key},W("code",n({},e.attrs,{className:e.lang?"lang-"+e.lang:""}),e.text))},4:{t:["```","~~~"],o:Te(y),i:0,u:e=>({attrs:ce("code",e[3]||""),lang:e[2]||void 0,text:e[4],type:"3"})},5:{t:["`"],o:Ie(g),i:3,u:e=>({text:Fe(e[2])}),l:(e,n,r)=>W("code",{key:r.key},e.text)},6:{t:["[^"],o:Te(x),i:0,u:e=>(ie.push({footnote:e[2],identifier:e[1]}),{}),l:Ve},7:{t:["[^"],o:Ce(q),i:1,u:e=>({target:"#"+l(e[1],Ae),text:e[1]}),l:(e,n,r)=>W("a",{key:r.key,href:G(e.target,"a","href")},W("sup",{key:r.key},e.text))},8:{t:["[ ]","[x]"],o:Ce($),i:1,u:e=>({completed:"x"===e[1].toLowerCase()}),l:(e,n,r)=>W("input",{checked:e.completed,key:r.key,readOnly:!0,type:"checkbox"})},9:{t:["#"],o:Te(t.enforceAtxHeadings?z:S),i:1,u:(e,n,r)=>({children:Pe(n,e[2],r),id:l(e[2],Ae),level:e[1].length}),l:(e,n,r)=>W("h"+e.level,{id:e.id,key:r.key},n(e.children,r))},10:{t:e=>{const n=e.indexOf("\n");return n>0&&n<e.length-1&&("="===e[n+1]||"-"===e[n+1])},o:Te(E),i:0,u:(e,n,r)=>({children:Pe(n,e[1],r),level:"="===e[2]?1:2,type:"9"})},11:{t:["<"],o:Me(A),i:1,u(e,n,r){const[,t]=e[3].match(ae),o=RegExp("^"+t,"gm"),a=e[3].replace(o,""),i=Q(H,a)?Ne:Pe,u=e[1].toLowerCase(),l=-1!==c.indexOf(u),s=(l?u:e[1]).trim(),f={attrs:ce(s,e[2]),noInnerParse:l,tag:s};if(r.inAnchor=r.inAnchor||"a"===u,l)f.text=e[3];else {const e=r.inHTML;r.inHTML=!0,f.children=i(n,a,r),r.inHTML=e;}return r.inAnchor=!1,f},l:(e,r,t)=>W(e.tag,n({key:t.key},e.attrs),e.text||(e.children?r(e.children,t):""))},13:{t:["<"],o:Me(O),i:1,u(e){const n=e[1].trim();return {attrs:ce(n,e[2]||""),tag:n}},l:(e,r,t)=>W(e.tag,n({},e.attrs,{key:t.key}))},12:{t:["\x3c!--"],o:Me(B),i:1,u:()=>({}),l:Ve},14:{t:["!["],o:Ie(be),i:1,u:e=>({alt:Fe(e[1]),target:Fe(e[2]),title:Fe(e[3])}),l:(e,n,r)=>W("img",{key:r.key,alt:e.alt||void 0,title:e.title||void 0,src:G(e.target,"img","src")})},15:{t:["["],o:Ce(ve),i:3,u:(e,n,r)=>({children:Ze(n,e[1],r),target:Fe(e[2]),title:Fe(e[3])}),l:(e,n,r)=>W("a",{key:r.key,href:G(e.target,"a","href"),title:e.title},n(e.children,r))},16:{t:["<"],o:Ce(I),i:0,u(e){let n=e[1],r=!1;return -1!==n.indexOf("@")&&-1===n.indexOf("//")&&(r=!0,n=n.replace("mailto:","")),{children:[{text:n,type:"27"}],target:r?"mailto:"+n:n,type:"15"}}},17:{t:(e,n)=>!n.inAnchor&&!t.disableAutoLink&&(ze(e,"http://")||ze(e,"https://")),o:Ce(C),i:0,u:e=>({children:[{text:e[1],type:"27"}],target:e[1],title:void 0,type:"15"})},20:qe(W,1),33:qe(W,2),19:{t:["\n"],o:Te(m),i:3,u:Ue,l:()=>"\n"},21:{o:je(function(e,n){if(n.inline||n.simple||n.inHTML&&-1===e.indexOf("\n\n")&&-1===n.prevCapture.indexOf("\n\n"))return null;let r="",t=0;for(;;){const n=e.indexOf("\n",t),o=e.slice(t,-1===n?void 0:n+1);if(Q(V,o))break;if(r+=o,-1===n||!o.trim())break;t=n+1;}const o=Se(r);return ""===o?null:[r,,o]}),i:3,u:Ge,l:(e,n,r)=>W("p",{key:r.key},n(e.children,r))},22:{t:["["],o:Ce(D),i:0,u:e=>(ue[e[1]]={target:e[2],title:e[4]},{}),l:Ve},23:{t:["!["],o:Ie(F),i:0,u:e=>({alt:e[1]?Fe(e[1]):void 0,ref:e[2]}),l:(e,n,r)=>ue[e.ref]?W("img",{key:r.key,alt:e.alt,src:G(ue[e.ref].target,"img","src"),title:ue[e.ref].title}):null},24:{t:e=>"["===e[0]&&-1===e.indexOf("]("),o:Ce(P),i:0,u:(e,n,r)=>({children:n(e[1],r),fallbackChildren:e[0],ref:e[2]}),l:(e,n,r)=>ue[e.ref]?W("a",{key:r.key,href:G(ue[e.ref].target,"a","href"),title:ue[e.ref].title},n(e.children,r)):W("span",{key:r.key},e.fallbackChildren)},25:{t:["|"],o:Te(M),i:1,u:Le,l(e,n,r){const t=e;return W("table",{key:r.key},W("thead",null,W("tr",null,t.header.map(function(e,o){return W("th",{key:o,style:Oe(t,o)},n(e,r))}))),W("tbody",null,t.cells.map(function(e,o){return W("tr",{key:o},e.map(function(e,o){return W("td",{key:o,style:Oe(t,o)},n(e,r))}))})))}},27:{o:je(function(e,n){let r;return ze(e,":")&&(r=ee.exec(e)),r||te.exec(e)}),i:4,u(e){const n=e[0];return {text:-1===n.indexOf("&")?n:n.replace(R,(e,n)=>t.namedCodesToUnicode[n]||e)}},l:e=>e.text},28:{t:["**","__"],o:Ie(J),i:2,u:(e,n,r)=>({children:n(e[2],r)}),l:(e,n,r)=>W("strong",{key:r.key},n(e.children,r))},29:{t:e=>{const n=e[0];return ("*"===n||"_"===n)&&e[1]!==n},o:Ie(K),i:3,u:(e,n,r)=>({children:n(e[2],r)}),l:(e,n,r)=>W("em",{key:r.key},n(e.children,r))},30:{t:["\\"],o:Ie(ne),i:1,u:e=>({text:e[1],type:"27"})},31:{t:["=="],o:Ie(X),i:3,u:Ge,l:(e,n,r)=>W("mark",{key:r.key},n(e.children,r))},32:{t:["~~"],o:Ie(Y),i:3,u:Ge,l:(e,n,r)=>W("del",{key:r.key},n(e.children,r))}};!0===t.disableParsingRawHTML&&(delete le[11],delete le[13]);const se=function(e){var n=Object.keys(e);function r(t,o){var a=[];if(o.prevCapture=o.prevCapture||"",t.trim())for(;t;)for(var c=0;c<n.length;){var i=n[c],u=e[i];if(!u.t||Ee(t,o,u.t)){var l=u.o(t,o);if(l&&l[0]){t=t.substring(l[0].length);var s=u.u(l,r,o);o.prevCapture+=l[0],s.type||(s.type=i),a.push(s);break}c++;}else c++;}return o.prevCapture="",a}return n.sort(function(n,r){return e[n].i-e[r].i||(n<r?-1:1)}),function(e,n){return r(function(e){return e.replace(k,"\n").replace(v,"").replace(N," ")}(e),n)}}(le),fe=function(e,n){return function r(t,o={}){if(Array.isArray(t)){const e=o.key,n=[];let a=!1;for(let e=0;e<t.length;e++){o.key=e;const c=r(t[e],o),i=$e(c);i&&a?n[n.length-1]+=c:null!==c&&n.push(c),a=i;}return o.key=e,n}return function(r,t,o){const a=e[r.type].l;return n?n(()=>a(r,t,o),r,t,o):a(r,t,o)}(t,r,o)}}(le,t.renderRule),_e=re(r);return ie.length?W("div",null,_e,W("footer",{key:"footer"},ie.map(function(e){return W("div",{id:l(e.identifier,Ae),key:e.identifier},e.identifier,fe(se(e.footnote,{inline:!0})))}))):_e}
20586
21452
 
21453
+ function createChatMessageReasoningComponent(param) {
21454
+ var createElement = param.createElement;
21455
+ return function ChatMessageReasoning(userProps) {
21456
+ var part = userProps.part, isStreaming = userProps.isStreaming, _userProps_parseMarkdown = userProps.parseMarkdown, parseMarkdown = _userProps_parseMarkdown === void 0 ? true : _userProps_parseMarkdown, translations = userProps.translations, classNames = userProps.classNames;
21457
+ var body = parseMarkdown ? We(part.text, {
21458
+ createElement: createElement,
21459
+ disableParsingRawHTML: true
21460
+ }) : // newlines markdown would collapse.
21461
+ /*#__PURE__*/ createElement("p", {
21462
+ className: "ais-ChatMessage-text"
21463
+ }, part.text);
21464
+ return /*#__PURE__*/ createElement("details", {
21465
+ className: cx(classNames.reasoning),
21466
+ "aria-label": translations.reasoningLabel,
21467
+ "aria-busy": isStreaming
21468
+ }, /*#__PURE__*/ createElement("summary", {
21469
+ className: cx(classNames.reasoningHeader)
21470
+ }, /*#__PURE__*/ createElement("span", {
21471
+ className: cx(classNames.reasoningIcon),
21472
+ "aria-hidden": "true"
21473
+ }, /*#__PURE__*/ createElement(BrainIcon, {
21474
+ createElement: createElement
21475
+ })), /*#__PURE__*/ createElement("span", {
21476
+ className: cx(classNames.reasoningLabel)
21477
+ }, translations.reasoningLabel), /*#__PURE__*/ createElement("span", {
21478
+ className: cx(classNames.reasoningChevron),
21479
+ "aria-hidden": "true"
21480
+ }, /*#__PURE__*/ createElement(ChevronDownIcon, {
21481
+ createElement: createElement
21482
+ }))), /*#__PURE__*/ createElement("div", {
21483
+ className: cx(classNames.reasoningBody),
21484
+ tabIndex: 0
21485
+ }, /*#__PURE__*/ createElement("div", {
21486
+ className: cx(classNames.reasoningText)
21487
+ }, body)));
21488
+ };
21489
+ }
21490
+
20587
21491
  // Keep in sync with packages/instantsearch.js/src/lib/chat/index.ts
20588
21492
  var SearchIndexToolType = 'algolia_search_index';
20589
21493
  function createChatMessageComponent(param) {
@@ -20591,8 +21495,12 @@
20591
21495
  var Button = createButtonComponent({
20592
21496
  createElement: createElement
20593
21497
  });
21498
+ var ChatMessageReasoning = createChatMessageReasoningComponent({
21499
+ createElement: createElement
21500
+ });
20594
21501
  return function ChatMessage(userProps) {
20595
- var _userProps_classNames = userProps.classNames, classNames = _userProps_classNames === void 0 ? {} : _userProps_classNames, message = userProps.message, status = userProps.status, _userProps_side = userProps.side, side = _userProps_side === void 0 ? 'left' : _userProps_side, _userProps_variant = userProps.variant, variant = _userProps_variant === void 0 ? 'subtle' : _userProps_variant, _userProps_actions = userProps.actions, actions = _userProps_actions === void 0 ? [] : _userProps_actions, _userProps_autoHideActions = userProps.autoHideActions, autoHideActions = _userProps_autoHideActions === void 0 ? false : _userProps_autoHideActions, LeadingComponent = userProps.leadingComponent, ActionsComponent = userProps.actionsComponent, FooterComponent = userProps.footerComponent, _userProps_tools = userProps.tools, tools = _userProps_tools === void 0 ? {} : _userProps_tools, indexUiState = userProps.indexUiState, setIndexUiState = userProps.setIndexUiState, messages = userProps.messages, onClose = userProps.onClose, userTranslations = userProps.translations, suggestionsElement = userProps.suggestionsElement, _userProps_parseMarkdown = userProps.parseMarkdown, parseMarkdown = _userProps_parseMarkdown === void 0 ? true : _userProps_parseMarkdown, props = _object_without_properties(userProps, [
21502
+ var _messages_;
21503
+ var _userProps_classNames = userProps.classNames, classNames = _userProps_classNames === void 0 ? {} : _userProps_classNames, message = userProps.message, status = userProps.status, _userProps_side = userProps.side, side = _userProps_side === void 0 ? 'left' : _userProps_side, _userProps_variant = userProps.variant, variant = _userProps_variant === void 0 ? 'subtle' : _userProps_variant, _userProps_actions = userProps.actions, actions = _userProps_actions === void 0 ? [] : _userProps_actions, _userProps_autoHideActions = userProps.autoHideActions, autoHideActions = _userProps_autoHideActions === void 0 ? false : _userProps_autoHideActions, LeadingComponent = userProps.leadingComponent, ActionsComponent = userProps.actionsComponent, FooterComponent = userProps.footerComponent, _userProps_tools = userProps.tools, tools = _userProps_tools === void 0 ? {} : _userProps_tools, indexUiState = userProps.indexUiState, setIndexUiState = userProps.setIndexUiState, messages = userProps.messages, onClose = userProps.onClose, userTranslations = userProps.translations, suggestionsElement = userProps.suggestionsElement, _userProps_showReasoning = userProps.showReasoning, showReasoning = _userProps_showReasoning === void 0 ? false : _userProps_showReasoning, _userProps_parseMarkdown = userProps.parseMarkdown, parseMarkdown = _userProps_parseMarkdown === void 0 ? true : _userProps_parseMarkdown, props = _object_without_properties(userProps, [
20596
21504
  "classNames",
20597
21505
  "message",
20598
21506
  "status",
@@ -20610,13 +21518,16 @@
20610
21518
  "onClose",
20611
21519
  "translations",
20612
21520
  "suggestionsElement",
21521
+ "showReasoning",
20613
21522
  "parseMarkdown"
20614
21523
  ]);
20615
21524
  var translations = _object_spread({
20616
21525
  messageLabel: 'Message',
20617
- actionsLabel: 'Message actions'
21526
+ actionsLabel: 'Message actions',
21527
+ reasoningLabel: 'Reasoning'
20618
21528
  }, userTranslations);
20619
21529
  var hasLeading = Boolean(LeadingComponent);
21530
+ var isCurrentMessage = messages === undefined || ((_messages_ = messages[messages.length - 1]) === null || _messages_ === void 0 ? void 0 : _messages_.id) === message.id;
20620
21531
  var showActions = Boolean(actions.length > 0 || ActionsComponent) && status === 'ready';
20621
21532
  var cssClasses = {
20622
21533
  root: cx('ais-ChatMessage', "ais-ChatMessage--".concat(side), "ais-ChatMessage--".concat(variant), autoHideActions && 'ais-ChatMessage--auto-hide-actions', classNames.root),
@@ -20625,12 +21536,38 @@
20625
21536
  content: cx('ais-ChatMessage-content', classNames.content),
20626
21537
  message: cx('ais-ChatMessage-message', classNames.message),
20627
21538
  actions: cx('ais-ChatMessage-actions', classNames.actions),
20628
- footer: cx('ais-ChatMessage-footer', classNames.footer)
21539
+ footer: cx('ais-ChatMessage-footer', classNames.footer),
21540
+ reasoning: cx('ais-ChatMessageReasoning', classNames.reasoning),
21541
+ reasoningHeader: cx('ais-ChatMessageReasoning-header', classNames.reasoningHeader),
21542
+ reasoningIcon: cx('ais-ChatMessageReasoning-icon', classNames.reasoningIcon),
21543
+ reasoningLabel: cx('ais-ChatMessageReasoning-label', classNames.reasoningLabel),
21544
+ reasoningChevron: cx('ais-ChatMessageReasoning-chevron', classNames.reasoningChevron),
21545
+ reasoningBody: cx('ais-ChatMessageReasoning-body', classNames.reasoningBody),
21546
+ reasoningText: cx('ais-ChatMessageReasoning-text', classNames.reasoningText)
20629
21547
  };
20630
21548
  function renderMessagePart(part, index) {
20631
21549
  if (part.type === 'step-start') {
20632
21550
  return null;
20633
21551
  }
21552
+ if (part.type === 'reasoning') {
21553
+ if (!showReasoning) {
21554
+ return null;
21555
+ }
21556
+ var isReasoningStreaming = status === 'streaming' && isCurrentMessage && isReasoningPartActive(message.parts, index);
21557
+ if (!isReasoningStreaming && part.text.trim().length === 0) {
21558
+ return null;
21559
+ }
21560
+ return /*#__PURE__*/ createElement(ChatMessageReasoning, {
21561
+ key: "".concat(message.id, "-").concat(index),
21562
+ part: part,
21563
+ isStreaming: isReasoningStreaming,
21564
+ parseMarkdown: parseMarkdown,
21565
+ translations: translations,
21566
+ classNames: _object_spread_props(_object_spread({}, cssClasses), {
21567
+ reasoningLabel: cx('ais-ChatMessageReasoning-label', isReasoningStreaming && 'ais-ChatMessageReasoning-label--streaming', classNames.reasoningLabel)
21568
+ })
21569
+ });
21570
+ }
20634
21571
  if (part.type === 'text') {
20635
21572
  // Back-compat shim for sessions started before the move from a
20636
21573
  // `<context>{...}</context>` text part to `metadata.turnContext`.
@@ -20672,6 +21609,7 @@
20672
21609
  return null;
20673
21610
  }
20674
21611
  if (tool) {
21612
+ var _tool_insightsEventContext;
20675
21613
  var ToolLayoutComponent = tool.layoutComponent;
20676
21614
  var toolMessage = part;
20677
21615
  var boundAddToolResult = function boundAddToolResult(params) {
@@ -20691,17 +21629,33 @@
20691
21629
  if (!ToolLayoutComponent) {
20692
21630
  return null;
20693
21631
  }
21632
+ var toolSendEvent = tool.sendEvent || function() {};
21633
+ var agentId = (_tool_insightsEventContext = tool.insightsEventContext) === null || _tool_insightsEventContext === void 0 ? void 0 : _tool_insightsEventContext.agentId;
21634
+ var sendEvent = function sendEvent(eventType, hits, eventName, additionalData) {
21635
+ if (hits === undefined && eventName === undefined && additionalData === undefined) {
21636
+ return toolSendEvent(eventType);
21637
+ }
21638
+ return toolSendEvent(eventType, hits, eventName, _object_spread_props(_object_spread(_object_spread_props(_object_spread({}, additionalData || {}), {
21639
+ queryID: 'message_' + message.id
21640
+ }), agentId ? {
21641
+ agentId: agentId
21642
+ } : {}), {
21643
+ toolCallId: toolMessage.toolCallId
21644
+ }));
21645
+ };
20694
21646
  return /*#__PURE__*/ createElement("div", {
20695
21647
  key: "".concat(message.id, "-").concat(index),
20696
21648
  className: "ais-ChatMessage-tool"
20697
21649
  }, /*#__PURE__*/ createElement(ToolLayoutComponent, {
20698
21650
  message: toolMessage,
21651
+ insightsEventContext: tool.insightsEventContext,
21652
+ status: status,
20699
21653
  indexUiState: indexUiState,
20700
21654
  setIndexUiState: setIndexUiState,
20701
21655
  messages: messages,
20702
21656
  addToolResult: boundAddToolResult,
20703
21657
  applyFilters: tool.applyFilters,
20704
- sendEvent: tool.sendEvent || function() {},
21658
+ sendEvent: sendEvent,
20705
21659
  onClose: onClose
20706
21660
  }));
20707
21661
  }
@@ -20853,6 +21807,17 @@
20853
21807
  var copyToClipboard = function copyToClipboard(message) {
20854
21808
  navigator.clipboard.writeText(getTextContent(message));
20855
21809
  };
21810
+ function getInstantSearchStatus(tools) {
21811
+ var _Object_values_find_insightsEventContext, _Object_values_find;
21812
+ return (_Object_values_find = Object.values(tools).find(function(tool) {
21813
+ return tool.insightsEventContext;
21814
+ })) === null || _Object_values_find === void 0 ? void 0 : (_Object_values_find_insightsEventContext = _Object_values_find.insightsEventContext) === null || _Object_values_find_insightsEventContext === void 0 ? void 0 : _Object_values_find_insightsEventContext.instantSearchStatus;
21815
+ }
21816
+ // Own-key presence is what a JSX spread copies; `in` would also answer for
21817
+ // inherited keys the spread leaves behind.
21818
+ var hasOwnKey = function hasOwnKey(target, key) {
21819
+ return target !== undefined && Object.prototype.hasOwnProperty.call(target, key);
21820
+ };
20856
21821
  function createDefaultMessageComponent(param) {
20857
21822
  var createElement = param.createElement, Fragment = param.Fragment;
20858
21823
  var ChatMessage = createChatMessageComponent({
@@ -20977,13 +21942,46 @@
20977
21942
  function MemoizedDefaultMessage(props) {
20978
21943
  var _props_feedbackState;
20979
21944
  var messageFeedback = (_props_feedbackState = props.feedbackState) === null || _props_feedbackState === void 0 ? void 0 : _props_feedbackState[props.message.id];
21945
+ var instantSearchStatus = getInstantSearchStatus(props.tools);
21946
+ // Read the row's own side, mirroring `DefaultMessage`, so one role's change
21947
+ // neither invalidates the other's completed rows nor goes unnoticed here.
21948
+ var messageProps = props.message.role === 'user' ? props.userMessageProps : props.assistantMessageProps;
21949
+ var showReasoning = messageProps === null || messageProps === void 0 ? void 0 : messageProps.showReasoning;
21950
+ var parseMarkdown = messageProps === null || messageProps === void 0 ? void 0 : messageProps.parseMarkdown;
21951
+ // Object-level fallback, matching the render: the spread replaces
21952
+ // `translations` wholesale, and it copies a key holding `undefined` too. Both
21953
+ // are why this resolves by own-key presence rather than key by key.
21954
+ var reasoningTranslations = hasOwnKey(messageProps, 'translations') ? messageProps === null || messageProps === void 0 ? void 0 : messageProps.translations : props.messageTranslations;
21955
+ var reasoningLabel = reasoningTranslations === null || reasoningTranslations === void 0 ? void 0 : reasoningTranslations.reasoningLabel;
21956
+ var reasoningClassNames = hasOwnKey(messageProps, 'classNames') ? messageProps === null || messageProps === void 0 ? void 0 : messageProps.classNames : props.classNames;
21957
+ var reasoningClassName = cx(reasoningClassNames === null || reasoningClassNames === void 0 ? void 0 : reasoningClassNames.reasoning);
21958
+ var reasoningHeaderClassName = cx(reasoningClassNames === null || reasoningClassNames === void 0 ? void 0 : reasoningClassNames.reasoningHeader);
21959
+ var reasoningIconClassName = cx(reasoningClassNames === null || reasoningClassNames === void 0 ? void 0 : reasoningClassNames.reasoningIcon);
21960
+ var reasoningLabelClassName = cx(reasoningClassNames === null || reasoningClassNames === void 0 ? void 0 : reasoningClassNames.reasoningLabel);
21961
+ var reasoningChevronClassName = cx(reasoningClassNames === null || reasoningClassNames === void 0 ? void 0 : reasoningClassNames.reasoningChevron);
21962
+ var reasoningBodyClassName = cx(reasoningClassNames === null || reasoningClassNames === void 0 ? void 0 : reasoningClassNames.reasoningBody);
21963
+ var reasoningTextClassName = cx(reasoningClassNames === null || reasoningClassNames === void 0 ? void 0 : reasoningClassNames.reasoningText);
21964
+ // The row comparator. The full props object would recompile every completed
21965
+ // message on each streaming update.
20980
21966
  return useMemo(function() {
20981
21967
  return /*#__PURE__*/ createElement(DefaultMessageComponent, props);
20982
21968
  }, [
20983
21969
  props.message,
21970
+ props.isCurrentMessage,
20984
21971
  props.status,
21972
+ instantSearchStatus,
20985
21973
  props.suggestionsElement,
20986
- messageFeedback
21974
+ messageFeedback,
21975
+ showReasoning,
21976
+ parseMarkdown,
21977
+ reasoningLabel,
21978
+ reasoningClassName,
21979
+ reasoningHeaderClassName,
21980
+ reasoningIconClassName,
21981
+ reasoningLabelClassName,
21982
+ reasoningChevronClassName,
21983
+ reasoningBodyClassName,
21984
+ reasoningTextClassName
20987
21985
  ]);
20988
21986
  }
20989
21987
  var DefaultLoaderComponent = createChatMessageLoaderComponent({
@@ -20993,7 +21991,8 @@
20993
21991
  createElement: createElement
20994
21992
  });
20995
21993
  return function ChatMessages(userProps) {
20996
- var _lastMessage_parts;
21994
+ var _ref;
21995
+ var _lastMessage_parts, _lastMessage_parts1;
20997
21996
  var _userProps_classNames = userProps.classNames, classNames = _userProps_classNames === void 0 ? {} : _userProps_classNames, _userProps_messageClassNames = userProps.messageClassNames, messageClassNames = _userProps_messageClassNames === void 0 ? {} : _userProps_messageClassNames, messageTranslations = userProps.messageTranslations, _userProps_messages = userProps.messages, messages = _userProps_messages === void 0 ? [] : _userProps_messages, MessageComponent = userProps.messageComponent, LoaderComponent = userProps.loaderComponent, ErrorComponent = userProps.errorComponent, EmptyComponent = userProps.emptyComponent, ActionsComponent = userProps.actionsComponent, tools = userProps.tools, indexUiState = userProps.indexUiState, setIndexUiState = userProps.setIndexUiState, _userProps_status = userProps.status, status = _userProps_status === void 0 ? 'ready' : _userProps_status, error = userProps.error, _userProps_hideScrollToBottom = userProps.hideScrollToBottom, hideScrollToBottom = _userProps_hideScrollToBottom === void 0 ? false : _userProps_hideScrollToBottom, onReload = userProps.onReload, onNewConversation = userProps.onNewConversation, onClose = userProps.onClose, sendMessage = userProps.sendMessage, setInput = userProps.setInput, userTranslations = userProps.translations, userMessageProps = userProps.userMessageProps, assistantMessageProps = userProps.assistantMessageProps, _userProps_isClearing = userProps.isClearing, isClearing = _userProps_isClearing === void 0 ? false : _userProps_isClearing, onClearTransitionEnd = userProps.onClearTransitionEnd, isScrollAtBottom = userProps.isScrollAtBottom, scrollRef = userProps.scrollRef, contentRef = userProps.contentRef, onScrollToBottom = userProps.onScrollToBottom, suggestionsElement = userProps.suggestionsElement, onFeedback = userProps.onFeedback, feedbackState = userProps.feedbackState, props = _object_without_properties(userProps, [
20998
21997
  "classNames",
20999
21998
  "messageClassNames",
@@ -21046,7 +22045,12 @@
21046
22045
  };
21047
22046
  var lastMessage = messages[messages.length - 1];
21048
22047
  var lastPart = lastMessage === null || lastMessage === void 0 ? void 0 : (_lastMessage_parts = lastMessage.parts) === null || _lastMessage_parts === void 0 ? void 0 : _lastMessage_parts[lastMessage.parts.length - 1];
21049
- var showLoader = getShowLoader(status, lastPart, tools);
22048
+ // The scan slices the remaining parts per candidate, and only the loader reads
22049
+ // it, so skip it entirely while the opt-in is off.
22050
+ var hasActiveReasoning = (assistantMessageProps === null || assistantMessageProps === void 0 ? void 0 : assistantMessageProps.showReasoning) ? (_ref = lastMessage === null || lastMessage === void 0 ? void 0 : (_lastMessage_parts1 = lastMessage.parts) === null || _lastMessage_parts1 === void 0 ? void 0 : _lastMessage_parts1.some(function(_, index, parts) {
22051
+ return isReasoningPartActive(parts, index);
22052
+ })) !== null && _ref !== void 0 ? _ref : false : false;
22053
+ var showLoader = getShowLoader(status, lastPart, tools, assistantMessageProps === null || assistantMessageProps === void 0 ? void 0 : assistantMessageProps.showReasoning, hasActiveReasoning);
21050
22054
  var showEmpty = messages.length === 0 && !showLoader && !isClearing && status !== 'error';
21051
22055
  var DefaultMessage = MessageComponent || MemoizedDefaultMessage;
21052
22056
  var DefaultLoader = LoaderComponent || DefaultLoaderComponent;
@@ -21075,6 +22079,7 @@
21075
22079
  return /*#__PURE__*/ createElement(DefaultMessage, {
21076
22080
  key: message.id,
21077
22081
  message: message,
22082
+ isCurrentMessage: index === messages.length - 1,
21078
22083
  status: status,
21079
22084
  userMessageProps: userMessageProps,
21080
22085
  assistantMessageProps: assistantMessageProps,
@@ -21122,10 +22127,13 @@
21122
22127
  })));
21123
22128
  };
21124
22129
  }
21125
- var getShowLoader = function getShowLoader(status, lastPart, tools) {
22130
+ var getShowLoader = function getShowLoader(status, lastPart, tools, showReasoning, hasActiveReasoning) {
21126
22131
  if (status !== 'submitted' && status !== 'streaming') return false;
21127
22132
  if (status === 'submitted') return true;
21128
22133
  if (!lastPart) return true;
22134
+ // An active disclosure carries its own progress affordance, so the loader would
22135
+ // double it. Settled reasoning still shows it: the answer has not started.
22136
+ if (showReasoning && hasActiveReasoning) return false;
21129
22137
  if (isPartText(lastPart)) return false;
21130
22138
  if (isPartTool(lastPart) && lastPart.state === 'input-streaming') {
21131
22139
  var tool = findTool(lastPart.type, tools);
@@ -21618,6 +22626,73 @@
21618
22626
  };
21619
22627
  }
21620
22628
 
22629
+ function createPromptSuggestionsComponent(param) {
22630
+ var createElement = param.createElement;
22631
+ var Button = createButtonComponent({
22632
+ createElement: createElement
22633
+ });
22634
+ function DefaultHeader(param) {
22635
+ var classNames = param.classNames, translations = param.translations;
22636
+ return /*#__PURE__*/ createElement("div", {
22637
+ className: cx('ais-PromptSuggestions-header', classNames.header)
22638
+ }, /*#__PURE__*/ createElement("span", {
22639
+ className: cx('ais-PromptSuggestions-headerTitle', classNames.headerTitle)
22640
+ }, translations.headerTitle));
22641
+ }
22642
+ return function PromptSuggestions(userProps) {
22643
+ var _userProps_suggestions = userProps.suggestions, suggestions = _userProps_suggestions === void 0 ? [] : _userProps_suggestions, onSuggestionClick = userProps.onSuggestionClick, _userProps_isLoading = userProps.isLoading, isLoading = _userProps_isLoading === void 0 ? false : _userProps_isLoading, _userProps_skeletonCount = userProps.skeletonCount, skeletonCount = _userProps_skeletonCount === void 0 ? 3 : _userProps_skeletonCount, _userProps_disabled = userProps.disabled, disabled = _userProps_disabled === void 0 ? false : _userProps_disabled, headerComponent = userProps.headerComponent, userTranslations = userProps.translations, _userProps_classNames = userProps.classNames, classNames = _userProps_classNames === void 0 ? {} : _userProps_classNames, props = _object_without_properties(userProps, [
22644
+ "suggestions",
22645
+ "onSuggestionClick",
22646
+ "isLoading",
22647
+ "skeletonCount",
22648
+ "disabled",
22649
+ "headerComponent",
22650
+ "translations",
22651
+ "classNames"
22652
+ ]);
22653
+ var translations = _object_spread({
22654
+ headerTitle: 'Suggestions'
22655
+ }, userTranslations);
22656
+ var HeaderComponent = headerComponent === false ? null : headerComponent !== null && headerComponent !== void 0 ? headerComponent : DefaultHeader;
22657
+ var visibleSuggestions = suggestions.filter(function(suggestion) {
22658
+ return suggestion.trim() !== '';
22659
+ });
22660
+ var hasContent = visibleSuggestions.length > 0 || isLoading;
22661
+ return /*#__PURE__*/ createElement("div", _object_spread_props(_object_spread({}, props), {
22662
+ className: cx('ais-PromptSuggestions', classNames.root, props.className)
22663
+ }), HeaderComponent && hasContent && /*#__PURE__*/ createElement(HeaderComponent, {
22664
+ classNames: {
22665
+ header: classNames.header,
22666
+ headerTitle: classNames.headerTitle
22667
+ },
22668
+ translations: translations
22669
+ }), isLoading && visibleSuggestions.length === 0 ? /*#__PURE__*/ createElement("div", {
22670
+ className: cx('ais-PromptSuggestions-skeleton', classNames.skeleton)
22671
+ }, _to_consumable_array(new Array(skeletonCount)).map(function(_, i) {
22672
+ return /*#__PURE__*/ createElement("div", {
22673
+ key: i,
22674
+ className: cx('ais-PromptSuggestions-skeletonItem', classNames.skeletonItem)
22675
+ });
22676
+ })) : visibleSuggestions.map(function(suggestion, index) {
22677
+ return /*#__PURE__*/ createElement(Button, {
22678
+ key: index,
22679
+ size: "sm",
22680
+ variant: "primary",
22681
+ className: cx('ais-PromptSuggestions-suggestion', classNames.suggestion),
22682
+ // Ignore clicks while streaming so an unfinished prompt (e.g.
22683
+ // `Wh..`) can't be sent before generation settles — without
22684
+ // toggling `disabled`, which would swap the pill's styling
22685
+ // mid-stream.
22686
+ onClick: function onClick() {
22687
+ if (isLoading) return;
22688
+ onSuggestionClick(suggestion);
22689
+ },
22690
+ disabled: disabled
22691
+ }, suggestion);
22692
+ }));
22693
+ };
22694
+ }
22695
+
21621
22696
  function createChatToggleButtonComponent(param) {
21622
22697
  var createElement = param.createElement;
21623
22698
  var Button = createButtonComponent({
@@ -21687,10 +22762,7 @@
21687
22762
  size: "sm",
21688
22763
  onClick: function onClick() {
21689
22764
  if (!input || !applyFilters) return;
21690
- var params = applyFilters({
21691
- query: input.query,
21692
- facetFilters: getFacetFiltersFromToolInput(input)
21693
- });
22765
+ var params = applyFilters(getApplyFiltersParamsFromToolInput(input));
21694
22766
  if (getSearchPageURL) {
21695
22767
  var searchPageURL = getSearchPageURL(params);
21696
22768
  var resolvedURL = new URL(searchPageURL, window.location.href);
@@ -21727,22 +22799,46 @@
21727
22799
  };
21728
22800
  }
21729
22801
  function createCarouselToolComponent(param) {
21730
- var createElement = param.createElement, Fragment = param.Fragment, useMemo = param.useMemo, useRef = param.useRef, useState = param.useState;
22802
+ var createElement = param.createElement, Fragment = param.Fragment, useEffect = param.useEffect, useMemo = param.useMemo, useRef = param.useRef, useState = param.useState;
21731
22803
  var DefaultHeader = createHeaderComponent({
21732
22804
  createElement: createElement,
21733
22805
  Fragment: Fragment
21734
22806
  });
21735
22807
  var Carousel = createCarouselComponent({
21736
22808
  createElement: createElement,
21737
- Fragment: Fragment
22809
+ Fragment: Fragment,
22810
+ useEffect: useEffect,
22811
+ useRef: useRef
21738
22812
  });
21739
22813
  return function CarouselTool(userProps) {
21740
- var ItemComponent = userProps.itemComponent, HeaderComponent = userProps.headerComponent, getSearchPageURL = userProps.getSearchPageURL, _userProps_toolProps = userProps.toolProps, message = _userProps_toolProps.message, applyFilters = _userProps_toolProps.applyFilters, onClose = _userProps_toolProps.onClose, sendEvent = _userProps_toolProps.sendEvent, showViewAll = userProps.headerProps.showViewAll;
22814
+ var _ref;
22815
+ var ItemComponent = userProps.itemComponent, HeaderComponent = userProps.headerComponent, getSearchPageURL = userProps.getSearchPageURL, _userProps_toolProps = userProps.toolProps, message = _userProps_toolProps.message, applyFilters = _userProps_toolProps.applyFilters, onClose = _userProps_toolProps.onClose, insightsEventContext = _userProps_toolProps.insightsEventContext, sendEvent = _userProps_toolProps.sendEvent, showViewAll = userProps.headerProps.showViewAll;
22816
+ var instantSearchStatus = (_ref = insightsEventContext === null || insightsEventContext === void 0 ? void 0 : insightsEventContext.instantSearchStatus) !== null && _ref !== void 0 ? _ref : 'idle';
21741
22817
  var input = message === null || message === void 0 ? void 0 : message.input;
21742
22818
  var output = message === null || message === void 0 ? void 0 : message.output;
21743
22819
  var hits = (output === null || output === void 0 ? void 0 : output.hits) || [];
21744
22820
  var items = addQueryID(addAbsolutePosition(hits, 0, hits.length), output === null || output === void 0 ? void 0 : output.queryID);
21745
- var nbItems = items.length;
22821
+ var viewedItemsSignature = items.map(function(item) {
22822
+ return "".concat(item.objectID, ":").concat(item.__position);
22823
+ }).join('|');
22824
+ var lastViewedItemsSignatureRef = useRef(undefined);
22825
+ useEffect(function() {
22826
+ if (instantSearchStatus !== 'idle' || items.length === 0 || viewedItemsSignature === lastViewedItemsSignatureRef.current) {
22827
+ return;
22828
+ }
22829
+ var timer = setTimeout(function() {
22830
+ lastViewedItemsSignatureRef.current = viewedItemsSignature;
22831
+ sendEvent('view:internal', items, 'items_shown');
22832
+ }, 0);
22833
+ return function() {
22834
+ clearTimeout(timer);
22835
+ };
22836
+ }, [
22837
+ instantSearchStatus,
22838
+ items,
22839
+ sendEvent,
22840
+ viewedItemsSignature
22841
+ ]);
21746
22842
  var _useState = _sliced_to_array(useState(false), 2), canScrollLeft = _useState[0], setCanScrollLeft = _useState[1];
21747
22843
  var _useState1 = _sliced_to_array(useState(true), 2), canScrollRight = _useState1[0], setCanScrollRight = _useState1[1];
21748
22844
  var carouselIdRef = useRef('');
@@ -21766,7 +22862,6 @@
21766
22862
  showViewAll: showViewAll,
21767
22863
  nbHits: output === null || output === void 0 ? void 0 : output.nbHits,
21768
22864
  input: input,
21769
- nbItems: nbItems,
21770
22865
  applyFilters: applyFilters,
21771
22866
  getSearchPageURL: getSearchPageURL,
21772
22867
  onClose: onClose
@@ -21778,7 +22873,6 @@
21778
22873
  showViewAll: showViewAll,
21779
22874
  nbHits: output === null || output === void 0 ? void 0 : output.nbHits,
21780
22875
  input: input,
21781
- nbItems: nbItems,
21782
22876
  applyFilters: applyFilters,
21783
22877
  getSearchPageURL: getSearchPageURL,
21784
22878
  onClose: onClose
@@ -21789,7 +22883,6 @@
21789
22883
  HeaderComponent,
21790
22884
  output === null || output === void 0 ? void 0 : output.nbHits,
21791
22885
  input,
21792
- nbItems,
21793
22886
  applyFilters,
21794
22887
  getSearchPageURL,
21795
22888
  onClose
@@ -21804,55 +22897,187 @@
21804
22897
  };
21805
22898
  }
21806
22899
 
22900
+ var isObject = function isObject(value) {
22901
+ return value !== null && (typeof value === "undefined" ? "undefined" : _type_of(value)) === 'object';
22902
+ };
22903
+ var hasOwn = function hasOwn(value, key) {
22904
+ return Object.prototype.hasOwnProperty.call(value, key);
22905
+ };
22906
+ var claimsDisplayResultsPayload = function claimsDisplayResultsPayload(value) {
22907
+ return isObject(value) && (hasOwn(value, 'intro') || hasOwn(value, 'groups'));
22908
+ };
22909
+ /**
22910
+ * Decodes a raw property-key body with JSON string semantics, so an escaped
22911
+ * spelling of `objectID` compares equal to the name `JSON.parse` produces.
22912
+ * An undecodable key is kept verbatim: it matches no name below, and the
22913
+ * document holding it cannot parse either.
22914
+ */ var decodeJsonKey = function decodeJsonKey(rawKey) {
22915
+ if (rawKey.indexOf('\\') === -1) {
22916
+ return rawKey;
22917
+ }
22918
+ try {
22919
+ return JSON.parse('"'.concat(rawKey, '"'));
22920
+ } catch (unused) {
22921
+ return rawKey;
22922
+ }
22923
+ };
22924
+ /**
22925
+ * Reports whether the raw input ends inside an unterminated
22926
+ * `groups[].results[].objectID` value.
22927
+ *
22928
+ * Partial input is parsed with repair that closes an open string literal, so an
22929
+ * identifier still mid-delta reaches `input` looking complete and can hydrate a
22930
+ * different record whose identifier is a prefix of the real one.
22931
+ */ var endsInsideResultObjectId = function endsInsideResultObjectId(rawInput) {
22932
+ var _frames_, _frames_1, _frames_2;
22933
+ var frames = [];
22934
+ var inString = false;
22935
+ var isEscaped = false;
22936
+ var isKey = false;
22937
+ var expectValue = false;
22938
+ var stringStart = 0;
22939
+ for(var index = 0; index < rawInput.length; index++){
22940
+ var char = rawInput[index];
22941
+ if (inString) {
22942
+ if (isEscaped) {
22943
+ isEscaped = false;
22944
+ } else if (char === '\\') {
22945
+ isEscaped = true;
22946
+ } else if (char === '"') {
22947
+ inString = false;
22948
+ if (isKey) {
22949
+ frames[frames.length - 1].lastKey = decodeJsonKey(rawInput.slice(stringStart, index));
22950
+ } else {
22951
+ expectValue = false;
22952
+ }
22953
+ }
22954
+ continue;
22955
+ }
22956
+ if (char === '"') {
22957
+ var _frames_3;
22958
+ inString = true;
22959
+ stringStart = index + 1;
22960
+ isKey = !expectValue && ((_frames_3 = frames[frames.length - 1]) === null || _frames_3 === void 0 ? void 0 : _frames_3.isObject) === true;
22961
+ } else if (char === ':') {
22962
+ expectValue = true;
22963
+ } else if (char === ',') {
22964
+ expectValue = false;
22965
+ } else if (char === '{' || char === '[') {
22966
+ var _ref;
22967
+ var _frames_4;
22968
+ frames.push({
22969
+ key: expectValue ? (_ref = (_frames_4 = frames[frames.length - 1]) === null || _frames_4 === void 0 ? void 0 : _frames_4.lastKey) !== null && _ref !== void 0 ? _ref : '' : '',
22970
+ lastKey: '',
22971
+ isObject: char === '{'
22972
+ });
22973
+ expectValue = false;
22974
+ } else if (char === '}' || char === ']') {
22975
+ frames.pop();
22976
+ expectValue = false;
22977
+ }
22978
+ }
22979
+ return inString && !isKey && ((_frames_ = frames[frames.length - 1]) === null || _frames_ === void 0 ? void 0 : _frames_.lastKey) === 'objectID' && ((_frames_1 = frames[frames.length - 2]) === null || _frames_1 === void 0 ? void 0 : _frames_1.key) === 'results' && ((_frames_2 = frames[frames.length - 4]) === null || _frames_2 === void 0 ? void 0 : _frames_2.key) === 'groups';
22980
+ };
21807
22981
  var DEFAULT_TRANSLATIONS$1 = {
21808
22982
  streamingLabel: 'Curating results…'
21809
22983
  };
21810
22984
  function createDisplayResultsToolComponent(param) {
21811
- var createElement = param.createElement, Fragment = param.Fragment, useMemo = param.useMemo;
22985
+ var createElement = param.createElement, Fragment = param.Fragment, useEffect = param.useEffect, useMemo = param.useMemo, useRef = param.useRef;
21812
22986
  return function DisplayResultsTool(userProps) {
22987
+ var _ref;
21813
22988
  var toolProps = userProps.toolProps, renderGroupCarousel = userProps.groupCarouselComponent, userTranslations = userProps.translations;
21814
- var message = toolProps.message, messages = toolProps.messages, sendEvent = toolProps.sendEvent;
22989
+ var message = toolProps.message, messages = toolProps.messages, insightsEventContext = toolProps.insightsEventContext, sendEvent = toolProps.sendEvent, status = toolProps.status;
22990
+ var instantSearchStatus = (_ref = insightsEventContext === null || insightsEventContext === void 0 ? void 0 : insightsEventContext.instantSearchStatus) !== null && _ref !== void 0 ? _ref : 'idle';
21815
22991
  var translations = _object_spread({}, DEFAULT_TRANSLATIONS$1, userTranslations);
21816
- var toolCallId = message === null || message === void 0 ? void 0 : message.toolCallId;
21817
22992
  var hitsByObjectID = useMemo(function() {
21818
- return messages ? getHitsByObjectID(messages, toolCallId) : undefined;
22993
+ return messages ? getHitsByObjectID(messages, message) : undefined;
21819
22994
  }, [
21820
22995
  messages,
21821
- toolCallId
22996
+ message
21822
22997
  ]);
21823
- var output = message === null || message === void 0 ? void 0 : message.output;
21824
- var intro = typeof (output === null || output === void 0 ? void 0 : output.intro) === 'string' ? output.intro : undefined;
21825
- var groups = Array.isArray(output === null || output === void 0 ? void 0 : output.groups) ? output.groups : [];
21826
- var isStreaming = (message === null || message === void 0 ? void 0 : message.state) === 'output-available' && message.preliminary === true;
21827
- if (!intro && groups.length === 0) {
22998
+ var inputClaimsPayload = claimsDisplayResultsPayload(message === null || message === void 0 ? void 0 : message.input);
22999
+ var legacyOutput = (message === null || message === void 0 ? void 0 : message.state) === 'output-available' && message.preliminary !== true && !inputClaimsPayload ? message.output : undefined;
23000
+ var payload = inputClaimsPayload ? message === null || message === void 0 ? void 0 : message.input : claimsDisplayResultsPayload(legacyOutput) ? legacyOutput : undefined;
23001
+ var intro = typeof (payload === null || payload === void 0 ? void 0 : payload.intro) === 'string' ? payload.intro : undefined;
23002
+ var groups = Array.isArray(payload === null || payload === void 0 ? void 0 : payload.groups) ? payload.groups.filter(isObject) : [];
23003
+ var latestMessage = messages === null || messages === void 0 ? void 0 : messages[messages.length - 1];
23004
+ var isStreaming = status === 'streaming' && (message === null || message === void 0 ? void 0 : message.state) === 'input-streaming' && (latestMessage === null || latestMessage === void 0 ? void 0 : latestMessage.parts.some(function(part) {
23005
+ return part === message;
23006
+ })) === true;
23007
+ // Only the last result of the last group can still be mid-delta, so it is
23008
+ // the only one ever withheld.
23009
+ var rawInput = (message === null || message === void 0 ? void 0 : message.state) === 'input-streaming' ? message.rawInput : undefined;
23010
+ var withholdsTrailingResult = typeof rawInput === 'string' && endsInsideResultObjectId(rawInput);
23011
+ var lastGroupIndex = groups.length - 1;
23012
+ var renderableGroups = groups.reduce(function(renderedGroups, group, groupIndex) {
23013
+ var suppliedResults = Array.isArray(group.results) ? withholdsTrailingResult && groupIndex === lastGroupIndex ? group.results.slice(0, -1) : group.results : [];
23014
+ var results = suppliedResults.filter(function(result) {
23015
+ return isObject(result) && typeof result.objectID === 'string' && result.objectID !== '';
23016
+ });
23017
+ var items = results.reduce(function(renderedItems, result) {
23018
+ if (!hitsByObjectID || !hasOwn(hitsByObjectID, result.objectID)) {
23019
+ return renderedItems;
23020
+ }
23021
+ var hydrated = hitsByObjectID[result.objectID];
23022
+ renderedItems.push(_object_spread_props(_object_spread({}, hydrated), {
23023
+ objectID: result.objectID,
23024
+ __position: renderedItems.length + 1,
23025
+ __displayToolResult: result
23026
+ }));
23027
+ return renderedItems;
23028
+ }, []);
23029
+ if (items.length === 0) {
23030
+ return renderedGroups;
23031
+ }
23032
+ renderedGroups.push({
23033
+ key: groupIndex,
23034
+ title: typeof group.title === 'string' ? group.title : undefined,
23035
+ why: typeof group.why === 'string' ? group.why : undefined,
23036
+ items: items
23037
+ });
23038
+ return renderedGroups;
23039
+ }, []);
23040
+ var viewedItems = renderableGroups.flatMap(function(group) {
23041
+ return group.items;
23042
+ });
23043
+ var viewedItemsSignature = viewedItems.map(function(item) {
23044
+ return "".concat(item.objectID, ":").concat(item.__position);
23045
+ }).join('|');
23046
+ var lastViewedItemsSignatureRef = useRef(undefined);
23047
+ useEffect(function() {
23048
+ if (instantSearchStatus !== 'idle' || viewedItems.length === 0 || viewedItemsSignature === lastViewedItemsSignatureRef.current) {
23049
+ return;
23050
+ }
23051
+ var timer = setTimeout(function() {
23052
+ lastViewedItemsSignatureRef.current = viewedItemsSignature;
23053
+ sendEvent('view:internal', viewedItems, 'items_shown');
23054
+ }, 0);
23055
+ return function() {
23056
+ clearTimeout(timer);
23057
+ };
23058
+ }, [
23059
+ instantSearchStatus,
23060
+ sendEvent,
23061
+ viewedItems,
23062
+ viewedItemsSignature
23063
+ ]);
23064
+ if (!intro && renderableGroups.length === 0 && !isStreaming) {
21828
23065
  return /*#__PURE__*/ createElement(Fragment, null);
21829
23066
  }
21830
23067
  return /*#__PURE__*/ createElement("div", {
21831
23068
  className: "ais-ChatToolDisplayResults"
21832
23069
  }, intro && /*#__PURE__*/ createElement("div", {
21833
23070
  className: "ais-ChatToolDisplayResults-intro"
21834
- }, intro), groups.map(function(group, groupIndex) {
21835
- var results = Array.isArray(group.results) ? group.results.filter(function(r) {
21836
- return Boolean(r) && typeof r.objectID === 'string' && r.objectID !== '';
21837
- }) : [];
21838
- if (results.length === 0) return null;
21839
- var items = results.map(function(result, idx) {
21840
- var hydrated = hitsByObjectID === null || hitsByObjectID === void 0 ? void 0 : hitsByObjectID[result.objectID];
21841
- return _object_spread_props(_object_spread({}, hydrated), {
21842
- objectID: result.objectID,
21843
- __position: idx + 1,
21844
- __displayToolResult: result
21845
- });
21846
- });
23071
+ }, intro), renderableGroups.map(function(group) {
21847
23072
  return /*#__PURE__*/ createElement("div", {
21848
- key: groupIndex,
23073
+ key: group.key,
21849
23074
  className: "ais-ChatToolDisplayResults-group"
21850
23075
  }, group.title && /*#__PURE__*/ createElement("div", {
21851
23076
  className: "ais-ChatToolDisplayResults-groupTitle"
21852
23077
  }, group.title), group.why && /*#__PURE__*/ createElement("div", {
21853
23078
  className: "ais-ChatToolDisplayResults-groupWhy"
21854
23079
  }, group.why), renderGroupCarousel({
21855
- items: items,
23080
+ items: group.items,
21856
23081
  sendEvent: sendEvent
21857
23082
  }));
21858
23083
  }), isStreaming && /*#__PURE__*/ createElement("div", {
@@ -23610,7 +24835,7 @@
23610
24835
  if (chatRenderState) {
23611
24836
  if (openChat(chatRenderState, {
23612
24837
  message: item.prompt,
23613
- referer: 'prompt-suggestions'
24838
+ referer: 'prompt-suggestions-autocomplete'
23614
24839
  })) {
23615
24840
  setQuery('');
23616
24841
  }
@@ -23925,7 +25150,9 @@
23925
25150
 
23926
25151
  var CarouselUiComponent = createCarouselComponent({
23927
25152
  createElement: React.createElement,
23928
- Fragment: React.Fragment
25153
+ Fragment: React.Fragment,
25154
+ useEffect: React.useEffect,
25155
+ useRef: React.useRef
23929
25156
  });
23930
25157
  function Carousel(props) {
23931
25158
  var _useState = _sliced_to_array(React.useState(false), 2), canScrollLeft = _useState[0], setCanScrollLeft = _useState[1];
@@ -23973,11 +25200,43 @@
23973
25200
  var DisplayResultsUIComponent = createDisplayResultsToolComponent({
23974
25201
  createElement: React.createElement,
23975
25202
  Fragment: React.Fragment,
23976
- useMemo: React.useMemo
25203
+ useEffect: React.useEffect,
25204
+ useMemo: React.useMemo,
25205
+ useRef: React.useRef
23977
25206
  });
23978
25207
  var Button = createButtonComponent({
23979
25208
  createElement: React.createElement
23980
25209
  });
25210
+ var DisplayResultsCarouselHeader = function DisplayResultsCarouselHeader(param) {
25211
+ var nbItems = param.nbItems, canScrollLeft = param.canScrollLeft, canScrollRight = param.canScrollRight, scrollLeft = param.scrollLeft, scrollRight = param.scrollRight;
25212
+ return /*#__PURE__*/ React.createElement("div", {
25213
+ className: "ais-ChatToolDisplayResultsCarouselHeader"
25214
+ }, /*#__PURE__*/ React.createElement("div", {
25215
+ className: "ais-ChatToolDisplayResultsCarouselHeaderCount"
25216
+ }, nbItems, " result", nbItems > 1 ? 's' : ''), /*#__PURE__*/ React.createElement("div", {
25217
+ className: "ais-ChatToolDisplayResultsCarouselHeaderScrollButtons"
25218
+ }, /*#__PURE__*/ React.createElement(Button, {
25219
+ variant: "outline",
25220
+ size: "sm",
25221
+ iconOnly: true,
25222
+ "aria-label": "Previous",
25223
+ onClick: scrollLeft,
25224
+ disabled: !canScrollLeft,
25225
+ className: "ais-ChatToolDisplayResultsCarouselHeaderScrollButton"
25226
+ }, /*#__PURE__*/ React.createElement(ChevronLeftIcon, {
25227
+ createElement: React.createElement
25228
+ })), /*#__PURE__*/ React.createElement(Button, {
25229
+ variant: "outline",
25230
+ size: "sm",
25231
+ iconOnly: true,
25232
+ "aria-label": "Next",
25233
+ onClick: scrollRight,
25234
+ disabled: !canScrollRight,
25235
+ className: "ais-ChatToolDisplayResultsCarouselHeaderScrollButton"
25236
+ }, /*#__PURE__*/ React.createElement(ChevronRightIcon, {
25237
+ createElement: React.createElement
25238
+ }))));
25239
+ };
23981
25240
  var DisplayResultsLayoutComponent = function DisplayResultsLayoutComponent(toolProps) {
23982
25241
  return /*#__PURE__*/ React.createElement(DisplayResultsUIComponent, {
23983
25242
  toolProps: toolProps,
@@ -23988,40 +25247,14 @@
23988
25247
  itemComponent: itemComponent,
23989
25248
  sendEvent: sendEvent,
23990
25249
  showNavigation: false,
23991
- headerComponent: function headerComponent(param) {
23992
- var canScrollLeft = param.canScrollLeft, canScrollRight = param.canScrollRight, scrollLeft = param.scrollLeft, scrollRight = param.scrollRight;
23993
- return /*#__PURE__*/ React.createElement("div", {
23994
- className: "ais-ChatToolDisplayResultsCarouselHeader"
23995
- }, /*#__PURE__*/ React.createElement("div", {
23996
- className: "ais-ChatToolDisplayResultsCarouselHeaderCount"
23997
- }, items.length, " result", items.length > 1 ? 's' : ''), /*#__PURE__*/ React.createElement("div", {
23998
- className: "ais-ChatToolDisplayResultsCarouselHeaderScrollButtons"
23999
- }, /*#__PURE__*/ React.createElement(Button, {
24000
- variant: "outline",
24001
- size: "sm",
24002
- iconOnly: true,
24003
- onClick: scrollLeft,
24004
- disabled: !canScrollLeft,
24005
- className: "ais-ChatToolDisplayResultsCarouselHeaderScrollButton"
24006
- }, /*#__PURE__*/ React.createElement(ChevronLeftIcon, {
24007
- createElement: React.createElement
24008
- })), /*#__PURE__*/ React.createElement(Button, {
24009
- variant: "outline",
24010
- size: "sm",
24011
- iconOnly: true,
24012
- onClick: scrollRight,
24013
- disabled: !canScrollRight,
24014
- className: "ais-ChatToolDisplayResultsCarouselHeaderScrollButton"
24015
- }, /*#__PURE__*/ React.createElement(ChevronRightIcon, {
24016
- createElement: React.createElement
24017
- }))));
24018
- }
25250
+ headerComponent: DisplayResultsCarouselHeader
24019
25251
  });
24020
25252
  }
24021
25253
  });
24022
25254
  };
24023
25255
  return {
24024
- layoutComponent: DisplayResultsLayoutComponent
25256
+ layoutComponent: DisplayResultsLayoutComponent,
25257
+ streamInput: true
24025
25258
  };
24026
25259
  }
24027
25260
 
@@ -24029,6 +25262,7 @@
24029
25262
  var SearchLayoutUIComponent = createCarouselToolComponent({
24030
25263
  createElement: React.createElement,
24031
25264
  Fragment: React.Fragment,
25265
+ useEffect: React.useEffect,
24032
25266
  useMemo: React.useMemo,
24033
25267
  useRef: React.useRef,
24034
25268
  useState: React.useState
@@ -24058,11 +25292,28 @@
24058
25292
  var _obj;
24059
25293
  return _obj = {}, _define_property(_obj, SearchIndexToolType$2, createCarouselTool(true, itemComponent, getSearchPageURL)), _define_property(_obj, RecommendToolType, createCarouselTool(false, itemComponent, getSearchPageURL)), _define_property(_obj, DisplayResultsToolType, createDisplayResultsTool(itemComponent)), _define_property(_obj, MemorizeToolType, {}), _define_property(_obj, MemorySearchToolType, {}), _define_property(_obj, PonderToolType, {}), _obj;
24060
25294
  }
25295
+ function mergeToolOptions(defaultTools, userTools) {
25296
+ if (!userTools) {
25297
+ return defaultTools;
25298
+ }
25299
+ var tools = _object_spread({}, defaultTools, userTools);
25300
+ Object.keys(userTools).forEach(function(toolName) {
25301
+ var _defaultTools_toolName;
25302
+ var userTool = userTools[toolName];
25303
+ var defaultStreamInput = (_defaultTools_toolName = defaultTools[toolName]) === null || _defaultTools_toolName === void 0 ? void 0 : _defaultTools_toolName.streamInput;
25304
+ if (userTool.layoutComponent !== undefined && userTool.streamInput === undefined && defaultStreamInput !== undefined) {
25305
+ tools[toolName] = _object_spread_props(_object_spread({}, userTool), {
25306
+ streamInput: defaultStreamInput
25307
+ });
25308
+ }
25309
+ });
25310
+ return tools;
25311
+ }
24061
25312
  function ChatInner(_0, _1) {
24062
25313
  var _ref = [
24063
25314
  _0,
24064
25315
  _1
24065
- ], _ref1 = _to_array(_ref), _ref2 = _ref1[0], _rest = _ref1.slice(1), userTools = _ref2.tools, headerProps = _ref2.headerProps, messagesProps = _ref2.messagesProps, promptProps = _ref2.promptProps, itemComponent = _ref2.itemComponent, layoutComponent = _ref2.layoutComponent, headerComponent = _ref2.headerComponent, headerTitleIconComponent = _ref2.headerTitleIconComponent, headerCloseIconComponent = _ref2.headerCloseIconComponent, headerMinimizeIconComponent = _ref2.headerMinimizeIconComponent, headerMaximizeIconComponent = _ref2.headerMaximizeIconComponent, loaderComponent = _ref2.loaderComponent, messagesErrorComponent = _ref2.messagesErrorComponent, promptComponent = _ref2.promptComponent, promptHeaderComponent = _ref2.promptHeaderComponent, promptFooterComponent = _ref2.promptFooterComponent, assistantMessageLeadingComponent = _ref2.assistantMessageLeadingComponent, assistantMessageFooterComponent = _ref2.assistantMessageFooterComponent, userMessageLeadingComponent = _ref2.userMessageLeadingComponent, userMessageFooterComponent = _ref2.userMessageFooterComponent, emptyComponent = _ref2.emptyComponent, actionsComponent = _ref2.actionsComponent, suggestionsComponent = _ref2.suggestionsComponent, classNames = _ref2.classNames, _ref_translations = _ref2.translations, translations = _ref_translations === void 0 ? {} : _ref_translations, title = _ref2.title, getSearchPageURL = _ref2.getSearchPageURL, _ref_disableTriggerValidation = _ref2.disableTriggerValidation, disableTriggerValidation = _ref_disableTriggerValidation === void 0 ? false : _ref_disableTriggerValidation, props = _object_without_properties(_ref2, [
25316
+ ], _ref1 = _to_array(_ref), _ref2 = _ref1[0], _rest = _ref1.slice(1), userTools = _ref2.tools, headerProps = _ref2.headerProps, messagesProps = _ref2.messagesProps, promptProps = _ref2.promptProps, itemComponent = _ref2.itemComponent, layoutComponent = _ref2.layoutComponent, headerComponent = _ref2.headerComponent, headerTitleIconComponent = _ref2.headerTitleIconComponent, headerCloseIconComponent = _ref2.headerCloseIconComponent, headerMinimizeIconComponent = _ref2.headerMinimizeIconComponent, headerMaximizeIconComponent = _ref2.headerMaximizeIconComponent, loaderComponent = _ref2.loaderComponent, messagesErrorComponent = _ref2.messagesErrorComponent, promptComponent = _ref2.promptComponent, promptHeaderComponent = _ref2.promptHeaderComponent, promptFooterComponent = _ref2.promptFooterComponent, assistantMessageLeadingComponent = _ref2.assistantMessageLeadingComponent, assistantMessageFooterComponent = _ref2.assistantMessageFooterComponent, userMessageLeadingComponent = _ref2.userMessageLeadingComponent, userMessageFooterComponent = _ref2.userMessageFooterComponent, emptyComponent = _ref2.emptyComponent, actionsComponent = _ref2.actionsComponent, suggestionsComponent = _ref2.suggestionsComponent, classNames = _ref2.classNames, _ref_translations = _ref2.translations, translations = _ref_translations === void 0 ? {} : _ref_translations, title = _ref2.title, getSearchPageURL = _ref2.getSearchPageURL, _ref_disableTriggerValidation = _ref2.disableTriggerValidation, disableTriggerValidation = _ref_disableTriggerValidation === void 0 ? false : _ref_disableTriggerValidation, showReasoning = _ref2.showReasoning, props = _object_without_properties(_ref2, [
24066
25317
  "tools",
24067
25318
  "headerProps",
24068
25319
  "messagesProps",
@@ -24090,8 +25341,10 @@
24090
25341
  "translations",
24091
25342
  "title",
24092
25343
  "getSearchPageURL",
24093
- "disableTriggerValidation"
25344
+ "disableTriggerValidation",
25345
+ "showReasoning"
24094
25346
  ]), _rest1 = _sliced_to_array(_rest, 1), ref = _rest1[0];
25347
+ var _ref3;
24095
25348
  var promptTranslations = translations.prompt, headerTranslations = translations.header, messageTranslations = translations.message, messagesTranslations = translations.messages;
24096
25349
  var _useInstantSearch = useInstantSearch(), indexUiState = _useInstantSearch.indexUiState, setIndexUiState = _useInstantSearch.setIndexUiState;
24097
25350
  var _useState = _sliced_to_array(React.useState(false), 2), maximized = _useState[0], setMaximized = _useState[1];
@@ -24102,7 +25355,7 @@
24102
25355
  }), scrollRef = _useStickToBottom.scrollRef, contentRef = _useStickToBottom.contentRef, scrollToBottom = _useStickToBottom.scrollToBottom, isAtBottom = _useStickToBottom.isAtBottom;
24103
25356
  var tools = React.useMemo(function() {
24104
25357
  var defaults = createDefaultTools(itemComponent, getSearchPageURL);
24105
- return _object_spread({}, defaults, userTools);
25358
+ return mergeToolOptions(defaults, userTools);
24106
25359
  }, [
24107
25360
  getSearchPageURL,
24108
25361
  itemComponent,
@@ -24117,7 +25370,7 @@
24117
25370
  tools: tools,
24118
25371
  disableTriggerValidation: effectiveDisableTriggerValidation
24119
25372
  }));
24120
- var messages = chatState.messages, sendMessage = chatState.sendMessage, status = chatState.status, regenerate = chatState.regenerate, stop = chatState.stop, error = chatState.error, input = chatState.input, setInput = chatState.setInput, open = chatState.open, setOpen = chatState.setOpen, clearMessages = chatState.clearMessages, toolsFromConnector = chatState.tools, suggestions = chatState.suggestions, onFeedback = chatState.sendChatMessageFeedback, feedbackState = chatState.feedbackState;
25373
+ var messages = chatState.messages, sendMessage = chatState.sendMessage, status = chatState.status, regenerate = chatState.regenerate, stop = chatState.stop, error = chatState.error, input = chatState.input, setInput = chatState.setInput, open = chatState.open, setOpen = chatState.setOpen, clearMessages = chatState.clearMessages, toolsFromConnector = chatState.tools, suggestions = chatState.suggestions, onFeedback = chatState.sendChatMessageFeedback, feedbackState = chatState.feedbackState, consumeInputFocus = chatState['~consumeInputFocus'], isOpenStatePersistenceEnabled = chatState['~isOpenStatePersistenceEnabled'];
24121
25374
  React.useImperativeHandle(ref, function() {
24122
25375
  return {
24123
25376
  setOpen: setOpen,
@@ -24127,19 +25380,14 @@
24127
25380
  setInput: setInput
24128
25381
  };
24129
25382
  });
24130
- var wasOpenRef = React.useRef(false);
24131
25383
  React.useEffect(function() {
24132
- var shouldFocusPrompt = !wasOpenRef.current && open;
24133
- if (shouldFocusPrompt) {
25384
+ if (consumeInputFocus === null || consumeInputFocus === void 0 ? void 0 : consumeInputFocus()) {
24134
25385
  window.requestAnimationFrame(function() {
24135
25386
  var _promptRef_current;
24136
25387
  (_promptRef_current = promptRef.current) === null || _promptRef_current === void 0 ? void 0 : _promptRef_current.focus();
24137
25388
  });
24138
25389
  }
24139
- wasOpenRef.current = open;
24140
- }, [
24141
- open
24142
- ]);
25390
+ });
24143
25391
  // Keep the conversation pinned to the bottom while streaming. The stick-to-
24144
25392
  // bottom ResizeObserver only reacts to content *height* changes, but tool
24145
25393
  // results such as a horizontally-growing carousel stream in without changing
@@ -24160,6 +25408,10 @@
24160
25408
  if (error) {
24161
25409
  throw error;
24162
25410
  }
25411
+ var _ref4 = messagesProps !== null && messagesProps !== void 0 ? messagesProps : {}, callerAssistantMessageProps = _ref4.assistantMessageProps, callerUserMessageProps = _ref4.userMessageProps, restMessagesProps = _object_without_properties(_ref4, [
25412
+ "assistantMessageProps",
25413
+ "userMessageProps"
25414
+ ]);
24163
25415
  return /*#__PURE__*/ React.createElement(ChatUiComponent, {
24164
25416
  title: title,
24165
25417
  open: open,
@@ -24215,20 +25467,21 @@
24215
25467
  errorComponent: messagesErrorComponent,
24216
25468
  emptyComponent: emptyComponent,
24217
25469
  actionsComponent: actionsComponent,
25470
+ translations: messagesTranslations,
25471
+ messageTranslations: messageTranslations
25472
+ }, restMessagesProps), {
24218
25473
  assistantMessageProps: _object_spread({
24219
25474
  leadingComponent: assistantMessageLeadingComponent,
24220
- footerComponent: assistantMessageFooterComponent
24221
- }, messagesProps === null || messagesProps === void 0 ? void 0 : messagesProps.assistantMessageProps),
25475
+ footerComponent: assistantMessageFooterComponent,
25476
+ showReasoning: showReasoning
25477
+ }, callerAssistantMessageProps),
24222
25478
  userMessageProps: _object_spread({
24223
25479
  leadingComponent: userMessageLeadingComponent,
24224
25480
  footerComponent: userMessageFooterComponent
24225
- }, messagesProps === null || messagesProps === void 0 ? void 0 : messagesProps.userMessageProps),
24226
- translations: messagesTranslations,
24227
- messageTranslations: messageTranslations
24228
- }, messagesProps), {
25481
+ }, callerUserMessageProps),
24229
25482
  error: error
24230
25483
  }),
24231
- promptProps: _object_spread({
25484
+ promptProps: _object_spread_props(_object_spread({
24232
25485
  promptRef: promptRef,
24233
25486
  status: status,
24234
25487
  value: input,
@@ -24247,7 +25500,9 @@
24247
25500
  },
24248
25501
  headerComponent: promptHeaderComponent,
24249
25502
  footerComponent: promptFooterComponent
24250
- }, promptProps),
25503
+ }, promptProps), {
25504
+ autoFocus: (_ref3 = promptProps === null || promptProps === void 0 ? void 0 : promptProps.autoFocus) !== null && _ref3 !== void 0 ? _ref3 : !isOpenStatePersistenceEnabled || isInlineLayoutComponent
25505
+ }),
24251
25506
  suggestionsProps: {
24252
25507
  suggestions: suggestions,
24253
25508
  onSuggestionClick: function onSuggestionClick(suggestion) {
@@ -24261,6 +25516,55 @@
24261
25516
  }
24262
25517
  var Chat = /*#__PURE__*/ React.forwardRef(ChatInner);
24263
25518
 
25519
+ var PromptSuggestionsUi = createPromptSuggestionsComponent({
25520
+ createElement: React.createElement,
25521
+ Fragment: React.Fragment
25522
+ });
25523
+ function PromptSuggestions(_0) {
25524
+ var _0_classNames = _0.classNames, classNames = _0_classNames === void 0 ? {} : _0_classNames, LayoutComponent = _0.layoutComponent, onSuggestionClickOverride = _0.onSuggestionClick, // Connector params — forwarded to the hook, not the UI root.
25525
+ agentId = _0.agentId, transport = _0.transport, configurationId = _0.configurationId, transformHits = _0.transformHits, context = _0.context, transformItems = _0.transformItems, props = _object_without_properties(_0, [
25526
+ "classNames",
25527
+ "layoutComponent",
25528
+ "onSuggestionClick",
25529
+ "agentId",
25530
+ "transport",
25531
+ "configurationId",
25532
+ "transformHits",
25533
+ "context",
25534
+ "transformItems"
25535
+ ]);
25536
+ var _usePromptSuggestions = usePromptSuggestions({
25537
+ agentId: agentId,
25538
+ transport: transport,
25539
+ configurationId: configurationId,
25540
+ transformHits: transformHits,
25541
+ context: context,
25542
+ transformItems: transformItems
25543
+ }, {
25544
+ $$widgetType: 'ais.promptSuggestions'
25545
+ }), suggestions = _usePromptSuggestions.suggestions, isLoading = _usePromptSuggestions.isLoading, onSuggestionClick = _usePromptSuggestions.onSuggestionClick, isChatBusy = _usePromptSuggestions.isChatBusy, sendToChat = _usePromptSuggestions.sendToChat;
25546
+ var handleClick = onSuggestionClickOverride ? function(prompt) {
25547
+ return onSuggestionClickOverride(prompt, {
25548
+ sendToChat: sendToChat
25549
+ });
25550
+ } : onSuggestionClick;
25551
+ if (LayoutComponent) {
25552
+ return /*#__PURE__*/ React.createElement(LayoutComponent, {
25553
+ suggestions: suggestions,
25554
+ isLoading: isLoading,
25555
+ onSuggestionClick: handleClick,
25556
+ isChatBusy: isChatBusy
25557
+ });
25558
+ }
25559
+ return /*#__PURE__*/ React.createElement(PromptSuggestionsUi, _object_spread_props(_object_spread({}, props), {
25560
+ classNames: classNames,
25561
+ suggestions: suggestions,
25562
+ isLoading: isLoading,
25563
+ onSuggestionClick: handleClick,
25564
+ disabled: isChatBusy
25565
+ }));
25566
+ }
25567
+
24264
25568
  var ChatToggleButton = createChatToggleButtonComponent({
24265
25569
  createElement: React.createElement,
24266
25570
  Fragment: React.Fragment
@@ -26151,6 +27455,7 @@
26151
27455
  exports.Pagination = Pagination;
26152
27456
  exports.PonderToolType = PonderToolType;
26153
27457
  exports.PoweredBy = PoweredBy;
27458
+ exports.PromptSuggestions = PromptSuggestions;
26154
27459
  exports.RangeInput = RangeInput;
26155
27460
  exports.RecommendToolType = RecommendToolType;
26156
27461
  exports.RefinementList = RefinementList;
@@ -26190,6 +27495,7 @@
26190
27495
  exports.useNumericMenu = useNumericMenu;
26191
27496
  exports.usePagination = usePagination;
26192
27497
  exports.usePoweredBy = usePoweredBy;
27498
+ exports.usePromptSuggestions = usePromptSuggestions;
26193
27499
  exports.useQueryRules = useQueryRules;
26194
27500
  exports.useRSCContext = useRSCContext;
26195
27501
  exports.useRange = useRange;