mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Security Solution][Elastic AI Assistant] Refactors Knowledge Base feature flag to UI feature toggle (#167935)
## Summary This PR refactors the `assistantLangChain` code feature flag introduced in https://github.com/elastic/kibana/pull/164908, to be a UI feature toggle that users can enable/disable via the `Knowledge Base` assistant advanced settings. Left image shows the feature disabled, and the right image shows the feature partly enabled. If ELSER is configured, the UI will attempt to install all resources automatically for a one-click UX, however if ELSER is not configured, or there are failures, the user can manually enable the Knowledge Base or ES|QL base documentation: <p align="center"> <img width="400" src="be85522e
-b2f5-4a39-9f0e-d359424caf37" /> <img width="400" src="d901c4f8
-2184-4fb7-8c59-f2ff877118b9" /> </p> Also, since this code feature flag was shared with the model evaluator experimental feature, a `modelEvaluatorEnabled` flag has been plumbed to fully decouple the two settings. Now _only the_ model evaluator is enabled when setting security Solution Advanced setting: ``` xpack.securitySolution.enableExperimental: ['assistantModelEvaluation'] ``` and the previous `assistantLangChain` code feature flag is now enabled by simply toggling on the Knowledge Base in the settings shown above. > [!NOTE] > Even if ELSER isn't configured, and the knowledge base/docs aren't setup, if the Knowledge Base is enabled, the LangChain code path will still be enabled as intended, but we can change this behavior if testing shows this is not ideal. ### Checklist Delete any items that are not applicable to this PR. - [X] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)added to match the most common scenarios - [X] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
This commit is contained in:
parent
ce5ae7d562
commit
e74e5e2bfc
16 changed files with 487 additions and 309 deletions
|
@ -1,193 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import {
|
||||
EuiFormRow,
|
||||
EuiTitle,
|
||||
EuiText,
|
||||
EuiTextColor,
|
||||
EuiHorizontalRule,
|
||||
EuiLoadingSpinner,
|
||||
EuiSpacer,
|
||||
EuiSwitch,
|
||||
EuiToolTip,
|
||||
EuiSwitchEvent,
|
||||
EuiLink,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import * as i18n from './translations';
|
||||
import { useKnowledgeBaseStatus } from '../../../knowledge_base/use_knowledge_base_status/use_knowledge_base_status';
|
||||
import { useAssistantContext } from '../../../assistant_context';
|
||||
import { useSetupKnowledgeBase } from '../../../knowledge_base/use_setup_knowledge_base/use_setup_knowledge_base';
|
||||
import { useDeleteKnowledgeBase } from '../../../knowledge_base/use_delete_knowledge_base/use_delete_knowledge_base';
|
||||
|
||||
const ESQL_RESOURCE = 'esql';
|
||||
interface Props {
|
||||
onAdvancedSettingsChange?: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advanced Settings -- enable and disable LangChain integration, Knowledge Base, and ESQL KB Documents
|
||||
*/
|
||||
export const AdvancedSettings: React.FC<Props> = React.memo(({ onAdvancedSettingsChange }) => {
|
||||
const { http, assistantLangChain } = useAssistantContext();
|
||||
const {
|
||||
data: kbStatus,
|
||||
isLoading,
|
||||
isFetching,
|
||||
} = useKnowledgeBaseStatus({ http, resource: ESQL_RESOURCE });
|
||||
const { mutate: setupKB, isLoading: isSettingUpKB } = useSetupKnowledgeBase({ http });
|
||||
const { mutate: deleteKB, isLoading: isDeletingUpKB } = useDeleteKnowledgeBase({ http });
|
||||
|
||||
const [isLangChainEnabled, setIsLangChainEnabled] = useState(assistantLangChain);
|
||||
const isKnowledgeBaseEnabled =
|
||||
(kbStatus?.index_exists && kbStatus?.pipeline_exists && kbStatus?.elser_exists) ?? false;
|
||||
const isESQLEnabled = kbStatus?.esql_exists ?? false;
|
||||
|
||||
const isLoadingKb = isLoading || isFetching || isSettingUpKB || isDeletingUpKB;
|
||||
const isKnowledgeBaseAvailable = isLangChainEnabled && kbStatus?.elser_exists;
|
||||
const isESQLAvailable = isLangChainEnabled && isKnowledgeBaseAvailable && isKnowledgeBaseEnabled;
|
||||
|
||||
const onEnableKnowledgeBaseChange = useCallback(
|
||||
(event: EuiSwitchEvent) => {
|
||||
if (event.target.checked) {
|
||||
setupKB();
|
||||
} else {
|
||||
deleteKB();
|
||||
}
|
||||
},
|
||||
[deleteKB, setupKB]
|
||||
);
|
||||
|
||||
const onEnableESQLChange = useCallback(
|
||||
(event: EuiSwitchEvent) => {
|
||||
if (event.target.checked) {
|
||||
setupKB(ESQL_RESOURCE);
|
||||
} else {
|
||||
deleteKB(ESQL_RESOURCE);
|
||||
}
|
||||
},
|
||||
[deleteKB, setupKB]
|
||||
);
|
||||
|
||||
const langchainSwitch = useMemo(() => {
|
||||
return (
|
||||
<EuiSwitch
|
||||
checked={isLangChainEnabled}
|
||||
compressed
|
||||
disabled={true} // Advanced settings only shown if assistantLangChain=true, remove when storing to localstorage as ui feature toggle
|
||||
label={i18n.LANNGCHAIN_LABEL}
|
||||
onChange={() => setIsLangChainEnabled(!isLangChainEnabled)}
|
||||
showLabel={false}
|
||||
/>
|
||||
);
|
||||
}, [isLangChainEnabled]);
|
||||
|
||||
const knowledgeBaseSwitch = useMemo(() => {
|
||||
return isLoadingKb ? (
|
||||
<EuiLoadingSpinner size="s" />
|
||||
) : (
|
||||
<EuiToolTip
|
||||
position={'right'}
|
||||
content={!isKnowledgeBaseAvailable ? i18n.KNOWLEDGE_BASE_LABEL_TOOLTIP : undefined}
|
||||
>
|
||||
<EuiSwitch
|
||||
showLabel={false}
|
||||
label={i18n.KNOWLEDGE_BASE_LABEL}
|
||||
checked={isKnowledgeBaseEnabled}
|
||||
disabled={!isKnowledgeBaseAvailable}
|
||||
onChange={onEnableKnowledgeBaseChange}
|
||||
compressed
|
||||
/>
|
||||
</EuiToolTip>
|
||||
);
|
||||
}, [isLoadingKb, isKnowledgeBaseAvailable, isKnowledgeBaseEnabled, onEnableKnowledgeBaseChange]);
|
||||
|
||||
const esqlSwitch = useMemo(() => {
|
||||
return isLoadingKb ? (
|
||||
<EuiLoadingSpinner size="s" />
|
||||
) : (
|
||||
<EuiToolTip
|
||||
position={'right'}
|
||||
content={!isESQLAvailable ? i18n.ESQL_LABEL_TOOLTIP : undefined}
|
||||
>
|
||||
<EuiSwitch
|
||||
showLabel={false}
|
||||
label={i18n.ESQL_LABEL}
|
||||
checked={isESQLEnabled}
|
||||
disabled={!isESQLAvailable}
|
||||
onChange={onEnableESQLChange}
|
||||
compressed
|
||||
/>
|
||||
</EuiToolTip>
|
||||
);
|
||||
}, [isLoadingKb, isESQLAvailable, isESQLEnabled, onEnableESQLChange]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiTitle size={'s'}>
|
||||
<h2>{i18n.SETTINGS_TITLE}</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="xs" />
|
||||
|
||||
<EuiText size={'s'}>{i18n.SETTINGS_DESCRIPTION}</EuiText>
|
||||
|
||||
<EuiHorizontalRule margin={'s'} />
|
||||
|
||||
<EuiFormRow display="columnCompressedSwitch" label={i18n.LANNGCHAIN_LABEL}>
|
||||
{langchainSwitch}
|
||||
</EuiFormRow>
|
||||
<EuiSpacer size="xs" />
|
||||
<EuiTextColor color={'subdued'}>{i18n.LANNGCHAIN_DESCRIPTION}</EuiTextColor>
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
<EuiFormRow
|
||||
display="columnCompressedSwitch"
|
||||
label={i18n.KNOWLEDGE_BASE_LABEL}
|
||||
isDisabled={!isKnowledgeBaseAvailable}
|
||||
>
|
||||
{knowledgeBaseSwitch}
|
||||
</EuiFormRow>
|
||||
<EuiSpacer size="xs" />
|
||||
<EuiTextColor color={'subdued'}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Initializes a local knowledge base for saving and retrieving relevant context for your conversations. Note: ELSER must be configured and started. {seeDocs}"
|
||||
id="xpack.elasticAssistant.assistant.settings.advancedSettings.knowledgeBaseDescription"
|
||||
values={{
|
||||
seeDocs: (
|
||||
<EuiLink
|
||||
external
|
||||
href={
|
||||
'https://www.elastic.co/guide/en/machine-learning/current/ml-nlp-elser.html#download-deploy-elser'
|
||||
}
|
||||
target="_blank"
|
||||
>
|
||||
{i18n.KNOWLEDGE_BASE_DESCRIPTION_ELSER_LEARN_MORE}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiTextColor>
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
<EuiFormRow
|
||||
isDisabled={!isESQLAvailable}
|
||||
display="columnCompressedSwitch"
|
||||
label={i18n.ESQL_LABEL}
|
||||
>
|
||||
{esqlSwitch}
|
||||
</EuiFormRow>
|
||||
<EuiSpacer size="xs" />
|
||||
<EuiTextColor color={'subdued'}>{i18n.ESQL_DESCRIPTION}</EuiTextColor>
|
||||
<EuiSpacer size="m" />
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
AdvancedSettings.displayName = 'AdvancedSettings';
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const SETTINGS_TITLE = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.advancedSettings.settingsTitle',
|
||||
{
|
||||
defaultMessage: 'Advanced Settings',
|
||||
}
|
||||
);
|
||||
export const SETTINGS_DESCRIPTION = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.advancedSettings.settingsDescription',
|
||||
{
|
||||
defaultMessage: 'Additional knobs and dials for the Elastic AI Assistant.',
|
||||
}
|
||||
);
|
||||
|
||||
export const LANNGCHAIN_LABEL = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.advancedSettings.langChainLabel',
|
||||
{
|
||||
defaultMessage: 'Experimental LangChain Integration',
|
||||
}
|
||||
);
|
||||
|
||||
export const LANNGCHAIN_DESCRIPTION = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.advancedSettings.langChainDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'Enables advanced features and workflows like the Knowledge Base, Functions, Memories, and advanced agent and chain configurations. ',
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_LABEL = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.advancedSettings.knowledgeBaseLabel',
|
||||
{
|
||||
defaultMessage: 'Knowledge Base',
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_LABEL_TOOLTIP = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.advancedSettings.knowledgeBaseLabelTooltip',
|
||||
{
|
||||
defaultMessage: 'Requires ELSER to be configured and started.',
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_DESCRIPTION_ELSER_LEARN_MORE = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.advancedSettings.knowledgeBaseElserLearnMoreDescription',
|
||||
{
|
||||
defaultMessage: 'Learn more.',
|
||||
}
|
||||
);
|
||||
|
||||
export const ESQL_LABEL = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.advancedSettings.esqlLabel',
|
||||
{
|
||||
defaultMessage: 'ES|QL Knowledge Base Documents',
|
||||
}
|
||||
);
|
||||
|
||||
export const ESQL_LABEL_TOOLTIP = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.advancedSettings.esqlTooltip',
|
||||
{
|
||||
defaultMessage: 'Requires `Knowledge Base` to be enabled.',
|
||||
}
|
||||
);
|
||||
|
||||
export const ESQL_DESCRIPTION = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.advancedSettings.esqlDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'Loads ES|QL documentation and language files into the Knowledge Base for use in generating ES|QL queries.',
|
||||
}
|
||||
);
|
|
@ -30,7 +30,7 @@ import { useAssistantContext } from '../../assistant_context';
|
|||
import { AnonymizationSettings } from '../../data_anonymization/settings/anonymization_settings';
|
||||
import { QuickPromptSettings } from '../quick_prompts/quick_prompt_settings/quick_prompt_settings';
|
||||
import { SystemPromptSettings } from '../prompt_editor/system_prompt/system_prompt_modal/system_prompt_settings';
|
||||
import { AdvancedSettings } from './advanced_settings/advanced_settings';
|
||||
import { KnowledgeBaseSettings } from '../../knowledge_base/knowledge_base_settings/knowledge_base_settings';
|
||||
import { ConversationSettings } from '../conversations/conversation_settings/conversation_settings';
|
||||
import { TEST_IDS } from '../constants';
|
||||
import { useSettingsUpdater } from './use_settings_updater/use_settings_updater';
|
||||
|
@ -45,7 +45,7 @@ export const CONVERSATIONS_TAB = 'CONVERSATION_TAB' as const;
|
|||
export const QUICK_PROMPTS_TAB = 'QUICK_PROMPTS_TAB' as const;
|
||||
export const SYSTEM_PROMPTS_TAB = 'SYSTEM_PROMPTS_TAB' as const;
|
||||
export const ANONYMIZATION_TAB = 'ANONYMIZATION_TAB' as const;
|
||||
export const ADVANCED_TAB = 'ADVANCED_TAB' as const;
|
||||
export const KNOWLEDGE_BASE_TAB = 'KNOWLEDGE_BASE_TAB' as const;
|
||||
export const EVALUATION_TAB = 'EVALUATION_TAB' as const;
|
||||
|
||||
export type SettingsTabs =
|
||||
|
@ -53,7 +53,7 @@ export type SettingsTabs =
|
|||
| typeof QUICK_PROMPTS_TAB
|
||||
| typeof SYSTEM_PROMPTS_TAB
|
||||
| typeof ANONYMIZATION_TAB
|
||||
| typeof ADVANCED_TAB
|
||||
| typeof KNOWLEDGE_BASE_TAB
|
||||
| typeof EVALUATION_TAB;
|
||||
interface Props {
|
||||
defaultConnectorId?: string;
|
||||
|
@ -68,7 +68,7 @@ interface Props {
|
|||
|
||||
/**
|
||||
* Modal for overall Assistant Settings, including conversation settings, quick prompts, system prompts,
|
||||
* anonymization, functions (coming soon!), and advanced settings.
|
||||
* anonymization, knowledge base, and evaluation via the `isModelEvaluationEnabled` feature flag.
|
||||
*/
|
||||
export const AssistantSettings: React.FC<Props> = React.memo(
|
||||
({
|
||||
|
@ -79,17 +79,19 @@ export const AssistantSettings: React.FC<Props> = React.memo(
|
|||
selectedConversation: defaultSelectedConversation,
|
||||
setSelectedConversationId,
|
||||
}) => {
|
||||
const { assistantLangChain, http, selectedSettingsTab, setSelectedSettingsTab } =
|
||||
const { modelEvaluatorEnabled, http, selectedSettingsTab, setSelectedSettingsTab } =
|
||||
useAssistantContext();
|
||||
const {
|
||||
conversationSettings,
|
||||
defaultAllow,
|
||||
defaultAllowReplacement,
|
||||
knowledgeBase,
|
||||
quickPromptSettings,
|
||||
systemPromptSettings,
|
||||
setUpdatedConversationSettings,
|
||||
setUpdatedDefaultAllow,
|
||||
setUpdatedDefaultAllowReplacement,
|
||||
setUpdatedKnowledgeBaseSettings,
|
||||
setUpdatedQuickPromptSettings,
|
||||
setUpdatedSystemPromptSettings,
|
||||
saveSettings,
|
||||
|
@ -236,17 +238,15 @@ export const AssistantSettings: React.FC<Props> = React.memo(
|
|||
>
|
||||
<EuiIcon type="eyeClosed" size="l" />
|
||||
</EuiKeyPadMenuItem>
|
||||
{assistantLangChain && (
|
||||
<EuiKeyPadMenuItem
|
||||
id={ADVANCED_TAB}
|
||||
label={i18n.ADVANCED_MENU_ITEM}
|
||||
isSelected={selectedSettingsTab === ADVANCED_TAB}
|
||||
onClick={() => setSelectedSettingsTab(ADVANCED_TAB)}
|
||||
>
|
||||
<EuiIcon type="advancedSettingsApp" size="l" />
|
||||
</EuiKeyPadMenuItem>
|
||||
)}
|
||||
{assistantLangChain && (
|
||||
<EuiKeyPadMenuItem
|
||||
id={KNOWLEDGE_BASE_TAB}
|
||||
label={i18n.KNOWLEDGE_BASE_MENU_ITEM}
|
||||
isSelected={selectedSettingsTab === KNOWLEDGE_BASE_TAB}
|
||||
onClick={() => setSelectedSettingsTab(KNOWLEDGE_BASE_TAB)}
|
||||
>
|
||||
<EuiIcon type="notebookApp" size="l" />
|
||||
</EuiKeyPadMenuItem>
|
||||
{modelEvaluatorEnabled && (
|
||||
<EuiKeyPadMenuItem
|
||||
id={EVALUATION_TAB}
|
||||
label={i18n.EVALUATION_MENU_ITEM}
|
||||
|
@ -307,7 +307,12 @@ export const AssistantSettings: React.FC<Props> = React.memo(
|
|||
setUpdatedDefaultAllowReplacement={setUpdatedDefaultAllowReplacement}
|
||||
/>
|
||||
)}
|
||||
{selectedSettingsTab === ADVANCED_TAB && <AdvancedSettings />}
|
||||
{selectedSettingsTab === KNOWLEDGE_BASE_TAB && (
|
||||
<KnowledgeBaseSettings
|
||||
knowledgeBase={knowledgeBase}
|
||||
setUpdatedKnowledgeBaseSettings={setUpdatedKnowledgeBaseSettings}
|
||||
/>
|
||||
)}
|
||||
{selectedSettingsTab === EVALUATION_TAB && <EvaluationSettings />}
|
||||
</EuiSplitPanel.Inner>
|
||||
<EuiSplitPanel.Inner
|
||||
|
|
|
@ -49,10 +49,10 @@ export const ANONYMIZATION_MENU_ITEM = i18n.translate(
|
|||
}
|
||||
);
|
||||
|
||||
export const ADVANCED_MENU_ITEM = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.settingsAdvancedMenuItemTitle',
|
||||
export const KNOWLEDGE_BASE_MENU_ITEM = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.settingsKnowledgeBaseMenuItemTitle',
|
||||
{
|
||||
defaultMessage: 'Advanced',
|
||||
defaultMessage: 'Knowledge Base',
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
import React, { useCallback, useState } from 'react';
|
||||
import { Prompt, QuickPrompt } from '../../../..';
|
||||
import { UseAssistantContext, useAssistantContext } from '../../../assistant_context';
|
||||
import type { KnowledgeBaseConfig } from '../../types';
|
||||
|
||||
interface UseSettingsUpdater {
|
||||
conversationSettings: UseAssistantContext['conversations'];
|
||||
defaultAllow: string[];
|
||||
defaultAllowReplacement: string[];
|
||||
knowledgeBase: KnowledgeBaseConfig;
|
||||
quickPromptSettings: QuickPrompt[];
|
||||
resetSettings: () => void;
|
||||
systemPromptSettings: Prompt[];
|
||||
|
@ -21,6 +23,7 @@ interface UseSettingsUpdater {
|
|||
setUpdatedConversationSettings: React.Dispatch<
|
||||
React.SetStateAction<UseAssistantContext['conversations']>
|
||||
>;
|
||||
setUpdatedKnowledgeBaseSettings: React.Dispatch<React.SetStateAction<KnowledgeBaseConfig>>;
|
||||
setUpdatedQuickPromptSettings: React.Dispatch<React.SetStateAction<QuickPrompt[]>>;
|
||||
setUpdatedSystemPromptSettings: React.Dispatch<React.SetStateAction<Prompt[]>>;
|
||||
saveSettings: () => void;
|
||||
|
@ -34,11 +37,13 @@ export const useSettingsUpdater = (): UseSettingsUpdater => {
|
|||
conversations,
|
||||
defaultAllow,
|
||||
defaultAllowReplacement,
|
||||
knowledgeBase,
|
||||
setAllQuickPrompts,
|
||||
setAllSystemPrompts,
|
||||
setConversations,
|
||||
setDefaultAllow,
|
||||
setDefaultAllowReplacement,
|
||||
setKnowledgeBase,
|
||||
} = useAssistantContext();
|
||||
|
||||
/**
|
||||
|
@ -57,6 +62,9 @@ export const useSettingsUpdater = (): UseSettingsUpdater => {
|
|||
const [updatedDefaultAllow, setUpdatedDefaultAllow] = useState<string[]>(defaultAllow);
|
||||
const [updatedDefaultAllowReplacement, setUpdatedDefaultAllowReplacement] =
|
||||
useState<string[]>(defaultAllowReplacement);
|
||||
// Knowledge Base
|
||||
const [updatedKnowledgeBaseSettings, setUpdatedKnowledgeBaseSettings] =
|
||||
useState<KnowledgeBaseConfig>(knowledgeBase);
|
||||
|
||||
/**
|
||||
* Reset all pending settings
|
||||
|
@ -64,10 +72,18 @@ export const useSettingsUpdater = (): UseSettingsUpdater => {
|
|||
const resetSettings = useCallback((): void => {
|
||||
setUpdatedConversationSettings(conversations);
|
||||
setUpdatedQuickPromptSettings(allQuickPrompts);
|
||||
setUpdatedKnowledgeBaseSettings(knowledgeBase);
|
||||
setUpdatedSystemPromptSettings(allSystemPrompts);
|
||||
setUpdatedDefaultAllow(defaultAllow);
|
||||
setUpdatedDefaultAllowReplacement(defaultAllowReplacement);
|
||||
}, [allQuickPrompts, allSystemPrompts, conversations, defaultAllow, defaultAllowReplacement]);
|
||||
}, [
|
||||
allQuickPrompts,
|
||||
allSystemPrompts,
|
||||
conversations,
|
||||
defaultAllow,
|
||||
defaultAllowReplacement,
|
||||
knowledgeBase,
|
||||
]);
|
||||
|
||||
/**
|
||||
* Save all pending settings
|
||||
|
@ -76,6 +92,7 @@ export const useSettingsUpdater = (): UseSettingsUpdater => {
|
|||
setAllQuickPrompts(updatedQuickPromptSettings);
|
||||
setAllSystemPrompts(updatedSystemPromptSettings);
|
||||
setConversations(updatedConversationSettings);
|
||||
setKnowledgeBase(updatedKnowledgeBaseSettings);
|
||||
setDefaultAllow(updatedDefaultAllow);
|
||||
setDefaultAllowReplacement(updatedDefaultAllowReplacement);
|
||||
}, [
|
||||
|
@ -84,9 +101,11 @@ export const useSettingsUpdater = (): UseSettingsUpdater => {
|
|||
setConversations,
|
||||
setDefaultAllow,
|
||||
setDefaultAllowReplacement,
|
||||
setKnowledgeBase,
|
||||
updatedConversationSettings,
|
||||
updatedDefaultAllow,
|
||||
updatedDefaultAllowReplacement,
|
||||
updatedKnowledgeBaseSettings,
|
||||
updatedQuickPromptSettings,
|
||||
updatedSystemPromptSettings,
|
||||
]);
|
||||
|
@ -95,6 +114,7 @@ export const useSettingsUpdater = (): UseSettingsUpdater => {
|
|||
conversationSettings: updatedConversationSettings,
|
||||
defaultAllow: updatedDefaultAllow,
|
||||
defaultAllowReplacement: updatedDefaultAllowReplacement,
|
||||
knowledgeBase: updatedKnowledgeBaseSettings,
|
||||
quickPromptSettings: updatedQuickPromptSettings,
|
||||
resetSettings,
|
||||
systemPromptSettings: updatedSystemPromptSettings,
|
||||
|
@ -102,6 +122,7 @@ export const useSettingsUpdater = (): UseSettingsUpdater => {
|
|||
setUpdatedDefaultAllow,
|
||||
setUpdatedDefaultAllowReplacement,
|
||||
setUpdatedConversationSettings,
|
||||
setUpdatedKnowledgeBaseSettings,
|
||||
setUpdatedQuickPromptSettings,
|
||||
setUpdatedSystemPromptSettings,
|
||||
};
|
||||
|
|
|
@ -15,3 +15,7 @@ export interface Prompt {
|
|||
isDefault?: boolean; // TODO: Should be renamed to isImmutable as this flag is used to prevent users from deleting prompts
|
||||
isNewConversationDefault?: boolean;
|
||||
}
|
||||
|
||||
export interface KnowledgeBaseConfig {
|
||||
assistantLangChain: boolean;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ interface UseSendMessages {
|
|||
}
|
||||
|
||||
export const useSendMessages = (): UseSendMessages => {
|
||||
const { assistantLangChain } = useAssistantContext();
|
||||
const { knowledgeBase } = useAssistantContext();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const sendMessages = useCallback(
|
||||
|
@ -37,7 +37,7 @@ export const useSendMessages = (): UseSendMessages => {
|
|||
setIsLoading(true);
|
||||
try {
|
||||
return await fetchConnectorExecuteAction({
|
||||
assistantLangChain,
|
||||
assistantLangChain: knowledgeBase.assistantLangChain,
|
||||
http,
|
||||
messages,
|
||||
apiConfig,
|
||||
|
@ -46,7 +46,7 @@ export const useSendMessages = (): UseSendMessages => {
|
|||
setIsLoading(false);
|
||||
}
|
||||
},
|
||||
[assistantLangChain]
|
||||
[knowledgeBase.assistantLangChain]
|
||||
);
|
||||
|
||||
return { isLoading, sendMessages };
|
||||
|
|
|
@ -5,7 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { KnowledgeBaseConfig } from '../assistant/types';
|
||||
|
||||
export const DEFAULT_ASSISTANT_NAMESPACE = 'elasticAssistantDefault';
|
||||
export const QUICK_PROMPT_LOCAL_STORAGE_KEY = 'quickPrompts';
|
||||
export const SYSTEM_PROMPT_LOCAL_STORAGE_KEY = 'systemPrompts';
|
||||
export const LAST_CONVERSATION_ID_LOCAL_STORAGE_KEY = 'lastConversationId';
|
||||
export const KNOWLEDGE_BASE_LOCAL_STORAGE_KEY = 'knowledgeBase';
|
||||
|
||||
export const DEFAULT_KNOWLEDGE_BASE_SETTINGS: KnowledgeBaseConfig = {
|
||||
assistantLangChain: false,
|
||||
};
|
||||
|
|
|
@ -28,7 +28,6 @@ const ContextWrapper: React.FC = ({ children }) => (
|
|||
<AssistantProvider
|
||||
actionTypeRegistry={actionTypeRegistry}
|
||||
assistantAvailability={mockAssistantAvailability}
|
||||
assistantLangChain={false}
|
||||
augmentMessageCodeBlocks={jest.fn()}
|
||||
baseAllow={[]}
|
||||
baseAllowReplacement={[]}
|
||||
|
|
|
@ -24,10 +24,12 @@ import { DEFAULT_ASSISTANT_TITLE } from '../assistant/translations';
|
|||
import { CodeBlockDetails } from '../assistant/use_conversation/helpers';
|
||||
import { PromptContextTemplate } from '../assistant/prompt_context/types';
|
||||
import { QuickPrompt } from '../assistant/quick_prompts/types';
|
||||
import { Prompt } from '../assistant/types';
|
||||
import type { KnowledgeBaseConfig, Prompt } from '../assistant/types';
|
||||
import { BASE_SYSTEM_PROMPTS } from '../content/prompts/system';
|
||||
import {
|
||||
DEFAULT_ASSISTANT_NAMESPACE,
|
||||
DEFAULT_KNOWLEDGE_BASE_SETTINGS,
|
||||
KNOWLEDGE_BASE_LOCAL_STORAGE_KEY,
|
||||
LAST_CONVERSATION_ID_LOCAL_STORAGE_KEY,
|
||||
QUICK_PROMPT_LOCAL_STORAGE_KEY,
|
||||
SYSTEM_PROMPT_LOCAL_STORAGE_KEY,
|
||||
|
@ -49,7 +51,6 @@ type ShowAssistantOverlay = ({
|
|||
export interface AssistantProviderProps {
|
||||
actionTypeRegistry: ActionTypeRegistryContract;
|
||||
assistantAvailability: AssistantAvailability;
|
||||
assistantLangChain: boolean;
|
||||
assistantTelemetry?: AssistantTelemetry;
|
||||
augmentMessageCodeBlocks: (currentConversation: Conversation) => CodeBlockDetails[][];
|
||||
baseAllow: string[];
|
||||
|
@ -73,6 +74,7 @@ export interface AssistantProviderProps {
|
|||
}) => EuiCommentProps[];
|
||||
http: HttpSetup;
|
||||
getInitialConversations: () => Record<string, Conversation>;
|
||||
modelEvaluatorEnabled?: boolean;
|
||||
nameSpace?: string;
|
||||
setConversations: React.Dispatch<React.SetStateAction<Record<string, Conversation>>>;
|
||||
setDefaultAllow: React.Dispatch<React.SetStateAction<string[]>>;
|
||||
|
@ -87,7 +89,6 @@ export interface UseAssistantContext {
|
|||
augmentMessageCodeBlocks: (currentConversation: Conversation) => CodeBlockDetails[][];
|
||||
allQuickPrompts: QuickPrompt[];
|
||||
allSystemPrompts: Prompt[];
|
||||
assistantLangChain: boolean;
|
||||
baseAllow: string[];
|
||||
baseAllowReplacement: string[];
|
||||
docLinks: Omit<DocLinksStart, 'links'>;
|
||||
|
@ -110,8 +111,10 @@ export interface UseAssistantContext {
|
|||
showAnonymizedValues: boolean;
|
||||
}) => EuiCommentProps[];
|
||||
http: HttpSetup;
|
||||
knowledgeBase: KnowledgeBaseConfig;
|
||||
localStorageLastConversationId: string | undefined;
|
||||
promptContexts: Record<string, PromptContext>;
|
||||
modelEvaluatorEnabled: boolean;
|
||||
nameSpace: string;
|
||||
registerPromptContext: RegisterPromptContext;
|
||||
selectedSettingsTab: SettingsTabs;
|
||||
|
@ -120,6 +123,7 @@ export interface UseAssistantContext {
|
|||
setConversations: React.Dispatch<React.SetStateAction<Record<string, Conversation>>>;
|
||||
setDefaultAllow: React.Dispatch<React.SetStateAction<string[]>>;
|
||||
setDefaultAllowReplacement: React.Dispatch<React.SetStateAction<string[]>>;
|
||||
setKnowledgeBase: React.Dispatch<React.SetStateAction<KnowledgeBaseConfig | undefined>>;
|
||||
setLastConversationId: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||
setSelectedSettingsTab: React.Dispatch<React.SetStateAction<SettingsTabs>>;
|
||||
setShowAssistantOverlay: (showAssistantOverlay: ShowAssistantOverlay) => void;
|
||||
|
@ -133,7 +137,6 @@ const AssistantContext = React.createContext<UseAssistantContext | undefined>(un
|
|||
export const AssistantProvider: React.FC<AssistantProviderProps> = ({
|
||||
actionTypeRegistry,
|
||||
assistantAvailability,
|
||||
assistantLangChain,
|
||||
assistantTelemetry,
|
||||
augmentMessageCodeBlocks,
|
||||
baseAllow,
|
||||
|
@ -149,6 +152,7 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({
|
|||
getComments,
|
||||
http,
|
||||
getInitialConversations,
|
||||
modelEvaluatorEnabled = false,
|
||||
nameSpace = DEFAULT_ASSISTANT_NAMESPACE,
|
||||
setConversations,
|
||||
setDefaultAllow,
|
||||
|
@ -174,6 +178,14 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({
|
|||
const [localStorageLastConversationId, setLocalStorageLastConversationId] =
|
||||
useLocalStorage<string>(`${nameSpace}.${LAST_CONVERSATION_ID_LOCAL_STORAGE_KEY}`);
|
||||
|
||||
/**
|
||||
* Local storage for knowledge base configuration, prefixed by assistant nameSpace
|
||||
*/
|
||||
const [localStorageKnowledgeBase, setLocalStorageKnowledgeBase] = useLocalStorage(
|
||||
`${nameSpace}.${KNOWLEDGE_BASE_LOCAL_STORAGE_KEY}`,
|
||||
DEFAULT_KNOWLEDGE_BASE_SETTINGS
|
||||
);
|
||||
|
||||
/**
|
||||
* Prompt contexts are used to provide components a way to register and make their data available to the assistant.
|
||||
*/
|
||||
|
@ -254,7 +266,6 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({
|
|||
() => ({
|
||||
actionTypeRegistry,
|
||||
assistantAvailability,
|
||||
assistantLangChain,
|
||||
assistantTelemetry,
|
||||
augmentMessageCodeBlocks,
|
||||
allQuickPrompts: localStorageQuickPrompts ?? [],
|
||||
|
@ -272,6 +283,8 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({
|
|||
docLinks,
|
||||
getComments,
|
||||
http,
|
||||
knowledgeBase: localStorageKnowledgeBase ?? DEFAULT_KNOWLEDGE_BASE_SETTINGS,
|
||||
modelEvaluatorEnabled,
|
||||
promptContexts,
|
||||
nameSpace,
|
||||
registerPromptContext,
|
||||
|
@ -281,6 +294,7 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({
|
|||
setConversations: onConversationsUpdated,
|
||||
setDefaultAllow,
|
||||
setDefaultAllowReplacement,
|
||||
setKnowledgeBase: setLocalStorageKnowledgeBase,
|
||||
setSelectedSettingsTab,
|
||||
setShowAssistantOverlay,
|
||||
showAssistantOverlay,
|
||||
|
@ -292,7 +306,6 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({
|
|||
[
|
||||
actionTypeRegistry,
|
||||
assistantAvailability,
|
||||
assistantLangChain,
|
||||
assistantTelemetry,
|
||||
augmentMessageCodeBlocks,
|
||||
baseAllow,
|
||||
|
@ -308,9 +321,11 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({
|
|||
docLinks,
|
||||
getComments,
|
||||
http,
|
||||
localStorageKnowledgeBase,
|
||||
localStorageLastConversationId,
|
||||
localStorageQuickPrompts,
|
||||
localStorageSystemPrompts,
|
||||
modelEvaluatorEnabled,
|
||||
nameSpace,
|
||||
onConversationsUpdated,
|
||||
promptContexts,
|
||||
|
@ -318,6 +333,7 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({
|
|||
selectedSettingsTab,
|
||||
setDefaultAllow,
|
||||
setDefaultAllowReplacement,
|
||||
setLocalStorageKnowledgeBase,
|
||||
setLocalStorageLastConversationId,
|
||||
setLocalStorageQuickPrompts,
|
||||
setLocalStorageSystemPrompts,
|
||||
|
|
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import {
|
||||
EuiFormRow,
|
||||
EuiTitle,
|
||||
EuiText,
|
||||
EuiHorizontalRule,
|
||||
EuiLoadingSpinner,
|
||||
EuiSpacer,
|
||||
EuiSwitchEvent,
|
||||
EuiLink,
|
||||
EuiBetaBadge,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiHealth,
|
||||
EuiButtonEmpty,
|
||||
EuiSwitch,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { css } from '@emotion/react';
|
||||
import * as i18n from './translations';
|
||||
import { useAssistantContext } from '../../assistant_context';
|
||||
import { useDeleteKnowledgeBase } from '../use_delete_knowledge_base/use_delete_knowledge_base';
|
||||
import { useKnowledgeBaseStatus } from '../use_knowledge_base_status/use_knowledge_base_status';
|
||||
import { useSetupKnowledgeBase } from '../use_setup_knowledge_base/use_setup_knowledge_base';
|
||||
|
||||
import type { KnowledgeBaseConfig } from '../../assistant/types';
|
||||
|
||||
const ESQL_RESOURCE = 'esql';
|
||||
const KNOWLEDGE_BASE_INDEX_PATTERN = '.kibana-elastic-ai-assistant-kb';
|
||||
|
||||
interface Props {
|
||||
knowledgeBase: KnowledgeBaseConfig;
|
||||
setUpdatedKnowledgeBaseSettings: React.Dispatch<React.SetStateAction<KnowledgeBaseConfig>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Knowledge Base Settings -- enable and disable LangChain integration, Knowledge Base, and ESQL KB Documents
|
||||
*/
|
||||
export const KnowledgeBaseSettings: React.FC<Props> = React.memo(
|
||||
({ knowledgeBase, setUpdatedKnowledgeBaseSettings }) => {
|
||||
const { http } = useAssistantContext();
|
||||
const {
|
||||
data: kbStatus,
|
||||
isLoading,
|
||||
isFetching,
|
||||
} = useKnowledgeBaseStatus({ http, resource: ESQL_RESOURCE });
|
||||
const { mutate: setupKB, isLoading: isSettingUpKB } = useSetupKnowledgeBase({ http });
|
||||
const { mutate: deleteKB, isLoading: isDeletingUpKB } = useDeleteKnowledgeBase({ http });
|
||||
|
||||
// Resource enabled state
|
||||
const isKnowledgeBaseEnabled =
|
||||
(kbStatus?.index_exists && kbStatus?.pipeline_exists && kbStatus?.elser_exists) ?? false;
|
||||
const isESQLEnabled = kbStatus?.esql_exists ?? false;
|
||||
|
||||
// Resource availability state
|
||||
const isLoadingKb = isLoading || isFetching || isSettingUpKB || isDeletingUpKB;
|
||||
const isKnowledgeBaseAvailable = knowledgeBase.assistantLangChain && kbStatus?.elser_exists;
|
||||
const isESQLAvailable =
|
||||
knowledgeBase.assistantLangChain && isKnowledgeBaseAvailable && isKnowledgeBaseEnabled;
|
||||
|
||||
// Calculated health state for EuiHealth component
|
||||
const elserHealth = kbStatus?.elser_exists ? 'success' : 'subdued';
|
||||
const knowledgeBaseHealth = isKnowledgeBaseEnabled ? 'success' : 'subdued';
|
||||
const esqlHealth = isESQLEnabled ? 'success' : 'subdued';
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Main `Knowledge Base` switch, which toggles the `assistantLangChain` UI feature toggle
|
||||
// setting that is saved to localstorage
|
||||
const onEnableAssistantLangChainChange = useCallback(
|
||||
(event: EuiSwitchEvent) => {
|
||||
setUpdatedKnowledgeBaseSettings({
|
||||
...knowledgeBase,
|
||||
assistantLangChain: event.target.checked,
|
||||
});
|
||||
|
||||
// If enabling and ELSER exists, try to set up automatically
|
||||
if (event.target.checked && kbStatus?.elser_exists) {
|
||||
setupKB(ESQL_RESOURCE);
|
||||
}
|
||||
},
|
||||
[kbStatus?.elser_exists, knowledgeBase, setUpdatedKnowledgeBaseSettings, setupKB]
|
||||
);
|
||||
|
||||
const assistantLangChainSwitch = useMemo(() => {
|
||||
return isLoadingKb ? (
|
||||
<EuiLoadingSpinner size="s" />
|
||||
) : (
|
||||
<EuiSwitch
|
||||
showLabel={false}
|
||||
checked={knowledgeBase.assistantLangChain}
|
||||
onChange={onEnableAssistantLangChainChange}
|
||||
label={i18n.KNOWLEDGE_BASE_LABEL}
|
||||
compressed
|
||||
/>
|
||||
);
|
||||
}, [isLoadingKb, knowledgeBase.assistantLangChain, onEnableAssistantLangChainChange]);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Knowledge Base Resource
|
||||
const onEnableKB = useCallback(
|
||||
(enabled: boolean) => {
|
||||
if (enabled) {
|
||||
setupKB();
|
||||
} else {
|
||||
deleteKB();
|
||||
}
|
||||
},
|
||||
[deleteKB, setupKB]
|
||||
);
|
||||
|
||||
const knowledgeBaseActionButton = useMemo(() => {
|
||||
return isLoadingKb || !isKnowledgeBaseAvailable ? (
|
||||
<></>
|
||||
) : (
|
||||
<EuiButtonEmpty
|
||||
color={isKnowledgeBaseEnabled ? 'danger' : 'primary'}
|
||||
flush="left"
|
||||
onClick={() => onEnableKB(!isKnowledgeBaseEnabled)}
|
||||
size="xs"
|
||||
>
|
||||
{isKnowledgeBaseEnabled
|
||||
? i18n.KNOWLEDGE_BASE_DELETE_BUTTON
|
||||
: i18n.KNOWLEDGE_BASE_INIT_BUTTON}
|
||||
</EuiButtonEmpty>
|
||||
);
|
||||
}, [isKnowledgeBaseAvailable, isKnowledgeBaseEnabled, isLoadingKb, onEnableKB]);
|
||||
|
||||
const knowledgeBaseDescription = useMemo(() => {
|
||||
return isKnowledgeBaseEnabled ? (
|
||||
<>
|
||||
{i18n.KNOWLEDGE_BASE_DESCRIPTION_INSTALLED(KNOWLEDGE_BASE_INDEX_PATTERN)}{' '}
|
||||
{knowledgeBaseActionButton}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{i18n.KNOWLEDGE_BASE_DESCRIPTION} {knowledgeBaseActionButton}
|
||||
</>
|
||||
);
|
||||
}, [isKnowledgeBaseEnabled, knowledgeBaseActionButton]);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ESQL Resource
|
||||
const onEnableESQL = useCallback(
|
||||
(enabled: boolean) => {
|
||||
if (enabled) {
|
||||
setupKB(ESQL_RESOURCE);
|
||||
} else {
|
||||
deleteKB(ESQL_RESOURCE);
|
||||
}
|
||||
},
|
||||
[deleteKB, setupKB]
|
||||
);
|
||||
|
||||
const esqlActionButton = useMemo(() => {
|
||||
return isLoadingKb || !isESQLAvailable ? (
|
||||
<></>
|
||||
) : (
|
||||
<EuiButtonEmpty
|
||||
color={isESQLEnabled ? 'danger' : 'primary'}
|
||||
flush="left"
|
||||
onClick={() => onEnableESQL(!isESQLEnabled)}
|
||||
size="xs"
|
||||
>
|
||||
{isESQLEnabled ? i18n.KNOWLEDGE_BASE_DELETE_BUTTON : i18n.KNOWLEDGE_BASE_INIT_BUTTON}
|
||||
</EuiButtonEmpty>
|
||||
);
|
||||
}, [isLoadingKb, isESQLAvailable, isESQLEnabled, onEnableESQL]);
|
||||
|
||||
const esqlDescription = useMemo(() => {
|
||||
return isESQLEnabled ? (
|
||||
<>
|
||||
{i18n.ESQL_DESCRIPTION_INSTALLED} {esqlActionButton}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{i18n.ESQL_DESCRIPTION} {esqlActionButton}
|
||||
</>
|
||||
);
|
||||
}, [esqlActionButton, isESQLEnabled]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiTitle size={'s'}>
|
||||
<h2>
|
||||
{i18n.SETTINGS_TITLE}{' '}
|
||||
<EuiBetaBadge iconType={'beaker'} label={i18n.SETTINGS_BADGE} size="s" color="hollow" />
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="xs" />
|
||||
<EuiText size={'s'}>{i18n.SETTINGS_DESCRIPTION}</EuiText>
|
||||
<EuiHorizontalRule margin={'s'} />
|
||||
|
||||
<EuiFormRow
|
||||
display="columnCompressedSwitch"
|
||||
label={i18n.KNOWLEDGE_BASE_LABEL}
|
||||
css={css`
|
||||
div {
|
||||
min-width: 95px !important;
|
||||
}
|
||||
`}
|
||||
>
|
||||
{assistantLangChainSwitch}
|
||||
</EuiFormRow>
|
||||
<EuiSpacer size="s" />
|
||||
|
||||
<EuiFlexGroup
|
||||
direction={'column'}
|
||||
gutterSize={'s'}
|
||||
css={css`
|
||||
padding-left: 5px;
|
||||
`}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<div>
|
||||
<EuiHealth color={elserHealth}>{i18n.KNOWLEDGE_BASE_ELSER_LABEL}</EuiHealth>
|
||||
<EuiText
|
||||
size={'xs'}
|
||||
color={'subdued'}
|
||||
css={css`
|
||||
padding-left: 20px;
|
||||
`}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Configure ELSER within {machineLearning} to get started. {seeDocs}"
|
||||
id="xpack.elasticAssistant.assistant.settings.knowledgeBasedSettings.knowledgeBaseDescription"
|
||||
values={{
|
||||
machineLearning: (
|
||||
<EuiLink
|
||||
external
|
||||
href={http.basePath.prepend('/app/ml/trained_models')}
|
||||
target="_blank"
|
||||
>
|
||||
{i18n.KNOWLEDGE_BASE_ELSER_MACHINE_LEARNING}
|
||||
</EuiLink>
|
||||
),
|
||||
seeDocs: (
|
||||
<EuiLink
|
||||
external
|
||||
href={
|
||||
'https://www.elastic.co/guide/en/machine-learning/current/ml-nlp-elser.html#download-deploy-elser'
|
||||
}
|
||||
target="_blank"
|
||||
>
|
||||
{i18n.KNOWLEDGE_BASE_ELSER_SEE_DOCS}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiText>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<div>
|
||||
<EuiHealth color={knowledgeBaseHealth}>{i18n.KNOWLEDGE_BASE_LABEL}</EuiHealth>
|
||||
<EuiText
|
||||
size={'xs'}
|
||||
color={'subdued'}
|
||||
css={css`
|
||||
padding-left: 20px;
|
||||
`}
|
||||
>
|
||||
{knowledgeBaseDescription}
|
||||
</EuiText>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<span>
|
||||
<EuiHealth color={esqlHealth}>{i18n.ESQL_LABEL}</EuiHealth>
|
||||
<EuiText
|
||||
size={'xs'}
|
||||
color={'subdued'}
|
||||
css={css`
|
||||
padding-left: 20px;
|
||||
`}
|
||||
>
|
||||
{esqlDescription}
|
||||
</EuiText>
|
||||
</span>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
KnowledgeBaseSettings.displayName = 'KnowledgeBaseSettings';
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const SETTINGS_TITLE = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.settingsTitle',
|
||||
{
|
||||
defaultMessage: 'Knowledge Base',
|
||||
}
|
||||
);
|
||||
|
||||
export const SETTINGS_BADGE = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.settingsBadgeTitle',
|
||||
{
|
||||
defaultMessage: 'Experimental',
|
||||
}
|
||||
);
|
||||
|
||||
export const SETTINGS_DESCRIPTION = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.settingsDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'Powered by ELSER, the Knowledge Base enables the ability to recall documents and other relevant context within your conversation.',
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_LABEL = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.knowledgeBaseLabel',
|
||||
{
|
||||
defaultMessage: 'Knowledge Base',
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_DESCRIPTION = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.knowledgeBaseDescription',
|
||||
{
|
||||
defaultMessage: 'Index where Knowledge Base docs are stored',
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_DESCRIPTION_INSTALLED = (kbIndexPattern: string) =>
|
||||
i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.knowledgeBaseInstalledDescription',
|
||||
{
|
||||
defaultMessage: 'Initialized to `{kbIndexPattern}`',
|
||||
values: { kbIndexPattern },
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_INIT_BUTTON = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.initializeKnowledgeBaseButton',
|
||||
{
|
||||
defaultMessage: 'Initialize',
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_DELETE_BUTTON = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.deleteKnowledgeBaseButton',
|
||||
{
|
||||
defaultMessage: 'Delete',
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_ELSER_LABEL = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.elserLabel',
|
||||
{
|
||||
defaultMessage: 'ELSER Configured',
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_ELSER_MACHINE_LEARNING = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.elserMachineLearningDescription',
|
||||
{
|
||||
defaultMessage: 'Machine Learning',
|
||||
}
|
||||
);
|
||||
|
||||
export const KNOWLEDGE_BASE_ELSER_SEE_DOCS = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.elserSeeDocsDescription',
|
||||
{
|
||||
defaultMessage: 'See docs',
|
||||
}
|
||||
);
|
||||
|
||||
export const ESQL_LABEL = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.esqlLabel',
|
||||
{
|
||||
defaultMessage: 'ES|QL Knowledge Base Documents',
|
||||
}
|
||||
);
|
||||
|
||||
export const ESQL_DESCRIPTION = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.esqlDescription',
|
||||
{
|
||||
defaultMessage: 'Knowledge Base docs for generating ES|QL queries',
|
||||
}
|
||||
);
|
||||
|
||||
export const ESQL_DESCRIPTION_INSTALLED = i18n.translate(
|
||||
'xpack.elasticAssistant.assistant.settings.knowledgeBaseSettings.esqlInstalledDescription',
|
||||
{
|
||||
defaultMessage: 'ES|QL Knowledge Base docs loaded',
|
||||
}
|
||||
);
|
|
@ -72,7 +72,6 @@ export const TestProvidersComponent: React.FC<Props> = ({
|
|||
<AssistantProvider
|
||||
actionTypeRegistry={actionTypeRegistry}
|
||||
assistantAvailability={assistantAvailability}
|
||||
assistantLangChain={false}
|
||||
augmentMessageCodeBlocks={jest.fn().mockReturnValue([])}
|
||||
baseAllow={[]}
|
||||
baseAllowReplacement={[]}
|
||||
|
|
|
@ -46,7 +46,6 @@ export const TestProvidersComponent: React.FC<Props> = ({ children, isILMAvailab
|
|||
<AssistantProvider
|
||||
actionTypeRegistry={actionTypeRegistry}
|
||||
assistantAvailability={mockAssistantAvailability}
|
||||
assistantLangChain={false}
|
||||
augmentMessageCodeBlocks={jest.fn()}
|
||||
baseAllow={[]}
|
||||
baseAllowReplacement={[]}
|
||||
|
|
|
@ -55,9 +55,6 @@ export const AssistantProvider: React.FC = ({ children }) => {
|
|||
actionTypeRegistry={actionTypeRegistry}
|
||||
augmentMessageCodeBlocks={augmentMessageCodeBlocks}
|
||||
assistantAvailability={assistantAvailability}
|
||||
// NOTE: `assistantLangChain` and `assistantModelEvaluation` experimental feature will be coupled until upcoming
|
||||
// Knowledge Base UI updates, which will remove the `assistantLangChain` feature flag in favor of a UI feature toggle
|
||||
assistantLangChain={isModelEvaluationEnabled}
|
||||
assistantTelemetry={assistantTelemetry}
|
||||
defaultAllow={defaultAllow}
|
||||
defaultAllowReplacement={defaultAllowReplacement}
|
||||
|
@ -71,6 +68,7 @@ export const AssistantProvider: React.FC = ({ children }) => {
|
|||
getInitialConversations={getInitialConversation}
|
||||
getComments={getComments}
|
||||
http={http}
|
||||
modelEvaluatorEnabled={isModelEvaluationEnabled}
|
||||
nameSpace={nameSpace}
|
||||
setConversations={setConversations}
|
||||
setDefaultAllow={setDefaultAllow}
|
||||
|
|
|
@ -34,7 +34,6 @@ export const MockAssistantProviderComponent: React.FC<Props> = ({ children }) =>
|
|||
<AssistantProvider
|
||||
actionTypeRegistry={actionTypeRegistry}
|
||||
assistantAvailability={mockAssistantAvailability}
|
||||
assistantLangChain={false}
|
||||
augmentMessageCodeBlocks={jest.fn(() => [])}
|
||||
baseAllow={[]}
|
||||
baseAllowReplacement={[]}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue