diff --git a/src/Elastic.Documentation.Site/Assets/eui-icons-cache.ts b/src/Elastic.Documentation.Site/Assets/eui-icons-cache.ts index b8ed475a9..39d9f5647 100644 --- a/src/Elastic.Documentation.Site/Assets/eui-icons-cache.ts +++ b/src/Elastic.Documentation.Site/Assets/eui-icons-cache.ts @@ -13,6 +13,8 @@ import { icon as EuiIconNewChat } from '@elastic/eui/es/components/icon/assets/n import { icon as EuiIconRefresh } from '@elastic/eui/es/components/icon/assets/refresh' import { icon as EuiIconSearch } from '@elastic/eui/es/components/icon/assets/search' import { icon as EuiIconSparkles } from '@elastic/eui/es/components/icon/assets/sparkles' +import { icon as EuiIconThumbDown } from '@elastic/eui/es/components/icon/assets/thumbDown' +import { icon as EuiIconThumbUp } from '@elastic/eui/es/components/icon/assets/thumbUp' import { icon as EuiIconTrash } from '@elastic/eui/es/components/icon/assets/trash' import { icon as EuiIconUser } from '@elastic/eui/es/components/icon/assets/user' import { icon as EuiIconWrench } from '@elastic/eui/es/components/icon/assets/wrench' @@ -37,4 +39,6 @@ appendIconComponentCache({ faceSad: EuiIconFaceSad, refresh: EuiIconRefresh, error: EuiIconError, + thumbUp: EuiIconThumbUp, + thumbDown: EuiIconThumbDown, }) diff --git a/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/AskAiAnswer.tsx b/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/AskAiAnswer.tsx index 7fffeff84..c269afcec 100644 --- a/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/AskAiAnswer.tsx +++ b/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/AskAiAnswer.tsx @@ -12,6 +12,7 @@ import { EuiToolTip, useEuiTheme, EuiCallOut, + EuiIcon, } from '@elastic/eui' import { css } from '@emotion/react' import * as React from 'react' @@ -69,6 +70,7 @@ export const AskAiAnswer = () => { hasShadow={false} hasBorder={false} css={css` + flex-grow: 1; .euiMarkdownFormat { font-size: ${euiTheme.size.base}; } @@ -77,15 +79,26 @@ export const AskAiAnswer = () => { } `} > +
+ + Ask Elastic Docs AI Assistant +
+ @@ -104,7 +117,7 @@ export const AskAiAnswer = () => { @@ -113,7 +126,7 @@ export const AskAiAnswer = () => { @@ -142,7 +155,7 @@ export const AskAiAnswer = () => { ).length > 0 && } diff --git a/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/useLlmGateway.ts b/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/useLlmGateway.ts index 3ebdbfd17..1d3c0deef 100644 --- a/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/useLlmGateway.ts +++ b/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/useLlmGateway.ts @@ -154,8 +154,10 @@ export const useLlmGateway = (props: Props): UseLlmGatewayResponse => { async (question: string) => { if (question.trim() && question !== lastSentQuestionRef.current) { abort() - lastSentQuestionRef.current = question setError(null) + setMessages([]) + clearQueue() + lastSentQuestionRef.current = question const payload = createLlmGatewayRequest( question, props.threadId diff --git a/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/Search/SearchResults.tsx b/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/Search/SearchResults.tsx index f0696fcf2..db88d7d7f 100644 --- a/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/Search/SearchResults.tsx +++ b/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/Search/SearchResults.tsx @@ -10,6 +10,7 @@ import { useEuiTheme, EuiIcon, EuiPagination, + EuiHorizontalRule, } from '@elastic/eui' import { css } from '@emotion/react' import { useDebounce } from '@uidotdev/usehooks' @@ -70,14 +71,15 @@ export const SearchResults = () => { ))} +
@@ -87,6 +89,7 @@ export const SearchResults = () => {
)} + ) } @@ -99,7 +102,11 @@ function SearchResultListItem({ item: result }: SearchResultListItemProps) { const { euiTheme } = useEuiTheme() const searchTerm = useSearchTerm() const highlightSearchTerms = useMemo( - () => searchTerm.toLowerCase().split(' '), + () => + searchTerm + .toLowerCase() + .split(' ') + .filter((i) => i.length > 1), [searchTerm] ) diff --git a/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/SearchOrAskAiModal.tsx b/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/SearchOrAskAiModal.tsx index b40407c24..bf5bf806c 100644 --- a/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/SearchOrAskAiModal.tsx +++ b/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/SearchOrAskAiModal.tsx @@ -1,6 +1,6 @@ import { AskAiAnswer } from './AskAi/AskAiAnswer' +import { AskAiSuggestions } from './AskAi/AskAiSuggestions' import { SearchResults } from './Search/SearchResults' -import { Suggestions } from './Suggestions' import { useAskAiTerm, useSearchActions, useSearchTerm } from './search.store' import { EuiFieldSearch, @@ -8,6 +8,7 @@ import { EuiBetaBadge, EuiText, EuiHorizontalRule, + useEuiOverflowScroll, } from '@elastic/eui' import { css } from '@emotion/react' import * as React from 'react' @@ -18,24 +19,59 @@ export const SearchOrAskAiModal = () => { const { setSearchTerm, submitAskAiTerm } = useSearchActions() return ( - <> - setSearchTerm(e.target.value)} - onSearch={(e) => { - submitAskAiTerm(e) - }} - isClearable - autoFocus={true} - /> - - - {askAiTerm ? : } +
+
+ setSearchTerm(e.target.value)} + onSearch={(e) => { + submitAskAiTerm(e) + }} + isClearable + autoFocus={true} + /> + +
+
+ + {askAiTerm ? ( + + ) : ( + + )} +
{ This feature is in beta. Got feedback? We'd love to hear it!
- +
) } diff --git a/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/Suggestions.tsx b/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/Suggestions.tsx deleted file mode 100644 index 35043a9d5..000000000 --- a/src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/Suggestions.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { AskAiSuggestions } from './AskAi/AskAiSuggestions' -import { SearchSuggestions } from './Search/SearchSuggestions' -import { useSearchTerm } from './search.store' -import { EuiHorizontalRule } from '@elastic/eui' -import * as React from 'react' - -export function Suggestions() { - const searchTerm = useSearchTerm() - return ( - <> - {!searchTerm && ( - - )} - - - - ) -} diff --git a/src/api/Elastic.Documentation.Api.Core/AskAi/AskAiUsecase.cs b/src/api/Elastic.Documentation.Api.Core/AskAi/AskAiUsecase.cs index 2c5f3e4ad..c39b23c38 100644 --- a/src/api/Elastic.Documentation.Api.Core/AskAi/AskAiUsecase.cs +++ b/src/api/Elastic.Documentation.Api.Core/AskAi/AskAiUsecase.cs @@ -28,6 +28,7 @@ public record AskAiRequest(string Message, string? ThreadId) - Handling Unknowns: If the information required to answer the question is not present in the provided documents, you must explicitly state that the answer cannot be found. Do not attempt to guess, infer, or provide a general response. - Helpful Fallback: If you cannot find a direct answer, you may suggest and link to a few related or similar topics that are present in the documentation. This provides value even when a direct answer is unavailable. - Output Format: Your final response should be a single, coherent block of text. + - Short and Concise: Keep your answers as brief as possible while still being complete and informative. For more more details refer to the documentation with links. ## Negative Constraints: