@docsearch/react 5.0.0-beta.0 → 5.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/esm/{AskAiScreenState-D0IZsCMJ.d.ts → AskAiScreenState-CRHicWbN.d.ts} +3 -3
  2. package/dist/esm/{DocSearch-Dq5Utfyb.d.ts → DocSearch-HJsNvtZr.d.ts} +3 -3
  3. package/dist/esm/{DocSearchAskAiModal-BwbMrrHv.d.ts → DocSearchAskAiModal-B7vpLudE.d.ts} +4 -4
  4. package/dist/esm/{DocSearchAskAiModal-CCrk6YLb.js → DocSearchAskAiModal-KaA6fBV4.js} +8 -8
  5. package/dist/esm/DocSearchAskAiModal-KaA6fBV4.js.map +1 -0
  6. package/dist/esm/{DocSearchButton-CRlNPf5k.d.ts → DocSearchButton-CZM_jACU.d.ts} +2 -2
  7. package/dist/esm/askaiModal.d.ts +1 -1
  8. package/dist/esm/askaiModal.js +1 -1
  9. package/dist/esm/button.d.ts +1 -1
  10. package/dist/esm/docsearchAi.d.ts +2 -2
  11. package/dist/esm/docsearchAi.js +1 -1
  12. package/dist/esm/{index-Dl8FMlR5.d.ts → index-Bqqv4HmN.d.ts} +19 -9
  13. package/dist/esm/index.d.ts +5 -5
  14. package/dist/esm/index.js +1 -1
  15. package/dist/esm/modal.d.ts +1 -1
  16. package/dist/esm/sidepanel.d.ts +4 -4
  17. package/dist/esm/sidepanel.js +4 -4
  18. package/dist/esm/sidepanel.js.map +1 -1
  19. package/dist/esm/{useDocSearchKeyboardEvents-68G8dw6c.d.ts → useDocSearchKeyboardEvents-u23fFhR9.d.ts} +2 -2
  20. package/dist/esm/useDocSearchKeyboardEvents.d.ts +1 -1
  21. package/dist/esm/{useSuggestedQuestions-D2TGVPsI.js → useSuggestedQuestions-CG2H3qm4.js} +34 -30
  22. package/dist/esm/useSuggestedQuestions-CG2H3qm4.js.map +1 -0
  23. package/dist/esm/useTheme.d.ts +1 -1
  24. package/dist/umd/index.js +15 -15
  25. package/dist/umd/index.js.map +1 -1
  26. package/package.json +4 -4
  27. package/dist/esm/DocSearchAskAiModal-CCrk6YLb.js.map +0 -1
  28. package/dist/esm/useSuggestedQuestions-D2TGVPsI.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import "./index-Dl8FMlR5.js";
2
- import { f as ResultsScreenTranslations, h as StoredSearchesSectionsTranslations, m as ErrorScreenTranslations, p as NoResultsScreenTranslations } from "./DocSearch-Dq5Utfyb.js";
1
+ import "./index-Bqqv4HmN.js";
2
+ import { f as ResultsScreenTranslations, h as StoredSearchesSectionsTranslations, m as ErrorScreenTranslations, p as NoResultsScreenTranslations } from "./DocSearch-HJsNvtZr.js";
3
3
  import React, { JSX } from "react";
4
4
  import { AutocompleteState, BaseItem } from "@algolia/autocomplete-core";
5
5
  import "@ai-sdk/react";
@@ -103,4 +103,4 @@ type AskAiScreenStateTranslations = Partial<{
103
103
  }>;
104
104
  //#endregion
105
105
  export { NewConversationTranslations as n, ToolCallTranslations as r, AskAiScreenStateTranslations as t };
106
- //# sourceMappingURL=AskAiScreenState-D0IZsCMJ.d.ts.map
106
+ //# sourceMappingURL=AskAiScreenState-CRHicWbN.d.ts.map
@@ -1,6 +1,6 @@
1
- import { a as StoredDocSearchHit, d as DocSearchHit } from "./index-Dl8FMlR5.js";
1
+ import { a as StoredDocSearchHit, d as DocSearchHit } from "./index-Bqqv4HmN.js";
2
2
  import { t as DocSearchTheme$1 } from "./DocSearchTheme-DvL4mf0D.js";
3
- import { t as ButtonTranslations } from "./DocSearchButton-CRlNPf5k.js";
3
+ import { t as ButtonTranslations } from "./DocSearchButton-CZM_jACU.js";
4
4
  import { DocSearchModalShortcuts, DocSearchRef, DocSearchRef as DocSearchRef$1 } from "@docsearch/core";
5
5
  import React, { JSX } from "react";
6
6
  import { AutocompleteOptions, AutocompleteState, BaseItem } from "@algolia/autocomplete-core";
@@ -292,4 +292,4 @@ declare const DocSearch$1: React.ForwardRefExoticComponent<DocSearchProps & Reac
292
292
  declare function DocSearchInner(props: DocSearchProps): JSX.Element;
293
293
  //#endregion
294
294
  export { FacetBarTranslations as _, DocSearchProps as a, DocSearchTranslations as c, ModalTranslations as d, ResultsScreenTranslations as f, FooterTranslations as g, StoredSearchesSectionsTranslations as h, DocSearchInner as i, DocSearchModal as l, ErrorScreenTranslations as m, DocSearchFacet as n, DocSearchRef$1 as o, NoResultsScreenTranslations as p, DocSearchIndex as r, DocSearchTransformClient as s, DocSearch$1 as t, DocSearchModalProps as u, InternalDocSearchHit as v };
295
- //# sourceMappingURL=DocSearch-Dq5Utfyb.d.ts.map
295
+ //# sourceMappingURL=DocSearch-HJsNvtZr.d.ts.map
@@ -1,7 +1,7 @@
1
- import "./index-Dl8FMlR5.js";
2
- import { _ as FacetBarTranslations, g as FooterTranslations } from "./DocSearch-Dq5Utfyb.js";
1
+ import "./index-Bqqv4HmN.js";
2
+ import { _ as FacetBarTranslations, g as FooterTranslations } from "./DocSearch-HJsNvtZr.js";
3
3
  import { DocSearchAIProps } from "./docsearchAi.js";
4
- import { n as NewConversationTranslations, t as AskAiScreenStateTranslations } from "./AskAiScreenState-D0IZsCMJ.js";
4
+ import { n as NewConversationTranslations, t as AskAiScreenStateTranslations } from "./AskAiScreenState-CRHicWbN.js";
5
5
  import { OnAskAiToggle } from "@docsearch/core";
6
6
  import React, { JSX } from "react";
7
7
  import { AutocompleteState } from "@algolia/autocomplete-core";
@@ -45,4 +45,4 @@ type DocSearchAskAiModalProps = DocSearchAIProps & {
45
45
  declare function DocSearchAskAiModal({ appId, apiKey, askAi, maxResultsPerGroup, theme, onClose, transformItems, hitComponent, resultsFooterComponent, navigator, initialScrollY, transformSearchClient, disableUserPersonalization, initialQuery: initialQueryFromProp, translations, getMissingResultsUrl, insights, onAskAiToggle, interceptAskAiEvent, isAskAiActive, recentSearchesLimit, recentSearchesWithFavoritesLimit, indices, indexName, searchParameters, facets, isHybridModeSupported, ...props }: DocSearchAskAiModalProps): JSX.Element;
46
46
  //#endregion
47
47
  export { DocSearchAskAiModalProps as n, DocSearchAskAiModalTranslations as r, DocSearchAskAiModal as t };
48
- //# sourceMappingURL=DocSearchAskAiModal-BwbMrrHv.d.ts.map
48
+ //# sourceMappingURL=DocSearchAskAiModal-B7vpLudE.d.ts.map
@@ -2,7 +2,7 @@ import { t as _objectSpread2 } from "./objectSpread2-BNmiQYyW.js";
2
2
  import { C as noop, D as getCollection, E as SOURCE_IDS, S as scrollTo, T as identity, _ as Hit, a as NoResultsScreen, b as SearchBoxForm, c as Results, d as useRefreshOnInitialQuery, f as useModalRefs, g as useDocSearchFacets, h as useSendItemClickEvent, i as ResultsScreen, l as useStoredDocSearches, m as useInitialModalQuery, n as buildNoQuerySources, o as ErrorScreen, p as useModalEnvironment, r as buildQuerySources, s as StoredSearchesSections, t as normalizeDocSearchIndexes, u as useSaveRecentSearch, v as Footer, w as isModifierEvent, x as FacetBar, y as ModalShell } from "./normalizeDocSearchIndexes-DAzlMybx.js";
3
3
  import { n as SearchIcon, t as _objectWithoutProperties } from "./objectWithoutProperties-phqYxDS0.js";
4
4
  import { l as CloseIcon, m as LoadingIcon, p as SparklesIcon, t as useSearchClient } from "./useSearchClient-mIHVB6ga.js";
5
- import { S as AlertIcon, _ as BackIcon, a as MemoizedMarkdown, b as MoreVerticalIcon, c as buildDummyAskAiHit, d as getMessageContent, f as isAIToolPart, g as ConversationPromptSuggestions, h as FeedbackActions, i as groupConsecutiveToolResults, l as extractLinksFromMessage, m as SourcesPanel, n as useAskAi, o as ToolCall, p as isThreadDepthError, r as Menu, s as EMPTY_TOOLS, t as useSuggestedQuestions, u as getAgentPromptSuggestions, v as NewConversationIcon, x as StopIcon, y as ConversationHistoryIcon } from "./useSuggestedQuestions-D2TGVPsI.js";
5
+ import { S as AlertIcon, _ as BackIcon, a as MemoizedMarkdown, b as MoreVerticalIcon, c as buildDummyAskAiHit, d as getMessageContent, f as isAIToolPart, g as ConversationPromptSuggestions, h as FeedbackActions, i as groupConsecutiveToolResults, l as extractLinksFromMessage, m as SourcesPanel, n as useAskAi, o as ToolCall, p as isThreadDepthError, r as Menu, s as EMPTY_TOOLS, t as useSuggestedQuestions, u as getAgentPromptSuggestions, v as NewConversationIcon, x as StopIcon, y as ConversationHistoryIcon } from "./useSuggestedQuestions-CG2H3qm4.js";
6
6
  import React, { Fragment, useMemo } from "react";
7
7
  import { createAutocomplete } from "@algolia/autocomplete-core";
8
8
 
@@ -38,7 +38,7 @@ function AggregatedSearchBlock({ queries, translations, onSearchQueryClick }) {
38
38
  tabIndex: 0,
39
39
  className: "DocSearch-AskAiScreen-MessageContent-Tool-Query",
40
40
  onKeyDown: (e) => {
41
- if (e.key === "enter" || e.key === " ") {
41
+ if (e.key === "Enter" || e.key === " ") {
42
42
  e.preventDefault();
43
43
  onSearchQueryClick(q);
44
44
  }
@@ -99,7 +99,7 @@ function AskAiExchangeCard({ exchange, askAiError, isLastExchange, loadingStatus
99
99
  }))), isThinking && /* @__PURE__ */ React.createElement("div", {
100
100
  className: "DocSearch-AskAiScreen-MessageContent-Thinking",
101
101
  role: "status"
102
- }, /* @__PURE__ */ React.createElement("span", { className: "shimmer" }, translations.thinkingText || "Thinking..."), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton shimmer" }), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton DocSearch-AskAi-Thinking-Skeleton--short shimmer" })), displayParts.map((part, idx) => {
102
+ }, /* @__PURE__ */ React.createElement("span", { className: "DocSearch-shimmer" }, translations.thinkingText || "Thinking..."), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton DocSearch-shimmer" }), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton DocSearch-AskAi-Thinking-Skeleton--short DocSearch-shimmer" })), displayParts.map((part, idx) => {
103
103
  const index = idx;
104
104
  if (typeof part === "string") return /* @__PURE__ */ React.createElement(MemoizedMarkdown, {
105
105
  key: index,
@@ -124,8 +124,8 @@ function AskAiExchangeCard({ exchange, askAiError, isLastExchange, loadingStatus
124
124
  });
125
125
  if (part.type === "reasoning" && part.state === "streaming") return /* @__PURE__ */ React.createElement("div", {
126
126
  key: index,
127
- className: "DocSearch-AskAiScreen-MessageContent-Reasoning shimmer"
128
- }, /* @__PURE__ */ React.createElement(LoadingIcon, { className: "DocSearch-AskAiScreen-SmallerLoadingIcon" }), /* @__PURE__ */ React.createElement("span", { className: "shimmer" }, "Reasoning..."));
127
+ className: "DocSearch-AskAiScreen-MessageContent-Reasoning DocSearch-shimmer"
128
+ }, /* @__PURE__ */ React.createElement(LoadingIcon, { className: "DocSearch-AskAiScreen-SmallerLoadingIcon" }), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-shimmer" }, "Reasoning..."));
129
129
  if (part.type === "text") return /* @__PURE__ */ React.createElement(MemoizedMarkdown, {
130
130
  key: index,
131
131
  content: part.text,
@@ -134,7 +134,7 @@ function AskAiExchangeCard({ exchange, askAiError, isLastExchange, loadingStatus
134
134
  isStreaming: part.state === "streaming"
135
135
  });
136
136
  return null;
137
- })), wasStopped && /* @__PURE__ */ React.createElement("p", { className: "DocSearck-AskAiScreen-MessageContent-Stopped" }, stoppedStreamingText)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Answer-Footer" }, /* @__PURE__ */ React.createElement(SourcesPanel, {
137
+ })), wasStopped && /* @__PURE__ */ React.createElement("p", { className: "DocSearch-AskAiScreen-MessageContent-Stopped" }, stoppedStreamingText)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Answer-Footer" }, /* @__PURE__ */ React.createElement(SourcesPanel, {
138
138
  links: urlsToDisplay,
