Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution] Fixes Preconfigured Connectors not working with Assistant #164900

Merged
merged 8 commits into from
Aug 28, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const AssistantTitle: React.FC<{
const content = useMemo(
() => (
<FormattedMessage
defaultMessage="The Elastic AI Assistant is currently in beta. For more information on the assistant feature and its usage, please reference the {documentationLink}."
defaultMessage="Responses from AI systems may not always be entirely accurate. For more information on the assistant feature and its usage, please reference the {documentationLink}."
id="xpack.elasticAssistant.assistant.technicalPreview.tooltipContent"
values={{
documentationLink,
Expand Down Expand Up @@ -106,7 +106,6 @@ export const AssistantTitle: React.FC<{
anchorPosition="rightUp"
>
<EuiText data-test-subj="tooltipContent" grow={false} css={{ maxWidth: '400px' }}>
<h4>{i18n.TOOLTIP_TITLE}</h4>
<EuiText size={'s'}>
<p>{content}</p>
</EuiText>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ModelSelector } from '../../../connectorland/models/model_selector/mode
import { UseAssistantContext } from '../../../assistant_context';
import { ConversationSelectorSettings } from '../conversation_selector_settings';
import { getDefaultSystemPrompt } from '../../use_conversation/helpers';
import { useLoadConnectors } from '../../../connectorland/use_load_connectors';

export interface ConversationSettingsProps {
actionTypeRegistry: ActionTypeRegistryContract;
Expand Down Expand Up @@ -63,6 +64,8 @@ export const ConversationSettings: React.FC<ConversationSettingsProps> = React.m
return getDefaultSystemPrompt({ allSystemPrompts, conversation: selectedConversation });
}, [allSystemPrompts, selectedConversation]);

const { data: connectors, isSuccess: areConnectorsFetched } = useLoadConnectors({ http });

// Conversation callbacks
// When top level conversation selection changes
const onConversationSelectionChange = useCallback(
Expand Down Expand Up @@ -131,10 +134,13 @@ export const ConversationSettings: React.FC<ConversationSettingsProps> = React.m
[selectedConversation, setUpdatedConversationSettings]
);

const selectedConnectorId = useMemo(
() => selectedConversation?.apiConfig.connectorId,
[selectedConversation?.apiConfig.connectorId]
);
const selectedConnector = useMemo(() => {
const selectedConnectorId = selectedConversation?.apiConfig.connectorId;
if (areConnectorsFetched) {
return connectors?.find((c) => c.id === selectedConnectorId);
}
return undefined;
}, [areConnectorsFetched, connectors, selectedConversation?.apiConfig.connectorId]);

const selectedProvider = useMemo(
() => selectedConversation?.apiConfig.provider,
Expand Down Expand Up @@ -244,23 +250,24 @@ export const ConversationSettings: React.FC<ConversationSettingsProps> = React.m
isDisabled={selectedConversation == null}
onConnectorModalVisibilityChange={() => {}}
onConnectorSelectionChange={handleOnConnectorSelectionChange}
selectedConnectorId={selectedConnectorId}
selectedConnectorId={selectedConnector?.id}
/>
</EuiFormRow>

{selectedProvider === OpenAiProviderType.OpenAi && (
<EuiFormRow
data-test-subj="model-field"
display="rowCompressed"
label={i18nModel.MODEL_TITLE}
helpText={i18nModel.HELP_LABEL}
>
<ModelSelector
onModelSelectionChange={handleOnModelSelectionChange}
selectedModel={selectedModel}
/>
</EuiFormRow>
)}
{selectedConnector?.isPreconfigured === false &&
selectedProvider === OpenAiProviderType.OpenAi && (
<EuiFormRow
data-test-subj="model-field"
display="rowCompressed"
label={i18nModel.MODEL_TITLE}
helpText={i18nModel.HELP_LABEL}
>
<ModelSelector
onModelSelectionChange={handleOnModelSelectionChange}
selectedModel={selectedModel}
/>
</EuiFormRow>
)}
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,6 @@ export const API_ERROR = i18n.translate('xpack.elasticAssistant.assistant.apiErr
'An error occurred sending your message. If the problem persists, please test the connector configuration.',
});

export const TOOLTIP_TITLE = i18n.translate(
'xpack.elasticAssistant.assistant.technicalPreview.tooltipTitle',
{
defaultMessage: 'Beta',
}
);

export const TOOLTIP_ARIA_LABEL = i18n.translate(
'xpack.elasticAssistant.documentationLinks.ariaLabel',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,18 @@ export const ConnectorSelector: React.FC<Props> = React.memo(
const apiProvider: string | undefined = (
connector as ActionConnectorProps<Config, unknown>
)?.config?.apiProvider;
const connectorDetails = connector.isPreconfigured
? i18n.PRECONFIGURED_CONNECTOR
: apiProvider;
return {
value: connector.id,
inputDisplay: connector.name,
dropdownDisplay: (
<React.Fragment key={connector.id}>
<strong>{connector.name}</strong>
{apiProvider && (
<EuiText size="s" color="subdued">
<p>{apiProvider}</p>
{connectorDetails && (
<EuiText size="xs" color="subdued">
<p>{connectorDetails}</p>
</EuiText>
)}
</React.Fragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ export const ConnectorSelectorInline: React.FC<Props> = React.memo(
const apiProvider: string | undefined = (
connector as ActionConnectorProps<Config, unknown>
)?.config?.apiProvider;
const connectorDetails = connector.isPreconfigured
? i18n.PRECONFIGURED_CONNECTOR
: apiProvider;
return {
value: connector.id,
inputDisplay: (
Expand All @@ -149,9 +152,9 @@ export const ConnectorSelectorInline: React.FC<Props> = React.memo(
dropdownDisplay: (
<React.Fragment key={connector.id}>
<strong>{connector.name}</strong>
{apiProvider && (
{connectorDetails && (
<EuiText size="xs" color="subdued">
<p>{apiProvider}</p>
<p>{connectorDetails}</p>
</EuiText>
)}
</React.Fragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ export const WELCOME_SECURITY = i18n.translate(
}
);

export const PRECONFIGURED_CONNECTOR = i18n.translate(
'xpack.elasticAssistant.assistant.connectors.preconfiguredTitle',
{
defaultMessage: 'Preconfigured',
}
);

export const CONNECTOR_SELECTOR_TITLE = i18n.translate(
'xpack.elasticAssistant.assistant.connectors.connectorSelector.ariaLabel',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
* 2.0.
*/

import React, { useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { NewChat } from '@kbn/elastic-assistant';
import { useUserData } from '../../../../detections/components/user_info';
import { TabNavigation } from '../../../../common/components/navigation/tab_navigation';
import { usePrebuiltRulesStatus } from '../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_status';
import { useRuleManagementFilters } from '../../../rule_management/logic/use_rule_management_filters';
import * as i18n from './translations';
import { getPromptContextFromDetectionRules } from '../../../../assistant/helpers';
import { useRulesTableContext } from './rules_table/rules_table_context';
import { useAssistantAvailability } from '../../../../assistant/use_assistant_availability';
import * as i18nAssistant from '../../../../detections/pages/detection_engine/rules/translations';

export enum AllRulesTabs {
management = 'management',
Expand Down Expand Up @@ -71,7 +77,39 @@ export const RulesTableToolbar = React.memo(() => {
[installedTotal, updateTotal, shouldDisplayRuleUpdatesTab]
);

return <TabNavigation navTabs={ruleTabs} />;
// Assistant integration for using selected rules as prompt context
const { hasAssistantPrivilege } = useAssistantAvailability();
const {
state: { rules, selectedRuleIds },
} = useRulesTableContext();
const selectedRules = useMemo(
() => rules.filter((rule) => selectedRuleIds.includes(rule.id)),
[rules, selectedRuleIds]
);
const getPromptContext = useCallback(
async () => getPromptContextFromDetectionRules(selectedRules),
[selectedRules]
);

return (
<EuiFlexGroup justifyContent={'spaceBetween'}>
<EuiFlexItem grow={false}>
<TabNavigation navTabs={ruleTabs} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
{hasAssistantPrivilege && selectedRules.length > 0 && (
<NewChat
category="detection-rules"
conversationId={i18nAssistant.DETECTION_RULES_CONVERSATION_ID}
description={i18nAssistant.RULE_MANAGEMENT_CONTEXT_DESCRIPTION}
getPromptContext={getPromptContext}
suggestedUserPrompt={i18nAssistant.EXPLAIN_THEN_SUMMARIZE_RULE_DETAILS}
tooltip={i18nAssistant.RULE_MANAGEMENT_CONTEXT_TOOLTIP}
/>
)}
</EuiFlexItem>
</EuiFlexGroup>
);
});

RulesTableToolbar.displayName = 'RulesTableToolbar';
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import { useInvalidateFindRulesQuery } from '../../../rule_management/api/hooks/
import { importRules } from '../../../rule_management/logic';
import { AllRules } from '../../components/rules_table';
import { RulesTableContextProvider } from '../../components/rules_table/rules_table/rules_table_context';
import { SuperHeader } from './super_header';
import { useInvalidateFetchCoverageOverviewQuery } from '../../../rule_management/api/hooks/use_fetch_coverage_overview';
import { HeaderPage } from '../../../../common/components/header_page';

const RulesPageComponent: React.FC = () => {
const [isImportModalVisible, showImportModal, hideImportModal] = useBoolState();
Expand Down Expand Up @@ -110,7 +110,7 @@ const RulesPageComponent: React.FC = () => {

<RulesTableContextProvider>
<SecuritySolutionPageWrapper>
<SuperHeader>
<HeaderPage title={i18n.PAGE_TITLE}>
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false} wrap={true}>
<EuiFlexItem grow={false}>
<AddElasticRulesButton isDisabled={!canUserCRUD || loading} />
Expand Down Expand Up @@ -149,7 +149,7 @@ const RulesPageComponent: React.FC = () => {
</SecuritySolutionLinkButton>
</EuiFlexItem>
</EuiFlexGroup>
</SuperHeader>
</HeaderPage>
<MaintenanceWindowCallout kibanaServices={kibanaServices} />
<AllRules data-test-subj="all-rules" />
</SecuritySolutionPageWrapper>
Expand Down

This file was deleted.