@docsearch/react 5.0.0-beta.1 → 5.0.0-beta.2
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.
- package/README.md +1 -1
- package/dist/esm/{AskAiScreenState-CRHicWbN.d.ts → AskAiScreenState-Bw2WIgv_.d.ts} +5 -2
- package/dist/esm/{DocSearch-HJsNvtZr.d.ts → DocSearch-CVj6U-nI.d.ts} +4 -18
- package/dist/esm/{DocSearchAskAiModal-KaA6fBV4.js → DocSearchAskAiModal-BczGFkvR.js} +26 -33
- package/dist/esm/DocSearchAskAiModal-BczGFkvR.js.map +1 -0
- package/dist/esm/{DocSearchAskAiModal-B7vpLudE.d.ts → DocSearchAskAiModal-MF2py4NM.d.ts} +4 -4
- package/dist/esm/{DocSearchModal-CpvDjo1O.js → DocSearchModal-D_tfhoN1.js} +13 -21
- package/dist/esm/DocSearchModal-D_tfhoN1.js.map +1 -0
- package/dist/esm/askaiModal.d.ts +1 -1
- package/dist/esm/askaiModal.js +1 -1
- package/dist/esm/docsearchAi.d.ts +4 -9
- package/dist/esm/docsearchAi.js +14 -4
- package/dist/esm/docsearchAi.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +15 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/modal.d.ts +1 -1
- package/dist/esm/modal.js +1 -1
- package/dist/esm/{normalizeDocSearchIndexes-DAzlMybx.js → normalizeDocSearchIndexes-D8P3VEXa.js} +90 -55
- package/dist/esm/normalizeDocSearchIndexes-D8P3VEXa.js.map +1 -0
- package/dist/esm/sidepanel.d.ts +14 -22
- package/dist/esm/sidepanel.js +14 -11
- package/dist/esm/sidepanel.js.map +1 -1
- package/dist/esm/{useSuggestedQuestions-CG2H3qm4.js → useSuggestedQuestions-Ds7H1JCr.js} +36 -26
- package/dist/esm/useSuggestedQuestions-Ds7H1JCr.js.map +1 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/umd/index.js +43 -41
- package/dist/umd/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/esm/DocSearchAskAiModal-KaA6fBV4.js.map +0 -1
- package/dist/esm/DocSearchModal-CpvDjo1O.js.map +0 -1
- package/dist/esm/normalizeDocSearchIndexes-DAzlMybx.js.map +0 -1
- package/dist/esm/useSuggestedQuestions-CG2H3qm4.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./index-Bqqv4HmN.js";
|
|
2
|
-
import { f as ResultsScreenTranslations, h as StoredSearchesSectionsTranslations, m as ErrorScreenTranslations, p as NoResultsScreenTranslations } from "./DocSearch-
|
|
2
|
+
import { f as ResultsScreenTranslations, h as StoredSearchesSectionsTranslations, m as ErrorScreenTranslations, p as NoResultsScreenTranslations } from "./DocSearch-CVj6U-nI.js";
|
|
3
3
|
import React, { JSX } from "react";
|
|
4
4
|
import { AutocompleteState, BaseItem } from "@algolia/autocomplete-core";
|
|
5
5
|
import "@ai-sdk/react";
|
|
@@ -20,7 +20,10 @@ type ToolCallTranslations = {
|
|
|
20
20
|
//#region src/AskAiScreen.d.ts
|
|
21
21
|
type AskAiScreenTranslations = Partial<Omit<ToolCallTranslations, 'searchingText' | 'toolCallResultText'> & {
|
|
22
22
|
disclaimerText: string;
|
|
23
|
+
/** Text shown describing a singular related source. */
|
|
23
24
|
relatedSourcesText: string;
|
|
25
|
+
/** Text shown describing multiple related sources. */
|
|
26
|
+
relatedSourcesTextPlural: string;
|
|
24
27
|
thinkingText: string;
|
|
25
28
|
copyButtonText: string;
|
|
26
29
|
copyButtonCopiedText: string;
|
|
@@ -103,4 +106,4 @@ type AskAiScreenStateTranslations = Partial<{
|
|
|
103
106
|
}>;
|
|
104
107
|
//#endregion
|
|
105
108
|
export { NewConversationTranslations as n, ToolCallTranslations as r, AskAiScreenStateTranslations as t };
|
|
106
|
-
//# sourceMappingURL=AskAiScreenState-
|
|
109
|
+
//# sourceMappingURL=AskAiScreenState-Bw2WIgv_.d.ts.map
|
|
@@ -148,7 +148,7 @@ type DocSearchModalProps = DocSearchProps & {
|
|
|
148
148
|
onClose?: () => void;
|
|
149
149
|
translations?: ModalTranslations;
|
|
150
150
|
};
|
|
151
|
-
declare function DocSearchModal({ appId, apiKey, maxResultsPerGroup, theme, onClose, transformItems, hitComponent, resultsFooterComponent, navigator, initialScrollY, transformSearchClient, disableUserPersonalization, initialQuery: initialQueryFromProp, translations, getMissingResultsUrl, insights, recentSearchesLimit, recentSearchesWithFavoritesLimit, indices,
|
|
151
|
+
declare function DocSearchModal({ appId, apiKey, maxResultsPerGroup, theme, onClose, transformItems, hitComponent, resultsFooterComponent, navigator, initialScrollY, transformSearchClient, disableUserPersonalization, initialQuery: initialQueryFromProp, translations, getMissingResultsUrl, insights, recentSearchesLimit, recentSearchesWithFavoritesLimit, indices, facets, ...props }: DocSearchModalProps): JSX.Element;
|
|
152
152
|
//#endregion
|
|
153
153
|
//#region src/DocSearch.d.ts
|
|
154
154
|
type DocSearchTranslations = Partial<{
|
|
@@ -173,19 +173,12 @@ interface DocSearchProps {
|
|
|
173
173
|
appId: string;
|
|
174
174
|
/** Public api key with search permissions for the index. */
|
|
175
175
|
apiKey: string;
|
|
176
|
-
/**
|
|
177
|
-
* Name of the algolia index to query.
|
|
178
|
-
*
|
|
179
|
-
* @deprecated `indexName` will be removed in a future version. Please use
|
|
180
|
-
* `indices` property going forward.
|
|
181
|
-
*/
|
|
182
|
-
indexName?: string;
|
|
183
176
|
/**
|
|
184
177
|
* List of indices and _optional_ searchParameters to be used for search.
|
|
185
178
|
*
|
|
186
179
|
* @see {@link https://docsearch.algolia.com/docs/api#indices}
|
|
187
180
|
*/
|
|
188
|
-
indices
|
|
181
|
+
indices: Array<DocSearchIndex | string>;
|
|
189
182
|
/**
|
|
190
183
|
* Facets to display as keyword-search filter controls. Values are read
|
|
191
184
|
* dynamically from the configured Algolia indices.
|
|
@@ -197,13 +190,6 @@ interface DocSearchProps {
|
|
|
197
190
|
theme?: DocSearchTheme$1;
|
|
198
191
|
/** Placeholder text for the search input. */
|
|
199
192
|
placeholder?: string;
|
|
200
|
-
/**
|
|
201
|
-
* Additional algolia search parameters to merge into each query.
|
|
202
|
-
*
|
|
203
|
-
* @deprecated `searchParameters` will be removed in a future version. Please
|
|
204
|
-
* use `indices` property going forward.
|
|
205
|
-
*/
|
|
206
|
-
searchParameters?: SearchParamsObject;
|
|
207
193
|
/** Maximum number of hits to display per source/group. */
|
|
208
194
|
maxResultsPerGroup?: number;
|
|
209
195
|
/** Hook to post-process hits before rendering. */
|
|
@@ -289,7 +275,7 @@ interface DocSearchProps {
|
|
|
289
275
|
resultBadgeKey?: string;
|
|
290
276
|
}
|
|
291
277
|
declare const DocSearch$1: React.ForwardRefExoticComponent<DocSearchProps & React.RefAttributes<DocSearchRef>>;
|
|
292
|
-
declare function DocSearchInner(props: DocSearchProps): JSX.Element;
|
|
278
|
+
declare function DocSearchInner(props: Omit<DocSearchProps, 'appId' | 'apiKey'>): JSX.Element;
|
|
293
279
|
//#endregion
|
|
294
280
|
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-
|
|
281
|
+
//# sourceMappingURL=DocSearch-CVj6U-nI.d.ts.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as _objectSpread2 } from "./objectSpread2-BNmiQYyW.js";
|
|
2
|
-
import { C as noop, D as
|
|
2
|
+
import { C as noop, D as SOURCE_IDS, E as identity, O as getCollection, S as scrollTo, T as isModifierEvent, _ 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 isQueryEmpty, x as FacetBar, y as ModalShell } from "./normalizeDocSearchIndexes-D8P3VEXa.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-
|
|
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-Ds7H1JCr.js";
|
|
6
6
|
import React, { Fragment, useMemo } from "react";
|
|
7
7
|
import { createAutocomplete } from "@algolia/autocomplete-core";
|
|
8
8
|
|
|
@@ -69,9 +69,9 @@ function AskAiScreenDisclaimer({ disclaimerText }) {
|
|
|
69
69
|
return /* @__PURE__ */ React.createElement("p", { className: "DocSearch-AskAiScreen-Disclaimer" }, /* @__PURE__ */ React.createElement(SparklesIcon, null), " ", disclaimerText);
|
|
70
70
|
}
|
|
71
71
|
function AskAiExchangeCard({ exchange, askAiError, isLastExchange, loadingStatus, onSearchQueryClick, translations, tools, conversations, onFeedback, memoryEnabled, onSelectPromptSuggestion }) {
|
|
72
|
-
var _userMessage$metadata, _assistantMessage$met
|
|
72
|
+
var _userMessage$metadata, _assistantMessage$met;
|
|
73
73
|
const { userMessage, assistantMessage } = exchange;
|
|
74
|
-
const { stoppedStreamingText = "You stopped this response", errorTitleText = "Chat error", relatedSourcesText, suggestedPromptsTitleText = "Suggested prompts" } = translations;
|
|
74
|
+
const { stoppedStreamingText = "You stopped this response", errorTitleText = "Chat error", relatedSourcesText, relatedSourcesTextPlural, suggestedPromptsTitleText = "Suggested prompts" } = translations;
|
|
75
75
|
const toolCallTranslations = useMemo(() => toToolCallTranslations(translations), [translations]);
|
|
76
76
|
const isThreadDepth = isThreadDepthError(askAiError);
|
|
77
77
|
const assistantContent = useMemo(() => getMessageContent(assistantMessage), [assistantMessage]);
|
|
@@ -88,7 +88,7 @@ function AskAiExchangeCard({ exchange, askAiError, isLastExchange, loadingStatus
|
|
|
88
88
|
const showActions = !wasStopped && (!isLastExchange || isLastExchange && loadingStatus === "ready" && Boolean(assistantMessage));
|
|
89
89
|
const isThinking = ["submitted", "streaming"].includes(loadingStatus) && isLastExchange && !displayParts.some((part) => part.type !== "step-start");
|
|
90
90
|
const messageId = (assistantMessage === null || assistantMessage === void 0 ? void 0 : assistantMessage.id) || exchange.id;
|
|
91
|
-
return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Response-Container" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Response" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--user" }, /* @__PURE__ */ React.createElement("p", { className: "DocSearch-AskAiScreen-Query" },
|
|
91
|
+
return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Response-Container" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Response" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--user" }, /* @__PURE__ */ React.createElement("p", { className: "DocSearch-AskAiScreen-Query" }, userContent !== null && userContent !== void 0 ? userContent : "")), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--assistant" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-MessageContent" }, loadingStatus === "error" && askAiError && isLastExchange && !isThreadDepth && /* @__PURE__ */ React.createElement("div", {
|
|
92
92
|
className: "DocSearch-AskAiScreen-Error",
|
|
93
93
|
role: "alert"
|
|
94
94
|
}, /* @__PURE__ */ React.createElement(AlertIcon, { "aria-hidden": "true" }), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Error-Content" }, /* @__PURE__ */ React.createElement("h4", { className: "DocSearch-AskAiScreen-Error-Title" }, errorTitleText), /* @__PURE__ */ React.createElement(MemoizedMarkdown, {
|
|
@@ -136,11 +136,12 @@ function AskAiExchangeCard({ exchange, askAiError, isLastExchange, loadingStatus
|
|
|
136
136
|
return null;
|
|
137
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
|
-
titleText: relatedSourcesText
|
|
139
|
+
titleText: relatedSourcesText,
|
|
140
|
+
pluralTitleText: relatedSourcesTextPlural
|
|
140
141
|
}), /* @__PURE__ */ React.createElement(FeedbackActions, {
|
|
141
142
|
id: messageId,
|
|
142
143
|
showActions,
|
|
143
|
-
latestAssistantMessageContent:
|
|
144
|
+
latestAssistantMessageContent: assistantContent || null,
|
|
144
145
|
translations,
|
|
145
146
|
conversations,
|
|
146
147
|
onFeedback
|
|
@@ -211,7 +212,7 @@ function RecentConversationsResults(_ref) {
|
|
|
211
212
|
return /* @__PURE__ */ React.createElement(Results, _objectSpread2(_objectSpread2({}, props), {}, {
|
|
212
213
|
title: recentConversationsTitle,
|
|
213
214
|
collection: recentConversations,
|
|
214
|
-
renderIcon: () => /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-icon DocSearch-Hit-icon--
|
|
215
|
+
renderIcon: () => /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-icon DocSearch-Hit-icon--start" }, /* @__PURE__ */ React.createElement(MessageIcon, null)),
|
|
215
216
|
renderAction: ({ item }) => /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-action" }, /* @__PURE__ */ React.createElement("button", {
|
|
216
217
|
className: "DocSearch-Hit-action-button",
|
|
217
218
|
title: removeRecentConversationButtonTitle,
|
|
@@ -301,15 +302,18 @@ const AskAiScreenState = React.memo((_ref) => {
|
|
|
301
302
|
onSelectPromptSuggestion: handleSelectPromptSuggestion
|
|
302
303
|
}));
|
|
303
304
|
if (((_props$state = props.state) === null || _props$state === void 0 ? void 0 : _props$state.status) === "error") return /* @__PURE__ */ React.createElement(ErrorScreen, { translations: translations === null || translations === void 0 ? void 0 : translations.errorScreen });
|
|
304
|
-
if (
|
|
305
|
+
if (isQueryEmpty(props.state.query)) return /* @__PURE__ */ React.createElement(AskAiStartScreen, _objectSpread2(_objectSpread2({}, props), {}, {
|
|
305
306
|
hasCollections: props.hasCollections,
|
|
306
307
|
translations: translations === null || translations === void 0 ? void 0 : translations.startScreen,
|
|
307
308
|
selectAskAiQuestion
|
|
308
309
|
}));
|
|
309
310
|
if (!props.hasCollections && !props.canHandleAskAi) return /* @__PURE__ */ React.createElement(NoResultsScreen, _objectSpread2(_objectSpread2({}, props), {}, { translations: translations === null || translations === void 0 ? void 0 : translations.noResultsScreen }));
|
|
310
311
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ResultsScreen, _objectSpread2(_objectSpread2({}, props), {}, { translations: translations === null || translations === void 0 ? void 0 : translations.resultsScreen })), props.canHandleAskAi && !props.hasCollections && /* @__PURE__ */ React.createElement(NoResultsScreen, _objectSpread2(_objectSpread2({}, props), {}, { translations: translations === null || translations === void 0 ? void 0 : translations.noResultsScreen })));
|
|
311
|
-
}, function areEqual(
|
|
312
|
-
|
|
312
|
+
}, function areEqual(prevProps, nextProps) {
|
|
313
|
+
if (prevProps.isAskAiActive !== nextProps.isAskAiActive || prevProps.askAiState !== nextProps.askAiState || prevProps.canHandleAskAi !== nextProps.canHandleAskAi) return false;
|
|
314
|
+
const isLoading = nextProps.state.status === "loading" || nextProps.state.status === "stalled";
|
|
315
|
+
const isWaitingForCollections = nextProps.state.status === "idle" && !isQueryEmpty(nextProps.state.query) && prevProps.state.query !== nextProps.state.query && prevProps.state.collections === nextProps.state.collections;
|
|
316
|
+
return isLoading || isWaitingForCollections;
|
|
313
317
|
});
|
|
314
318
|
|
|
315
319
|
//#endregion
|
|
@@ -370,7 +374,7 @@ function AskAiSearchBox(_ref) {
|
|
|
370
374
|
onKeyDown: (e) => {
|
|
371
375
|
let askAiHandled = false;
|
|
372
376
|
if (props.isAskAiActive && blockedKeys.has(e.key)) {
|
|
373
|
-
if (e.key === "Enter" && !isAskAiStreaming && props.state.query) props.onAskAgain(props.state.query);
|
|
377
|
+
if (e.key === "Enter" && !isAskAiStreaming && !isQueryEmpty(props.state.query)) props.onAskAgain(props.state.query);
|
|
374
378
|
askAiHandled = true;
|
|
375
379
|
}
|
|
376
380
|
if (askAiHandled) {
|
|
@@ -578,8 +582,6 @@ const _excluded = [
|
|
|
578
582
|
"recentSearchesLimit",
|
|
579
583
|
"recentSearchesWithFavoritesLimit",
|
|
580
584
|
"indices",
|
|
581
|
-
"indexName",
|
|
582
|
-
"searchParameters",
|
|
583
585
|
"facets",
|
|
584
586
|
"isHybridModeSupported"
|
|
585
587
|
];
|
|
@@ -590,7 +592,7 @@ const _excluded2 = [
|
|
|
590
592
|
];
|
|
591
593
|
function DocSearchAskAiModal(_ref) {
|
|
592
594
|
var _translations$searchB, _askAiConfig$memory$e, _askAiConfig$memory, _askAiConfig$tools;
|
|
593
|
-
let { appId, apiKey, askAi, maxResultsPerGroup, theme, onClose = noop, transformItems = identity, hitComponent = Hit, resultsFooterComponent = () => null, navigator, initialScrollY = 0, transformSearchClient = identity, disableUserPersonalization = false, initialQuery: initialQueryFromProp = "", translations = {}, getMissingResultsUrl, insights = false, onAskAiToggle, interceptAskAiEvent, isAskAiActive = false, recentSearchesLimit = 7, recentSearchesWithFavoritesLimit = 4, indices
|
|
595
|
+
let { appId, apiKey, askAi, maxResultsPerGroup, theme, onClose = noop, transformItems = identity, hitComponent = Hit, resultsFooterComponent = () => null, navigator, initialScrollY = 0, transformSearchClient = identity, disableUserPersonalization = false, initialQuery: initialQueryFromProp = "", translations = {}, getMissingResultsUrl, insights = false, onAskAiToggle, interceptAskAiEvent, isAskAiActive = false, recentSearchesLimit = 7, recentSearchesWithFavoritesLimit = 4, indices, facets, isHybridModeSupported = false } = _ref, props = _objectWithoutProperties(_ref, _excluded);
|
|
594
596
|
const { footer: footerTranslations, searchBox: searchBoxTranslations, facets: facetBarTranslations } = translations, screenStateTranslations = _objectWithoutProperties(translations, _excluded2);
|
|
595
597
|
const [state, setState] = React.useState({
|
|
596
598
|
query: "",
|
|
@@ -615,25 +617,17 @@ function DocSearchAskAiModal(_ref) {
|
|
|
615
617
|
const { initialQuery, initialQueryFromSelection } = useInitialModalQuery(initialQueryFromProp);
|
|
616
618
|
const searchClient = useSearchClient(appId, apiKey, transformSearchClient);
|
|
617
619
|
const askAiConfig = typeof askAi === "object" ? askAi : null;
|
|
618
|
-
const askAiConfigurationId = askAiConfig ? askAiConfig.
|
|
620
|
+
const askAiConfigurationId = askAiConfig ? askAiConfig.agentId : askAi;
|
|
619
621
|
const askAiSearchParameters = askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.searchParameters;
|
|
620
622
|
const [askAiState, setAskAiState] = React.useState("initial");
|
|
621
623
|
const suggestedQuestions = useSuggestedQuestions({
|
|
622
|
-
|
|
624
|
+
agentId: askAiConfigurationId,
|
|
623
625
|
searchClient,
|
|
624
626
|
suggestedQuestionsEnabled: askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.suggestedQuestions
|
|
625
627
|
});
|
|
626
628
|
const memoryEnabled = (_askAiConfig$memory$e = askAiConfig === null || askAiConfig === void 0 || (_askAiConfig$memory = askAiConfig.memory) === null || _askAiConfig$memory === void 0 ? void 0 : _askAiConfig$memory.enabled) !== null && _askAiConfig$memory$e !== void 0 ? _askAiConfig$memory$e : false;
|
|
627
629
|
const tools = (_askAiConfig$tools = askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.tools) !== null && _askAiConfig$tools !== void 0 ? _askAiConfig$tools : EMPTY_TOOLS;
|
|
628
|
-
const indexes = React.useMemo(() => normalizeDocSearchIndexes({
|
|
629
|
-
indexName,
|
|
630
|
-
indices,
|
|
631
|
-
searchParameters
|
|
632
|
-
}), [
|
|
633
|
-
indexName,
|
|
634
|
-
indices,
|
|
635
|
-
searchParameters
|
|
636
|
-
]);
|
|
630
|
+
const indexes = React.useMemo(() => normalizeDocSearchIndexes({ indices }), [indices]);
|
|
637
631
|
const defaultIndexName = indexes[0].name;
|
|
638
632
|
const autocompleteRef = React.useRef(void 0);
|
|
639
633
|
const { visibleFacets, facetSelections, facetSelectionsRef, handleFacetSelectionChange, clearFacetSelections } = useDocSearchFacets({
|
|
@@ -652,10 +646,9 @@ function DocSearchAskAiModal(_ref) {
|
|
|
652
646
|
});
|
|
653
647
|
const [stoppedStream, setStoppedStream] = React.useState(false);
|
|
654
648
|
const { chatId, messages, status, setMessages, sendMessage, stopAskAiStreaming, askAiError, sendFeedback, conversations, startNewConversation, restoreConversation } = useAskAi({
|
|
655
|
-
|
|
649
|
+
agentId: askAiConfigurationId,
|
|
656
650
|
apiKey: (askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.apiKey) || apiKey,
|
|
657
651
|
appId: (askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.appId) || appId,
|
|
658
|
-
indexName: (askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.indexName) || defaultIndexName,
|
|
659
652
|
searchParameters: askAiSearchParameters,
|
|
660
653
|
tools,
|
|
661
654
|
memory: askAiConfig === null || askAiConfig === void 0 ? void 0 : askAiConfig.memory,
|
|
@@ -752,7 +745,7 @@ function DocSearchAskAiModal(_ref) {
|
|
|
752
745
|
setState(changes.state);
|
|
753
746
|
},
|
|
754
747
|
async getSources({ query, state: sourcesState, setContext, setStatus }) {
|
|
755
|
-
if (
|
|
748
|
+
if (isQueryEmpty(query)) {
|
|
756
749
|
const noQuerySources = buildNoQuerySources({
|
|
757
750
|
recentSearches,
|
|
758
751
|
favoriteSearches,
|
|
@@ -850,7 +843,7 @@ function DocSearchAskAiModal(_ref) {
|
|
|
850
843
|
};
|
|
851
844
|
let showDocsearchDropdown = true;
|
|
852
845
|
const hasCollections = state.collections.some((collection) => collection.source.sourceId !== SOURCE_IDS.askAI && collection.items.length > 0);
|
|
853
|
-
if (state.status === "idle" && hasCollections === false && state.query
|
|
846
|
+
if (state.status === "idle" && hasCollections === false && isQueryEmpty(state.query) && !isAskAiActive) showDocsearchDropdown = false;
|
|
854
847
|
return /* @__PURE__ */ React.createElement(ModalShell, {
|
|
855
848
|
state,
|
|
856
849
|
containerRef,
|
|
@@ -862,7 +855,7 @@ function DocSearchAskAiModal(_ref) {
|
|
|
862
855
|
searchBox: /* @__PURE__ */ React.createElement(AskAiSearchBox, _objectSpread2(_objectSpread2({}, autocomplete), {}, {
|
|
863
856
|
state,
|
|
864
857
|
placeholder: placeholder || "Search docs",
|
|
865
|
-
autoFocus: initialQuery
|
|
858
|
+
autoFocus: isQueryEmpty(initialQuery),
|
|
866
859
|
inputRef,
|
|
867
860
|
isFromSelection: Boolean(initialQuery) && initialQuery === initialQueryFromSelection,
|
|
868
861
|
translations: searchBoxTranslations,
|
|
@@ -881,7 +874,7 @@ function DocSearchAskAiModal(_ref) {
|
|
|
881
874
|
onNewConversation: handleNewConversation,
|
|
882
875
|
onViewConversationHistory: handleViewConversationHistory
|
|
883
876
|
})),
|
|
884
|
-
filterBar: !isAskAiActive && state.query
|
|
877
|
+
filterBar: !isAskAiActive && !isQueryEmpty(state.query) ? /* @__PURE__ */ React.createElement(FacetBar, {
|
|
885
878
|
facets: visibleFacets,
|
|
886
879
|
selections: facetSelections,
|
|
887
880
|
translations: facetBarTranslations,
|
|
@@ -951,4 +944,4 @@ function DocSearchAskAiModal(_ref) {
|
|
|
951
944
|
|
|
952
945
|
//#endregion
|
|
953
946
|
export { DocSearchAskAiModal as t };
|
|
954
|
-
//# sourceMappingURL=DocSearchAskAiModal-
|
|
947
|
+
//# sourceMappingURL=DocSearchAskAiModal-BczGFkvR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocSearchAskAiModal-BczGFkvR.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 "{q}"\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 /** Text shown describing a singular related source. */\n relatedSourcesText: string;\n /** Text shown describing multiple related sources. */\n relatedSourcesTextPlural: 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 relatedSourcesTextPlural,\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\">{userContent ?? ''}</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\n links={urlsToDisplay}\n titleText={relatedSourcesText}\n pluralTitleText={relatedSourcesTextPlural}\n />\n <FeedbackActions\n id={messageId}\n showActions={showActions}\n latestAssistantMessageContent={assistantContent || 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--start\">\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';\nimport { isQueryEmpty } from './utils';\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: string;\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 (isQueryEmpty(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 const askAiStateChanged =\n prevProps.isAskAiActive !== nextProps.isAskAiActive ||\n prevProps.askAiState !== nextProps.askAiState ||\n prevProps.canHandleAskAi !== nextProps.canHandleAskAi;\n\n // Something triggered an Ask AI related state change, perform a new render\n if (askAiStateChanged) {\n return false;\n }\n\n const isLoading =\n nextProps.state.status === 'loading' ||\n nextProps.state.status === 'stalled';\n\n const isWaitingForCollections =\n nextProps.state.status === 'idle' &&\n !isQueryEmpty(nextProps.state.query) &&\n prevProps.state.query !== nextProps.state.query &&\n prevProps.state.collections === nextProps.state.collections;\n\n return isLoading || isWaitingForCollections;\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, isQueryEmpty } 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 (\n e.key === 'Enter' &&\n !isAskAiStreaming &&\n !isQueryEmpty(props.state.query)\n ) {\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 isQueryEmpty,\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 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.agentId\n : (askAi as string);\n const askAiSearchParameters = askAiConfig?.searchParameters;\n const [askAiState, setAskAiState] = React.useState<AskAiState>('initial');\n const suggestedQuestions = useSuggestedQuestions({\n agentId: 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 indices,\n }),\n [indices]\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 agentId: askAiConfigurationId,\n apiKey: askAiConfig?.apiKey || apiKey,\n appId: askAiConfig?.appId || appId,\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 (isQueryEmpty(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 isQueryEmpty(state.query) &&\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={isQueryEmpty(initialQuery)}\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 && !isQueryEmpty(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,7 +1,7 @@
|
|
|
1
1
|
import "./index-Bqqv4HmN.js";
|
|
2
|
-
import { _ as FacetBarTranslations, g as FooterTranslations } from "./DocSearch-
|
|
2
|
+
import { _ as FacetBarTranslations, g as FooterTranslations } from "./DocSearch-CVj6U-nI.js";
|
|
3
3
|
import { DocSearchAIProps } from "./docsearchAi.js";
|
|
4
|
-
import { n as NewConversationTranslations, t as AskAiScreenStateTranslations } from "./AskAiScreenState-
|
|
4
|
+
import { n as NewConversationTranslations, t as AskAiScreenStateTranslations } from "./AskAiScreenState-Bw2WIgv_.js";
|
|
5
5
|
import { OnAskAiToggle } from "@docsearch/core";
|
|
6
6
|
import React, { JSX } from "react";
|
|
7
7
|
import { AutocompleteState } from "@algolia/autocomplete-core";
|
|
@@ -42,7 +42,7 @@ type DocSearchAskAiModalProps = DocSearchAIProps & {
|
|
|
42
42
|
translations?: DocSearchAskAiModalTranslations;
|
|
43
43
|
isHybridModeSupported?: boolean;
|
|
44
44
|
};
|
|
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,
|
|
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, facets, isHybridModeSupported, ...props }: DocSearchAskAiModalProps): JSX.Element;
|
|
46
46
|
//#endregion
|
|
47
47
|
export { DocSearchAskAiModalProps as n, DocSearchAskAiModalTranslations as r, DocSearchAskAiModal as t };
|
|
48
|
-
//# sourceMappingURL=DocSearchAskAiModal-
|
|
48
|
+
//# sourceMappingURL=DocSearchAskAiModal-MF2py4NM.d.ts.map
|