139
139
  titleText: relatedSourcesText
140
140
  }), /* @__PURE__ */ React.createElement(FeedbackActions, {
@@ -315,7 +315,7 @@ const AskAiScreenState = React.memo((_ref) => {
315
315
  //#endregion
316
316
  //#region src/ModalHeading.tsx
317
317
  function ModalHeading({ heading, shimmer = false }) {
318
- return /* @__PURE__ */ React.createElement("span", { className: `DocSearch-Modal-heading${shimmer ? " shimmer" : ""}` }, heading);
318
+ return /* @__PURE__ */ React.createElement("span", { className: `DocSearch-Modal-heading${shimmer ? " DocSearch-shimmer" : ""}` }, heading);
319
319
  }
320
320
 
321
321
  //#endregion
@@ -951,4 +951,4 @@ function DocSearchAskAiModal(_ref) {
951
951
 
952
952
  //#endregion
953
953
  export { DocSearchAskAiModal as t };
954
- //# sourceMappingURL=DocSearchAskAiModal-CCrk6YLb.js.map
954
+ //# sourceMappingURL=DocSearchAskAiModal-KaA6fBV4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DocSearchAskAiModal-KaA6fBV4.js","names":[],"sources":["../../src/icons/MessageIcon.tsx","../../src/AggregatedSearchBlock.tsx","../../src/AskAiScreen.tsx","../../src/components/ui/RecentConversationsResults.tsx","../../src/components/AskAiStartScreen.tsx","../../src/ConversationHistoryScreen.tsx","../../src/NewConversationScreen.tsx","../../src/AskAiScreenState.tsx","../../src/ModalHeading.tsx","../../src/components/AskAiSearchBox.tsx","../../src/utils/createAskAiSources.ts","../../src/DocSearchAskAiModal.tsx"],"sourcesContent":["import React, { type JSX } from 'react';\n\nexport function MessageIcon(): JSX.Element {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"13\"\n height=\"13\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n );\n}\n","import React, { type JSX, Fragment } from 'react';\n\nimport type { AskAiScreenTranslations } from './AskAiScreen';\nimport { SearchIcon } from './icons';\n\ninterface AggregatedSearchBlockProps {\n queries: string[];\n translations: AskAiScreenTranslations;\n onSearchQueryClick: (query: string) => void;\n}\n\n// allow translators to return either simple string parts or a fully custom node\nexport interface AggregatedToolCallParts {\n before?: string;\n separator?: string;\n lastSeparator?: string;\n after?: string;\n}\n\n// default english implementation (\"Searched for \\\"A\\\", \\\"B\\\" and \\\"C\\\"\")\nconst defaultAggregatedToolCallParts: AggregatedToolCallParts = {\n before: 'Searched for ',\n separator: ', ',\n lastSeparator: ' and ',\n after: '',\n};\n\nexport function AggregatedSearchBlock({\n queries,\n translations,\n onSearchQueryClick,\n}: AggregatedSearchBlockProps): JSX.Element | null {\n // no queries? no render\n if (queries.length === 0) return null;\n\n // if the translator provides a fully custom node, render it and bail out.\n if (typeof translations.aggregatedToolCallNode === 'function') {\n return (\n <>{translations.aggregatedToolCallNode(queries, onSearchQueryClick)}</>\n );\n }\n\n // otherwise fall back to the classic english-pattern renderer.\n const parts = translations.aggregatedToolCallText\n ? translations.aggregatedToolCallText(queries)\n : defaultAggregatedToolCallParts;\n\n const {\n before = '',\n separator = ', ',\n lastSeparator = ' and ',\n after = '',\n } = parts || {};\n\n return (\n <div className=\"DocSearch-AskAiScreen-MessageContent-Tool Tool--AggregatedResult\">\n <SearchIcon size={18} />\n <span>\n {before && <span>{before}</span>}\n {queries.map((q, idx) => (\n // eslint-disable-next-line react/no-array-index-key\n <Fragment key={q + idx}>\n <span\n role=\"button\"\n tabIndex={0}\n className=\"DocSearch-AskAiScreen-MessageContent-Tool-Query\"\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onSearchQueryClick(q);\n }\n }}\n onClick={() => onSearchQueryClick(q)}\n >\n &quot;{q}&quot;\n </span>\n {idx < queries.length - 2 && separator}\n {idx === queries.length - 2 && lastSeparator}\n </Fragment>\n ))}\n {after && <span>{after}</span>}\n </span>\n </div>\n );\n}\n","import type { UseChatHelpers } from '@ai-sdk/react';\nimport React, { type JSX, useMemo } from 'react';\n\nimport { AggregatedSearchBlock } from './AggregatedSearchBlock';\nimport type { AskAiScreenStateProps } from './AskAiScreenState';\nimport { ConversationPromptSuggestions } from './components/ConversationPromptSuggestions';\nimport { FeedbackActions } from './components/FeedbackActions';\nimport { SourcesPanel } from './components/SourcesPanel';\nimport { ToolCall, type ToolCallTranslations } from './components/ToolCall';\nimport { AlertIcon, LoadingIcon, SparklesIcon } from './icons';\nimport { MemoizedMarkdown } from './MemoizedMarkdown';\nimport type { StoredSearchPlugin } from './stored-searches';\nimport type {\n InternalDocSearchHit,\n OnAskAiFeedback,\n StoredAskAiState,\n} from './types';\nimport { type AIMessage, type ToolCalls } from './types/AskiAi';\nimport {\n extractLinksFromMessage,\n getMessageContent,\n isThreadDepthError,\n isAIToolPart,\n getAgentPromptSuggestions,\n} from './utils/ai';\nimport { groupConsecutiveToolResults } from './utils/groupConsecutiveToolResults';\n\nexport type AskAiScreenTranslations = Partial<\n // Inherit the shared tool-call translations, but expose the search-related\n // keys under AskAiScreen's own public names (see mapping below).\n Omit<ToolCallTranslations, 'searchingText' | 'toolCallResultText'> & {\n // Misc texts\n disclaimerText: string;\n relatedSourcesText: string;\n thinkingText: string;\n copyButtonText: string;\n copyButtonCopiedText: string;\n // Feedback buttons\n copyButtonTitle: string;\n likeButtonTitle: string;\n dislikeButtonTitle: string;\n thanksForFeedbackText: string;\n // Negative feedback note panel\n feedbackPanelTitle: string;\n feedbackDetailsPlaceholder: string;\n feedbackDisclaimerText: string;\n feedbackSubmitButtonText: string;\n feedbackCloseButtonTitle: string;\n feedbackTagIncorrect: string;\n feedbackTagNotWhatIAsked: string;\n feedbackTagSlowOrBuggy: string;\n feedbackTagStyleOrTone: string;\n feedbackTagSafetyOrLegal: string;\n feedbackTagOther: string;\n // Tool call texts\n /**\n * Text shown while assistant is performing search tool call. Maps to\n * `ToolCallTranslations.searchingText`.\n */\n duringToolCallText: string;\n /**\n * Text shown while assistant is finished performing tool call. Maps to\n * `ToolCallTranslations.toolCallResultText`.\n */\n afterToolCallText: string;\n /**\n * Build the full jsx element for the aggregated search block. If provided,\n * completely overrides the default english renderer.\n */\n aggregatedToolCallNode?: (\n queries: string[],\n onSearchQueryClick: (query: string) => void\n ) => React.ReactNode;\n /**\n * Generate the list connective parts only (backwards compatibility).\n * Receives full list of queries and should return translation parts for\n * before/after/separators. Example: (qs) => ({ before: 'searched for ',\n * separator: ', ', lastSeparator: ' and ', after: '' }).\n */\n aggregatedToolCallText?: (queries: string[]) => {\n before?: string;\n separator?: string;\n lastSeparator?: string;\n after?: string;\n };\n /** Message that's shown when user has stopped the streaming of a message. */\n stoppedStreamingText: string;\n /** Error title shown if there is an error while chatting. */\n errorTitleText: string;\n /** Message shown when thread depth limit is exceeded (AI-217 error). */\n threadDepthExceededMessage: string;\n /** Button text for starting a new conversation after thread depth error. */\n startNewConversationButtonText: string;\n suggestedPromptsTitleText: string;\n }\n>;\n\n/**\n * Maps AskAiScreen's public translation keys to the shared\n * `ToolCallTranslations` shape consumed by the `ToolCall` component, applying\n * default English values.\n */\nfunction toToolCallTranslations(\n translations: AskAiScreenTranslations\n): ToolCallTranslations {\n const {\n preToolCallText = 'Searching...',\n duringToolCallText = 'Searching...',\n afterToolCallText = 'Searched for',\n savedMemoryToolResultText = 'Saved to memory',\n memoryToolResultText = 'Used memory to enhance results',\n } = translations;\n\n return {\n preToolCallText,\n searchingText: duringToolCallText,\n toolCallResultText: afterToolCallText,\n savedMemoryToolResultText,\n memoryToolResultText,\n };\n}\n\ntype AskAiScreenProps = Omit<\n AskAiScreenStateProps<InternalDocSearchHit>,\n 'translations'\n> & {\n messages: AIMessage[];\n tools: ToolCalls;\n status: UseChatHelpers<AIMessage>['status'];\n askAiError?: Error;\n translations?: AskAiScreenTranslations;\n onNewConversation: () => void;\n onSelectPromptSuggestion: (prompt: string) => void;\n memoryEnabled?: boolean;\n};\n\ninterface AskAiScreenHeaderProps {\n disclaimerText: string;\n}\n\nexport interface Exchange {\n id: string;\n userMessage: AIMessage;\n assistantMessage: AIMessage | null;\n}\n\nfunction AskAiScreenDisclaimer({\n disclaimerText,\n}: AskAiScreenHeaderProps): JSX.Element {\n return (\n <p className=\"DocSearch-AskAiScreen-Disclaimer\">\n <SparklesIcon /> {disclaimerText}\n </p>\n );\n}\n\ninterface AskAiExchangeCardProps {\n exchange: Exchange;\n askAiError?: Error;\n isLastExchange: boolean;\n loadingStatus: UseChatHelpers<AIMessage>['status'];\n onSearchQueryClick: (query: string) => void;\n translations: AskAiScreenTranslations;\n tools: ToolCalls;\n conversations: StoredSearchPlugin<StoredAskAiState>;\n onFeedback?: OnAskAiFeedback;\n memoryEnabled?: boolean;\n onSelectPromptSuggestion: (prompt: string) => void;\n}\n\nfunction AskAiExchangeCard({\n exchange,\n askAiError,\n isLastExchange,\n loadingStatus,\n onSearchQueryClick,\n translations,\n tools,\n conversations,\n onFeedback,\n memoryEnabled,\n onSelectPromptSuggestion,\n}: AskAiExchangeCardProps): JSX.Element {\n const { userMessage, assistantMessage } = exchange;\n\n const {\n stoppedStreamingText = 'You stopped this response',\n errorTitleText = 'Chat error',\n relatedSourcesText,\n suggestedPromptsTitleText = 'Suggested prompts',\n } = translations;\n\n const toolCallTranslations = useMemo(\n () => toToolCallTranslations(translations),\n [translations]\n );\n\n const isThreadDepth = isThreadDepthError(askAiError);\n\n const assistantContent = useMemo(\n () => getMessageContent(assistantMessage),\n [assistantMessage]\n );\n const userContent = useMemo(\n () => getMessageContent(userMessage),\n [userMessage]\n );\n\n const urlsToDisplay = React.useMemo(\n () => extractLinksFromMessage(assistantMessage),\n [assistantMessage]\n );\n\n const displayParts = React.useMemo(() => {\n return groupConsecutiveToolResults(assistantMessage?.parts || []);\n }, [assistantMessage]);\n\n const promptSuggestions = useMemo(() => {\n if (!isLastExchange) return [];\n return getAgentPromptSuggestions(assistantMessage?.parts || []);\n }, [assistantMessage, isLastExchange]);\n\n const wasStopped =\n userMessage.metadata?.stopped || assistantMessage?.metadata?.stopped;\n\n const showActions =\n !wasStopped &&\n (!isLastExchange ||\n (isLastExchange &&\n loadingStatus === 'ready' &&\n Boolean(assistantMessage)));\n\n const isThinking =\n ['submitted', 'streaming'].includes(loadingStatus) &&\n isLastExchange &&\n !displayParts.some((part) => part.type !== 'step-start');\n\n const messageId = assistantMessage?.id || exchange.id;\n\n return (\n <div className=\"DocSearch-AskAiScreen-Response-Container\">\n <div className=\"DocSearch-AskAiScreen-Response\">\n <div className=\"DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--user\">\n <p className=\"DocSearch-AskAiScreen-Query\">\n {userContent?.text ?? ''}\n </p>\n </div>\n <div className=\"DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--assistant\">\n <div className=\"DocSearch-AskAiScreen-MessageContent\">\n {loadingStatus === 'error' &&\n askAiError &&\n isLastExchange &&\n !isThreadDepth && (\n <div className=\"DocSearch-AskAiScreen-Error\" role=\"alert\">\n <AlertIcon aria-hidden=\"true\" />\n <div className=\"DocSearch-AskAiScreen-Error-Content\">\n <h4 className=\"DocSearch-AskAiScreen-Error-Title\">\n {errorTitleText}\n </h4>\n <MemoizedMarkdown\n content={askAiError.message}\n copyButtonText=\"\"\n copyButtonCopiedText=\"\"\n isStreaming={false}\n />\n </div>\n </div>\n )}\n {isThinking && (\n <div\n className=\"DocSearch-AskAiScreen-MessageContent-Thinking\"\n role=\"status\"\n >\n <span className=\"DocSearch-shimmer\">\n {translations.thinkingText || 'Thinking...'}\n </span>\n <span className=\"DocSearch-AskAi-Thinking-Skeleton DocSearch-shimmer\" />\n <span className=\"DocSearch-AskAi-Thinking-Skeleton DocSearch-AskAi-Thinking-Skeleton--short DocSearch-shimmer\" />\n </div>\n )}\n {displayParts.map((part, idx) => {\n const index = idx;\n\n if (typeof part === 'string') {\n return (\n <MemoizedMarkdown\n key={index}\n content={part}\n copyButtonText={translations.copyButtonText || 'Copy'}\n copyButtonCopiedText={\n translations.copyButtonCopiedText || 'Copied!'\n }\n isStreaming={loadingStatus === 'streaming'}\n />\n );\n }\n\n if (isAIToolPart(part)) {\n return (\n <ToolCall\n key={index}\n translations={toolCallTranslations}\n part={part}\n tools={tools}\n memoryEnabled={memoryEnabled}\n onSearchQueryClick={onSearchQueryClick}\n />\n );\n }\n\n if (part.type === 'aggregated-tool-call') {\n return (\n <AggregatedSearchBlock\n key={index}\n queries={part.queries}\n translations={translations}\n onSearchQueryClick={onSearchQueryClick}\n />\n );\n }\n\n if (part.type === 'reasoning' && part.state === 'streaming') {\n return (\n <div\n key={index}\n className=\"DocSearch-AskAiScreen-MessageContent-Reasoning DocSearch-shimmer\"\n >\n <LoadingIcon className=\"DocSearch-AskAiScreen-SmallerLoadingIcon\" />\n <span className=\"DocSearch-shimmer\">Reasoning...</span>\n </div>\n );\n }\n\n if (part.type === 'text') {\n return (\n <MemoizedMarkdown\n key={index}\n content={part.text}\n copyButtonText={translations.copyButtonText || 'Copy'}\n copyButtonCopiedText={\n translations.copyButtonCopiedText || 'Copied!'\n }\n isStreaming={part.state === 'streaming'}\n />\n );\n }\n\n // fallback for unknown part type\n return null;\n })}\n </div>\n\n {wasStopped && (\n <p className=\"DocSearch-AskAiScreen-MessageContent-Stopped\">\n {stoppedStreamingText}\n </p>\n )}\n </div>\n <div className=\"DocSearch-AskAiScreen-Answer-Footer\">\n <SourcesPanel links={urlsToDisplay} titleText={relatedSourcesText} />\n <FeedbackActions\n id={messageId}\n showActions={showActions}\n latestAssistantMessageContent={assistantContent?.text || null}\n translations={translations}\n conversations={conversations}\n onFeedback={onFeedback}\n />\n </div>\n\n {promptSuggestions.length > 0 && (\n <ConversationPromptSuggestions\n title={suggestedPromptsTitleText}\n suggestions={promptSuggestions}\n onSelectPromptSuggestion={onSelectPromptSuggestion}\n />\n )}\n </div>\n </div>\n );\n}\n\nexport function AskAiScreen({\n translations = {},\n ...props\n}: AskAiScreenProps): JSX.Element | null {\n const {\n disclaimerText = 'Answers are generated with AI which can make mistakes.',\n threadDepthExceededMessage = 'This conversation is now closed to keep responses accurate.',\n startNewConversationButtonText = 'Start a new conversation',\n } = translations;\n\n const { messages, tools, askAiError, status, memoryEnabled } = props;\n\n // Check if there's a thread depth error\n const hasThreadDepthError = useMemo(() => {\n return status === 'error' && isThreadDepthError(askAiError);\n }, [status, askAiError]);\n\n // Group messages into exchanges (user + assistant pairs)\n const exchanges: Exchange[] = useMemo(() => {\n const grouped: Exchange[] = [];\n for (let i = 0; i < messages.length; i++) {\n if (messages[i].role === 'user') {\n const userMessage = messages[i];\n const assistantMessage =\n messages[i + 1]?.role === 'assistant' ? messages[i + 1] : null;\n grouped.push({ id: userMessage.id, userMessage, assistantMessage });\n if (assistantMessage) {\n i++;\n }\n }\n }\n\n // If there's a thread depth error, remove the last exchange (the one that triggered the error)\n // We only want to show successful exchanges\n if (hasThreadDepthError && grouped.length > 0) {\n // Check if the last exchange has no assistant message (failed to complete)\n const lastExchange = grouped[grouped.length - 1];\n if (!lastExchange.assistantMessage) {\n grouped.pop();\n }\n }\n\n return grouped;\n }, [messages, hasThreadDepthError]);\n\n const handleSearchQueryClick = (query: string): void => {\n props.onAskAiToggle(false);\n props.setQuery(query);\n };\n\n // Only show the thread depth error if we have assistant messages\n const showThreadDepthError =\n hasThreadDepthError && messages.some((m) => m.role === 'assistant');\n\n return (\n <div className=\"DocSearch-AskAiScreen DocSearch-AskAiScreen-Container\">\n {/* Thread Depth Error */}\n {showThreadDepthError && (\n <div className=\"DocSearch-AskAiScreen-MessageContent DocSearch-AskAiScreen-Error DocSearch-AskAiScreen-Error--ThreadDepth\">\n <div className=\"DocSearch-AskAiScreen-Error-Content\">\n <p>\n {threadDepthExceededMessage}{' '}\n <button\n type=\"button\"\n className=\"DocSearch-ThreadDepthError-Link\"\n onClick={props.onNewConversation}\n >\n {startNewConversationButtonText}\n </button>{' '}\n to continue.\n </p>\n </div>\n </div>\n )}\n\n <AskAiScreenDisclaimer disclaimerText={disclaimerText} />\n\n <div className=\"DocSearch-AskAiScreen-Body\">\n <div className=\"DocSearch-AskAiScreen-ExchangesList\">\n {exchanges\n .slice()\n .reverse()\n .map((exchange, index) => (\n <AskAiExchangeCard\n key={exchange.id}\n exchange={exchange}\n askAiError={props.askAiError}\n isLastExchange={index === 0}\n loadingStatus={props.status}\n translations={translations}\n tools={tools}\n conversations={props.conversations}\n memoryEnabled={memoryEnabled}\n onSearchQueryClick={handleSearchQueryClick}\n onFeedback={props.onFeedback}\n onSelectPromptSuggestion={props.onSelectPromptSuggestion}\n />\n ))}\n </div>\n </div>\n </div>\n );\n}\n","import React, { type JSX } from 'react';\n\nimport type { AskAiScreenStateProps } from '../../AskAiScreenState';\nimport { CloseIcon, MessageIcon } from '../../icons';\nimport { Results } from '../../Results';\nimport type { InternalDocSearchHit } from '../../types';\nimport { getCollection } from '../../utils';\n\nexport type RecentConversationsResultsTranslations = Partial<{\n recentConversationsTitle: string;\n removeRecentConversationButtonTitle: string;\n}>;\n\ntype RecentConversationsResultsProps = Omit<\n AskAiScreenStateProps<InternalDocSearchHit>,\n 'translations'\n> & {\n translations?: RecentConversationsResultsTranslations;\n};\n\nexport function RecentConversationsResults({\n translations = {},\n ...props\n}: RecentConversationsResultsProps): JSX.Element | null {\n const {\n recentConversationsTitle = 'Resume AI conversations',\n removeRecentConversationButtonTitle = 'Remove this conversation from history',\n } = translations;\n const recentConversations = getCollection(props.state, 'recentConversations');\n\n if (!recentConversations) {\n return null;\n }\n\n return (\n <Results\n {...props}\n title={recentConversationsTitle}\n collection={recentConversations}\n renderIcon={() => (\n <div className=\"DocSearch-Hit-icon DocSearch-Hit-icon--small\">\n <MessageIcon />\n </div>\n )}\n renderAction={({ item }) => (\n <div className=\"DocSearch-Hit-action\">\n <button\n className=\"DocSearch-Hit-action-button\"\n title={removeRecentConversationButtonTitle}\n type=\"submit\"\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n props.conversations.remove(item);\n props.refresh();\n }}\n >\n <CloseIcon />\n </button>\n </div>\n )}\n />\n );\n}\n","import React, { type JSX } from 'react';\n\nimport type { AskAiScreenStateProps } from '../AskAiScreenState';\nimport type { InternalDocSearchHit } from '../types';\n\nimport type { RecentConversationsResultsTranslations } from './ui/RecentConversationsResults';\nimport { RecentConversationsResults } from './ui/RecentConversationsResults';\nimport type { StoredSearchesSectionsTranslations } from './ui/StoredSearchesSections';\nimport { StoredSearchesSections } from './ui/StoredSearchesSections';\n\nexport type AskAiStartScreenTranslations =\n RecentConversationsResultsTranslations & StoredSearchesSectionsTranslations;\n\ntype AskAiStartScreenProps = Omit<\n AskAiScreenStateProps<InternalDocSearchHit>,\n 'translations'\n> & {\n hasCollections: boolean;\n translations?: AskAiStartScreenTranslations;\n};\n\nexport function AskAiStartScreen({\n translations = {},\n ...props\n}: AskAiStartScreenProps): JSX.Element | null {\n return (\n <div className=\"DocSearch-Dropdown-Container\">\n <RecentConversationsResults {...props} translations={translations} />\n <StoredSearchesSections {...props} translations={translations} />\n </div>\n );\n}\n","import type { JSX } from 'react';\nimport React from 'react';\n\nimport type { AskAiScreenStateProps } from './AskAiScreenState';\nimport { CloseIcon, SparklesIcon } from './icons';\nimport { Results } from './Results';\nimport type { ResultsScreenTranslations } from './ResultsScreen';\nimport type { InternalDocSearchHit } from './types';\nimport { getCollection } from './utils';\n\ntype ConversationHistoryScreenProps = Omit<\n AskAiScreenStateProps<InternalDocSearchHit>,\n 'translations'\n> & {\n translations?: ResultsScreenTranslations;\n};\n\nexport function ConversationHistoryScreen({\n onAskAiToggle,\n ...props\n}: ConversationHistoryScreenProps): JSX.Element | null {\n const collection = React.useMemo(\n () => getCollection(props.state, 'recentConversations'),\n [props.state]\n );\n\n React.useEffect(() => {\n if (!collection || collection.items.length === 0) {\n onAskAiToggle(true);\n }\n }, [collection, onAskAiToggle]);\n\n if (!collection) {\n return null;\n }\n\n return (\n <div className=\"DocSearch-Dropdown-Container DocSearch-Conversation-History\">\n <Results\n {...props}\n key={collection.source.sourceId}\n title=\"\"\n translations={props.translations}\n collection={collection}\n renderIcon={() => (\n <div className=\"DocSearch-Hit-icon\">\n <SparklesIcon />\n </div>\n )}\n renderAction={({ item }) => (\n <div className=\"DocSearch-Hit-action\">\n <button\n type=\"button\"\n className=\"DocSearch-Hit-action-button\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n props.conversations.remove(item);\n props.refresh();\n }}\n >\n <CloseIcon />\n </button>\n </div>\n )}\n />\n </div>\n );\n}\n","import React, { type JSX } from 'react';\n\nimport type { SuggestedQuestionHit } from './types';\n\nexport type NewConversationTranslations = Partial<{\n newConversationTitle: string;\n newConversationDescription: string;\n}>;\n\ninterface NewConversationProps {\n suggestedQuestions?: SuggestedQuestionHit[];\n selectSuggestedQuestion: (question: SuggestedQuestionHit) => void;\n translations?: NewConversationTranslations;\n}\n\nexport function NewConversationScreen({\n translations = {},\n suggestedQuestions = [],\n selectSuggestedQuestion,\n}: NewConversationProps): JSX.Element {\n const {\n newConversationTitle = 'How can I help you today?',\n newConversationDescription = 'I search through your documentation to help you find setup guides, feature details and troubleshooting tips, fast.',\n } = translations;\n\n return (\n <div className=\"DocSearch-NewConversationScreen\">\n <h3 className=\"DocSearch-NewConversationScreen-Title\">\n {newConversationTitle}\n </h3>\n <p className=\"DocSearch-NewConversationScreen-Description\">\n {newConversationDescription}\n </p>\n\n <div className=\"DocSearch-NewConversationScreen-SuggestedQuestions\">\n {suggestedQuestions.map((question) => (\n <button\n key={question.objectID}\n type=\"button\"\n className=\"DocSearch-NewConversationScreen-SuggestedQuestion\"\n onClick={() => selectSuggestedQuestion(question)}\n >\n {question.question}\n </button>\n ))}\n </div>\n </div>\n );\n}\n","import type { UseChatHelpers } from '@ai-sdk/react';\nimport type {\n AutocompleteApi,\n AutocompleteState,\n BaseItem,\n} from '@algolia/autocomplete-core';\nimport type { JSX } from 'react';\nimport React from 'react';\n\nimport type { AskAiScreenTranslations } from './AskAiScreen';\nimport { AskAiScreen } from './AskAiScreen';\nimport type { AskAiStartScreenTranslations } from './components/AskAiStartScreen';\nimport { AskAiStartScreen } from './components/AskAiStartScreen';\nimport { ConversationHistoryScreen } from './ConversationHistoryScreen';\nimport type { DocSearchProps } from './DocSearch';\nimport type { ErrorScreenTranslations } from './ErrorScreen';\nimport { ErrorScreen } from './ErrorScreen';\nimport type { NewConversationTranslations } from './NewConversationScreen';\nimport { NewConversationScreen } from './NewConversationScreen';\nimport type { NoResultsScreenTranslations } from './NoResultsScreen';\nimport { NoResultsScreen } from './NoResultsScreen';\nimport type { ResultsScreenTranslations } from './ResultsScreen';\nimport { ResultsScreen } from './ResultsScreen';\nimport type { StoredSearchPlugin } from './stored-searches';\nimport type {\n InternalDocSearchHit,\n OnAskAiFeedback,\n StoredAskAiState,\n StoredDocSearchHit,\n SuggestedQuestionHit,\n} from './types';\nimport type { AIMessage, AskAiState, ToolCalls } from './types/AskiAi';\n\nexport type AskAiScreenStateTranslations = Partial<{\n errorScreen: ErrorScreenTranslations;\n startScreen: AskAiStartScreenTranslations;\n noResultsScreen: NoResultsScreenTranslations;\n resultsScreen: ResultsScreenTranslations;\n askAiScreen: AskAiScreenTranslations;\n newConversation: NewConversationTranslations;\n}>;\n\nexport interface AskAiScreenStateProps<\n TItem extends BaseItem,\n> extends AutocompleteApi<\n TItem,\n React.FormEvent,\n React.MouseEvent,\n React.KeyboardEvent\n> {\n state: AutocompleteState<TItem>;\n recentSearches: StoredSearchPlugin<StoredDocSearchHit>;\n favoriteSearches: StoredSearchPlugin<StoredDocSearchHit>;\n conversations: StoredSearchPlugin<StoredAskAiState>;\n onItemClick: (\n item: InternalDocSearchHit,\n event: KeyboardEvent | MouseEvent\n ) => void;\n onAskAiToggle: (toggle: boolean) => void;\n isAskAiActive: boolean;\n canHandleAskAi: boolean;\n inputRef: React.MutableRefObject<HTMLInputElement | null>;\n hitComponent: DocSearchProps['hitComponent'];\n indexName: DocSearchProps['indexName'];\n messages: UseChatHelpers<AIMessage>['messages'];\n tools: ToolCalls;\n status: UseChatHelpers<AIMessage>['status'];\n askAiError?: Error;\n disableUserPersonalization: boolean;\n resultsFooterComponent: DocSearchProps['resultsFooterComponent'];\n translations: AskAiScreenStateTranslations;\n getMissingResultsUrl?: DocSearchProps['getMissingResultsUrl'];\n hasCollections: boolean;\n onFeedback?: OnAskAiFeedback;\n askAiState: AskAiState;\n selectAskAiQuestion: (toggle: boolean, query: string) => void;\n suggestedQuestions: SuggestedQuestionHit[];\n selectSuggestedQuestion: (question: SuggestedQuestionHit) => void;\n onNewConversation: () => void;\n memoryEnabled?: boolean;\n resultBadgeKey?: string;\n}\n\nexport const AskAiScreenState = React.memo(\n ({\n translations = {},\n selectAskAiQuestion,\n ...props\n }: AskAiScreenStateProps<InternalDocSearchHit>): JSX.Element => {\n const handleSelectPromptSuggestion = React.useCallback(\n (prompt: string) => {\n selectAskAiQuestion(true, prompt);\n },\n [selectAskAiQuestion]\n );\n\n if (\n props.canHandleAskAi &&\n props.isAskAiActive &&\n props.askAiState === 'conversation-history'\n ) {\n return (\n <ConversationHistoryScreen\n selectAskAiQuestion={selectAskAiQuestion}\n {...props}\n />\n );\n }\n\n if (\n props.canHandleAskAi &&\n props.isAskAiActive &&\n props.askAiState === 'new-conversation'\n ) {\n return (\n <NewConversationScreen\n translations={translations?.newConversation}\n selectSuggestedQuestion={props.selectSuggestedQuestion}\n suggestedQuestions={props.suggestedQuestions}\n />\n );\n }\n\n if (props.isAskAiActive && props.canHandleAskAi) {\n return (\n <AskAiScreen\n {...props}\n messages={props.messages}\n tools={props.tools}\n status={props.status}\n askAiError={props.askAiError}\n translations={translations?.askAiScreen}\n memoryEnabled={props.memoryEnabled}\n selectAskAiQuestion={selectAskAiQuestion}\n onSelectPromptSuggestion={handleSelectPromptSuggestion}\n />\n );\n }\n\n if (props.state?.status === 'error') {\n return <ErrorScreen translations={translations?.errorScreen} />;\n }\n\n if (!props.state.query) {\n return (\n <AskAiStartScreen\n {...props}\n hasCollections={props.hasCollections}\n translations={translations?.startScreen}\n selectAskAiQuestion={selectAskAiQuestion}\n />\n );\n }\n\n if (!props.hasCollections && !props.canHandleAskAi) {\n return (\n <NoResultsScreen\n {...props}\n translations={translations?.noResultsScreen}\n />\n );\n }\n\n return (\n <>\n <ResultsScreen {...props} translations={translations?.resultsScreen} />\n {props.canHandleAskAi &&\n !props.hasCollections && (\n // if there's one collection it is the ask ai action, show the no results screen\n <NoResultsScreen\n {...props}\n translations={translations?.noResultsScreen}\n />\n )}\n </>\n );\n },\n function areEqual(_prevProps, nextProps) {\n // We don't update the screen when Autocomplete is loading or stalled to\n // avoid UI flashes:\n // - Empty screen → Results screen\n // - NoResults screen → NoResults screen with another query\n return (\n nextProps.state.status === 'loading' ||\n nextProps.state.status === 'stalled'\n );\n }\n);\n","import React from 'react';\nimport type { JSX } from 'react';\n\ntype ModalHeadingProps = {\n heading: string;\n shimmer?: boolean;\n};\n\nexport function ModalHeading({\n heading,\n shimmer = false,\n}: ModalHeadingProps): JSX.Element {\n return (\n <span\n className={`DocSearch-Modal-heading${shimmer ? ' DocSearch-shimmer' : ''}`}\n >\n {heading}\n </span>\n );\n}\n","import type { UseChatHelpers } from '@ai-sdk/react';\nimport type {\n AutocompleteApi,\n AutocompleteState,\n} from '@algolia/autocomplete-core';\nimport React, { type JSX, type RefObject } from 'react';\n\nimport {\n ConversationHistoryIcon,\n MoreVerticalIcon,\n NewConversationIcon,\n StopIcon,\n BackIcon,\n} from '../icons';\nimport { Menu } from '../Menu';\nimport { ModalHeading } from '../ModalHeading';\nimport type { InternalDocSearchHit } from '../types';\nimport type { AIMessage, AskAiState } from '../types/AskiAi';\nimport { getCollection } from '../utils';\n\nimport { SearchBoxForm } from './ui/SearchBoxForm';\n\nexport type AskAiSearchBoxTranslations = Partial<{\n clearButtonTitle: string;\n clearButtonAriaLabel: string;\n closeButtonText: string;\n closeButtonAriaLabel: string;\n placeholderText: string;\n placeholderTextAskAi: string;\n placeholderTextAskAiStreaming: string;\n enterKeyHint: string;\n enterKeyHintAskAi: string;\n searchInputLabel: string;\n backToKeywordSearchButtonText: string;\n backToKeywordSearchButtonAriaLabel: string;\n newConversationPlaceholder: string;\n conversationHistoryTitle: string;\n startNewConversationText: string;\n viewConversationHistoryText: string;\n threadDepthErrorPlaceholder: string;\n}>;\n\ninterface AskAiSearchBoxProps extends AutocompleteApi<\n InternalDocSearchHit,\n React.FormEvent,\n React.MouseEvent,\n React.KeyboardEvent\n> {\n state: AutocompleteState<InternalDocSearchHit>;\n autoFocus: boolean;\n inputRef: RefObject<HTMLInputElement | null>;\n onClose: () => void;\n onAskAiToggle: (toggle: boolean) => void;\n onAskAgain: (query: string) => void;\n onStopAskAiStreaming: () => Promise<void>;\n placeholder: string;\n isAskAiActive: boolean;\n askAiStatus: UseChatHelpers<AIMessage>['status'];\n askAiError?: Error;\n isFromSelection: boolean;\n translations?: AskAiSearchBoxTranslations;\n askAiState: AskAiState;\n setAskAiState: (state: AskAiState) => void;\n onNewConversation: () => void;\n onViewConversationHistory: () => void;\n isThreadDepthError?: boolean;\n}\n\nexport function AskAiSearchBox({\n translations = {},\n askAiState,\n onAskAiToggle,\n setAskAiState,\n ...props\n}: AskAiSearchBoxProps): JSX.Element {\n const {\n clearButtonTitle = 'Clear',\n clearButtonAriaLabel = 'Clear the query',\n closeButtonText = 'Close',\n closeButtonAriaLabel = 'Close',\n searchInputLabel = 'Search',\n backToKeywordSearchButtonText = 'Back to keyword search',\n backToKeywordSearchButtonAriaLabel = 'Back to keyword search',\n placeholderTextAskAiStreaming = 'Answering...',\n newConversationPlaceholder = 'Ask a question',\n conversationHistoryTitle = 'My conversation history',\n startNewConversationText = 'Start a new conversation',\n viewConversationHistoryText = 'Conversation history',\n threadDepthErrorPlaceholder = 'Conversation limit reached',\n } = translations;\n\n const hasRecentConversations = React.useMemo(() => {\n const askAiSource = getCollection(props.state, 'recentConversations');\n\n if (!askAiSource) {\n return false;\n }\n\n return askAiSource.items.length > 0;\n }, [props.state]);\n\n const baseInputProps = props.getInputProps({\n inputElement: props.inputRef.current!,\n autoFocus: props.autoFocus,\n });\n const blockedKeys = new Set(['ArrowUp', 'ArrowDown', 'Enter']);\n const origOnKeyDown = baseInputProps.onKeyDown;\n const origOnChange = baseInputProps.onChange;\n const isAskAiStreaming =\n props.askAiStatus === 'streaming' || props.askAiStatus === 'submitted';\n const renderMoreOptions =\n props.isAskAiActive && askAiState !== 'conversation-history';\n\n // Use the thread depth error state passed from parent\n const isThreadDepthError = props.isThreadDepthError || false;\n let searchPlaceholder = props.placeholder;\n\n if (askAiState === 'new-conversation') {\n searchPlaceholder = newConversationPlaceholder;\n }\n\n // Override placeholder when thread depth error occurs (only in Ask AI mode)\n if (isThreadDepthError && props.isAskAiActive) {\n searchPlaceholder = threadDepthErrorPlaceholder;\n }\n\n let heading: string | null = null;\n\n if (isAskAiStreaming) {\n heading = placeholderTextAskAiStreaming;\n }\n\n if (askAiState === 'conversation-history') {\n heading = conversationHistoryTitle;\n }\n\n // when returning to another status than streaming or submitted, we focus on the input\n React.useEffect(() => {\n if (\n props.askAiStatus !== 'streaming' &&\n props.askAiStatus !== 'submitted' &&\n props.inputRef.current\n ) {\n props.inputRef.current.focus();\n }\n }, [props.askAiStatus, props.inputRef]);\n\n /**\n * We need to block the default behavior of the input when Ask AI is active.\n * This is because the input is used to ask another question when the user\n * presses enter.\n *\n * Learn more on default autocomplete behavior:\n * https://github.com/algolia/autocomplete/blob/next/packages/autocomplete-core/src/getDefaultProps.ts.\n */\n const inputProps = {\n enterKeyHint: props.isAskAiActive\n ? ('enter' as const)\n : ('search' as const),\n onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>): void => {\n let askAiHandled = false;\n // block these up, down, enter listeners when Ask AI is active\n if (props.isAskAiActive && blockedKeys.has(e.key)) {\n // enter key asks another question\n if (e.key === 'Enter' && !isAskAiStreaming && props.state.query) {\n props.onAskAgain(props.state.query);\n }\n\n askAiHandled = true;\n }\n\n if (askAiHandled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n\n origOnKeyDown?.(e);\n },\n onChange: (e: React.ChangeEvent<HTMLInputElement>): void => {\n if (props.isAskAiActive) {\n props.setQuery(e.currentTarget.value);\n // block search when Ask AI is active\n // we don't want to trigger the search when the user types\n // we already know they are asking a question\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n origOnChange?.(e);\n },\n disabled: isAskAiStreaming || (isThreadDepthError && props.isAskAiActive),\n };\n\n const handleAskAiBackClick = React.useCallback((): void => {\n // If there's a thread depth error, start a new conversation instead of exiting\n if (isThreadDepthError) {\n props.onNewConversation();\n return;\n }\n\n if (askAiState === 'conversation-history') {\n onAskAiToggle(true);\n setAskAiState('initial');\n return;\n }\n\n onAskAiToggle(false);\n }, [askAiState, isThreadDepthError, onAskAiToggle, setAskAiState, props]);\n\n const leadingElement = props.isAskAiActive ? (\n <button\n type=\"button\"\n tabIndex={0}\n className=\"DocSearch-Action DocSearch-AskAi-Return\"\n title={backToKeywordSearchButtonText}\n aria-label={backToKeywordSearchButtonAriaLabel}\n onClick={handleAskAiBackClick}\n >\n <BackIcon />\n </button>\n ) : undefined;\n const inputOverlay = heading ? (\n <ModalHeading heading={heading} shimmer={isAskAiStreaming} />\n ) : null;\n const actionsBeforeClose = (\n <>\n {!props.isAskAiActive && (\n <>\n <button\n className=\"DocSearch-Clear\"\n type=\"reset\"\n aria-label={clearButtonAriaLabel}\n hidden={!props.state.query}\n tabIndex={props.state.query ? 0 : -1}\n aria-hidden={!props.state.query ? 'true' : 'false'}\n >\n {clearButtonTitle}\n </button>\n\n {props.state.query && <div className=\"DocSearch-Divider\" />}\n </>\n )}\n\n {isAskAiStreaming && (\n <>\n <button\n type=\"button\"\n className=\"DocSearch-Action DocSearch-StopStreaming\"\n onClick={props.onStopAskAiStreaming}\n >\n <StopIcon />\n </button>\n\n <div className=\"DocSearch-Divider\" />\n </>\n )}\n\n {renderMoreOptions && (\n <>\n <Menu>\n <Menu.Trigger className=\"DocSearch-Action\">\n <MoreVerticalIcon />\n </Menu.Trigger>\n <Menu.Content>\n <Menu.Item onClick={props.onNewConversation}>\n <NewConversationIcon />\n {startNewConversationText}\n </Menu.Item>\n {hasRecentConversations && (\n <Menu.Item onClick={props.onViewConversationHistory}>\n <ConversationHistoryIcon />\n {viewConversationHistoryText}\n </Menu.Item>\n )}\n </Menu.Content>\n </Menu>\n\n <div className=\"DocSearch-Divider\" />\n </>\n )}\n </>\n );\n\n return (\n <SearchBoxForm\n {...props}\n placeholder={searchPlaceholder}\n clearButtonTitle={clearButtonTitle}\n clearButtonAriaLabel={clearButtonAriaLabel}\n closeButtonText={closeButtonText}\n closeButtonAriaLabel={closeButtonAriaLabel}\n searchInputLabel={searchInputLabel}\n leadingElement={leadingElement}\n inputOverlay={inputOverlay}\n hideInput={Boolean(heading)}\n actionsBeforeClose={actionsBeforeClose}\n inputProps={inputProps}\n />\n );\n}\n","import type { AutocompleteSource } from '@algolia/autocomplete-core';\nimport type { SearchResponse } from 'algoliasearch/lite';\n\nimport type { DocSearchTransformClient } from '../DocSearch';\nimport type { PromptSuggestions } from '../DocSearchAI';\nimport type { InternalDocSearchHit } from '../types';\nimport type { AIMessage, PromptSuggestion } from '../types/AskiAi';\n\nimport { SOURCE_IDS } from './collections';\n\nconst MAX_RECENT_CONVERSATIONS_DISPLAYED = 3;\n\nconst EMPTY_RESULT_CONTENT = {\n value: '',\n matchLevel: 'none',\n matchedWords: [],\n} satisfies InternalDocSearchHit['_highlightResult']['content'];\nconst EMPTY_HIERARCHY_HIGHLIGHT_RESULT = {\n lvl0: EMPTY_RESULT_CONTENT,\n lvl1: EMPTY_RESULT_CONTENT,\n lvl2: EMPTY_RESULT_CONTENT,\n lvl3: EMPTY_RESULT_CONTENT,\n lvl4: EMPTY_RESULT_CONTENT,\n lvl5: EMPTY_RESULT_CONTENT,\n lvl6: EMPTY_RESULT_CONTENT,\n} satisfies InternalDocSearchHit['_highlightResult']['hierarchy'];\nconst EMPTY_HIGHLIGHT_RESULT: InternalDocSearchHit['_highlightResult'] = {\n content: EMPTY_RESULT_CONTENT,\n hierarchy: EMPTY_HIERARCHY_HIGHLIGHT_RESULT,\n hierarchy_camel: [],\n};\nconst EMPTY_SNIPPET_RESULT: InternalDocSearchHit['_snippetResult'] = {\n content: EMPTY_RESULT_CONTENT,\n hierarchy: EMPTY_HIERARCHY_HIGHLIGHT_RESULT,\n hierarchy_camel: [],\n};\n\nexport function buildRecentConversationSources({\n conversations,\n disableUserPersonalization,\n setMessages,\n onAskAiToggle,\n}: {\n conversations: { getAll: () => unknown[] };\n disableUserPersonalization: boolean;\n setMessages: (messages: AIMessage[]) => void;\n onAskAiToggle: (toggle: boolean) => void;\n}): Array<\n AutocompleteSource<InternalDocSearchHit & { messages?: AIMessage[] }>\n> {\n return [\n {\n sourceId: SOURCE_IDS.recentConversations,\n getItems(): InternalDocSearchHit[] {\n if (disableUserPersonalization) {\n return [];\n }\n return (\n conversations.getAll() as unknown as InternalDocSearchHit[]\n ).slice(0, MAX_RECENT_CONVERSATIONS_DISPLAYED);\n },\n onSelect({ item }): void {\n if (item.messages) {\n setMessages(item.messages);\n onAskAiToggle(true);\n }\n },\n },\n ];\n}\n\nfunction createAskAiHit({\n query,\n objectID,\n lvl0,\n}: {\n query: string;\n objectID: string;\n lvl0: string;\n}): InternalDocSearchHit {\n return {\n type: 'askAI',\n query,\n url_without_anchor: '',\n objectID,\n content: null,\n url: '',\n anchor: null,\n hierarchy: {\n lvl0,\n lvl1: query,\n lvl2: null,\n lvl3: null,\n lvl4: null,\n lvl5: null,\n lvl6: null,\n },\n _highlightResult: EMPTY_HIGHLIGHT_RESULT,\n _snippetResult: EMPTY_SNIPPET_RESULT,\n __docsearch_parent: null,\n };\n}\n\nasync function getPromptSuggestions({\n query,\n indexName,\n searchClient,\n hitsPerPage = 3,\n}: {\n query: string;\n indexName: string;\n searchClient: DocSearchTransformClient;\n hitsPerPage?: number;\n}): Promise<InternalDocSearchHit[]> {\n try {\n const { results } = await searchClient.search<PromptSuggestion>({\n requests: [\n {\n query,\n indexName,\n hitsPerPage,\n attributesToRetrieve: ['prompt'],\n },\n ],\n });\n\n const res = results[0] as SearchResponse<PromptSuggestion>;\n\n return res.hits.map((hit) =>\n createAskAiHit({\n query: hit.prompt,\n objectID: hit.objectID,\n lvl0: 'Prompt Suggestions',\n })\n );\n // NOTE: Not checking the exception here and just returning empty array since this isn't the hot path\n } catch {\n return [];\n }\n}\n\nexport async function buildAskAiActionSources({\n query,\n handleSelectAskAiQuestion,\n promptSuggestionsOptions,\n searchClient,\n}: {\n query: string;\n handleSelectAskAiQuestion: (toggle: boolean, query: string) => void;\n promptSuggestionsOptions?: PromptSuggestions;\n searchClient: DocSearchTransformClient;\n}): Promise<Array<AutocompleteSource<InternalDocSearchHit>>> {\n const promptSuggestions = promptSuggestionsOptions\n ? await getPromptSuggestions({\n query,\n indexName: promptSuggestionsOptions.indexName,\n hitsPerPage: promptSuggestionsOptions.hitsPerPage,\n searchClient,\n })\n : [];\n\n return [\n {\n sourceId: SOURCE_IDS.askAI,\n getItems(): InternalDocSearchHit[] {\n return [\n createAskAiHit({ query, objectID: 'ask-ai-button', lvl0: 'Ask AI' }),\n ...promptSuggestions,\n ];\n },\n onSelect({ item }): void {\n if (item.type === 'askAI' && item.query) {\n handleSelectAskAiQuestion(true, item.query);\n }\n },\n },\n ];\n}\n","import { createAutocomplete } from '@algolia/autocomplete-core';\nimport type { InitialAskAiMessage, OnAskAiToggle } from '@docsearch/core';\nimport type { ChatRequestOptions } from 'ai';\nimport React, { type JSX } from 'react';\n\nimport type { AskAiScreenStateTranslations } from './AskAiScreenState';\nimport { AskAiScreenState } from './AskAiScreenState';\nimport type { AskAiSearchBoxTranslations } from './components/AskAiSearchBox';\nimport { AskAiSearchBox } from './components/AskAiSearchBox';\nimport type { FacetBarTranslations } from './components/FacetBar';\nimport { FacetBar } from './components/FacetBar';\nimport { ModalShell } from './components/ui/ModalShell';\nimport type { DocSearchAIProps } from './DocSearchAI';\nimport type { FooterTranslations } from './Footer';\nimport { Footer } from './Footer';\nimport { Hit } from './Hit';\nimport { useDocSearchFacets } from './hooks/useDocSearchFacets';\nimport { useSendItemClickEvent } from './hooks/useDocSearchInsights';\nimport { useInitialModalQuery } from './hooks/useInitialModalQuery';\nimport { useModalEnvironment } from './hooks/useModalEnvironment';\nimport { useModalRefs } from './hooks/useModalRefs';\nimport { useRefreshOnInitialQuery } from './hooks/useRefreshOnInitialQuery';\nimport { useSaveRecentSearch } from './hooks/useSaveRecentSearch';\nimport { useStoredDocSearches } from './hooks/useStoredDocSearches';\nimport type { NewConversationTranslations } from './NewConversationScreen';\nimport type {\n DocSearchState,\n InternalDocSearchHit,\n OnAskAiFeedback,\n StoredAskAiMessage,\n StoredAskAiState,\n SuggestedQuestionHit,\n} from './types';\nimport { type AskAiState } from './types/AskiAi';\nimport { useAskAi } from './useAskAi';\nimport { useSearchClient } from './useSearchClient';\nimport { useSuggestedQuestions } from './useSuggestedQuestions';\nimport {\n identity,\n isModifierEvent,\n noop,\n scrollTo as scrollToUtils,\n SOURCE_IDS,\n} from './utils';\nimport {\n buildDummyAskAiHit,\n isThreadDepthError,\n EMPTY_TOOLS,\n} from './utils/ai';\nimport {\n buildAskAiActionSources,\n buildRecentConversationSources,\n} from './utils/createAskAiSources';\nimport {\n buildNoQuerySources,\n buildQuerySources,\n type BuildQuerySourcesState,\n} from './utils/createDocSearchSources';\nimport { normalizeDocSearchIndexes } from './utils/normalizeDocSearchIndexes';\n\nexport type DocSearchAskAiModalTranslations = AskAiScreenStateTranslations &\n Partial<{\n searchBox: AskAiSearchBoxTranslations;\n newConversation: NewConversationTranslations;\n footer: FooterTranslations;\n facets: FacetBarTranslations;\n }>;\n\nexport type DocSearchAskAiModalProps = DocSearchAIProps & {\n initialScrollY: number;\n onAskAiToggle: OnAskAiToggle;\n onClose?: () => void;\n isAskAiActive?: boolean;\n translations?: DocSearchAskAiModalTranslations;\n isHybridModeSupported?: boolean;\n};\n\nexport function DocSearchAskAiModal({\n appId,\n apiKey,\n askAi,\n maxResultsPerGroup,\n theme,\n onClose = noop,\n transformItems = identity,\n hitComponent = Hit,\n resultsFooterComponent = (): JSX.Element | null => null,\n navigator,\n initialScrollY = 0,\n transformSearchClient = identity,\n disableUserPersonalization = false,\n initialQuery: initialQueryFromProp = '',\n translations = {},\n getMissingResultsUrl,\n insights = false,\n onAskAiToggle,\n interceptAskAiEvent,\n isAskAiActive = false,\n recentSearchesLimit = 7,\n recentSearchesWithFavoritesLimit = 4,\n indices = [],\n indexName,\n searchParameters,\n facets,\n isHybridModeSupported = false,\n ...props\n}: DocSearchAskAiModalProps): JSX.Element {\n const {\n footer: footerTranslations,\n searchBox: searchBoxTranslations,\n facets: facetBarTranslations,\n ...screenStateTranslations\n } = translations;\n const [state, setState] = React.useState<\n DocSearchState<InternalDocSearchHit>\n >({\n query: '',\n collections: [],\n completion: null,\n context: {},\n isOpen: false,\n activeItemId: null,\n status: 'idle',\n });\n\n // check if the instance is configured to handle ask ai\n const canHandleAskAi = Boolean(askAi);\n\n let placeholder =\n translations?.searchBox?.placeholderText ||\n props.placeholder ||\n 'Search docs';\n\n if (canHandleAskAi) {\n placeholder =\n translations?.searchBox?.placeholderText ||\n 'Search docs or ask AI a question';\n }\n\n if (isAskAiActive) {\n placeholder =\n translations?.searchBox?.placeholderTextAskAi ||\n 'Ask another question...';\n }\n\n const {\n containerRef,\n modalRef,\n formElementRef,\n dropdownRef,\n inputRef,\n snippetLength,\n } = useModalRefs();\n const { initialQuery, initialQueryFromSelection } =\n useInitialModalQuery(initialQueryFromProp);\n\n const searchClient = useSearchClient(appId, apiKey, transformSearchClient);\n\n const askAiConfig = typeof askAi === 'object' ? askAi : null;\n const askAiConfigurationId = askAiConfig\n ? askAiConfig.assistantId\n : (askAi as string);\n const askAiSearchParameters = askAiConfig?.searchParameters;\n const [askAiState, setAskAiState] = React.useState<AskAiState>('initial');\n const suggestedQuestions = useSuggestedQuestions({\n assistantId: askAiConfigurationId,\n searchClient,\n suggestedQuestionsEnabled: askAiConfig?.suggestedQuestions,\n });\n const memoryEnabled = askAiConfig?.memory?.enabled ?? false;\n const tools = askAiConfig?.tools ?? EMPTY_TOOLS;\n\n const indexes = React.useMemo(\n () =>\n normalizeDocSearchIndexes({\n indexName,\n indices,\n searchParameters,\n }),\n [indexName, indices, searchParameters]\n );\n const defaultIndexName = indexes[0].name;\n\n const autocompleteRef =\n React.useRef<\n ReturnType<\n typeof createAutocomplete<\n InternalDocSearchHit,\n React.FormEvent<HTMLFormElement>,\n React.MouseEvent,\n React.KeyboardEvent\n >\n >\n >(undefined);\n\n const {\n visibleFacets,\n facetSelections,\n facetSelectionsRef,\n handleFacetSelectionChange,\n clearFacetSelections,\n } = useDocSearchFacets({\n facets,\n indexes,\n searchClient,\n onSelectionsChange: () => autocompleteRef.current?.refresh(),\n });\n\n const { favoriteSearches, recentSearches } = useStoredDocSearches({\n defaultIndexName,\n recentSearchesLimit,\n recentSearchesWithFavoritesLimit,\n });\n\n const [stoppedStream, setStoppedStream] = React.useState(false);\n\n const {\n chatId,\n messages,\n status,\n setMessages,\n sendMessage,\n stopAskAiStreaming,\n askAiError,\n sendFeedback,\n conversations,\n startNewConversation,\n restoreConversation,\n } = useAskAi({\n assistantId: askAiConfigurationId,\n apiKey: askAiConfig?.apiKey || apiKey,\n appId: askAiConfig?.appId || appId,\n indexName: askAiConfig?.indexName || defaultIndexName,\n searchParameters: askAiSearchParameters,\n tools,\n memory: askAiConfig?.memory,\n indices: askAiConfig?.indices,\n });\n\n const prevStatus = React.useRef(status);\n React.useEffect(() => {\n if (disableUserPersonalization) {\n return;\n }\n // if we just transitioned from \"streaming\" → \"ready\", persist\n if (prevStatus.current === 'streaming' && status === 'ready') {\n // if we stopped the stream, store it on the most recent message\n if (stoppedStream && messages.at(-1)) {\n messages.at(-1)!.metadata = {\n stopped: true,\n };\n }\n\n for (const part of messages[0].parts) {\n if (part.type === 'text') {\n conversations.add(buildDummyAskAiHit(part.text, messages, chatId));\n }\n }\n }\n prevStatus.current = status;\n }, [\n status,\n messages,\n conversations,\n disableUserPersonalization,\n stoppedStream,\n chatId,\n ]);\n\n // Check if there's a thread depth error (AI-217)\n const hasThreadDepthError = React.useMemo(() => {\n return (\n status === 'error' && isThreadDepthError(askAiError as Error | undefined)\n );\n }, [status, askAiError]);\n\n const saveRecentSearch = useSaveRecentSearch({\n favoriteSearches,\n recentSearches,\n disableUserPersonalization,\n });\n const sendItemClickEvent = useSendItemClickEvent(state);\n\n const handleSelectAskAiQuestion = React.useCallback(\n (\n toggle: boolean,\n query: string,\n suggestedQuestion: SuggestedQuestionHit | undefined = undefined\n ) => {\n if (toggle) {\n const initialMessage: InitialAskAiMessage = {\n query,\n suggestedQuestionId: suggestedQuestion?.objectID,\n };\n\n if (interceptAskAiEvent?.(initialMessage)) {\n // Consumer handled it. Avoid *all* default Ask AI behavior.\n if (autocompleteRef.current) {\n autocompleteRef.current.setQuery('');\n }\n return;\n }\n }\n\n if (toggle && askAiState === 'new-conversation') {\n setAskAiState('initial');\n }\n\n onAskAiToggle(toggle, {\n query,\n suggestedQuestionId: suggestedQuestion?.objectID,\n });\n\n // If we're in hybrid mode, we don't need to send the message,\n // it will be handled by the Sidepanel.\n if (isHybridModeSupported) return;\n\n setStoppedStream(false);\n\n const messageOptions: ChatRequestOptions = {};\n\n if (suggestedQuestion) {\n messageOptions.body = {\n suggestedQuestionId: suggestedQuestion.objectID,\n };\n }\n\n sendMessage(\n {\n role: 'user',\n parts: [\n {\n type: 'text',\n text: query,\n },\n ],\n },\n messageOptions\n );\n\n if (dropdownRef.current) {\n // some test environments (like jsdom) don't implement element.scrollTo\n const el = dropdownRef.current;\n if (typeof (el as any).scrollTo === 'function') {\n el.scrollTo({ top: 0, behavior: 'smooth' });\n } else {\n // fallback for environments without scrollTo support\n el.scrollTop = 0;\n }\n }\n\n // clear the query\n if (autocompleteRef.current) {\n autocompleteRef.current.setQuery('');\n }\n },\n [\n askAiState,\n onAskAiToggle,\n isHybridModeSupported,\n sendMessage,\n dropdownRef,\n interceptAskAiEvent,\n ]\n );\n\n // feedback handler\n const handleFeedbackSubmit = React.useCallback<OnAskAiFeedback>(\n async (messageId, feedback): Promise<void> => {\n if (!askAiConfigurationId || !appId) return;\n await sendFeedback(messageId, feedback);\n },\n [askAiConfigurationId, appId, sendFeedback]\n );\n\n if (!autocompleteRef.current) {\n autocompleteRef.current = createAutocomplete({\n id: 'docsearch',\n defaultActiveItemId: 0,\n openOnFocus: true,\n initialState: {\n query: initialQuery,\n context: {\n searchSuggestions: [],\n },\n },\n insights: Boolean(insights),\n navigator,\n onStateChange(changes) {\n setState(changes.state);\n },\n async getSources({ query, state: sourcesState, setContext, setStatus }) {\n if (!query) {\n const noQuerySources = buildNoQuerySources({\n recentSearches,\n favoriteSearches,\n saveRecentSearch,\n onClose,\n disableUserPersonalization,\n });\n\n const recentConversationSource = canHandleAskAi\n ? buildRecentConversationSources({\n conversations,\n disableUserPersonalization,\n setMessages,\n onAskAiToggle,\n })\n : [];\n return [...recentConversationSource, ...noQuerySources];\n }\n\n const querySourcesState: BuildQuerySourcesState = {\n context: sourcesState.context,\n };\n\n const algoliaSourcesPromise = buildQuerySources({\n query,\n state: querySourcesState,\n setContext,\n setStatus,\n searchClient,\n indexes,\n snippetLength,\n insights: Boolean(insights),\n appId,\n apiKey,\n maxResultsPerGroup,\n transformItems,\n saveRecentSearch,\n onClose,\n facetSelections: facetSelectionsRef,\n });\n\n const askAiSourcesPromise = canHandleAskAi\n ? buildAskAiActionSources({\n query,\n handleSelectAskAiQuestion,\n promptSuggestionsOptions: askAiConfig?.promptSuggestions,\n searchClient,\n })\n : Promise.resolve([]);\n\n const [askAiSources, algoliaSources] = await Promise.all([\n askAiSourcesPromise,\n algoliaSourcesPromise,\n ]);\n\n // Combine Algolia results (once resolved) with the Ask AI source\n return [...askAiSources, ...algoliaSources];\n },\n });\n }\n\n const autocomplete = autocompleteRef.current;\n\n const { getEnvironmentProps, getRootProps, refresh } = autocomplete;\n\n useModalEnvironment({\n getEnvironmentProps,\n containerRef,\n dropdownRef,\n formElementRef,\n inputRef,\n initialScrollY,\n modalRef,\n snippetLength,\n theme,\n });\n\n React.useEffect(() => {\n if (dropdownRef.current && !isAskAiActive) {\n scrollToUtils(dropdownRef.current);\n }\n }, [state.query, isAskAiActive, dropdownRef]);\n\n useRefreshOnInitialQuery({ initialQuery, inputRef, refresh });\n\n const hasCurrentMessages = messages.length > 0;\n\n // Refresh the autocomplete results when ask ai is toggled off\n // helps return to the previous ac state and start screen\n React.useEffect(() => {\n if (!isAskAiActive) {\n autocomplete.refresh();\n\n if (hasCurrentMessages) {\n startNewConversation();\n }\n }\n }, [isAskAiActive, autocomplete, startNewConversation, hasCurrentMessages]);\n\n // Track external state in order to manage internal askAiState\n React.useEffect(() => {\n setAskAiState('initial');\n }, [isAskAiActive, setAskAiState]);\n\n const onStopAskAiStreaming = async (): Promise<void> => {\n setStoppedStream(true);\n\n await stopAskAiStreaming();\n };\n\n const handleNewConversation = (): void => {\n startNewConversation();\n setAskAiState('new-conversation');\n };\n\n const handleViewConversationHistory = (): void => {\n setAskAiState('conversation-history');\n };\n\n const selectSuggestedQuestion = (\n suggestedQuestion: SuggestedQuestionHit\n ): void => {\n handleSelectAskAiQuestion(\n true,\n suggestedQuestion.question,\n suggestedQuestion\n );\n };\n\n // hide the dropdown on idle and no collections\n let showDocsearchDropdown = true;\n const hasCollections = state.collections.some(\n (collection) =>\n collection.source.sourceId !== SOURCE_IDS.askAI &&\n collection.items.length > 0\n );\n if (\n state.status === 'idle' &&\n hasCollections === false &&\n state.query.length === 0 &&\n !isAskAiActive\n ) {\n showDocsearchDropdown = false;\n }\n\n return (\n <ModalShell\n state={state}\n containerRef={containerRef}\n modalRef={modalRef}\n formElementRef={formElementRef}\n dropdownRef={dropdownRef}\n getRootProps={getRootProps}\n showDropdown={showDocsearchDropdown}\n searchBox={\n <AskAiSearchBox\n {...autocomplete}\n state={state}\n placeholder={placeholder || 'Search docs'}\n autoFocus={initialQuery.length === 0}\n inputRef={inputRef}\n isFromSelection={\n Boolean(initialQuery) && initialQuery === initialQueryFromSelection\n }\n translations={searchBoxTranslations}\n isAskAiActive={isAskAiActive}\n askAiStatus={status}\n askAiError={askAiError}\n askAiState={askAiState}\n setAskAiState={setAskAiState}\n isThreadDepthError={\n hasThreadDepthError && askAiState !== 'new-conversation'\n }\n onClose={onClose}\n onAskAiToggle={onAskAiToggle}\n onAskAgain={(query) => {\n handleSelectAskAiQuestion(true, query);\n }}\n onStopAskAiStreaming={onStopAskAiStreaming}\n onNewConversation={handleNewConversation}\n onViewConversationHistory={handleViewConversationHistory}\n />\n }\n filterBar={\n !isAskAiActive && state.query !== '' ? (\n <FacetBar\n facets={visibleFacets}\n selections={facetSelections}\n translations={facetBarTranslations}\n clearSelections={clearFacetSelections}\n onSelectionChange={handleFacetSelectionChange}\n />\n ) : null\n }\n screenState={\n <AskAiScreenState\n {...autocomplete}\n indexName={defaultIndexName}\n state={state}\n hitComponent={hitComponent}\n resultsFooterComponent={resultsFooterComponent}\n disableUserPersonalization={disableUserPersonalization}\n recentSearches={recentSearches}\n favoriteSearches={favoriteSearches}\n conversations={conversations}\n inputRef={inputRef}\n translations={screenStateTranslations}\n getMissingResultsUrl={getMissingResultsUrl}\n isAskAiActive={isAskAiActive}\n canHandleAskAi={canHandleAskAi}\n messages={messages}\n tools={tools}\n askAiError={askAiError}\n status={status}\n hasCollections={hasCollections}\n askAiState={askAiState}\n selectAskAiQuestion={handleSelectAskAiQuestion}\n suggestedQuestions={suggestedQuestions}\n selectSuggestedQuestion={selectSuggestedQuestion}\n memoryEnabled={memoryEnabled}\n resultBadgeKey={props.resultBadgeKey}\n onAskAiToggle={onAskAiToggle}\n onNewConversation={handleNewConversation}\n onItemClick={(item, event) => {\n if (item.type === 'askAI' && item.query) {\n if (item.anchor === 'stored' && 'messages' in item) {\n const hitMessages = item.messages as StoredAskAiMessage[];\n restoreConversation(\n hitMessages,\n (item as StoredAskAiState).chatId\n );\n const initialMessage: InitialAskAiMessage = {\n query: item.query,\n messageId: hitMessages[0].id,\n };\n\n if (interceptAskAiEvent?.(initialMessage)) {\n if (autocompleteRef.current) {\n autocompleteRef.current.setQuery('');\n }\n event.preventDefault();\n return;\n }\n\n onAskAiToggle(true, initialMessage);\n } else {\n handleSelectAskAiQuestion(true, item.query);\n }\n setAskAiState('initial');\n event.preventDefault();\n return;\n }\n\n sendItemClickEvent(item);\n saveRecentSearch(item);\n if (!isModifierEvent(event)) {\n onClose();\n }\n }}\n onFeedback={handleFeedbackSubmit}\n />\n }\n footer={\n <Footer\n translations={footerTranslations}\n isAskAiActive={isAskAiActive}\n />\n }\n onClose={onClose}\n />\n );\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import "./index-Dl8FMlR5.js";
1
+ import "./index-Bqqv4HmN.js";
2
2
  import { t as DocSearchTheme$1 } from "./DocSearchTheme-DvL4mf0D.js";
3
3
  import { DocSearchModalShortcuts } from "@docsearch/core";
4
4
  import React from "react";
@@ -15,4 +15,4 @@ type DocSearchButtonProps = React.ComponentProps<'button'> & {
15
15
  declare const DocSearchButton: React.ForwardRefExoticComponent<Omit<DocSearchButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
16
16
  //#endregion
17
17
  export { DocSearchButton as n, DocSearchButtonProps as r, ButtonTranslations as t };
18
- //# sourceMappingURL=DocSearchButton-CRlNPf5k.d.ts.map
18
+ //# sourceMappingURL=DocSearchButton-CZM_jACU.d.ts.map
@@ -1,2 +1,2 @@
1
- import { n as DocSearchAskAiModalProps, r as DocSearchAskAiModalTranslations, t as DocSearchAskAiModal } from "./DocSearchAskAiModal-BwbMrrHv.js";
1
+ import { n as DocSearchAskAiModalProps, r as DocSearchAskAiModalTranslations, t as DocSearchAskAiModal } from "./DocSearchAskAiModal-B7vpLudE.js";
2
2
  export { DocSearchAskAiModal, DocSearchAskAiModalProps, DocSearchAskAiModalTranslations };
@@ -1,3 +1,3 @@
1
- import { t as DocSearchAskAiModal } from "./DocSearchAskAiModal-CCrk6YLb.js";
1
+ import { t as DocSearchAskAiModal } from "./DocSearchAskAiModal-KaA6fBV4.js";
2
2
 
3
3
  export { DocSearchAskAiModal };
@@ -1,2 +1,2 @@
1
- import { n as DocSearchButton, r as DocSearchButtonProps, t as ButtonTranslations } from "./DocSearchButton-CRlNPf5k.js";
1
+ import { n as DocSearchButton, r as DocSearchButtonProps, t as ButtonTranslations } from "./DocSearchButton-CZM_jACU.js";
2
2
  export { ButtonTranslations, DocSearchButton, DocSearchButtonProps };
@@ -1,5 +1,5 @@
1
- import { o as ToolCalls } from "./index-Dl8FMlR5.js";
2
- import { a as DocSearchProps } from "./DocSearch-Dq5Utfyb.js";
1
+ import { o as ToolCalls } from "./index-Bqqv4HmN.js";
2
+ import { a as DocSearchProps } from "./DocSearch-HJsNvtZr.js";
3
3
  import { DocSearchRef, InitialAskAiMessage } from "@docsearch/core";
4
4
  import React, { JSX } from "react";
5
5
  import { SearchParamsObject } from "algoliasearch/lite";
@@ -1,6 +1,6 @@
1
1
  import { t as _objectSpread2 } from "./objectSpread2-BNmiQYyW.js";
2
2
  import { t as DocSearchButton } from "./DocSearchButton-CaxxOzQU.js";
3
- import { t as DocSearchAskAiModal } from "./DocSearchAskAiModal-CCrk6YLb.js";
3
+ import { t as DocSearchAskAiModal } from "./DocSearchAskAiModal-KaA6fBV4.js";
4
4
  import { DocSearch, useDocSearch } from "@docsearch/core";
5
5
  import React from "react";
6
6
  import { createPortal } from "react-dom";
@@ -124,18 +124,28 @@ interface SearchIndexTool {
124
124
  hits?: any[];
125
125
  };
126
126
  }
127
+ interface MCPSearchToolQuery {
128
+ query: string;
129
+ [key: string]: unknown;
130
+ }
131
+ interface MCPSearchToolInputV1 {
132
+ query: string;
133
+ index: string;
134
+ number_of_results?: number;
135
+ facet_filters?: string[];
136
+ }
137
+ interface MCPSearchToolInputV2 {
138
+ queries: MCPSearchToolQuery[];
139
+ clickAnalytics: boolean;
140
+ originalQuery: string;
141
+ }
127
142
  interface AlgoliaMCPSearchTool {
128
- input: {
129
- query: string;
130
- index: string;
131
- number_of_results?: number;
132
- facet_filters?: string[];
133
- };
143
+ input: MCPSearchToolInputV1 | MCPSearchToolInputV2;
134
144
  output: {
135
- hits?: any[];
145
+ hits?: unknown[];
136
146
  nbHits?: number;
137
147
  queryId?: string;
138
- };
148
+ } | undefined;
139
149
  }
140
150
  interface MemoryTool {
141
151
  input: unknown;
@@ -220,4 +230,4 @@ type SuggestedQuestion = {
220
230
  type SuggestedQuestionHit = Hit<SuggestedQuestion>;
221
231
  //#endregion
222
232
  export { StoredDocSearchHit as a, AskAiFeedbackReason as c, DocSearchHit as d, StoredAskAiState as i, OnAskAiFeedback as l, SuggestedQuestionHit as n, ToolCalls as o, StoredAskAiMessage as r, AskAiFeedbackPayload as s, SuggestedQuestion as t, DocSearchState as u };
223
- //# sourceMappingURL=index-Dl8FMlR5.d.ts.map
233
+ //# sourceMappingURL=index-Bqqv4HmN.d.ts.map
@@ -1,9 +1,9 @@
1
- import { a as StoredDocSearchHit, c as AskAiFeedbackReason, d as DocSearchHit, i as StoredAskAiState, l as OnAskAiFeedback, n as SuggestedQuestionHit, o as ToolCalls, r as StoredAskAiMessage, s as AskAiFeedbackPayload, t as SuggestedQuestion, u as DocSearchState } from "./index-Dl8FMlR5.js";
1
+ import { a as StoredDocSearchHit, c as AskAiFeedbackReason, d as DocSearchHit, i as StoredAskAiState, l as OnAskAiFeedback, n as SuggestedQuestionHit, o as ToolCalls, r as StoredAskAiMessage, s as AskAiFeedbackPayload, t as SuggestedQuestion, u as DocSearchState } from "./index-Bqqv4HmN.js";
2
2
  import { t as DocSearchTheme } from "./DocSearchTheme-DvL4mf0D.js";
3
- import { a as DocSearchProps, c as DocSearchTranslations, d as ModalTranslations, i as DocSearchInner, l as DocSearchModal, n as DocSearchFacet, o as DocSearchRef, r as DocSearchIndex, s as DocSearchTransformClient, t as DocSearch, u as DocSearchModalProps, v as InternalDocSearchHit } from "./DocSearch-Dq5Utfyb.js";
4
- import { n as useDocSearchKeyboardEvents, r as KeyboardShortcuts, t as UseDocSearchKeyboardEventsProps } from "./useDocSearchKeyboardEvents-68G8dw6c.js";
5
- import { n as DocSearchButton, r as DocSearchButtonProps, t as ButtonTranslations } from "./DocSearchButton-CRlNPf5k.js";
3
+ import { a as DocSearchProps, c as DocSearchTranslations, d as ModalTranslations, i as DocSearchInner, l as DocSearchModal, n as DocSearchFacet, o as DocSearchRef, r as DocSearchIndex, s as DocSearchTransformClient, t as DocSearch, u as DocSearchModalProps, v as InternalDocSearchHit } from "./DocSearch-HJsNvtZr.js";
4
+ import { n as useDocSearchKeyboardEvents, r as KeyboardShortcuts, t as UseDocSearchKeyboardEventsProps } from "./useDocSearchKeyboardEvents-u23fFhR9.js";
5
+ import { n as DocSearchButton, r as DocSearchButtonProps, t as ButtonTranslations } from "./DocSearchButton-CZM_jACU.js";
6
6
  import { AgentStudioIndices, AgentStudioSearchControls, AgentStudioSearchParameters, AskAiSearchParameters, DocSearchAI, DocSearchAIInner, DocSearchAIProps, DocSearchAskAi, Memory, PromptSuggestions } from "./docsearchAi.js";
7
- import { n as DocSearchAskAiModalProps, r as DocSearchAskAiModalTranslations, t as DocSearchAskAiModal } from "./DocSearchAskAiModal-BwbMrrHv.js";
7
+ import { n as DocSearchAskAiModalProps, r as DocSearchAskAiModalTranslations, t as DocSearchAskAiModal } from "./DocSearchAskAiModal-B7vpLudE.js";
8
8
  import { version } from "./version.js";
9
9
  export { AgentStudioIndices, AgentStudioSearchControls, AgentStudioSearchParameters, AskAiFeedbackPayload, AskAiFeedbackReason, AskAiSearchParameters, ButtonTranslations, DocSearch, DocSearchAI, DocSearchAIInner, DocSearchAIProps, DocSearchAskAi, DocSearchAskAiModal, DocSearchAskAiModalProps, DocSearchAskAiModalTranslations, DocSearchButton, DocSearchButtonProps, DocSearchFacet, DocSearchHit, DocSearchIndex, DocSearchInner, DocSearchModal, DocSearchModalProps, DocSearchProps, type DocSearchRef, DocSearchState, DocSearchTheme, DocSearchTransformClient, DocSearchTranslations, InternalDocSearchHit, KeyboardShortcuts, Memory, ModalTranslations, OnAskAiFeedback, PromptSuggestions, StoredAskAiMessage, StoredAskAiState, StoredDocSearchHit, SuggestedQuestion, SuggestedQuestionHit, type ToolCalls, UseDocSearchKeyboardEventsProps, useDocSearchKeyboardEvents, version };
package/dist/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { t as _objectSpread2 } from "./objectSpread2-BNmiQYyW.js";
2
2
  import { t as DocSearchButton } from "./DocSearchButton-CaxxOzQU.js";
3
- import { t as DocSearchAskAiModal } from "./DocSearchAskAiModal-CCrk6YLb.js";
3
+ import { t as DocSearchAskAiModal } from "./DocSearchAskAiModal-KaA6fBV4.js";
4
4
  import { t as DocSearchModal } from "./DocSearchModal-CpvDjo1O.js";
5
5
  import { version } from "./version.js";
6
6
  import { DocSearchAI, DocSearchAIInner } from "./docsearchAi.js";
@@ -1,2 +1,2 @@
1
- import { d as ModalTranslations, l as DocSearchModal, u as DocSearchModalProps } from "./DocSearch-Dq5Utfyb.js";
1
+ import { d as ModalTranslations, l as DocSearchModal, u as DocSearchModalProps } from "./DocSearch-HJsNvtZr.js";
2
2
  export { DocSearchModal, DocSearchModalProps, ModalTranslations };
@@ -1,7 +1,7 @@
1
- import { o as ToolCalls } from "./index-Dl8FMlR5.js";
2
- import "./DocSearch-Dq5Utfyb.js";
1
+ import { o as ToolCalls } from "./index-Bqqv4HmN.js";
2
+ import "./DocSearch-HJsNvtZr.js";
3
3
  import { AgentStudioIndices, AgentStudioSearchParameters, Memory } from "./docsearchAi.js";
4
- import { r as ToolCallTranslations } from "./AskAiScreenState-D0IZsCMJ.js";
4
+ import { r as ToolCallTranslations } from "./AskAiScreenState-CRHicWbN.js";
5
5
  import { DocSearchCallbacks, DocSearchCallbacks as DocSearchCallbacks$1, DocSearchRef, DocSearchRef as DocSearchRef$1, DocSearchTheme, InitialAskAiMessage, SidepanelShortcuts } from "@docsearch/core";
6
6
  import React, { JSX } from "react";
7
7
  import "@ai-sdk/react";
@@ -176,7 +176,7 @@ type SidepanelProps = Pick<DocSearchSidepanelProps, 'indices' | 'memory' | 'tool
176
176
  */
177
177
  keyboardShortcuts?: SidepanelShortcuts;
178
178
  };
179
- declare const Sidepanel: React.ForwardRefExoticComponent<Omit<DocSearchSidepanelProps, "indices" | "button" | "panel" | "tools" | "memory"> & Pick<DocSearchSidepanelProps, "indices" | "tools" | "memory"> & {
179
+ declare const Sidepanel: React.ForwardRefExoticComponent<Omit<DocSearchSidepanelProps, "button" | "panel" | "tools" | "memory" | "indices"> & Pick<DocSearchSidepanelProps, "tools" | "memory" | "indices"> & {
180
180
  /**
181
181
  * Variant of the Sidepanel positioning.
182
182
  *
@@ -2,7 +2,7 @@ import { t as _objectSpread2 } from "./objectSpread2-BNmiQYyW.js";
2
2
  import { n as isAppleDevice, t as ACTION_KEY_DEFAULT } from "./keyboard-BkSdCzTU.js";
3
3
  import { n as SearchIcon, t as _objectWithoutProperties } from "./objectWithoutProperties-phqYxDS0.js";
4
4
  import { a as AlgoliaLogo, f as RecentIcon, l as CloseIcon, m as LoadingIcon, p as SparklesIcon, t as useSearchClient } from "./useSearchClient-mIHVB6ga.js";
5
- import { S as AlertIcon, _ as BackIcon, a as MemoizedMarkdown, b as MoreVerticalIcon, c as buildDummyAskAiHit, d as getMessageContent, f as isAIToolPart, g as ConversationPromptSuggestions, h as FeedbackActions, i as groupConsecutiveToolResults, l as extractLinksFromMessage, m as SourcesPanel, n as useAskAi, o as ToolCall, r as Menu, s as EMPTY_TOOLS, t as useSuggestedQuestions, u as getAgentPromptSuggestions, v as NewConversationIcon, x as StopIcon, y as ConversationHistoryIcon } from "./useSuggestedQuestions-D2TGVPsI.js";
5
+ import { S as AlertIcon, _ as BackIcon, a as MemoizedMarkdown, b as MoreVerticalIcon, c as buildDummyAskAiHit, d as getMessageContent, f as isAIToolPart, g as ConversationPromptSuggestions, h as FeedbackActions, i as groupConsecutiveToolResults, l as extractLinksFromMessage, m as SourcesPanel, n as useAskAi, o as ToolCall, r as Menu, s as EMPTY_TOOLS, t as useSuggestedQuestions, u as getAgentPromptSuggestions, v as NewConversationIcon, x as StopIcon, y as ConversationHistoryIcon } from "./useSuggestedQuestions-CG2H3qm4.js";
6
6
  import { version } from "./version.js";
7
7
  import { DocSearch, useDocSearch } from "@docsearch/core";
8
8
  import React, { Fragment, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
@@ -163,8 +163,8 @@ const ConversationExchange = React.forwardRef(({ exchange, translations = {}, is
163
163
  const index = idx;
164
164
  if (part.type === "reasoning" && part.state === "streaming") return /* @__PURE__ */ React.createElement("div", {
165
165
  key: index,
166
- className: "DocSearch-AskAiScreen-MessageContent-Reasoning shimmer"
167
- }, /* @__PURE__ */ React.createElement(LoadingIcon, { className: "DocSearch-AskAiScreen-SmallerLoadingIcon" }), /* @__PURE__ */ React.createElement("span", { className: "shimmer" }, reasoningText));
166
+ className: "DocSearch-AskAiScreen-MessageContent-Reasoning DocSearch-shimmer"
167
+ }, /* @__PURE__ */ React.createElement(LoadingIcon, { className: "DocSearch-AskAiScreen-SmallerLoadingIcon" }), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-shimmer" }, reasoningText));
168
168
  if (part.type === "aggregated-tool-call") return /* @__PURE__ */ React.createElement(AggregatedSearchBlock, {
169
169
  key: index,
170
170
  queries: part.queries
@@ -200,7 +200,7 @@ const ConversationExchange = React.forwardRef(({ exchange, translations = {}, is
200
200
  }), isThinking && isLastExchange && assistantParts.length === 0 && /* @__PURE__ */ React.createElement("div", {
201
201
  className: "DocSearch-AskAiScreen-MessageContent-Thinking",
202
202
  role: "status"
203
- }, /* @__PURE__ */ React.createElement("span", { className: "shimmer" }, thinkingText), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton shimmer" }), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton DocSearch-AskAi-Thinking-Skeleton--short shimmer" }))), wasStopped && /* @__PURE__ */ React.createElement("p", { className: "DocSearck-AskAiScreen-MessageContent-Stopped" }, stoppedStreamingText)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Answer-Footer" }, /* @__PURE__ */ React.createElement(SourcesPanel, {
203
+ }, /* @__PURE__ */ React.createElement("span", { className: "DocSearch-shimmer" }, thinkingText), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton DocSearch-shimmer" }), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton DocSearch-AskAi-Thinking-Skeleton--short DocSearch-shimmer" }))), wasStopped && /* @__PURE__ */ React.createElement("p", { className: "DocSearch-AskAiScreen-MessageContent-Stopped" }, stoppedStreamingText)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Answer-Footer" }, /* @__PURE__ */ React.createElement(SourcesPanel, {
204
204
  links: urlsToDisplay,
205
205
  titleText: relatedSourcesText
206
206
  }), /* @__PURE__ */ React.createElement(FeedbackActions, {