react-instantsearch 7.45.0 → 7.46.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.45.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch */
1
+ /*! React InstantSearch 7.46.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.45.0';
27
+ var version$2 = '7.46.0';
28
28
 
29
29
  function _define_property(obj, key, value) {
30
30
  if (key in obj) {
@@ -9223,7 +9223,7 @@
9223
9223
  });
9224
9224
  }
9225
9225
 
9226
- var version = '4.112.0';
9226
+ var version = '4.113.0';
9227
9227
 
9228
9228
  var ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';
9229
9229
  function getCookie(name) {
@@ -13953,17 +13953,61 @@
13953
13953
  return laterPart.type !== 'reasoning' || laterPart.state === 'streaming';
13954
13954
  });
13955
13955
  }
13956
- var findTool = function findTool(partType, tools) {
13957
- var toolName = partType.replace('tool-', '');
13958
- var tool = tools[toolName];
13959
- if (!tool) {
13960
- var _Object_entries_find;
13961
- tool = (_Object_entries_find = Object.entries(tools).find(function(param) {
13962
- var _param = _sliced_to_array(param, 1), key = _param[0];
13963
- return startsWith(toolName, "".concat(key, "_"));
13964
- })) === null || _Object_entries_find === void 0 ? void 0 : _Object_entries_find[1];
13965
- }
13966
- return tool;
13956
+ /**
13957
+ * Whether a text part renders nothing. `text-start` creates the part before its
13958
+ * first delta, and `<context>` wrappers are a shim `ChatMessage` also drops.
13959
+ */ var isPartTextEmpty = function isPartTextEmpty(part) {
13960
+ return part.text.trim().length === 0 || part.text.startsWith('<context>') && part.text.endsWith('</context>');
13961
+ };
13962
+ /**
13963
+ * Whether a part says something about the turn's progress. Data parts and
13964
+ * unwritten text parts render nothing, so reading them would answer "what is
13965
+ * this turn doing" with a part that changed nothing on screen.
13966
+ */ var isPartProgressSignal = function isPartProgressSignal(part) {
13967
+ if (startsWith(part.type, 'data-')) {
13968
+ return false;
13969
+ }
13970
+ if (isPartText(part)) {
13971
+ return !isPartTextEmpty(part);
13972
+ }
13973
+ return true;
13974
+ };
13975
+ var findLastProgressPart = function findLastProgressPart(parts) {
13976
+ if (!parts) {
13977
+ return undefined;
13978
+ }
13979
+ for(var index = parts.length - 1; index >= 0; index--){
13980
+ var part = parts[index];
13981
+ if (isPartProgressSignal(part)) {
13982
+ return part;
13983
+ }
13984
+ }
13985
+ return undefined;
13986
+ };
13987
+ var TOOL_PART_PREFIX = 'tool-';
13988
+ /**
13989
+ * Resolves the tool a message part belongs to, from either a part type
13990
+ * (`tool-algolia_search_index`) or a bare tool name.
13991
+ *
13992
+ * Generic over the tool shape so the renderer, the loader and the connector —
13993
+ * which hold different subsets of the tool contract — all resolve names the same
13994
+ * way.
13995
+ */ var findTool = function findTool(partType, tools) {
13996
+ var toolName = startsWith(partType, TOOL_PART_PREFIX) ? partType.slice(TOOL_PART_PREFIX.length) : partType;
13997
+ if (tools[toolName]) {
13998
+ return tools[toolName];
13999
+ }
14000
+ // Compatibility shim for tool names suffixed by the index name, as the Algolia
14001
+ // MCP Server does (`algolia_search_index_products`). The longest matching key
14002
+ // wins, so registering both `foo` and `foo_bar` resolves `foo_bar_products` to
14003
+ // `foo_bar` — otherwise the winner would depend on registration order.
14004
+ var match;
14005
+ Object.keys(tools).forEach(function(key) {
14006
+ if (startsWith(toolName, "".concat(key, "_")) && (match === undefined || key.length > match.length)) {
14007
+ match = key;
14008
+ }
14009
+ });
14010
+ return match === undefined ? undefined : tools[match];
13967
14011
  };
13968
14012
  var FACET_KEY_PREFIX = 'facet_';
13969
14013
  var hasQueries = function hasQueries(input) {
@@ -14130,8 +14174,6 @@
14130
14174
  sendEvent: context.sendEvent
14131
14175
  };
14132
14176
  }
14133
- // Keep in sync with packages/instantsearch.js/src/lib/chat/index.ts
14134
- var SearchIndexToolType$1 = 'algolia_search_index';
14135
14177
  function createChatMessageComponent(param) {
14136
14178
  var createElement = param.createElement, Fragment = param.Fragment;
14137
14179
  var Button = createButtonComponent({
@@ -14142,7 +14184,7 @@
14142
14184
  });
14143
14185
  return function ChatMessage(userProps) {
14144
14186
  var _messages_;
14145
- var _userProps_classNames = userProps.classNames, classNames = _userProps_classNames === void 0 ? {} : _userProps_classNames, message = userProps.message, _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, TextComponent = userProps.textComponent, indexUiState = userProps.indexUiState, setIndexUiState = userProps.setIndexUiState, 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, ownMessages = userProps.messages, /* eslint-disable typescript/no-deprecated -- reading the
14187
+ var _userProps_classNames = userProps.classNames, classNames = _userProps_classNames === void 0 ? {} : _userProps_classNames, message = userProps.message, _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, TextComponent = userProps.textComponent, indexUiState = userProps.indexUiState, setIndexUiState = userProps.setIndexUiState, userTranslations = userProps.translations, suggestionsElement = userProps.suggestionsElement, loaderElement = userProps.loaderElement, _userProps_showReasoning = userProps.showReasoning, showReasoning = _userProps_showReasoning === void 0 ? false : _userProps_showReasoning, _userProps_parseMarkdown = userProps.parseMarkdown, parseMarkdown = _userProps_parseMarkdown === void 0 ? true : _userProps_parseMarkdown, ownMessages = userProps.messages, /* eslint-disable typescript/no-deprecated -- reading the
14146
14188
  deprecated aliases is the point: they are resolved into `context`
14147
14189
  below so callers on the previous API keep working. */ ownStatus = userProps.status, ownTools = userProps.tools, ownOnClose = userProps.onClose, /* eslint-enable typescript/no-deprecated */ sharedContext = userProps.context, props = _object_without_properties(userProps, [
14148
14190
  "classNames",
@@ -14159,6 +14201,7 @@
14159
14201
  "setIndexUiState",
14160
14202
  "translations",
14161
14203
  "suggestionsElement",
14204
+ "loaderElement",
14162
14205
  "showReasoning",
14163
14206
  "parseMarkdown",
14164
14207
  "messages",
@@ -14273,15 +14316,12 @@
14273
14316
  }, markdown);
14274
14317
  }
14275
14318
  if (startsWith(part.type, 'tool-')) {
14276
- var _message_metadata;
14277
- var toolName = part.type.replace('tool-', '');
14278
- var tool = tools[toolName];
14279
- // Compatibility shim with Algolia MCP Server search tool
14280
- if (!tool && startsWith(toolName, "".concat(SearchIndexToolType$1, "_"))) {
14281
- tool = tools[SearchIndexToolType$1];
14282
- }
14283
- var displayResultsEnabled = ((_message_metadata = message.metadata) === null || _message_metadata === void 0 ? void 0 : _message_metadata.displayResultsEnabled) === true;
14284
- if (displayResultsEnabled && tool && tool === tools[SearchIndexToolType$1]) {
14319
+ var _tool_shouldRender;
14320
+ var tool = findTool(part.type, tools);
14321
+ if ((tool === null || tool === void 0 ? void 0 : (_tool_shouldRender = tool.shouldRender) === null || _tool_shouldRender === void 0 ? void 0 : _tool_shouldRender.call(tool, _object_spread_props(_object_spread({}, context), {
14322
+ message: part,
14323
+ parentMessage: message
14324
+ }))) === false) {
14285
14325
  return null;
14286
14326
  }
14287
14327
  if (tool) {
@@ -14350,7 +14390,7 @@
14350
14390
  className: cx(cssClasses.content)
14351
14391
  }, /*#__PURE__*/ createElement("div", {
14352
14392
  className: cx(cssClasses.message)
14353
- }, message.parts.map(renderMessagePart)), suggestionsElement, showActions && /*#__PURE__*/ createElement("div", {
14393
+ }, message.parts.map(renderMessagePart), loaderElement), suggestionsElement, showActions && /*#__PURE__*/ createElement("div", {
14354
14394
  className: cx(cssClasses.actions),
14355
14395
  "aria-label": translations.actionsLabel
14356
14396
  }, ActionsComponent ? /*#__PURE__*/ createElement(ActionsComponent, {
@@ -14453,28 +14493,23 @@
14453
14493
  function createChatMessageLoaderComponent(param) {
14454
14494
  var createElement = param.createElement;
14455
14495
  return function ChatMessageLoader(userProps) {
14456
- var userTranslations = userProps.translations;
14496
+ var userTranslations = userProps.translations, _userProps_inline = userProps.inline, inline = _userProps_inline === void 0 ? false : _userProps_inline, className = userProps.className; // The turn context is for custom loaders, not for the DOM.
14457
14497
  userProps.context;
14458
14498
  var props = _object_without_properties(userProps, [
14459
14499
  "translations",
14500
+ "inline",
14501
+ "className",
14460
14502
  "context"
14461
14503
  ]);
14462
14504
  var translations = _object_spread({
14463
14505
  loaderText: ''
14464
14506
  }, userTranslations);
14465
- return /*#__PURE__*/ createElement("article", _object_spread({
14466
- className: "ais-ChatMessageLoader ais-ChatMessage ais-ChatMessage--left ais-ChatMessage--subtle"
14467
- }, props), /*#__PURE__*/ createElement("div", {
14468
- className: "ais-ChatMessage-container"
14469
- }, /*#__PURE__*/ createElement("div", {
14470
- className: "ais-ChatMessage-leading"
14471
- }, /*#__PURE__*/ createElement("div", {
14507
+ var spinner = /*#__PURE__*/ createElement("div", {
14472
14508
  className: "ais-ChatMessageLoader-spinner"
14473
14509
  }, /*#__PURE__*/ createElement(LoadingSpinnerIcon, {
14474
14510
  createElement: createElement
14475
- }))), /*#__PURE__*/ createElement("div", {
14476
- className: "ais-ChatMessage-content"
14477
- }, /*#__PURE__*/ createElement("div", {
14511
+ }));
14512
+ var body = /*#__PURE__*/ createElement("div", {
14478
14513
  className: "ais-ChatMessage-message"
14479
14514
  }, translations.loaderText && /*#__PURE__*/ createElement("div", {
14480
14515
  className: "ais-ChatMessageLoader-text"
@@ -14484,13 +14519,30 @@
14484
14519
  className: "ais-ChatMessageLoader-skeletonItem"
14485
14520
  }), /*#__PURE__*/ createElement("div", {
14486
14521
  className: "ais-ChatMessageLoader-skeletonItem"
14487
- }))))));
14522
+ })));
14523
+ if (inline) {
14524
+ return /*#__PURE__*/ createElement("div", _object_spread_props(_object_spread({}, props), {
14525
+ className: cx('ais-ChatMessageLoader', 'ais-ChatMessageLoader--inline', className)
14526
+ }), spinner, body);
14527
+ }
14528
+ return /*#__PURE__*/ createElement("article", _object_spread_props(_object_spread({}, props), {
14529
+ className: cx('ais-ChatMessageLoader ais-ChatMessage ais-ChatMessage--left ais-ChatMessage--subtle', className)
14530
+ }), /*#__PURE__*/ createElement("div", {
14531
+ className: "ais-ChatMessage-container"
14532
+ }, /*#__PURE__*/ createElement("div", {
14533
+ className: "ais-ChatMessage-leading"
14534
+ }, spinner), /*#__PURE__*/ createElement("div", {
14535
+ className: "ais-ChatMessage-content"
14536
+ }, body)));
14488
14537
  };
14489
14538
  }
14490
14539
 
14491
14540
  var copyToClipboard = function copyToClipboard(message) {
14492
14541
  navigator.clipboard.writeText(getTextContent(message));
14493
14542
  };
14543
+ var DEFAULT_LOADER_SHOW_DELAY = 250;
14544
+ // Short enough that it never lingers over the content that replaced it.
14545
+ var DEFAULT_LOADER_MIN_DURATION = 200;
14494
14546
  function getInstantSearchStatus(tools) {
14495
14547
  var _Object_values_find_insightsEventContext, _Object_values_find;
14496
14548
  return (_Object_values_find = Object.values(tools).find(function(tool) {
@@ -14509,7 +14561,7 @@
14509
14561
  Fragment: Fragment
14510
14562
  });
14511
14563
  return function DefaultMessage(param) {
14512
- var message = param.message, userMessageProps = param.userMessageProps, assistantMessageProps = param.assistantMessageProps, indexUiState = param.indexUiState, setIndexUiState = param.setIndexUiState, onReload = param.onReload, onFeedback = param.onFeedback, feedbackState = param.feedbackState, actionsComponent = param.actionsComponent, classNames = param.classNames, messageTranslations = param.messageTranslations, translations = param.translations, suggestionsElement = param.suggestionsElement, context = param.context;
14564
+ var message = param.message, userMessageProps = param.userMessageProps, assistantMessageProps = param.assistantMessageProps, indexUiState = param.indexUiState, setIndexUiState = param.setIndexUiState, onReload = param.onReload, onFeedback = param.onFeedback, feedbackState = param.feedbackState, actionsComponent = param.actionsComponent, classNames = param.classNames, messageTranslations = param.messageTranslations, translations = param.translations, suggestionsElement = param.suggestionsElement, loaderElement = param.loaderElement, context = param.context;
14513
14565
  var defaultAssistantActions = _to_consumable_array(hasTextContent(message) ? [
14514
14566
  {
14515
14567
  title: translations.copyToClipboardLabel,
@@ -14600,6 +14652,7 @@
14600
14652
  classNames: classNames,
14601
14653
  translations: messageTranslations,
14602
14654
  suggestionsElement: suggestionsElement,
14655
+ loaderElement: loaderElement,
14603
14656
  context: context
14604
14657
  }, messageProps), {
14605
14658
  message: message,
@@ -14608,10 +14661,128 @@
14608
14661
  };
14609
14662
  }
14610
14663
  function createChatMessagesComponent(param) {
14611
- var createElement = param.createElement, Fragment = param.Fragment, useMemo = param.useMemo;
14664
+ var createElement = param.createElement, Fragment = param.Fragment, useMemo = param.useMemo, useState = param.useState, useEffect = param.useEffect;
14612
14665
  var Button = createButtonComponent({
14613
14666
  createElement: createElement
14614
14667
  });
14668
+ /**
14669
+ * Smooths the loading state into a visibility. Several transitions in a turn
14670
+ * flip it twice within a few frames, which reads as the loader popping in and
14671
+ * out, so a loader coming back mid-turn waits out `showDelay` and a visible
14672
+ * one holds for `minDuration`.
14673
+ */ function useLoaderVisibility(param) {
14674
+ var isLoading = param.isLoading, isTurnActive = param.isTurnActive, showDelay = param.showDelay, minDuration = param.minDuration;
14675
+ var _useState = _sliced_to_array(useState({
14676
+ phase: 'idle'
14677
+ }), 2), loaderState = _useState[0], setLoaderState = _useState[1];
14678
+ var isVisible = isTurnActive && (isLoading && (loaderState.phase === 'idle' || loaderState.phase === 'ready' || loaderState.phase === 'hidden' && showDelay <= 0) || loaderState.phase === 'visible' && (isLoading || minDuration > loaderState.elapsedDuration));
14679
+ useEffect(function() {
14680
+ if (!isTurnActive) {
14681
+ if (loaderState.phase !== 'idle') {
14682
+ setLoaderState({
14683
+ phase: 'idle'
14684
+ });
14685
+ }
14686
+ return undefined;
14687
+ }
14688
+ if (loaderState.phase === 'idle') {
14689
+ if (isLoading) {
14690
+ setLoaderState({
14691
+ phase: 'visible',
14692
+ shownAt: Date.now(),
14693
+ elapsedDuration: 0
14694
+ });
14695
+ }
14696
+ return undefined;
14697
+ }
14698
+ if (loaderState.phase === 'visible') {
14699
+ if (!isLoading && minDuration <= loaderState.elapsedDuration) {
14700
+ setLoaderState({
14701
+ phase: 'hidden'
14702
+ });
14703
+ return undefined;
14704
+ }
14705
+ if (minDuration <= loaderState.elapsedDuration) {
14706
+ return undefined;
14707
+ }
14708
+ var remaining = Math.max(0, loaderState.shownAt + minDuration - Date.now());
14709
+ if (remaining === 0) {
14710
+ setLoaderState(_object_spread_props(_object_spread({}, loaderState), {
14711
+ elapsedDuration: minDuration
14712
+ }));
14713
+ return undefined;
14714
+ }
14715
+ var timer = setTimeout(function() {
14716
+ setLoaderState(function(current) {
14717
+ return current.phase === 'visible' && current.shownAt === loaderState.shownAt ? _object_spread_props(_object_spread({}, current), {
14718
+ elapsedDuration: Math.max(current.elapsedDuration, minDuration)
14719
+ }) : current;
14720
+ });
14721
+ }, remaining);
14722
+ return function() {
14723
+ return clearTimeout(timer);
14724
+ };
14725
+ }
14726
+ if (loaderState.phase === 'hidden') {
14727
+ if (isLoading) {
14728
+ var now = Date.now();
14729
+ setLoaderState(showDelay <= 0 ? {
14730
+ phase: 'visible',
14731
+ shownAt: now,
14732
+ elapsedDuration: 0
14733
+ } : {
14734
+ phase: 'waiting',
14735
+ pendingSince: now
14736
+ });
14737
+ }
14738
+ return undefined;
14739
+ }
14740
+ if (loaderState.phase === 'ready') {
14741
+ setLoaderState(isLoading ? {
14742
+ phase: 'visible',
14743
+ shownAt: loaderState.shownAt,
14744
+ elapsedDuration: loaderState.elapsedDuration
14745
+ } : {
14746
+ phase: 'hidden'
14747
+ });
14748
+ return undefined;
14749
+ }
14750
+ if (!isLoading) {
14751
+ setLoaderState({
14752
+ phase: 'hidden'
14753
+ });
14754
+ return undefined;
14755
+ }
14756
+ var remaining1 = Math.max(0, loaderState.pendingSince + showDelay - Date.now());
14757
+ if (remaining1 === 0) {
14758
+ setLoaderState({
14759
+ phase: 'visible',
14760
+ shownAt: Date.now(),
14761
+ elapsedDuration: 0
14762
+ });
14763
+ return undefined;
14764
+ }
14765
+ var timer1 = setTimeout(function() {
14766
+ setLoaderState(function(current) {
14767
+ return current.phase === 'waiting' && current.pendingSince === loaderState.pendingSince ? {
14768
+ phase: 'ready',
14769
+ shownAt: Date.now(),
14770
+ elapsedDuration: 0
14771
+ } : current;
14772
+ });
14773
+ }, remaining1);
14774
+ return function() {
14775
+ return clearTimeout(timer1);
14776
+ };
14777
+ }, [
14778
+ isLoading,
14779
+ isTurnActive,
14780
+ loaderState,
14781
+ minDuration,
14782
+ showDelay
14783
+ ]);
14784
+ return isVisible;
14785
+ }
14615
14786
  var DefaultMessageComponent = createDefaultMessageComponent({
14616
14787
  createElement: createElement,
14617
14788
  Fragment: Fragment
@@ -14632,6 +14803,12 @@
14632
14803
  var showReasoning = messageProps === null || messageProps === void 0 ? void 0 : messageProps.showReasoning;
14633
14804
  var parseMarkdown = messageProps === null || messageProps === void 0 ? void 0 : messageProps.parseMarkdown;
14634
14805
  var textComponent = messageProps === null || messageProps === void 0 ? void 0 : messageProps.textComponent;
14806
+ // A completed row is memoized against its own message, but `shouldRender`
14807
+ // reads the whole `context`: a predicate can hide an older tool result once a
14808
+ // newer message arrives. Track the verdicts themselves rather than
14809
+ // `context.messages`, so the row re-renders exactly when one flips instead of
14810
+ // on every streaming delta.
14811
+ var shouldRenderVerdicts = getShouldRenderVerdicts(props.context, props.message);
14635
14812
  // Custom text components receive the conversation, so their completed rows
14636
14813
  // must update with it. Keep the default renderer's streaming optimization.
14637
14814
  var textComponentMessages = textComponent ? props.context.messages : undefined;
@@ -14659,10 +14836,12 @@
14659
14836
  props.message,
14660
14837
  props.isCurrentMessage,
14661
14838
  props.status,
14839
+ shouldRenderVerdicts,
14662
14840
  props.context.maximized,
14663
14841
  props.context.open,
14664
14842
  instantSearchStatus,
14665
14843
  props.suggestionsElement,
14844
+ props.loaderElement,
14666
14845
  messageFeedback,
14667
14846
  showReasoning,
14668
14847
  parseMarkdown,
@@ -14687,17 +14866,21 @@
14687
14866
  return function ChatMessages(userProps) {
14688
14867
  var _ref;
14689
14868
  var _lastMessage_parts, _lastMessage_parts1;
14690
- 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, _userProps_regenerate = userProps.regenerate, regenerate = _userProps_regenerate === void 0 ? function() {
14869
+ 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, _userProps_loaderPosition = userProps.loaderPosition, loaderPosition = _userProps_loaderPosition === void 0 ? 'messages-end' : _userProps_loaderPosition, shouldShowLoader = userProps.shouldShowLoader, _userProps_loaderShowDelay = userProps.loaderShowDelay, loaderShowDelay = _userProps_loaderShowDelay === void 0 ? DEFAULT_LOADER_SHOW_DELAY : _userProps_loaderShowDelay, _userProps_loaderMinDuration = userProps.loaderMinDuration, loaderMinDuration = _userProps_loaderMinDuration === void 0 ? DEFAULT_LOADER_MIN_DURATION : _userProps_loaderMinDuration, 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, _userProps_regenerate = userProps.regenerate, regenerate = _userProps_regenerate === void 0 ? function() {
14691
14870
  return Promise.resolve();
14692
14871
  } : _userProps_regenerate, _userProps_stop = userProps.stop, stop = _userProps_stop === void 0 ? function() {
14693
14872
  return Promise.resolve();
14694
- } : _userProps_stop, _userProps_open = userProps.open, open = _userProps_open === void 0 ? false : _userProps_open, _userProps_maximized = userProps.maximized, maximized = _userProps_maximized === void 0 ? false : _userProps_maximized, 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, [
14873
+ } : _userProps_stop, _userProps_open = userProps.open, open = _userProps_open === void 0 ? false : _userProps_open, _userProps_maximized = userProps.maximized, maximized = _userProps_maximized === void 0 ? false : _userProps_maximized, 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, _userProps_suggestionsLoading = userProps.suggestionsLoading, suggestionsLoading = _userProps_suggestionsLoading === void 0 ? false : _userProps_suggestionsLoading, onFeedback = userProps.onFeedback, feedbackState = userProps.feedbackState, props = _object_without_properties(userProps, [
14695
14874
  "classNames",
14696
14875
  "messageClassNames",
14697
14876
  "messageTranslations",
14698
14877
  "messages",
14699
14878
  "messageComponent",
14700
14879
  "loaderComponent",
14880
+ "loaderPosition",
14881
+ "shouldShowLoader",
14882
+ "loaderShowDelay",
14883
+ "loaderMinDuration",
14701
14884
  "errorComponent",
14702
14885
  "emptyComponent",
14703
14886
  "actionsComponent",
@@ -14726,6 +14909,7 @@
14726
14909
  "contentRef",
14727
14910
  "onScrollToBottom",
14728
14911
  "suggestionsElement",
14912
+ "suggestionsLoading",
14729
14913
  "onFeedback",
14730
14914
  "feedbackState"
14731
14915
  ]);
@@ -14746,6 +14930,7 @@
14746
14930
  scrollToBottomHidden: cx('ais-ChatMessages-scrollToBottom--hidden', classNames.scrollToBottomHidden)
14747
14931
  };
14748
14932
  var lastMessage = messages[messages.length - 1];
14933
+ var showReasoning = assistantMessageProps === null || assistantMessageProps === void 0 ? void 0 : assistantMessageProps.showReasoning;
14749
14934
  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];
14750
14935
  // `activePart` means "the part currently being processed". It must clear
14751
14936
  // when nothing is in progress: once the response settles (`ready`/`error`),
@@ -14756,10 +14941,13 @@
14756
14941
  var activePart = isProcessing && (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'assistant' ? lastPart : undefined;
14757
14942
  // The scan slices the remaining parts per candidate, and only the loader reads
14758
14943
  // it, so skip it entirely while the opt-in is off.
14759
- 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) {
14944
+ // The loader reports on the assistant's turn, so it only ever belongs to an
14945
+ // assistant message. While `submitted` the last message is still the user's
14946
+ // own, and the loader belongs to no message at all.
14947
+ var loaderMessage = (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 'assistant' ? lastMessage : undefined;
14948
+ var hasActiveReasoning = 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) {
14760
14949
  return isReasoningPartActive(parts, index);
14761
14950
  })) !== null && _ref !== void 0 ? _ref : false : false;
14762
- var showLoader = getShowLoader(status, lastPart, tools, assistantMessageProps === null || assistantMessageProps === void 0 ? void 0 : assistantMessageProps.showReasoning, hasActiveReasoning);
14763
14951
  // The shared context handed to every overridable chat component, so custom
14764
14952
  // components can read the current chat state and common callbacks from a
14765
14953
  // single, consistent place.
@@ -14780,14 +14968,45 @@
14780
14968
  onNewConversation: onNewConversation,
14781
14969
  onClose: onClose
14782
14970
  };
14971
+ // The loader also reads what the turn is doing, which no other component
14972
+ // needs, so its context extends the shared one.
14973
+ var loaderContext = _object_spread_props(_object_spread({}, context), {
14974
+ phase: getLoaderPhase(status, loaderMessage, showReasoning),
14975
+ message: loaderMessage
14976
+ });
14977
+ var defaultShowLoader = getShowLoader(context, showReasoning, hasActiveReasoning);
14978
+ var isLoading = shouldShowLoader ? shouldShowLoader(_object_spread_props(_object_spread({}, loaderContext), {
14979
+ defaultValue: defaultShowLoader
14980
+ })) : defaultShowLoader;
14981
+ var showLoader = useLoaderVisibility({
14982
+ isLoading: isLoading,
14983
+ isTurnActive: isProcessing,
14984
+ showDelay: loaderShowDelay,
14985
+ minDuration: loaderMinDuration
14986
+ });
14783
14987
  var showEmpty = messages.length === 0 && !showLoader && !isClearing && status !== 'error';
14784
14988
  var DefaultMessage = MessageComponent || MemoizedDefaultMessage;
14785
14989
  var DefaultLoader = LoaderComponent || DefaultLoaderComponent;
14786
14990
  var DefaultError = ErrorComponent || DefaultErrorComponent;
14991
+ // An inline loader needs an assistant message to live in; before the first
14992
+ // response part there is none, so it falls back to its own row.
14993
+ var isLoaderInline = loaderPosition === 'message-inline' && loaderMessage !== undefined;
14994
+ var loaderText = typeof translations.loaderText === 'function' ? translations.loaderText(loaderContext) : translations.loaderText;
14995
+ var loaderElement = showLoader ? /*#__PURE__*/ createElement(DefaultLoader, {
14996
+ context: loaderContext,
14997
+ inline: isLoaderInline,
14998
+ translations: {
14999
+ loaderText: loaderText
15000
+ }
15001
+ }) : undefined;
15002
+ // Waits for the answer's text and for the loader to step aside, so two
15003
+ // progress affordances never stack up.
15004
+ var showPendingSuggestions = suggestionsLoading && !showLoader && lastMessage !== undefined && hasTextContent(lastMessage);
14787
15005
  return /*#__PURE__*/ createElement("div", _object_spread_props(_object_spread({}, props), {
14788
15006
  className: cx(cssClasses.root, props.className),
14789
15007
  role: "log",
14790
- "aria-live": "polite"
15008
+ "aria-live": "polite",
15009
+ "aria-busy": isProcessing ? 'true' : undefined
14791
15010
  }), /*#__PURE__*/ createElement("div", {
14792
15011
  className: cx(cssClasses.scroll),
14793
15012
  ref: scrollRef
@@ -14826,14 +15045,10 @@
14826
15045
  classNames: messageClassNames,
14827
15046
  messageTranslations: messageTranslations,
14828
15047
  context: context,
14829
- suggestionsElement: status === 'ready' && message.role === 'assistant' && index === messages.length - 1 ? suggestionsElement : undefined
15048
+ suggestionsElement: (status === 'ready' || showPendingSuggestions) && message.role === 'assistant' && index === messages.length - 1 ? suggestionsElement : undefined,
15049
+ loaderElement: isLoaderInline && index === messages.length - 1 ? loaderElement : undefined
14830
15050
  });
14831
- }), showLoader && /*#__PURE__*/ createElement(DefaultLoader, {
14832
- translations: {
14833
- loaderText: translations.loaderText
14834
- },
14835
- context: context
14836
- }), status === 'error' && /*#__PURE__*/ createElement(DefaultError, {
15051
+ }), !isLoaderInline && loaderElement, status === 'error' && /*#__PURE__*/ createElement(DefaultError, {
14837
15052
  onNewConversation: onNewConversation,
14838
15053
  errorMessage: error === null || error === void 0 ? void 0 : error.message,
14839
15054
  translations: // `fallbackResponse` that's safe to display verbatim; for
@@ -14860,17 +15075,65 @@
14860
15075
  })));
14861
15076
  };
14862
15077
  }
14863
- var getShowLoader = function getShowLoader(status, lastPart, tools, showReasoning, hasActiveReasoning) {
15078
+ var getLoaderPhase = function getLoaderPhase(status, message, showReasoning) {
15079
+ if (status === 'submitted') return 'submitted';
15080
+ var lastPart = findLastProgressPart(message === null || message === void 0 ? void 0 : message.parts);
15081
+ if (!lastPart) return 'thinking';
15082
+ if (isPartTool(lastPart)) return 'tool';
15083
+ if (showReasoning && lastPart.type === 'reasoning') return 'reasoning';
15084
+ return 'thinking';
15085
+ };
15086
+ /**
15087
+ * A stable signature of every `shouldRender` verdict in a message, so a memoized
15088
+ * row can be invalidated when a verdict changes. `undefined` when no tool part
15089
+ * in the message declares the predicate.
15090
+ */ var getShouldRenderVerdicts = function getShouldRenderVerdicts(context, message) {
15091
+ var _message_parts;
15092
+ var verdicts;
15093
+ (_message_parts = message.parts) === null || _message_parts === void 0 ? void 0 : _message_parts.forEach(function(part, index) {
15094
+ var _findTool;
15095
+ if (!isPartTool(part)) {
15096
+ return;
15097
+ }
15098
+ var shouldRender = (_findTool = findTool(part.type, context.tools)) === null || _findTool === void 0 ? void 0 : _findTool.shouldRender;
15099
+ if (!shouldRender) {
15100
+ return;
15101
+ }
15102
+ verdicts = "".concat(verdicts !== null && verdicts !== void 0 ? verdicts : '').concat(index, ":").concat(shouldRender(_object_spread_props(_object_spread({}, context), {
15103
+ message: part,
15104
+ parentMessage: message
15105
+ })), ";");
15106
+ });
15107
+ return verdicts;
15108
+ };
15109
+ var getShowLoader = function getShowLoader(context, showReasoning, hasActiveReasoning) {
15110
+ var status = context.status, messages = context.messages, tools = context.tools;
14864
15111
  if (status !== 'submitted' && status !== 'streaming') return false;
14865
15112
  if (status === 'submitted') return true;
15113
+ var lastMessage = messages[messages.length - 1];
15114
+ // Parts that render nothing must not answer for the turn's progress, or the
15115
+ // loader flips on a part that changed nothing on screen.
15116
+ var lastPart = findLastProgressPart(lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.parts);
14866
15117
  if (!lastPart) return true;
14867
15118
  // An active disclosure carries its own progress affordance, so the loader would
14868
15119
  // double it. Settled reasoning still shows it: the answer has not started.
14869
15120
  if (showReasoning && hasActiveReasoning) return false;
14870
15121
  if (isPartText(lastPart)) return false;
14871
- if (isPartTool(lastPart) && lastPart.state === 'input-streaming') {
15122
+ if (isPartTool(lastPart)) {
15123
+ var _tool_shouldRender;
14872
15124
  var tool = findTool(lastPart.type, tools);
14873
- return !(tool === null || tool === void 0 ? void 0 : tool.streamInput);
15125
+ // A part the tool declines to render leaves nothing on screen, so the turn
15126
+ // still reads as in progress — keep the loader up rather than letting a
15127
+ // settled-but-hidden part terminate it.
15128
+ if (lastMessage && (tool === null || tool === void 0 ? void 0 : (_tool_shouldRender = tool.shouldRender) === null || _tool_shouldRender === void 0 ? void 0 : _tool_shouldRender.call(tool, _object_spread_props(_object_spread({}, context), {
15129
+ message: lastPart,
15130
+ parentMessage: lastMessage
15131
+ }))) === false) {
15132
+ return true;
15133
+ }
15134
+ if (lastPart.state === 'input-streaming') {
15135
+ return !(tool === null || tool === void 0 ? void 0 : tool.streamInput);
15136
+ }
14874
15137
  }
14875
15138
  return true;
14876
15139
  };
@@ -15086,20 +15349,31 @@
15086
15349
  createElement: createElement
15087
15350
  });
15088
15351
  return function ChatPromptSuggestions(userProps) {
15089
- var _userProps_suggestions = userProps.suggestions, suggestions = _userProps_suggestions === void 0 ? [] : _userProps_suggestions, onSuggestionClick = userProps.onSuggestionClick, _userProps_classNames = userProps.classNames, classNames = _userProps_classNames === void 0 ? {} : _userProps_classNames;
15090
- if (suggestions.length === 0) {
15352
+ 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_classNames = userProps.classNames, classNames = _userProps_classNames === void 0 ? {} : _userProps_classNames;
15353
+ var visibleSuggestions = suggestions.filter(function(suggestion) {
15354
+ return suggestion.trim() !== '';
15355
+ });
15356
+ if (visibleSuggestions.length === 0 && !isLoading) {
15091
15357
  return null;
15092
15358
  }
15093
15359
  return /*#__PURE__*/ createElement("div", {
15094
15360
  className: cx('ais-ChatPromptSuggestions', classNames.root)
15095
- }, suggestions.map(function(suggestion, index) {
15361
+ }, isLoading && visibleSuggestions.length === 0 ? _to_consumable_array(new Array(skeletonCount)).map(function(_, index) {
15362
+ return /*#__PURE__*/ createElement("div", {
15363
+ key: index,
15364
+ className: cx('ais-ChatPromptSuggestions-skeletonItem', classNames.skeletonItem)
15365
+ });
15366
+ }) : visibleSuggestions.map(function(suggestion, index) {
15096
15367
  return /*#__PURE__*/ createElement(Button, {
15097
15368
  key: index,
15098
15369
  size: "sm",
15099
15370
  variant: "primary",
15100
15371
  className: cx('ais-ChatPromptSuggestions-suggestion', classNames.suggestion),
15372
+ // A half-written suggestion can't be sent. Not `disabled`,
15373
+ // which would restyle the pill mid-stream.
15101
15374
  onClick: function onClick() {
15102
- return onSuggestionClick(suggestion);
15375
+ if (isLoading) return;
15376
+ onSuggestionClick(suggestion);
15103
15377
  }
15104
15378
  }, suggestion);
15105
15379
  }));
@@ -15110,7 +15384,7 @@
15110
15384
  return typeof window !== 'undefined' && typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
15111
15385
  }
15112
15386
  function createChatComponent(param) {
15113
- var createElement = param.createElement, Fragment = param.Fragment, useMemo = param.useMemo, useState = param.useState;
15387
+ var createElement = param.createElement, Fragment = param.Fragment, useMemo = param.useMemo, useState = param.useState, useEffect = param.useEffect;
15114
15388
  var ChatHeader = createChatHeaderComponent({
15115
15389
  createElement: createElement,
15116
15390
  Fragment: Fragment
@@ -15118,7 +15392,9 @@
15118
15392
  var ChatMessages = createChatMessagesComponent({
15119
15393
  createElement: createElement,
15120
15394
  Fragment: Fragment,
15121
- useMemo: useMemo
15395
+ useMemo: useMemo,
15396
+ useState: useState,
15397
+ useEffect: useEffect
15122
15398
  });
15123
15399
  var ChatPrompt = createChatPromptComponent({
15124
15400
  createElement: createElement,
@@ -15190,6 +15466,7 @@
15190
15466
  error: error,
15191
15467
  classNames: classNames.messages,
15192
15468
  messageClassNames: classNames.message,
15469
+ suggestionsLoading: suggestionsProps.isLoading,
15193
15470
  suggestionsElement: createElement(SuggestionsComponent || ChatPromptSuggestions, _object_spread_props(_object_spread({}, suggestionsProps), {
15194
15471
  classNames: classNames.suggestions
15195
15472
  }))
@@ -16851,75 +17128,11 @@
16851
17128
  return Boolean(item && (typeof item === "undefined" ? "undefined" : _type_of(item)) === 'object' && item[PROMPT_SUGGESTION_FLAG]);
16852
17129
  }
16853
17130
 
16854
- var tryParseJson = function tryParseJson(value) {
16855
- try {
16856
- return JSON.parse(value);
16857
- } catch (unused) {
16858
- return undefined;
16859
- }
16860
- };
16861
- var repairPartialJson = function repairPartialJson(value) {
16862
- var repaired = value.trim();
16863
- if (!repaired) {
16864
- return repaired;
16865
- }
16866
- var inString = false;
16867
- var isEscaped = false;
16868
- var stack = [];
16869
- for(var index = 0; index < repaired.length; index++){
16870
- var char = repaired[index];
16871
- if (inString) {
16872
- if (isEscaped) {
16873
- isEscaped = false;
16874
- } else if (char === '\\') {
16875
- isEscaped = true;
16876
- } else if (char === '"') {
16877
- inString = false;
16878
- }
16879
- continue;
16880
- }
16881
- if (char === '"') {
16882
- inString = true;
16883
- continue;
16884
- }
16885
- if (char === '{' || char === '[') {
16886
- stack.push(char);
16887
- continue;
16888
- }
16889
- if (char === '}' && stack[stack.length - 1] === '{') {
16890
- stack.pop();
16891
- continue;
16892
- }
16893
- if (char === ']' && stack[stack.length - 1] === '[') {
16894
- stack.pop();
16895
- }
16896
- }
16897
- if (inString && !isEscaped) {
16898
- repaired += '"';
16899
- }
16900
- repaired = repaired.replace(RegExp(",\\s*$", "u"), '');
16901
- if (stack.length > 0) {
16902
- repaired += stack.reverse().map(function(opening) {
16903
- return opening === '{' ? '}' : ']';
16904
- }).join('');
16905
- }
16906
- return repaired.replace(RegExp(",\\s*([}\\]])", "gu"), '$1');
16907
- };
16908
- var parsePartialJson = function parsePartialJson(accumulatedRawJson, fallbackValue) {
16909
- var normalized = accumulatedRawJson.trim();
16910
- if (!normalized) {
16911
- return fallbackValue;
16912
- }
16913
- var directParsed = tryParseJson(normalized);
16914
- if (directParsed !== undefined) {
16915
- return directParsed;
16916
- }
16917
- var repairedParsed = tryParseJson(repairPartialJson(normalized));
16918
- if (repairedParsed !== undefined) {
16919
- return repairedParsed;
16920
- }
16921
- return fallbackValue;
16922
- };
17131
+ function flat(arr) {
17132
+ return arr.reduce(function(acc, array) {
17133
+ return acc.concat(array);
17134
+ }, []);
17135
+ }
16923
17136
 
16924
17137
  /**
16925
17138
  * Stream parser for parsing SSE (Server-Sent Events) streams.
@@ -17211,67 +17424,327 @@
17211
17424
  return undefined;
17212
17425
  }
17213
17426
 
17214
- var _computedKey$1;
17215
- var defaultGuardrailFallbackResponse = 'Sorry, we are not able to generate a response at the moment.';
17216
- var TOOL_CALL_CANCELLED_ERROR_TEXT = 'The tool call was cancelled: the conversation moved on before a result was provided.';
17217
- function getToolName(part) {
17218
- if (part.type === 'dynamic-tool') {
17219
- var _part_toolName;
17220
- return (_part_toolName = part.toolName) !== null && _part_toolName !== void 0 ? _part_toolName : part.type;
17221
- }
17222
- return part.type.slice('tool-'.length);
17223
- }
17224
- function warnInvalidGlobalToolResult(toolCallId) {}
17225
- // A tool call awaiting an output that the client owns. Provider-executed calls
17226
- // are resolved server-side, so they are left alone.
17227
- function isPendingToolPart(part) {
17228
- var candidate = part;
17229
- return typeof candidate.type === 'string' && typeof candidate.toolCallId === 'string' && (candidate.state === 'input-streaming' || candidate.state === 'input-available') && candidate.providerExecuted !== true;
17230
- }
17231
- // Drops the fields that only belong to the state being left behind:
17232
- // `output-error` forbids `output`, and a committed output is not `preliminary`.
17233
- function withTerminalToolState(part, terminalState) {
17234
- // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
17235
- part.preliminary; // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
17236
- part.rawOutput; // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
17237
- part.output; // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
17238
- part.errorText;
17239
- var retainedPart = _object_without_properties(part, [
17240
- "preliminary",
17241
- "rawOutput",
17242
- "output",
17243
- "errorText"
17244
- ]);
17245
- return _object_spread({}, retainedPart, terminalState);
17427
+ /**
17428
+ * Reads a human-readable message from a failed HTTP response body when the
17429
+ * server returns JSON such as `{ "message": "..." }` (the shared
17430
+ * `ErrorResponse` shape used by every status code), falling back to the HTTP
17431
+ * status line when the body is empty or not parseable.
17432
+ */ function getHttpErrorMessage(response) {
17433
+ var fallback = "HTTP error: ".concat(response.status, " ").concat(response.statusText);
17434
+ return response.text().then(function(text) {
17435
+ var _tryParseErrorMessage;
17436
+ return (_tryParseErrorMessage = tryParseErrorMessage(text)) !== null && _tryParseErrorMessage !== void 0 ? _tryParseErrorMessage : fallback;
17437
+ }).catch(function() {
17438
+ return fallback;
17439
+ });
17246
17440
  }
17247
- _computedKey$1 = /** @internal */ '~addToolResultForMessage';
17248
- var _computedKey1$1 = _computedKey$1;
17249
17441
  /**
17250
- * Abstract base class for chat implementations.
17251
- */ var AbstractChat = /*#__PURE__*/ function() {
17252
- function AbstractChat(param) {
17253
- var _this = this;
17254
- var _param_generateId = param.generateId, generateId$1 = _param_generateId === void 0 ? generateId : _param_generateId, _param_id = param.id, id = _param_id === void 0 ? generateId$1() : _param_id, transport = param.transport, state = param.state, onError = param.onError, onToolCall = param.onToolCall, onFinish = param.onFinish, onData = param.onData, sendAutomaticallyWhen = param.sendAutomaticallyWhen, shouldRepairToolInput = param.shouldRepairToolInput, resolveCancelledToolOutput = param.resolveCancelledToolOutput;
17255
- var _this1 = this;
17256
- _class_call_check(this, AbstractChat);
17257
- _define_property(this, "conversationId", void 0);
17258
- _define_property(this, "generateId", void 0);
17259
- _define_property(this, "state", void 0);
17260
- _define_property(this, "transport", void 0);
17261
- _define_property(this, "onError", void 0);
17262
- _define_property(this, "onToolCall", void 0);
17263
- _define_property(this, "onFinish", void 0);
17264
- _define_property(this, "onData", void 0);
17265
- _define_property(this, "sendAutomaticallyWhen", void 0);
17266
- _define_property(this, "shouldRepairToolInput", void 0);
17267
- _define_property(this, "resolveCancelledToolOutput", void 0);
17268
- _define_property(this, "activeResponse", null);
17269
- _define_property(this, "latestResponse", null);
17270
- _define_property(this, "responsesByToolCallId", new Map());
17271
- _define_property(this, "responseByMessage", new WeakMap());
17272
- // Once tool ownership is discarded, an identifier-only result cannot prove
17273
- // which response generation submitted it. Scoped submissions remain safe.
17274
- _define_property(this, "acceptsIdentifierOnlyToolResults", true);
17442
+ * Abstract base class for HTTP-based chat transports.
17443
+ */ var HttpChatTransport = /*#__PURE__*/ function() {
17444
+ function HttpChatTransport(param) {
17445
+ var _param_api = param.api, api = _param_api === void 0 ? '/api/chat' : _param_api, credentials = param.credentials, headers = param.headers, body = param.body, customFetch = param.fetch, prepareSendMessagesRequest = param.prepareSendMessagesRequest, prepareReconnectToStreamRequest = param.prepareReconnectToStreamRequest;
17446
+ _class_call_check(this, HttpChatTransport);
17447
+ _define_property(this, "api", void 0);
17448
+ _define_property(this, "credentials", void 0);
17449
+ _define_property(this, "headers", void 0);
17450
+ _define_property(this, "body", void 0);
17451
+ _define_property(this, "fetch", void 0);
17452
+ _define_property(this, "prepareSendMessagesRequest", void 0);
17453
+ _define_property(this, "prepareReconnectToStreamRequest", void 0);
17454
+ this.api = api;
17455
+ this.credentials = credentials;
17456
+ this.headers = headers;
17457
+ this.body = body;
17458
+ this.fetch = customFetch;
17459
+ this.prepareSendMessagesRequest = prepareSendMessagesRequest;
17460
+ this.prepareReconnectToStreamRequest = prepareReconnectToStreamRequest;
17461
+ }
17462
+ _create_class(HttpChatTransport, [
17463
+ {
17464
+ key: "sendMessages",
17465
+ value: function sendMessages(param) {
17466
+ var _this = this;
17467
+ var abortSignal = param.abortSignal, chatId = param.chatId, messages = param.messages, requestMetadata = param.requestMetadata, trigger = param.trigger, messageId = param.messageId, requestHeaders = param.headers, requestBody = param.body;
17468
+ var _this_fetch;
17469
+ var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
17470
+ // Resolve configurable values
17471
+ return Promise.all([
17472
+ resolveValue(this.credentials),
17473
+ resolveValue(this.headers),
17474
+ resolveValue(this.body)
17475
+ ]).then(function(param) {
17476
+ var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
17477
+ // Build default request options
17478
+ var api = _this.api;
17479
+ var body = _object_spread({
17480
+ id: chatId,
17481
+ messages: messages
17482
+ }, resolvedBody, requestBody);
17483
+ var headers = _object_spread({
17484
+ 'Content-Type': 'application/json'
17485
+ }, _instanceof(resolvedHeaders, Headers) ? Object.fromEntries(resolvedHeaders.entries()) : resolvedHeaders, _instanceof(requestHeaders, Headers) ? Object.fromEntries(requestHeaders.entries()) : requestHeaders);
17486
+ var credentials = resolvedCredentials;
17487
+ // Apply custom preparation if provided
17488
+ var prepareRequestBody = _object_spread({}, resolvedBody, requestBody);
17489
+ var preparePromise = _this.prepareSendMessagesRequest ? Promise.resolve(_this.prepareSendMessagesRequest({
17490
+ id: chatId,
17491
+ messages: messages,
17492
+ requestMetadata: requestMetadata,
17493
+ body: prepareRequestBody,
17494
+ credentials: resolvedCredentials,
17495
+ headers: resolvedHeaders,
17496
+ api: _this.api,
17497
+ trigger: trigger,
17498
+ messageId: messageId
17499
+ })) : Promise.resolve(null);
17500
+ return preparePromise.then(function(prepared) {
17501
+ if (prepared) {
17502
+ body = prepared.body;
17503
+ if (prepared.api) api = prepared.api;
17504
+ if (prepared.headers) {
17505
+ headers = _object_spread({
17506
+ 'Content-Type': 'application/json'
17507
+ }, _instanceof(prepared.headers, Headers) ? Object.fromEntries(prepared.headers.entries()) : prepared.headers);
17508
+ }
17509
+ if (prepared.credentials) credentials = prepared.credentials;
17510
+ }
17511
+ return fetchFn(api, {
17512
+ method: 'POST',
17513
+ headers: headers,
17514
+ body: JSON.stringify(body),
17515
+ signal: abortSignal,
17516
+ credentials: credentials
17517
+ }).then(function(response) {
17518
+ if (!response.ok) {
17519
+ return getHttpErrorMessage(response).then(function(message) {
17520
+ throw new Error(message);
17521
+ });
17522
+ }
17523
+ if (!response.body) {
17524
+ throw new Error('Response body is empty');
17525
+ }
17526
+ return _this.processResponseStream(response.body);
17527
+ });
17528
+ });
17529
+ });
17530
+ }
17531
+ },
17532
+ {
17533
+ key: "reconnectToStream",
17534
+ value: function reconnectToStream(param) {
17535
+ var _this = this;
17536
+ var chatId = param.chatId, requestHeaders = param.headers, requestBody = param.body;
17537
+ var _this_fetch;
17538
+ var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
17539
+ // Resolve configurable values
17540
+ return Promise.all([
17541
+ resolveValue(this.credentials),
17542
+ resolveValue(this.headers),
17543
+ resolveValue(this.body)
17544
+ ]).then(function(param) {
17545
+ var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
17546
+ // Build default request options
17547
+ var api = _this.api;
17548
+ var headers = _object_spread({}, _instanceof(resolvedHeaders, Headers) ? Object.fromEntries(resolvedHeaders.entries()) : resolvedHeaders, _instanceof(requestHeaders, Headers) ? Object.fromEntries(requestHeaders.entries()) : requestHeaders);
17549
+ var credentials = resolvedCredentials;
17550
+ // Apply custom preparation if provided
17551
+ var prepareRequestBody = _object_spread({}, resolvedBody, requestBody);
17552
+ var preparePromise = _this.prepareReconnectToStreamRequest ? Promise.resolve(_this.prepareReconnectToStreamRequest({
17553
+ id: chatId,
17554
+ requestMetadata: undefined,
17555
+ body: prepareRequestBody,
17556
+ credentials: resolvedCredentials,
17557
+ headers: resolvedHeaders,
17558
+ api: _this.api
17559
+ })) : Promise.resolve(null);
17560
+ return preparePromise.then(function(prepared) {
17561
+ if (prepared) {
17562
+ if (prepared.api) api = prepared.api;
17563
+ if (prepared.headers) {
17564
+ headers = _instanceof(prepared.headers, Headers) ? Object.fromEntries(prepared.headers.entries()) : prepared.headers;
17565
+ }
17566
+ if (prepared.credentials) credentials = prepared.credentials;
17567
+ }
17568
+ // GET request for reconnection
17569
+ return fetchFn("".concat(api, "?chatId=").concat(chatId), {
17570
+ method: 'GET',
17571
+ headers: headers,
17572
+ credentials: credentials
17573
+ }).then(function(response) {
17574
+ if (!response.ok) {
17575
+ // 404 means no stream to reconnect to, which is not an error
17576
+ if (response.status === 404) {
17577
+ return null;
17578
+ }
17579
+ return getHttpErrorMessage(response).then(function(message) {
17580
+ throw new Error(message);
17581
+ });
17582
+ }
17583
+ if (!response.body) {
17584
+ return null;
17585
+ }
17586
+ return _this.processResponseStream(response.body);
17587
+ });
17588
+ });
17589
+ });
17590
+ }
17591
+ }
17592
+ ]);
17593
+ return HttpChatTransport;
17594
+ }();
17595
+ /**
17596
+ * Default chat transport implementation using NDJSON streaming.
17597
+ */ var DefaultChatTransport = /*#__PURE__*/ function(HttpChatTransport) {
17598
+ _inherits(DefaultChatTransport, HttpChatTransport);
17599
+ function DefaultChatTransport() {
17600
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
17601
+ _class_call_check(this, DefaultChatTransport);
17602
+ return _call_super(this, DefaultChatTransport, [
17603
+ options
17604
+ ]);
17605
+ }
17606
+ _create_class(DefaultChatTransport, [
17607
+ {
17608
+ key: "processResponseStream",
17609
+ value: function processResponseStream(stream) {
17610
+ return parseJsonEventStream(stream);
17611
+ }
17612
+ }
17613
+ ]);
17614
+ return DefaultChatTransport;
17615
+ }(HttpChatTransport);
17616
+
17617
+ var tryParseJson = function tryParseJson(value) {
17618
+ try {
17619
+ return JSON.parse(value);
17620
+ } catch (unused) {
17621
+ return undefined;
17622
+ }
17623
+ };
17624
+ var repairPartialJson = function repairPartialJson(value) {
17625
+ var repaired = value.trim();
17626
+ if (!repaired) {
17627
+ return repaired;
17628
+ }
17629
+ var inString = false;
17630
+ var isEscaped = false;
17631
+ var stack = [];
17632
+ for(var index = 0; index < repaired.length; index++){
17633
+ var char = repaired[index];
17634
+ if (inString) {
17635
+ if (isEscaped) {
17636
+ isEscaped = false;
17637
+ } else if (char === '\\') {
17638
+ isEscaped = true;
17639
+ } else if (char === '"') {
17640
+ inString = false;
17641
+ }
17642
+ continue;
17643
+ }
17644
+ if (char === '"') {
17645
+ inString = true;
17646
+ continue;
17647
+ }
17648
+ if (char === '{' || char === '[') {
17649
+ stack.push(char);
17650
+ continue;
17651
+ }
17652
+ if (char === '}' && stack[stack.length - 1] === '{') {
17653
+ stack.pop();
17654
+ continue;
17655
+ }
17656
+ if (char === ']' && stack[stack.length - 1] === '[') {
17657
+ stack.pop();
17658
+ }
17659
+ }
17660
+ if (inString && !isEscaped) {
17661
+ repaired += '"';
17662
+ }
17663
+ repaired = repaired.replace(RegExp(",\\s*$", "u"), '');
17664
+ if (stack.length > 0) {
17665
+ repaired += stack.reverse().map(function(opening) {
17666
+ return opening === '{' ? '}' : ']';
17667
+ }).join('');
17668
+ }
17669
+ return repaired.replace(RegExp(",\\s*([}\\]])", "gu"), '$1');
17670
+ };
17671
+ var parsePartialJson = function parsePartialJson(accumulatedRawJson, fallbackValue) {
17672
+ var normalized = accumulatedRawJson.trim();
17673
+ if (!normalized) {
17674
+ return fallbackValue;
17675
+ }
17676
+ var directParsed = tryParseJson(normalized);
17677
+ if (directParsed !== undefined) {
17678
+ return directParsed;
17679
+ }
17680
+ var repairedParsed = tryParseJson(repairPartialJson(normalized));
17681
+ if (repairedParsed !== undefined) {
17682
+ return repairedParsed;
17683
+ }
17684
+ return fallbackValue;
17685
+ };
17686
+
17687
+ var _computedKey$1;
17688
+ var defaultGuardrailFallbackResponse = 'Sorry, we are not able to generate a response at the moment.';
17689
+ var TOOL_CALL_CANCELLED_ERROR_TEXT = 'The tool call was cancelled: the conversation moved on before a result was provided.';
17690
+ function getToolName(part) {
17691
+ if (part.type === 'dynamic-tool') {
17692
+ var _part_toolName;
17693
+ return (_part_toolName = part.toolName) !== null && _part_toolName !== void 0 ? _part_toolName : part.type;
17694
+ }
17695
+ return part.type.slice('tool-'.length);
17696
+ }
17697
+ function warnInvalidGlobalToolResult(toolCallId) {}
17698
+ // A tool call awaiting an output that the client owns. Provider-executed calls
17699
+ // are resolved server-side, so they are left alone.
17700
+ function isPendingToolPart(part) {
17701
+ var candidate = part;
17702
+ return typeof candidate.type === 'string' && typeof candidate.toolCallId === 'string' && (candidate.state === 'input-streaming' || candidate.state === 'input-available') && candidate.providerExecuted !== true;
17703
+ }
17704
+ // Drops the fields that only belong to the state being left behind:
17705
+ // `output-error` forbids `output`, and a committed output is not `preliminary`.
17706
+ function withTerminalToolState(part, terminalState) {
17707
+ // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
17708
+ part.preliminary; // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
17709
+ part.rawOutput; // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
17710
+ part.output; // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
17711
+ part.errorText;
17712
+ var retainedPart = _object_without_properties(part, [
17713
+ "preliminary",
17714
+ "rawOutput",
17715
+ "output",
17716
+ "errorText"
17717
+ ]);
17718
+ return _object_spread({}, retainedPart, terminalState);
17719
+ }
17720
+ _computedKey$1 = /** @internal */ '~addToolResultForMessage';
17721
+ var _computedKey1$1 = _computedKey$1;
17722
+ /**
17723
+ * Abstract base class for chat implementations.
17724
+ */ var AbstractChat = /*#__PURE__*/ function() {
17725
+ function AbstractChat(param) {
17726
+ var _this = this;
17727
+ var _param_generateId = param.generateId, generateId$1 = _param_generateId === void 0 ? generateId : _param_generateId, _param_id = param.id, id = _param_id === void 0 ? generateId$1() : _param_id, transport = param.transport, state = param.state, onError = param.onError, onToolCall = param.onToolCall, onFinish = param.onFinish, onData = param.onData, sendAutomaticallyWhen = param.sendAutomaticallyWhen, shouldRepairToolInput = param.shouldRepairToolInput, resolveCancelledToolOutput = param.resolveCancelledToolOutput;
17728
+ var _this1 = this;
17729
+ _class_call_check(this, AbstractChat);
17730
+ _define_property(this, "conversationId", void 0);
17731
+ _define_property(this, "generateId", void 0);
17732
+ _define_property(this, "state", void 0);
17733
+ _define_property(this, "transport", void 0);
17734
+ _define_property(this, "onError", void 0);
17735
+ _define_property(this, "onToolCall", void 0);
17736
+ _define_property(this, "onFinish", void 0);
17737
+ _define_property(this, "onData", void 0);
17738
+ _define_property(this, "sendAutomaticallyWhen", void 0);
17739
+ _define_property(this, "shouldRepairToolInput", void 0);
17740
+ _define_property(this, "resolveCancelledToolOutput", void 0);
17741
+ _define_property(this, "activeResponse", null);
17742
+ _define_property(this, "latestResponse", null);
17743
+ _define_property(this, "responsesByToolCallId", new Map());
17744
+ _define_property(this, "responseByMessage", new WeakMap());
17745
+ // Once tool ownership is discarded, an identifier-only result cannot prove
17746
+ // which response generation submitted it. Scoped submissions remain safe.
17747
+ _define_property(this, "acceptsIdentifierOnlyToolResults", true);
17275
17748
  _define_property(this, "jobExecutor", new SerialJobExecutor());
17276
17749
  /**
17277
17750
  * Appends or replaces a user message to the chat list. This triggers the API call to fetch
@@ -18624,338 +19097,92 @@
18624
19097
  });
18625
19098
  });
18626
19099
  if (initialMessages !== undefined) {
18627
- this._messages = initialMessages;
18628
- } else if (persistence) {
18629
- this._messages = getDefaultInitialMessages(id);
18630
- } else {
18631
- this._messages = [];
18632
- }
18633
- if (!persistence) {
18634
- return;
18635
- }
18636
- var saveMessagesInLocalStorage = function saveMessagesInLocalStorage() {
18637
- if (_this.status === 'ready') {
18638
- safelyRunOnBrowser(function() {
18639
- try {
18640
- sessionStorage.setItem(CACHE_KEY + (id ? "-".concat(id) : ''), JSON.stringify(_this.messages));
18641
- } catch (e) {
18642
- // Do nothing if sessionStorage is not available or full
18643
- }
18644
- });
18645
- }
18646
- };
18647
- this['~registerMessagesCallback'](saveMessagesInLocalStorage);
18648
- this['~registerStatusCallback'](saveMessagesInLocalStorage);
18649
- }
18650
- _create_class(ChatState, [
18651
- {
18652
- key: "status",
18653
- get: function get() {
18654
- return this._status;
18655
- },
18656
- set: function set(newStatus) {
18657
- this._status = newStatus;
18658
- this._callStatusCallbacks();
18659
- }
18660
- },
18661
- {
18662
- key: "error",
18663
- get: function get() {
18664
- return this._error;
18665
- },
18666
- set: function set(newError) {
18667
- this._error = newError;
18668
- this._callErrorCallbacks();
18669
- }
18670
- },
18671
- {
18672
- key: "messages",
18673
- get: function get() {
18674
- return this._messages;
18675
- },
18676
- set: function set(newMessages) {
18677
- this._messages = _to_consumable_array(newMessages);
18678
- this._callMessagesCallbacks();
18679
- }
18680
- }
18681
- ]);
18682
- return ChatState;
18683
- }();
18684
- _computedKey3 = '~registerMessagesCallback', _computedKey4 = '~registerStatusCallback', _computedKey5 = '~registerErrorCallback';
18685
- var _computedKey9 = _computedKey3, _computedKey10 = _computedKey4, _computedKey11 = _computedKey5;
18686
- var Chat$1 = /*#__PURE__*/ function(AbstractChat) {
18687
- _inherits(Chat, AbstractChat);
18688
- function Chat(_0) {
18689
- _class_call_check(this, Chat);
18690
- var _this;
18691
- var messages = _0.messages, agentId = _0.agentId, _0_persistence = _0.persistence, persistence = _0_persistence === void 0 ? true : _0_persistence, init = _object_without_properties(_0, [
18692
- "messages",
18693
- "agentId",
18694
- "persistence"
18695
- ]);
18696
- var state = new ChatState(agentId, messages, persistence);
18697
- _this = _call_super(this, Chat, [
18698
- _object_spread_props(_object_spread({}, init), {
18699
- state: state
18700
- })
18701
- ]), _define_property(_this, "_state", void 0), _define_property(_this, _computedKey9, function(onChange) {
18702
- return _this._state['~registerMessagesCallback'](onChange);
18703
- }), _define_property(_this, _computedKey10, function(onChange) {
18704
- return _this._state['~registerStatusCallback'](onChange);
18705
- }), _define_property(_this, _computedKey11, function(onChange) {
18706
- return _this._state['~registerErrorCallback'](onChange);
18707
- });
18708
- _this._state = state;
18709
- return _this;
18710
- }
18711
- return Chat;
18712
- }(AbstractChat);
18713
-
18714
- // Centralizes the "open the chat from an entry point" behavior shared by the
18715
- // SearchBox AI button, the Autocomplete AI button, prompt suggestions, and any
18716
- // future entry point. The chat is always opened; the message is only sent when
18717
- // it is non-empty and the chat is not already processing a message.
18718
- // Returns true when a message was submitted, so callers can clear their input.
18719
- function openChat(chatRenderState) {
18720
- var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, message = _ref.message, referer = _ref.referer, turnContext = _ref.turnContext;
18721
- var _ref1;
18722
- var _chatRenderState_setOpen;
18723
- if (!chatRenderState) {
18724
- return false;
18725
- }
18726
- var trimmed = (_ref1 = message === null || message === void 0 ? void 0 : message.trim()) !== null && _ref1 !== void 0 ? _ref1 : '';
18727
- if (!trimmed) {
18728
- if (chatRenderState.focusInput) {
18729
- chatRenderState.focusInput();
18730
- } else {
18731
- var _chatRenderState_setOpen1;
18732
- (_chatRenderState_setOpen1 = chatRenderState.setOpen) === null || _chatRenderState_setOpen1 === void 0 ? void 0 : _chatRenderState_setOpen1.call(chatRenderState, true);
18733
- }
18734
- return false;
18735
- }
18736
- (_chatRenderState_setOpen = chatRenderState.setOpen) === null || _chatRenderState_setOpen === void 0 ? void 0 : _chatRenderState_setOpen.call(chatRenderState, true);
18737
- if (isChatBusy(chatRenderState) || !chatRenderState.sendMessage) {
18738
- return false;
18739
- }
18740
- chatRenderState.sendMessage(_object_spread({
18741
- text: trimmed
18742
- }, turnContext ? {
18743
- metadata: {
18744
- turnContext: turnContext
18745
- }
18746
- } : {}), referer ? {
18747
- headers: {
18748
- 'x-algolia-referer': referer
18749
- }
18750
- } : undefined);
18751
- return true;
18752
- }
18753
- function isChatBusy(chatRenderState) {
18754
- return (chatRenderState === null || chatRenderState === void 0 ? void 0 : chatRenderState.status) === 'submitted' || (chatRenderState === null || chatRenderState === void 0 ? void 0 : chatRenderState.status) === 'streaming';
18755
- }
18756
-
18757
- var SearchIndexToolType = 'algolia_search_index';
18758
- var RecommendToolType = 'algolia_recommend';
18759
- var MemorizeToolType = 'algolia_memorize';
18760
- var MemorySearchToolType = 'algolia_memory_search';
18761
- var PonderToolType = 'algolia_ponder';
18762
- var DisplayResultsToolType = 'algolia_display_results';
18763
-
18764
- function flat(arr) {
18765
- return arr.reduce(function(acc, array) {
18766
- return acc.concat(array);
18767
- }, []);
18768
- }
18769
-
18770
- /**
18771
- * Reads a human-readable message from a failed HTTP response body when the
18772
- * server returns JSON such as `{ "message": "..." }` (the shared
18773
- * `ErrorResponse` shape used by every status code), falling back to the HTTP
18774
- * status line when the body is empty or not parseable.
18775
- */ function getHttpErrorMessage(response) {
18776
- var fallback = "HTTP error: ".concat(response.status, " ").concat(response.statusText);
18777
- return response.text().then(function(text) {
18778
- var _tryParseErrorMessage;
18779
- return (_tryParseErrorMessage = tryParseErrorMessage(text)) !== null && _tryParseErrorMessage !== void 0 ? _tryParseErrorMessage : fallback;
18780
- }).catch(function() {
18781
- return fallback;
18782
- });
18783
- }
18784
- /**
18785
- * Abstract base class for HTTP-based chat transports.
18786
- */ var HttpChatTransport = /*#__PURE__*/ function() {
18787
- function HttpChatTransport(param) {
18788
- var _param_api = param.api, api = _param_api === void 0 ? '/api/chat' : _param_api, credentials = param.credentials, headers = param.headers, body = param.body, customFetch = param.fetch, prepareSendMessagesRequest = param.prepareSendMessagesRequest, prepareReconnectToStreamRequest = param.prepareReconnectToStreamRequest;
18789
- _class_call_check(this, HttpChatTransport);
18790
- _define_property(this, "api", void 0);
18791
- _define_property(this, "credentials", void 0);
18792
- _define_property(this, "headers", void 0);
18793
- _define_property(this, "body", void 0);
18794
- _define_property(this, "fetch", void 0);
18795
- _define_property(this, "prepareSendMessagesRequest", void 0);
18796
- _define_property(this, "prepareReconnectToStreamRequest", void 0);
18797
- this.api = api;
18798
- this.credentials = credentials;
18799
- this.headers = headers;
18800
- this.body = body;
18801
- this.fetch = customFetch;
18802
- this.prepareSendMessagesRequest = prepareSendMessagesRequest;
18803
- this.prepareReconnectToStreamRequest = prepareReconnectToStreamRequest;
18804
- }
18805
- _create_class(HttpChatTransport, [
18806
- {
18807
- key: "sendMessages",
18808
- value: function sendMessages(param) {
18809
- var _this = this;
18810
- var abortSignal = param.abortSignal, chatId = param.chatId, messages = param.messages, requestMetadata = param.requestMetadata, trigger = param.trigger, messageId = param.messageId, requestHeaders = param.headers, requestBody = param.body;
18811
- var _this_fetch;
18812
- var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
18813
- // Resolve configurable values
18814
- return Promise.all([
18815
- resolveValue(this.credentials),
18816
- resolveValue(this.headers),
18817
- resolveValue(this.body)
18818
- ]).then(function(param) {
18819
- var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
18820
- // Build default request options
18821
- var api = _this.api;
18822
- var body = _object_spread({
18823
- id: chatId,
18824
- messages: messages
18825
- }, resolvedBody, requestBody);
18826
- var headers = _object_spread({
18827
- 'Content-Type': 'application/json'
18828
- }, _instanceof(resolvedHeaders, Headers) ? Object.fromEntries(resolvedHeaders.entries()) : resolvedHeaders, _instanceof(requestHeaders, Headers) ? Object.fromEntries(requestHeaders.entries()) : requestHeaders);
18829
- var credentials = resolvedCredentials;
18830
- // Apply custom preparation if provided
18831
- var prepareRequestBody = _object_spread({}, resolvedBody, requestBody);
18832
- var preparePromise = _this.prepareSendMessagesRequest ? Promise.resolve(_this.prepareSendMessagesRequest({
18833
- id: chatId,
18834
- messages: messages,
18835
- requestMetadata: requestMetadata,
18836
- body: prepareRequestBody,
18837
- credentials: resolvedCredentials,
18838
- headers: resolvedHeaders,
18839
- api: _this.api,
18840
- trigger: trigger,
18841
- messageId: messageId
18842
- })) : Promise.resolve(null);
18843
- return preparePromise.then(function(prepared) {
18844
- if (prepared) {
18845
- body = prepared.body;
18846
- if (prepared.api) api = prepared.api;
18847
- if (prepared.headers) {
18848
- headers = _object_spread({
18849
- 'Content-Type': 'application/json'
18850
- }, _instanceof(prepared.headers, Headers) ? Object.fromEntries(prepared.headers.entries()) : prepared.headers);
18851
- }
18852
- if (prepared.credentials) credentials = prepared.credentials;
18853
- }
18854
- return fetchFn(api, {
18855
- method: 'POST',
18856
- headers: headers,
18857
- body: JSON.stringify(body),
18858
- signal: abortSignal,
18859
- credentials: credentials
18860
- }).then(function(response) {
18861
- if (!response.ok) {
18862
- return getHttpErrorMessage(response).then(function(message) {
18863
- throw new Error(message);
18864
- });
18865
- }
18866
- if (!response.body) {
18867
- throw new Error('Response body is empty');
18868
- }
18869
- return _this.processResponseStream(response.body);
18870
- });
18871
- });
19100
+ this._messages = initialMessages;
19101
+ } else if (persistence) {
19102
+ this._messages = getDefaultInitialMessages(id);
19103
+ } else {
19104
+ this._messages = [];
19105
+ }
19106
+ if (!persistence) {
19107
+ return;
19108
+ }
19109
+ var saveMessagesInLocalStorage = function saveMessagesInLocalStorage() {
19110
+ if (_this.status === 'ready') {
19111
+ safelyRunOnBrowser(function() {
19112
+ try {
19113
+ sessionStorage.setItem(CACHE_KEY + (id ? "-".concat(id) : ''), JSON.stringify(_this.messages));
19114
+ } catch (e) {
19115
+ // Do nothing if sessionStorage is not available or full
19116
+ }
18872
19117
  });
18873
19118
  }
19119
+ };
19120
+ this['~registerMessagesCallback'](saveMessagesInLocalStorage);
19121
+ this['~registerStatusCallback'](saveMessagesInLocalStorage);
19122
+ }
19123
+ _create_class(ChatState, [
19124
+ {
19125
+ key: "status",
19126
+ get: function get() {
19127
+ return this._status;
19128
+ },
19129
+ set: function set(newStatus) {
19130
+ this._status = newStatus;
19131
+ this._callStatusCallbacks();
19132
+ }
18874
19133
  },
18875
19134
  {
18876
- key: "reconnectToStream",
18877
- value: function reconnectToStream(param) {
18878
- var _this = this;
18879
- var chatId = param.chatId, requestHeaders = param.headers, requestBody = param.body;
18880
- var _this_fetch;
18881
- var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
18882
- // Resolve configurable values
18883
- return Promise.all([
18884
- resolveValue(this.credentials),
18885
- resolveValue(this.headers),
18886
- resolveValue(this.body)
18887
- ]).then(function(param) {
18888
- var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
18889
- // Build default request options
18890
- var api = _this.api;
18891
- var headers = _object_spread({}, _instanceof(resolvedHeaders, Headers) ? Object.fromEntries(resolvedHeaders.entries()) : resolvedHeaders, _instanceof(requestHeaders, Headers) ? Object.fromEntries(requestHeaders.entries()) : requestHeaders);
18892
- var credentials = resolvedCredentials;
18893
- // Apply custom preparation if provided
18894
- var prepareRequestBody = _object_spread({}, resolvedBody, requestBody);
18895
- var preparePromise = _this.prepareReconnectToStreamRequest ? Promise.resolve(_this.prepareReconnectToStreamRequest({
18896
- id: chatId,
18897
- requestMetadata: undefined,
18898
- body: prepareRequestBody,
18899
- credentials: resolvedCredentials,
18900
- headers: resolvedHeaders,
18901
- api: _this.api
18902
- })) : Promise.resolve(null);
18903
- return preparePromise.then(function(prepared) {
18904
- if (prepared) {
18905
- if (prepared.api) api = prepared.api;
18906
- if (prepared.headers) {
18907
- headers = _instanceof(prepared.headers, Headers) ? Object.fromEntries(prepared.headers.entries()) : prepared.headers;
18908
- }
18909
- if (prepared.credentials) credentials = prepared.credentials;
18910
- }
18911
- // GET request for reconnection
18912
- return fetchFn("".concat(api, "?chatId=").concat(chatId), {
18913
- method: 'GET',
18914
- headers: headers,
18915
- credentials: credentials
18916
- }).then(function(response) {
18917
- if (!response.ok) {
18918
- // 404 means no stream to reconnect to, which is not an error
18919
- if (response.status === 404) {
18920
- return null;
18921
- }
18922
- return getHttpErrorMessage(response).then(function(message) {
18923
- throw new Error(message);
18924
- });
18925
- }
18926
- if (!response.body) {
18927
- return null;
18928
- }
18929
- return _this.processResponseStream(response.body);
18930
- });
18931
- });
18932
- });
19135
+ key: "error",
19136
+ get: function get() {
19137
+ return this._error;
19138
+ },
19139
+ set: function set(newError) {
19140
+ this._error = newError;
19141
+ this._callErrorCallbacks();
19142
+ }
19143
+ },
19144
+ {
19145
+ key: "messages",
19146
+ get: function get() {
19147
+ return this._messages;
19148
+ },
19149
+ set: function set(newMessages) {
19150
+ this._messages = _to_consumable_array(newMessages);
19151
+ this._callMessagesCallbacks();
18933
19152
  }
18934
19153
  }
18935
19154
  ]);
18936
- return HttpChatTransport;
19155
+ return ChatState;
18937
19156
  }();
18938
- /**
18939
- * Default chat transport implementation using NDJSON streaming.
18940
- */ var DefaultChatTransport = /*#__PURE__*/ function(HttpChatTransport) {
18941
- _inherits(DefaultChatTransport, HttpChatTransport);
18942
- function DefaultChatTransport() {
18943
- var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
18944
- _class_call_check(this, DefaultChatTransport);
18945
- return _call_super(this, DefaultChatTransport, [
18946
- options
19157
+ _computedKey3 = '~registerMessagesCallback', _computedKey4 = '~registerStatusCallback', _computedKey5 = '~registerErrorCallback';
19158
+ var _computedKey9 = _computedKey3, _computedKey10 = _computedKey4, _computedKey11 = _computedKey5;
19159
+ var Chat$1 = /*#__PURE__*/ function(AbstractChat) {
19160
+ _inherits(Chat, AbstractChat);
19161
+ function Chat(_0) {
19162
+ _class_call_check(this, Chat);
19163
+ var _this;
19164
+ var messages = _0.messages, agentId = _0.agentId, _0_persistence = _0.persistence, persistence = _0_persistence === void 0 ? true : _0_persistence, init = _object_without_properties(_0, [
19165
+ "messages",
19166
+ "agentId",
19167
+ "persistence"
18947
19168
  ]);
19169
+ var state = new ChatState(agentId, messages, persistence);
19170
+ _this = _call_super(this, Chat, [
19171
+ _object_spread_props(_object_spread({}, init), {
19172
+ state: state
19173
+ })
19174
+ ]), _define_property(_this, "_state", void 0), _define_property(_this, _computedKey9, function(onChange) {
19175
+ return _this._state['~registerMessagesCallback'](onChange);
19176
+ }), _define_property(_this, _computedKey10, function(onChange) {
19177
+ return _this._state['~registerStatusCallback'](onChange);
19178
+ }), _define_property(_this, _computedKey11, function(onChange) {
19179
+ return _this._state['~registerErrorCallback'](onChange);
19180
+ });
19181
+ _this._state = state;
19182
+ return _this;
18948
19183
  }
18949
- _create_class(DefaultChatTransport, [
18950
- {
18951
- key: "processResponseStream",
18952
- value: function processResponseStream(stream) {
18953
- return parseJsonEventStream(stream);
18954
- }
18955
- }
18956
- ]);
18957
- return DefaultChatTransport;
18958
- }(HttpChatTransport);
19184
+ return Chat;
19185
+ }(AbstractChat);
18959
19186
 
18960
19187
  var withUsage$q = createDocumentationMessageGenerator({
18961
19188
  name: 'chat',
@@ -19085,11 +19312,6 @@
19085
19312
  "requiresSearch"
19086
19313
  ]);
19087
19314
  var normalizedPersistence = normalizePersistence(persistence, 'chat' in options);
19088
- // Compatibility shim with Algolia MCP Server search tool, which suffixes
19089
- // the tool name with the index name (`searchIndex_products`).
19090
- var resolveTool = function resolveTool(toolName) {
19091
- return tools[toolName] || (toolName.startsWith("".concat(SearchIndexToolType, "_")) ? tools[SearchIndexToolType] : undefined);
19092
- };
19093
19315
  var _chatInstance;
19094
19316
  var input = '';
19095
19317
  var open = false;
@@ -19117,21 +19339,44 @@
19117
19339
  return unsubscribe();
19118
19340
  });
19119
19341
  };
19120
- // Extract suggestions from the last assistant message's data-suggestions part
19121
- var getSuggestionsFromMessages = function getSuggestionsFromMessages(messages) {
19122
- // Find the last assistant message (iterate from end)
19123
- var lastAssistantMessage = _to_consumable_array(messages).reverse().find(function(message) {
19342
+ var findSuggestionsPart = function findSuggestionsPart(message) {
19343
+ var _message_parts;
19344
+ return message === null || message === void 0 ? void 0 : (_message_parts = message.parts) === null || _message_parts === void 0 ? void 0 : _message_parts.find(function(part) {
19345
+ var _part_data;
19346
+ return 'type' in part && part.type === 'data-suggestions' && 'data' in part && Array.isArray((_part_data = part.data) === null || _part_data === void 0 ? void 0 : _part_data.suggestions);
19347
+ });
19348
+ };
19349
+ var findLastAssistantMessage = function findLastAssistantMessage(messages) {
19350
+ return _to_consumable_array(messages).reverse().find(function(message) {
19124
19351
  return message.role === 'assistant' && message.parts;
19125
19352
  });
19126
- if (!(lastAssistantMessage === null || lastAssistantMessage === void 0 ? void 0 : lastAssistantMessage.parts)) {
19127
- return undefined;
19353
+ };
19354
+ // Extract suggestions from the last assistant message's data-suggestions part
19355
+ var getSuggestionsFromMessages = function getSuggestionsFromMessages(messages) {
19356
+ var _findSuggestionsPart;
19357
+ return (_findSuggestionsPart = findSuggestionsPart(findLastAssistantMessage(messages))) === null || _findSuggestionsPart === void 0 ? void 0 : _findSuggestionsPart.data.suggestions;
19358
+ };
19359
+ // "Still coming" has to be inferred: the turn is running and has no
19360
+ // `data-suggestions` part yet. Expecting any at all needs evidence, or an
19361
+ // agent that never sends them would sit under a placeholder forever.
19362
+ var getSuggestionsStatus = function getSuggestionsStatus(messages) {
19363
+ var _lastAssistantMessage_metadata;
19364
+ var status = _chatInstance.status;
19365
+ if (status !== 'submitted' && status !== 'streaming') {
19366
+ return 'idle';
19128
19367
  }
19129
- // Find the data-suggestions part
19130
- var suggestionsPart = lastAssistantMessage.parts.find(function(part) {
19131
- var _part_data;
19132
- return 'type' in part && part.type === 'data-suggestions' && 'data' in part && Array.isArray((_part_data = part.data) === null || _part_data === void 0 ? void 0 : _part_data.suggestions);
19368
+ var lastAssistantMessage = findLastAssistantMessage(messages);
19369
+ if (findSuggestionsPart(lastAssistantMessage)) {
19370
+ return 'idle';
19371
+ }
19372
+ var declaresSuggestions = (lastAssistantMessage === null || lastAssistantMessage === void 0 ? void 0 : (_lastAssistantMessage_metadata = lastAssistantMessage.metadata) === null || _lastAssistantMessage_metadata === void 0 ? void 0 : _lastAssistantMessage_metadata.suggestionsEnabled) === true;
19373
+ if (declaresSuggestions) {
19374
+ return 'loading';
19375
+ }
19376
+ var hasSuggestionsHistory = messages.some(function(message) {
19377
+ return message !== lastAssistantMessage && message.role === 'assistant' && Boolean(findSuggestionsPart(message));
19133
19378
  });
19134
- return suggestionsPart === null || suggestionsPart === void 0 ? void 0 : suggestionsPart.data.suggestions;
19379
+ return hasSuggestionsHistory ? 'loading' : 'idle';
19135
19380
  };
19136
19381
  var setMessages = function setMessages(messagesParam) {
19137
19382
  if (typeof messagesParam === 'function') {
@@ -19274,14 +19519,14 @@
19274
19519
  sendAutomaticallyWhen: sendAutomaticallyWhen,
19275
19520
  transport: transport,
19276
19521
  shouldRepairToolInput: function shouldRepairToolInput(toolName) {
19277
- var tool = resolveTool(toolName);
19522
+ var tool = findTool(toolName, tools);
19278
19523
  if (!tool) return true;
19279
19524
  return Boolean(tool.streamInput);
19280
19525
  },
19281
19526
  resolveCancelledToolOutput: function resolveCancelledToolOutput(param) {
19282
19527
  var toolName = param.toolName, toolCallId = param.toolCallId, input = param.input;
19283
- var _resolveTool;
19284
- var cancelOutput = (_resolveTool = resolveTool(toolName)) === null || _resolveTool === void 0 ? void 0 : _resolveTool.cancelOutput;
19528
+ var _findTool;
19529
+ var cancelOutput = (_findTool = findTool(toolName, tools)) === null || _findTool === void 0 ? void 0 : _findTool.cancelOutput;
19285
19530
  if (!cancelOutput) return undefined;
19286
19531
  try {
19287
19532
  var output = cancelOutput({
@@ -19298,7 +19543,7 @@
19298
19543
  },
19299
19544
  onToolCall: function onToolCall(param, submitToolResult) {
19300
19545
  var toolCall = param.toolCall;
19301
- var tool = resolveTool(toolCall.toolName);
19546
+ var tool = findTool(toolCall.toolName, tools);
19302
19547
  if (!tool) {
19303
19548
  return submitToolResult({
19304
19549
  output: 'No tool implemented for "'.concat(toolCall.toolName, '".'),
@@ -19528,6 +19773,7 @@
19528
19773
  '~isOpenStatePersistenceEnabled': normalizedPersistence.open,
19529
19774
  setMessages: setMessages,
19530
19775
  suggestions: getSuggestionsFromMessages(_chatInstance.messages),
19776
+ suggestionsStatus: getSuggestionsStatus(_chatInstance.messages),
19531
19777
  clearMessages: clearMessages,
19532
19778
  tools: toolsWithAddToolResult,
19533
19779
  records: records,
@@ -19631,120 +19877,295 @@
19631
19877
  });
19632
19878
  }
19633
19879
 
19880
+ function isHeaders$1(headers) {
19881
+ return !Array.isArray(headers) && 'entries' in headers && typeof headers.entries === 'function';
19882
+ }
19883
+ function headersToRecord$1(headers) {
19884
+ if (!headers) {
19885
+ return {};
19886
+ }
19887
+ if (isHeaders$1(headers)) {
19888
+ return Object.fromEntries(headers.entries());
19889
+ }
19890
+ if (Array.isArray(headers)) {
19891
+ return Object.fromEntries(headers);
19892
+ }
19893
+ return headers;
19894
+ }
19895
+ function withJsonContentType(headers) {
19896
+ var merged = _object_spread({}, headersToRecord$1(headers));
19897
+ Object.keys(merged).forEach(function(name) {
19898
+ if (name.toLowerCase() === 'content-type') {
19899
+ delete merged[name];
19900
+ }
19901
+ });
19902
+ merged['Content-Type'] = 'application/json';
19903
+ return merged;
19904
+ }
19905
+ function withStreamParam(url) {
19906
+ return url.includes('?') ? "".concat(url, "&stream=true") : "".concat(url, "?stream=true");
19907
+ }
19908
+ function resolveStreamedOutput(data, previous) {
19909
+ return typeof data === 'string' ? parsePartialJson(data, previous) : data;
19910
+ }
19911
+ function createTaskPreparationContext(context) {
19912
+ function hideProperty(key) {
19913
+ var value = context[key];
19914
+ Object.defineProperty(context, key, {
19915
+ configurable: true,
19916
+ enumerable: false,
19917
+ get: function get() {
19918
+ return value;
19919
+ },
19920
+ set: function set(nextValue) {
19921
+ Reflect.deleteProperty(context, key);
19922
+ Object.defineProperty(context, key, {
19923
+ configurable: true,
19924
+ enumerable: true,
19925
+ value: nextValue,
19926
+ writable: true
19927
+ });
19928
+ }
19929
+ });
19930
+ }
19931
+ // Rich metadata stays out of legacy body spreads until assigned as payload.
19932
+ hideProperty('stream');
19933
+ hideProperty('body');
19934
+ hideProperty('credentials');
19935
+ hideProperty('headers');
19936
+ hideProperty('api');
19937
+ return context;
19938
+ }
19939
+ function unwrap(envelope) {
19940
+ if ((typeof envelope === "undefined" ? "undefined" : _type_of(envelope)) === 'object' && envelope !== null && 'output' in envelope) {
19941
+ return envelope.output;
19942
+ }
19943
+ return undefined;
19944
+ }
19945
+ function consumeTaskStream(body, onData) {
19946
+ return new Promise(function(resolve, reject) {
19947
+ var chunkStream = parseJsonEventStream(body);
19948
+ var latest;
19949
+ processStream(chunkStream, function(chunk) {
19950
+ if (!chunk) {
19951
+ return;
19952
+ }
19953
+ if (chunk.type === 'error') {
19954
+ throw new Error(chunk.errorText || 'Task stream error');
19955
+ }
19956
+ if (chunk.type !== 'data-task-output') {
19957
+ return;
19958
+ }
19959
+ latest = resolveStreamedOutput(chunk.data, latest);
19960
+ if (onData) {
19961
+ onData(latest);
19962
+ }
19963
+ }, function() {
19964
+ return resolve(latest);
19965
+ }, reject);
19966
+ });
19967
+ }
19968
+ /** Default HTTP transport for named Tasks requests and task-output streams. */ var DefaultTaskTransport = /*#__PURE__*/ function() {
19969
+ function DefaultTaskTransport() {
19970
+ var _ref = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}, _ref_api = _ref.api, api = _ref_api === void 0 ? '/api/tasks' : _ref_api, credentials = _ref.credentials, headers = _ref.headers, body = _ref.body, customFetch = _ref.fetch, prepareSendMessagesRequest = _ref.prepareSendMessagesRequest;
19971
+ _class_call_check(this, DefaultTaskTransport);
19972
+ _define_property(this, "api", void 0);
19973
+ _define_property(this, "credentials", void 0);
19974
+ _define_property(this, "headers", void 0);
19975
+ _define_property(this, "body", void 0);
19976
+ _define_property(this, "fetch", void 0);
19977
+ _define_property(this, "prepareSendMessagesRequest", void 0);
19978
+ this.api = api;
19979
+ this.credentials = credentials;
19980
+ this.headers = headers;
19981
+ this.body = body;
19982
+ this.fetch = customFetch;
19983
+ this.prepareSendMessagesRequest = prepareSendMessagesRequest;
19984
+ }
19985
+ _create_class(DefaultTaskTransport, [
19986
+ {
19987
+ key: "sendTask",
19988
+ value: function sendTask(param) {
19989
+ var task = param.task, input = param.input, stream = param.stream, onData = param.onData;
19990
+ return this.sendTaskRequest({
19991
+ task: task,
19992
+ input: input,
19993
+ stream: stream,
19994
+ onData: onData ? function(data) {
19995
+ return onData(unwrap(data));
19996
+ } : undefined
19997
+ }).then(unwrap);
19998
+ }
19999
+ },
20000
+ {
20001
+ /** @internal */ key: "sendTaskRequest",
20002
+ value: function sendTaskRequest(param) {
20003
+ var _this = this;
20004
+ var task = param.task, input = param.input, stream = param.stream, onData = param.onData;
20005
+ var _this_fetch;
20006
+ var fetchFn = (_this_fetch = this.fetch) !== null && _this_fetch !== void 0 ? _this_fetch : fetch;
20007
+ return Promise.all([
20008
+ resolveValue(this.credentials),
20009
+ resolveValue(this.headers),
20010
+ resolveValue(this.body)
20011
+ ]).then(function(param) {
20012
+ var _param = _sliced_to_array(param, 3), resolvedCredentials = _param[0], resolvedHeaders = _param[1], resolvedBody = _param[2];
20013
+ var api = _this.api;
20014
+ var credentials = resolvedCredentials;
20015
+ var headers = withJsonContentType(resolvedHeaders);
20016
+ var body = _object_spread({
20017
+ task: task,
20018
+ input: input
20019
+ }, resolvedBody);
20020
+ var preparedBody = resolvedBody ? _object_spread({}, resolvedBody) : undefined;
20021
+ var preparePromise = _this.prepareSendMessagesRequest ? Promise.resolve(_this.prepareSendMessagesRequest(createTaskPreparationContext({
20022
+ task: task,
20023
+ input: input,
20024
+ stream: stream,
20025
+ body: preparedBody,
20026
+ credentials: resolvedCredentials,
20027
+ headers: resolvedHeaders,
20028
+ api: _this.api
20029
+ }))) : Promise.resolve(null);
20030
+ return preparePromise.then(function(prepared) {
20031
+ if (prepared) {
20032
+ body = prepared.body;
20033
+ if (prepared.api) {
20034
+ api = prepared.api;
20035
+ }
20036
+ if (prepared.credentials) {
20037
+ credentials = prepared.credentials;
20038
+ }
20039
+ if (prepared.headers) {
20040
+ headers = withJsonContentType(prepared.headers);
20041
+ }
20042
+ }
20043
+ var request = {
20044
+ method: 'POST',
20045
+ headers: headers,
20046
+ body: JSON.stringify(body)
20047
+ };
20048
+ if (credentials !== undefined) {
20049
+ request.credentials = credentials;
20050
+ }
20051
+ return fetchFn(stream ? withStreamParam(api) : api, request).then(function(response) {
20052
+ var _response_headers_get, _response_headers;
20053
+ if (!response.ok) {
20054
+ throw new Error("HTTP error ".concat(response.status));
20055
+ }
20056
+ 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')) || '';
20057
+ if (stream && response.body && contentType.includes('text/event-stream')) {
20058
+ return consumeTaskStream(response.body, onData);
20059
+ }
20060
+ return response.json();
20061
+ });
20062
+ });
20063
+ });
20064
+ }
20065
+ }
20066
+ ]);
20067
+ return DefaultTaskTransport;
20068
+ }();
20069
+
19634
20070
  function buildEndpoint(param) {
19635
20071
  var appId = param.appId, agentId = param.agentId;
19636
20072
  return "https://".concat(appId, ".algolia.net/agent-studio/1/agents/").concat(agentId, "/tasks");
19637
20073
  }
19638
- function resolveEndpoint(params) {
19639
- if (params.transport) {
19640
- return {
19641
- endpoint: params.transport.api,
19642
- headers: params.transport.headers || {},
19643
- prepareSendMessagesRequest: params.transport.prepareSendMessagesRequest
19644
- };
20074
+ function isHeaders(headers) {
20075
+ return !Array.isArray(headers) && 'entries' in headers && typeof headers.entries === 'function';
20076
+ }
20077
+ function headersToRecord(headers) {
20078
+ if (!headers) {
20079
+ return {};
19645
20080
  }
19646
- if (!params.appId || !params.apiKey || !params.agentId) {
19647
- throw new Error('[tasks] Either `transport` or `{ appId, apiKey, agentId }` is required.');
20081
+ if (isHeaders(headers)) {
20082
+ return Object.fromEntries(headers.entries());
19648
20083
  }
19649
- var headers = {
19650
- 'x-algolia-application-id': params.appId,
19651
- 'x-algolia-api-key': params.apiKey
19652
- };
19653
- if (params.algoliaAgent) {
19654
- headers['x-algolia-agent'] = "".concat(params.algoliaAgent, "; tasks");
20084
+ if (Array.isArray(headers)) {
20085
+ return Object.fromEntries(headers);
19655
20086
  }
19656
- return {
19657
- endpoint: buildEndpoint({
19658
- appId: params.appId,
19659
- agentId: params.agentId
19660
- }),
19661
- headers: headers
19662
- };
19663
- }
19664
-
19665
- function buildTaskPayload(param) {
19666
- var task = param.task, input = param.input, prepareRequest = param.prepareRequest;
19667
- var payload = {
19668
- task: task,
19669
- input: input
19670
- };
19671
- return prepareRequest ? prepareRequest(payload).body : payload;
19672
- }
19673
- function withStreamParam(url) {
19674
- return url.includes('?') ? "".concat(url, "&stream=true") : "".concat(url, "?stream=true");
19675
- }
19676
- function resolveStreamedOutput(data, previous) {
19677
- return typeof data === 'string' ? parsePartialJson(data, previous) : data;
20087
+ return _object_spread({}, headers);
19678
20088
  }
19679
- function consumeTaskStream(body, onData) {
19680
- return new Promise(function(resolve, reject) {
19681
- var chunkStream = parseJsonEventStream(body);
19682
- var latest;
19683
- processStream(chunkStream, function(chunk) {
19684
- if (!chunk) {
19685
- return;
19686
- }
19687
- // A terminal `error` event aborts the task: reject rather than let the
19688
- // stream close and resolve the last partial snapshot as a success.
19689
- // Throwing here lets `processStream` release the reader and stop
19690
- // consuming; the rejection propagates to the caller's `.catch`.
19691
- if (chunk.type === 'error') {
19692
- throw new Error(chunk.errorText || 'Task stream error');
19693
- }
19694
- if (chunk.type !== 'data-task-output') {
19695
- return;
19696
- }
19697
- latest = resolveStreamedOutput(chunk.data, latest);
19698
- if (onData) {
19699
- onData(latest);
20089
+ function mergeProtectedHeaders(headers, protectedHeaders) {
20090
+ var merged = headersToRecord(headers);
20091
+ Object.entries(protectedHeaders).forEach(function(param) {
20092
+ var _param = _sliced_to_array(param, 2), protectedName = _param[0], value = _param[1];
20093
+ Object.keys(merged).forEach(function(name) {
20094
+ if (name.toLowerCase() === protectedName.toLowerCase()) {
20095
+ delete merged[name];
19700
20096
  }
19701
- }, function() {
19702
- return resolve(latest);
19703
- }, reject);
20097
+ });
20098
+ merged[protectedName] = value;
19704
20099
  });
20100
+ return merged;
19705
20101
  }
19706
- function fetchTask(param) {
19707
- 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;
19708
- return fetch(stream ? withStreamParam(endpoint) : endpoint, {
19709
- method: 'POST',
19710
- headers: _object_spread_props(_object_spread({}, headers), {
19711
- 'Content-Type': 'application/json'
20102
+ /** @internal */ function createTaskTransport(param) {
20103
+ var _param_transport = param.transport, transport = _param_transport === void 0 ? {} : _param_transport, appId = param.appId, apiKey = param.apiKey, agentId = param.agentId, algoliaAgent = param.algoliaAgent;
20104
+ var _transport_api;
20105
+ if (!agentId) {
20106
+ return new DefaultTaskTransport(transport);
20107
+ }
20108
+ if (!appId || !apiKey) {
20109
+ throw new Error('[tasks] `appId` and `apiKey` are required when `agentId` is provided.');
20110
+ }
20111
+ var protectedHeaders = {
20112
+ 'x-algolia-application-id': appId,
20113
+ 'x-algolia-api-key': apiKey
20114
+ };
20115
+ if (algoliaAgent) {
20116
+ protectedHeaders['x-algolia-agent'] = "".concat(algoliaAgent, "; tasks");
20117
+ }
20118
+ var originalPrepare = transport.prepareSendMessagesRequest;
20119
+ var prepareSendMessagesRequest = originalPrepare ? function(request) {
20120
+ return Promise.resolve(originalPrepare(request)).then(function(prepared) {
20121
+ return _object_spread_props(_object_spread({}, prepared), {
20122
+ headers: prepared.headers ? mergeProtectedHeaders(prepared.headers, protectedHeaders) : undefined
20123
+ });
20124
+ });
20125
+ } : undefined;
20126
+ return new DefaultTaskTransport(_object_spread_props(_object_spread({}, transport), {
20127
+ api: (_transport_api = transport.api) !== null && _transport_api !== void 0 ? _transport_api : buildEndpoint({
20128
+ appId: appId,
20129
+ agentId: agentId
19712
20130
  }),
19713
- body: JSON.stringify(payload)
19714
- }).then(function(response) {
19715
- var _response_headers_get, _response_headers;
19716
- if (!response.ok) {
19717
- throw new Error("HTTP error ".concat(response.status));
19718
- }
19719
- 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')) || '';
19720
- if (stream && response.body && contentType.includes('text/event-stream')) {
19721
- return consumeTaskStream(response.body, onData);
19722
- }
19723
- return response.json();
19724
- });
19725
- }
19726
- function unwrap(envelope) {
19727
- return envelope === null || envelope === void 0 ? void 0 : envelope.output;
20131
+ headers: function headers() {
20132
+ return Promise.resolve(resolveValue(transport.headers)).then(function(headers) {
20133
+ return mergeProtectedHeaders(headers, protectedHeaders);
20134
+ });
20135
+ },
20136
+ prepareSendMessagesRequest: prepareSendMessagesRequest
20137
+ }));
19728
20138
  }
19729
- function createTaskRunner(param) {
19730
- 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;
20139
+
20140
+ function createTaskRunner(options) {
20141
+ var task = options.task, _options_stream = options.stream, stream = _options_stream === void 0 ? true : _options_stream;
20142
+ var transport;
20143
+ if (options.transport !== undefined) {
20144
+ transport = options.transport;
20145
+ } else {
20146
+ var prepareRequest = options.prepareRequest;
20147
+ transport = new DefaultTaskTransport({
20148
+ api: options.endpoint,
20149
+ headers: options.headers,
20150
+ fetch: options.fetch,
20151
+ prepareSendMessagesRequest: prepareRequest ? function(param) {
20152
+ var requestTask = param.task, input = param.input;
20153
+ return prepareRequest({
20154
+ task: requestTask,
20155
+ input: input
20156
+ });
20157
+ } : undefined
20158
+ });
20159
+ }
19731
20160
  return {
19732
- submit: function submit(variables) {
20161
+ submit: function submit(input) {
19733
20162
  var onData = (arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}).onData;
19734
- var payload = buildTaskPayload({
20163
+ return transport.sendTask({
19735
20164
  task: task,
19736
- input: variables,
19737
- prepareRequest: prepareRequest
19738
- });
19739
- return fetchTask({
19740
- endpoint: endpoint,
19741
- headers: headers,
19742
- payload: payload,
20165
+ input: input,
19743
20166
  stream: stream,
19744
- onData: onData ? function(partial) {
19745
- return onData(unwrap(partial));
19746
- } : undefined
19747
- }).then(unwrap);
20167
+ onData: onData
20168
+ });
19748
20169
  }
19749
20170
  };
19750
20171
  }
@@ -19831,31 +20252,28 @@
19831
20252
  $$type: 'ais.tasks',
19832
20253
  init: function init(initOptions) {
19833
20254
  var instantSearchInstance = initOptions.instantSearchInstance;
19834
- if (transport) {
19835
- var resolved = resolveEndpoint({
19836
- transport: transport
19837
- });
19838
- runner = createTaskRunner({
19839
- endpoint: resolved.endpoint,
19840
- headers: resolved.headers,
19841
- task: task,
19842
- stream: stream,
19843
- prepareRequest: resolved.prepareSendMessagesRequest
19844
- });
19845
- } else {
20255
+ if (agentId) {
19846
20256
  var _getAppIdAndApiKey = _sliced_to_array(getAppIdAndApiKey(instantSearchInstance.client), 2), appId = _getAppIdAndApiKey[0], apiKey = _getAppIdAndApiKey[1];
19847
20257
  if (!appId || !apiKey) {
19848
20258
  throw new Error(withUsage$p('Could not extract Algolia credentials from the search client.'));
19849
20259
  }
19850
- var resolved1 = resolveEndpoint({
20260
+ var taskTransport = createTaskTransport({
20261
+ transport: transport,
19851
20262
  appId: appId,
19852
20263
  apiKey: apiKey,
19853
20264
  agentId: agentId,
19854
20265
  algoliaAgent: getAlgoliaAgent(instantSearchInstance.client)
19855
20266
  });
19856
20267
  runner = createTaskRunner({
19857
- endpoint: resolved1.endpoint,
19858
- headers: resolved1.headers,
20268
+ transport: taskTransport,
20269
+ task: task,
20270
+ stream: stream
20271
+ });
20272
+ } else {
20273
+ runner = createTaskRunner({
20274
+ transport: createTaskTransport({
20275
+ transport: transport
20276
+ }),
19859
20277
  task: task,
19860
20278
  stream: stream
19861
20279
  });
@@ -19882,6 +20300,49 @@
19882
20300
  };
19883
20301
  };
19884
20302
 
20303
+ // Centralizes the "open the chat from an entry point" behavior shared by the
20304
+ // SearchBox AI button, the Autocomplete AI button, prompt suggestions, and any
20305
+ // future entry point. The chat is always opened; the message is only sent when
20306
+ // it is non-empty and the chat is not already processing a message.
20307
+ // Returns true when a message was submitted, so callers can clear their input.
20308
+ function openChat(chatRenderState) {
20309
+ var _ref = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, message = _ref.message, referer = _ref.referer, turnContext = _ref.turnContext;
20310
+ var _ref1;
20311
+ var _chatRenderState_setOpen;
20312
+ if (!chatRenderState) {
20313
+ return false;
20314
+ }
20315
+ var trimmed = (_ref1 = message === null || message === void 0 ? void 0 : message.trim()) !== null && _ref1 !== void 0 ? _ref1 : '';
20316
+ if (!trimmed) {
20317
+ if (chatRenderState.focusInput) {
20318
+ chatRenderState.focusInput();
20319
+ } else {
20320
+ var _chatRenderState_setOpen1;
20321
+ (_chatRenderState_setOpen1 = chatRenderState.setOpen) === null || _chatRenderState_setOpen1 === void 0 ? void 0 : _chatRenderState_setOpen1.call(chatRenderState, true);
20322
+ }
20323
+ return false;
20324
+ }
20325
+ (_chatRenderState_setOpen = chatRenderState.setOpen) === null || _chatRenderState_setOpen === void 0 ? void 0 : _chatRenderState_setOpen.call(chatRenderState, true);
20326
+ if (isChatBusy(chatRenderState) || !chatRenderState.sendMessage) {
20327
+ return false;
20328
+ }
20329
+ chatRenderState.sendMessage(_object_spread({
20330
+ text: trimmed
20331
+ }, turnContext ? {
20332
+ metadata: {
20333
+ turnContext: turnContext
20334
+ }
20335
+ } : {}), referer ? {
20336
+ headers: {
20337
+ 'x-algolia-referer': referer
20338
+ }
20339
+ } : undefined);
20340
+ return true;
20341
+ }
20342
+ function isChatBusy(chatRenderState) {
20343
+ return (chatRenderState === null || chatRenderState === void 0 ? void 0 : chatRenderState.status) === 'submitted' || (chatRenderState === null || chatRenderState === void 0 ? void 0 : chatRenderState.status) === 'streaming';
20344
+ }
20345
+
19885
20346
  var withUsage$o = createDocumentationMessageGenerator({
19886
20347
  name: 'prompt-suggestions',
19887
20348
  connector: true
@@ -20123,14 +20584,24 @@
20123
20584
  if (!latestRenderOptions) return;
20124
20585
  renderOutward(latestRenderOptions);
20125
20586
  };
20126
- var tasksWidget = connectTasks(handleInnerRender, noop)(_object_spread_props(_object_spread({}, transport ? {
20127
- transport: transport
20128
- } : {
20129
- agentId: agentId
20130
- }), {
20131
- task: configurationId,
20132
- stream: true
20133
- }));
20587
+ var tasksParams;
20588
+ if (agentId) {
20589
+ tasksParams = {
20590
+ agentId: agentId,
20591
+ transport: transport,
20592
+ task: configurationId,
20593
+ stream: true
20594
+ };
20595
+ } else if (transport) {
20596
+ tasksParams = {
20597
+ transport: transport,
20598
+ task: configurationId,
20599
+ stream: true
20600
+ };
20601
+ } else {
20602
+ throw new Error(withUsage$o('The `agentId` option is required unless a custom `transport` is provided.'));
20603
+ }
20604
+ var tasksWidget = connectTasks(handleInnerRender, noop)(tasksParams);
20134
20605
  return {
20135
20606
  $$type: 'ais.promptSuggestions',
20136
20607
  init: function init(initOptions) {
@@ -24397,6 +24868,13 @@
24397
24868
  });
24398
24869
  }
24399
24870
 
24871
+ var SearchIndexToolType = 'algolia_search_index';
24872
+ var RecommendToolType = 'algolia_recommend';
24873
+ var MemorizeToolType = 'algolia_memorize';
24874
+ var MemorySearchToolType = 'algolia_memory_search';
24875
+ var PonderToolType = 'algolia_ponder';
24876
+ var DisplayResultsToolType = 'algolia_display_results';
24877
+
24400
24878
  var AutocompleteSearchComponent = createAutocompleteSearchComponent({
24401
24879
  createElement: React.createElement,
24402
24880
  Fragment: React.Fragment
@@ -25431,6 +25909,202 @@
25431
25909
  return /*#__PURE__*/ React.createElement(Breadcrumb$1, _object_spread({}, props, uiProps));
25432
25910
  }
25433
25911
 
25912
+ var containersHeldInert = new WeakSet();
25913
+ var revealAnimationsHeldByContainer = new WeakMap();
25914
+ function getContainer(prompt) {
25915
+ var _ref;
25916
+ return (_ref = prompt === null || prompt === void 0 ? void 0 : prompt.closest('.ais-Chat-container')) !== null && _ref !== void 0 ? _ref : null;
25917
+ }
25918
+ function getActiveContainerAnimations(prompt) {
25919
+ return getActiveAnimations(getContainer(prompt));
25920
+ }
25921
+ function getActiveAnimations(container) {
25922
+ if (!container || typeof container.getAnimations !== 'function') {
25923
+ return [];
25924
+ }
25925
+ return container.getAnimations().filter(function(animation) {
25926
+ return animation.playState !== 'finished';
25927
+ }).map(function(animation) {
25928
+ return {
25929
+ animation: animation,
25930
+ currentTime: animation.currentTime,
25931
+ playState: animation.playState,
25932
+ startTime: animation.startTime
25933
+ };
25934
+ });
25935
+ }
25936
+ var revealProperties = [
25937
+ 'opacity',
25938
+ 'transform',
25939
+ 'translate',
25940
+ 'scale',
25941
+ 'rotate',
25942
+ 'visibility',
25943
+ 'clip',
25944
+ 'clipPath'
25945
+ ];
25946
+ function isRevealed(style, property) {
25947
+ if (property === 'opacity') {
25948
+ return style.opacity === '1';
25949
+ }
25950
+ if (property === 'transform') {
25951
+ return [
25952
+ 'none',
25953
+ 'matrix(1, 0, 0, 1, 0, 0)',
25954
+ 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)'
25955
+ ].includes(style.transform);
25956
+ }
25957
+ if (property === 'translate') {
25958
+ return [
25959
+ 'none',
25960
+ '0px',
25961
+ '0px 0px',
25962
+ '0px 0px 0px'
25963
+ ].includes(style.translate);
25964
+ }
25965
+ if (property === 'scale') {
25966
+ return [
25967
+ 'none',
25968
+ '1',
25969
+ '1 1'
25970
+ ].includes(style.scale);
25971
+ }
25972
+ if (property === 'rotate') {
25973
+ return [
25974
+ 'none',
25975
+ '0deg'
25976
+ ].includes(style.rotate);
25977
+ }
25978
+ if (property === 'visibility') {
25979
+ return style.visibility === 'visible';
25980
+ }
25981
+ if (property === 'clip') {
25982
+ return [
25983
+ 'auto',
25984
+ 'rect(auto, auto, auto, auto)'
25985
+ ].includes(style.getPropertyValue('clip'));
25986
+ }
25987
+ return style.clipPath === 'none';
25988
+ }
25989
+ function getPendingRevealProperties(container) {
25990
+ if (!container || typeof getComputedStyle !== 'function') {
25991
+ return new Set(revealProperties);
25992
+ }
25993
+ var style = getComputedStyle(container);
25994
+ return new Set(revealProperties.filter(function(property) {
25995
+ return !isRevealed(style, property);
25996
+ }));
25997
+ }
25998
+ function affectsReveal(animation, pendingRevealProperties) {
25999
+ if (pendingRevealProperties.size === 0) {
26000
+ return false;
26001
+ }
26002
+ var effect = animation.effect;
26003
+ if (typeof (effect === null || effect === void 0 ? void 0 : effect.getKeyframes) !== 'function') {
26004
+ return true;
26005
+ }
26006
+ return effect.getKeyframes().some(function(keyframe) {
26007
+ return Array.from(pendingRevealProperties).some(function(property) {
26008
+ return Object.prototype.hasOwnProperty.call(keyframe, property);
26009
+ });
26010
+ });
26011
+ }
26012
+ function startedDuringReveal(current, animationsBeforeReveal) {
26013
+ var previous = animationsBeforeReveal.find(function(param) {
26014
+ var animation = param.animation;
26015
+ return animation === current.animation;
26016
+ });
26017
+ if (!previous) {
26018
+ return true;
26019
+ }
26020
+ if (previous.playState !== current.playState) {
26021
+ return true;
26022
+ }
26023
+ if (current.startTime !== null && previous.startTime !== current.startTime) {
26024
+ return true;
26025
+ }
26026
+ return typeof previous.currentTime === 'number' && typeof current.currentTime === 'number' && current.currentTime < previous.currentTime;
26027
+ }
26028
+ function holdContainerInertUntilReveal(prompt) {
26029
+ var container = getContainer(prompt);
26030
+ if (!(container === null || container === void 0 ? void 0 : container.classList.contains('ais-Chat-container--open')) || container.hasAttribute('inert')) {
26031
+ return;
26032
+ }
26033
+ container.setAttribute('inert', '');
26034
+ containersHeldInert.add(container);
26035
+ }
26036
+ function restoreContainerInertUntilReveal(prompt) {
26037
+ var container = getContainer(prompt);
26038
+ if (container && containersHeldInert.has(container) && getPendingRevealProperties(container).size > 0) {
26039
+ container.setAttribute('inert', '');
26040
+ }
26041
+ }
26042
+ function requestAnimationFrameOrRun(callback) {
26043
+ if (typeof requestAnimationFrame === 'function') {
26044
+ requestAnimationFrame(callback);
26045
+ } else {
26046
+ callback();
26047
+ }
26048
+ }
26049
+ function focusAfterReveal(prompt, animationsBeforeReveal, shouldFocus) {
26050
+ var shouldRelease = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : shouldFocus;
26051
+ var container = getContainer(prompt);
26052
+ var settle = function settle() {
26053
+ if (!shouldRelease()) {
26054
+ return;
26055
+ }
26056
+ if (container) {
26057
+ revealAnimationsHeldByContainer.delete(container);
26058
+ }
26059
+ if (container && containersHeldInert.has(container) && container.classList.contains('ais-Chat-container--open')) {
26060
+ container.removeAttribute('inert');
26061
+ containersHeldInert.delete(container);
26062
+ }
26063
+ if (prompt && shouldFocus()) {
26064
+ prompt.focus();
26065
+ }
26066
+ };
26067
+ var waitForReveal = function waitForReveal1() {
26068
+ var requestIsCurrent = shouldRelease();
26069
+ var pendingRevealProperties = getPendingRevealProperties(container);
26070
+ var heldRevealAnimations = container ? revealAnimationsHeldByContainer.get(container) : undefined;
26071
+ var activeAnimations = getActiveAnimations(container);
26072
+ var heldRevealIsActive = activeAnimations.some(function(param) {
26073
+ var animation = param.animation;
26074
+ return heldRevealAnimations === null || heldRevealAnimations === void 0 ? void 0 : heldRevealAnimations.has(animation);
26075
+ });
26076
+ var replacesInactiveHeldReveal = heldRevealAnimations !== undefined && !heldRevealIsActive;
26077
+ var revealAnimations = activeAnimations.filter(function(current) {
26078
+ var _current_animation_effect;
26079
+ return (startedDuringReveal(current, animationsBeforeReveal) || (heldRevealAnimations === null || heldRevealAnimations === void 0 ? void 0 : heldRevealAnimations.has(current.animation)) || replacesInactiveHeldReveal) && ((_current_animation_effect = current.animation.effect) === null || _current_animation_effect === void 0 ? void 0 : _current_animation_effect.getTiming().iterations) !== Infinity && affectsReveal(current.animation, pendingRevealProperties);
26080
+ });
26081
+ if (container && revealAnimations.length > 0 && (!heldRevealAnimations || requestIsCurrent || !heldRevealIsActive)) {
26082
+ revealAnimationsHeldByContainer.set(container, new Set(revealAnimations.map(function(param) {
26083
+ var animation = param.animation;
26084
+ return animation;
26085
+ })));
26086
+ }
26087
+ if (!requestIsCurrent) {
26088
+ if (container && !container.classList.contains('ais-Chat-container--open')) {
26089
+ revealAnimationsHeldByContainer.delete(container);
26090
+ containersHeldInert.delete(container);
26091
+ }
26092
+ return;
26093
+ }
26094
+ if (revealAnimations.length === 0) {
26095
+ settle();
26096
+ return;
26097
+ }
26098
+ Promise.all(revealAnimations.map(function(param) {
26099
+ var animation = param.animation;
26100
+ return animation.finished.catch(function() {});
26101
+ })).then(function() {
26102
+ return requestAnimationFrameOrRun(waitForReveal);
26103
+ });
26104
+ };
26105
+ waitForReveal();
26106
+ }
26107
+
25434
26108
  var useStickToBottom = createStickToBottom({
25435
26109
  useCallback: React.useCallback,
25436
26110
  useEffect: React.useEffect,
@@ -25576,11 +26250,24 @@
25576
26250
  createElement: React.createElement,
25577
26251
  Fragment: React.Fragment,
25578
26252
  useMemo: React.useMemo,
25579
- useState: React.useState
26253
+ useState: React.useState,
26254
+ useEffect: React.useEffect
25580
26255
  });
25581
26256
  function createDefaultTools(itemComponent, getSearchPageURL) {
25582
26257
  var _obj;
25583
- return _obj = {}, _define_property(_obj, SearchIndexToolType, 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;
26258
+ return _obj = {}, _define_property(_obj, SearchIndexToolType, _object_spread_props(_object_spread({}, createCarouselTool(true, itemComponent, getSearchPageURL)), {
26259
+ // The agent decides per turn whether the richer display-results tool
26260
+ // takes over the rendering of the search results.
26261
+ shouldRender: isDisplayResultsDisabled
26262
+ })), _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;
26263
+ }
26264
+ /**
26265
+ * Whether the search tool renders its own results, i.e. the agent did not hand
26266
+ * the turn to the display-results tool. Set on the message by the backend.
26267
+ */ function isDisplayResultsDisabled(param) {
26268
+ var parentMessage = param.parentMessage;
26269
+ var _parentMessage_metadata;
26270
+ return ((_parentMessage_metadata = parentMessage.metadata) === null || _parentMessage_metadata === void 0 ? void 0 : _parentMessage_metadata.displayResultsEnabled) !== true;
25584
26271
  }
25585
26272
  function mergeToolOptions(defaultTools, userTools) {
25586
26273
  if (!userTools) {
@@ -25588,22 +26275,62 @@
25588
26275
  }
25589
26276
  var tools = _object_spread({}, defaultTools, userTools);
25590
26277
  Object.keys(userTools).forEach(function(toolName) {
25591
- var _defaultTools_toolName;
25592
26278
  var userTool = userTools[toolName];
25593
- var defaultStreamInput = (_defaultTools_toolName = defaultTools[toolName]) === null || _defaultTools_toolName === void 0 ? void 0 : _defaultTools_toolName.streamInput;
26279
+ var defaultTool = defaultTools[toolName];
26280
+ var defaultStreamInput = defaultTool === null || defaultTool === void 0 ? void 0 : defaultTool.streamInput;
25594
26281
  if (userTool.layoutComponent !== undefined && userTool.streamInput === undefined && defaultStreamInput !== undefined) {
25595
- tools[toolName] = _object_spread_props(_object_spread({}, userTool), {
26282
+ tools[toolName] = _object_spread_props(_object_spread({}, tools[toolName]), {
25596
26283
  streamInput: defaultStreamInput
25597
26284
  });
25598
26285
  }
26286
+ // Overriding a tool's rendering shouldn't opt it out of the conditions
26287
+ // under which the default renders at all.
26288
+ if (userTool.shouldRender === undefined && (defaultTool === null || defaultTool === void 0 ? void 0 : defaultTool.shouldRender)) {
26289
+ tools[toolName] = _object_spread_props(_object_spread({}, tools[toolName]), {
26290
+ shouldRender: defaultTool.shouldRender
26291
+ });
26292
+ }
25599
26293
  });
25600
26294
  return tools;
25601
26295
  }
26296
+ var AnimationSnapshot = /*#__PURE__*/ function(_React_Component) {
26297
+ _inherits(AnimationSnapshot, _React_Component);
26298
+ function AnimationSnapshot() {
26299
+ _class_call_check(this, AnimationSnapshot);
26300
+ return _call_super(this, AnimationSnapshot, arguments);
26301
+ }
26302
+ _create_class(AnimationSnapshot, [
26303
+ {
26304
+ key: "getSnapshotBeforeUpdate",
26305
+ value: function getSnapshotBeforeUpdate() {
26306
+ return getActiveContainerAnimations(this.props.promptRef.current);
26307
+ }
26308
+ },
26309
+ {
26310
+ key: "componentDidUpdate",
26311
+ value: function componentDidUpdate(_previousProps, _previousState, animationsBeforeReveal) {
26312
+ this.props.animationsBeforeReveal.current = animationsBeforeReveal;
26313
+ if (!_previousProps.open && this.props.open) {
26314
+ holdContainerInertUntilReveal(this.props.promptRef.current);
26315
+ } else if (this.props.open) {
26316
+ restoreContainerInertUntilReveal(this.props.promptRef.current);
26317
+ }
26318
+ }
26319
+ },
26320
+ {
26321
+ key: "render",
26322
+ value: function render() {
26323
+ return null;
26324
+ }
26325
+ }
26326
+ ]);
26327
+ return AnimationSnapshot;
26328
+ }(React.Component);
25602
26329
  function ChatInner(_0, _1) {
25603
26330
  var _ref = [
25604
26331
  _0,
25605
26332
  _1
25606
- ], _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, [
26333
+ ], _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, loaderPosition = _ref2.loaderPosition, shouldShowLoader = _ref2.shouldShowLoader, loaderShowDelay = _ref2.loaderShowDelay, loaderMinDuration = _ref2.loaderMinDuration, 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, [
25607
26334
  "tools",
25608
26335
  "headerProps",
25609
26336
  "messagesProps",
@@ -25616,6 +26343,10 @@
25616
26343
  "headerMinimizeIconComponent",
25617
26344
  "headerMaximizeIconComponent",
25618
26345
  "loaderComponent",
26346
+ "loaderPosition",
26347
+ "shouldShowLoader",
26348
+ "loaderShowDelay",
26349
+ "loaderMinDuration",
25619
26350
  "messagesErrorComponent",
25620
26351
  "promptComponent",
25621
26352
  "promptHeaderComponent",
@@ -25639,6 +26370,8 @@
25639
26370
  var _useInstantSearch = useInstantSearch(), indexUiState = _useInstantSearch.indexUiState, setIndexUiState = _useInstantSearch.setIndexUiState;
25640
26371
  var _useState = _sliced_to_array(React.useState(false), 2), maximized = _useState[0], setMaximized = _useState[1];
25641
26372
  var promptRef = React.useRef(null);
26373
+ var focusRequestId = React.useRef(0);
26374
+ var animationsBeforeReveal = React.useRef([]);
25642
26375
  var _useStickToBottom = useStickToBottom({
25643
26376
  initial: 'smooth',
25644
26377
  resize: 'smooth'
@@ -25660,7 +26393,7 @@
25660
26393
  tools: tools,
25661
26394
  disableTriggerValidation: effectiveDisableTriggerValidation
25662
26395
  }));
25663
- 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'];
26396
+ 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, suggestionsStatus = chatState.suggestionsStatus, onFeedback = chatState.sendChatMessageFeedback, feedbackState = chatState.feedbackState, consumeInputFocus = chatState['~consumeInputFocus'], isOpenStatePersistenceEnabled = chatState['~isOpenStatePersistenceEnabled'];
25664
26397
  React.useImperativeHandle(ref, function() {
25665
26398
  return {
25666
26399
  setOpen: setOpen,
@@ -25671,10 +26404,21 @@
25671
26404
  };
25672
26405
  });
25673
26406
  React.useEffect(function() {
26407
+ if (!open) {
26408
+ focusRequestId.current++;
26409
+ return;
26410
+ }
25674
26411
  if (consumeInputFocus === null || consumeInputFocus === void 0 ? void 0 : consumeInputFocus()) {
26412
+ var currentFocusRequestId = ++focusRequestId.current;
26413
+ var previousAnimations = animationsBeforeReveal.current;
26414
+ holdContainerInertUntilReveal(promptRef.current);
25675
26415
  window.requestAnimationFrame(function() {
25676
- var _promptRef_current;
25677
- (_promptRef_current = promptRef.current) === null || _promptRef_current === void 0 ? void 0 : _promptRef_current.focus();
26416
+ var prompt = promptRef.current;
26417
+ focusAfterReveal(prompt, previousAnimations, function() {
26418
+ return focusRequestId.current === currentFocusRequestId && promptRef.current === prompt;
26419
+ }, function() {
26420
+ return focusRequestId.current === currentFocusRequestId;
26421
+ });
25678
26422
  });
25679
26423
  }
25680
26424
  });
@@ -25702,7 +26446,7 @@
25702
26446
  "assistantMessageProps",
25703
26447
  "userMessageProps"
25704
26448
  ]);
25705
- return /*#__PURE__*/ React.createElement(ChatUiComponent, {
26449
+ var chat = /*#__PURE__*/ React.createElement(ChatUiComponent, {
25706
26450
  title: title,
25707
26451
  open: open,
25708
26452
  maximized: maximized,
@@ -25754,6 +26498,10 @@
25754
26498
  contentRef: contentRef,
25755
26499
  onScrollToBottom: scrollToBottom,
25756
26500
  loaderComponent: loaderComponent,
26501
+ loaderPosition: loaderPosition,
26502
+ shouldShowLoader: shouldShowLoader,
26503
+ loaderShowDelay: loaderShowDelay,
26504
+ loaderMinDuration: loaderMinDuration,
25757
26505
  errorComponent: messagesErrorComponent,
25758
26506
  emptyComponent: emptyComponent,
25759
26507
  actionsComponent: actionsComponent,
@@ -25795,6 +26543,7 @@
25795
26543
  }),
25796
26544
  suggestionsProps: {
25797
26545
  suggestions: suggestions,
26546
+ isLoading: suggestionsStatus === 'loading',
25798
26547
  onSuggestionClick: function onSuggestionClick(suggestion) {
25799
26548
  sendMessage({
25800
26549
  text: suggestion
@@ -25803,6 +26552,11 @@
25803
26552
  },
25804
26553
  classNames: classNames
25805
26554
  });
26555
+ return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(AnimationSnapshot, {
26556
+ promptRef: promptRef,
26557
+ animationsBeforeReveal: animationsBeforeReveal,
26558
+ open: open
26559
+ }), chat);
25806
26560
  }
25807
26561
  var Chat = /*#__PURE__*/ React.forwardRef(ChatInner);
25808
26562
 
@@ -25823,14 +26577,18 @@
25823
26577
  "context",
25824
26578
  "transformItems"
25825
26579
  ]);
25826
- var _usePromptSuggestions = usePromptSuggestions({
26580
+ var source = agentId !== undefined ? {
25827
26581
  agentId: agentId,
25828
- transport: transport,
26582
+ transport: transport
26583
+ } : {
26584
+ transport: transport
26585
+ };
26586
+ var _usePromptSuggestions = usePromptSuggestions(_object_spread_props(_object_spread({}, source), {
25829
26587
  configurationId: configurationId,
25830
26588
  transformHits: transformHits,
25831
26589
  context: context,
25832
26590
  transformItems: transformItems
25833
- }, {
26591
+ }), {
25834
26592
  $$widgetType: 'ais.promptSuggestions'
25835
26593
  }), suggestions = _usePromptSuggestions.suggestions, isLoading = _usePromptSuggestions.isLoading, onSuggestionClick = _usePromptSuggestions.onSuggestionClick, isChatBusy = _usePromptSuggestions.isChatBusy, sendToChat = _usePromptSuggestions.sendToChat;
25836
26594
  var handleClick = onSuggestionClickOverride ? function(prompt) {