diff --git a/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_body.tsx b/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_body.tsx
index cc85c5bf8c1a1..a26eaf015ebb8 100644
--- a/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_body.tsx
+++ b/x-pack/platform/packages/shared/kbn-ai-assistant/src/chat/chat_body.tsx
@@ -383,7 +383,7 @@ export function ChatBody({
const { conversationCalloutDismissed, tourCalloutDismissed } = useElasticLlmCalloutsStatus(false);
const showElasticLlmCalloutInChat =
- elasticManagedLlm &&
+ !!elasticManagedLlm &&
connectors.selectedConnector === elasticManagedLlm.id &&
!conversationCalloutDismissed &&
tourCalloutDismissed;
diff --git a/x-pack/platform/plugins/shared/observability_ai_assistant/public/utils/get_elastic_managed_llm_connector.ts b/x-pack/platform/plugins/shared/observability_ai_assistant/public/utils/get_elastic_managed_llm_connector.ts
index 00c5330934c91..eb6985ea1258c 100644
--- a/x-pack/platform/plugins/shared/observability_ai_assistant/public/utils/get_elastic_managed_llm_connector.ts
+++ b/x-pack/platform/plugins/shared/observability_ai_assistant/public/utils/get_elastic_managed_llm_connector.ts
@@ -13,13 +13,13 @@ export const getElasticManagedLlmConnector = (
connectors: UseGenAIConnectorsResult['connectors'] | undefined
) => {
if (!Array.isArray(connectors) || connectors.length === 0) {
- return false;
+ return undefined;
}
- return connectors.filter(
+ return connectors.find(
(connector) =>
connector.actionTypeId === INFERENCE_CONNECTOR_ACTION_TYPE_ID &&
connector.isPreconfigured &&
connector.config?.provider === 'elastic'
- )[0];
+ );
};
diff --git a/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/generate_pattern_button.tsx b/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/generate_pattern_button.tsx
index 8ff1ac1f2e036..82ea62f15eae8 100644
--- a/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/generate_pattern_button.tsx
+++ b/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/generate_pattern_button.tsx
@@ -21,6 +21,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useBoolean } from '@kbn/react-hooks';
+import { FormattedMessage } from '@kbn/i18n-react';
import { AIFeatures } from './use_ai_features';
import { useKibana } from '../../../../../hooks/use_kibana';
@@ -140,17 +141,47 @@ export const GeneratePatternButton = ({
)}
- {aiFeatures.isManagedAIConnector && !aiFeatures.hasAcknowledgedAdditionalCharges && (
- aiFeatures.acknowledgeAdditionalCharges(true)}>
- {i18n.translate(
- 'xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.managedConnectorTooltip',
- {
- defaultMessage:
- 'Generating patterns is powered by a preconfigured LLM. Additional charges apply',
- }
- )}
-
- )}
>
);
};
+
+export interface AdditionalChargesCalloutProps {
+ aiFeatures: AIFeatures;
+}
+
+export const AdditionalChargesCallout = ({ aiFeatures }: AdditionalChargesCalloutProps) => {
+ const {
+ core: { docLinks },
+ } = useKibana();
+
+ return (
+ aiFeatures.acknowledgeAdditionalCharges(true)}>
+ (
+
+ {chunks}
+
+ ),
+ learnMoreLink: (...chunks: React.ReactNode[]) => (
+
+ {chunks}
+
+ ),
+ }}
+ />
+
+ );
+};
diff --git a/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/grok_patterns_editor.tsx b/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/grok_patterns_editor.tsx
index 48245ba438935..9b10a81528d1a 100644
--- a/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/grok_patterns_editor.tsx
+++ b/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/grok_patterns_editor.tsx
@@ -27,6 +27,7 @@ import {
EuiIcon,
EuiButtonIcon,
EuiFlexItem,
+ EuiSpacer,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { DraftGrokExpression, GrokCollection } from '@kbn/grok-ui';
@@ -36,7 +37,7 @@ import useObservable from 'react-use/lib/useObservable';
import { useStreamsEnrichmentSelector } from '../../state_management/stream_enrichment_state_machine';
import { SortableList } from '../../sortable_list';
import { GrokPatternSuggestion } from './grok_pattern_suggestion';
-import { GeneratePatternButton } from './generate_pattern_button';
+import { GeneratePatternButton, AdditionalChargesCallout } from './generate_pattern_button';
import { useGrokPatternSuggestion } from './use_grok_pattern_suggestion';
import { useSimulatorSelector } from '../../state_management/stream_enrichment_state_machine';
import { selectPreviewDocuments } from '../../state_management/simulation_state_machine/selectors';
@@ -145,39 +146,49 @@ export const GrokPatternsEditor = () => {
onDismiss={() => refreshSuggestions(null)}
/>
) : (
-
- {aiFeatures && (
+ <>
+
+ {aiFeatures && (
+
+
+ refreshSuggestions({
+ connectorId,
+ streamName: stream.name,
+ samples: previewDocuments,
+ fieldName: fieldValue,
+ })
+ }
+ isLoading={suggestionsState.loading}
+ isDisabled={!isValidField}
+ />
+
+ )}
-
- refreshSuggestions({
- connectorId,
- streamName: stream.name,
- samples: previewDocuments,
- fieldName: fieldValue,
- })
- }
- isLoading={suggestionsState.loading}
- isDisabled={!isValidField}
- />
+
+ {i18n.translate(
+ 'xpack.streams.streamDetailView.managementTab.enrichment.processor.grokEditor.addPattern',
+ { defaultMessage: 'Add pattern' }
+ )}
+
- )}
-
-
- {i18n.translate(
- 'xpack.streams.streamDetailView.managementTab.enrichment.processor.grokEditor.addPattern',
- { defaultMessage: 'Add pattern' }
- )}
-
-
-
+
+ {aiFeatures &&
+ aiFeatures.isManagedAIConnector &&
+ !aiFeatures.hasAcknowledgedAdditionalCharges && (
+ <>
+
+
+ >
+ )}
+ >
)}
>
);
diff --git a/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/use_ai_features.tsx b/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/use_ai_features.tsx
index 56e49e044e8e8..66f2415a0cd64 100644
--- a/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/use_ai_features.tsx
+++ b/x-pack/platform/plugins/shared/streams_app/public/components/data_management/stream_detail_enrichment/processors/grok/use_ai_features.tsx
@@ -7,11 +7,13 @@
import useObservable from 'react-use/lib/useObservable';
import { isEmpty } from 'lodash';
-import useLocalStorage from 'react-use/lib/useLocalStorage';
+import {
+ ElasticLlmCalloutKey,
+ useElasticLlmCalloutDismissed,
+ getElasticManagedLlmConnector,
+} from '@kbn/observability-ai-assistant-plugin/public';
import { useKibana } from '../../../../../hooks/use_kibana';
-const INTERNAL_INFERENCE_CONNECTORS = ['Elastic-Managed-LLM'];
-
export function useAIFeatures() {
const {
dependencies: {
@@ -21,10 +23,10 @@ export function useAIFeatures() {
} = useKibana();
const genAiConnectors = observabilityAIAssistant.useGenAIConnectors();
const license = useObservable(licensing.license$);
- const [hasAcknowledgedAdditionalCharges, acknowledgeAdditionalCharges] = useLocalStorage(
- 'streams:additionalChargesAcknowledged',
- false
+ const [tourCalloutDismissed, setTourCalloutDismissed] = useElasticLlmCalloutDismissed(
+ ElasticLlmCalloutKey.TOUR_CALLOUT
);
+ const elasticManagedLlmConnector = getElasticManagedLlmConnector(genAiConnectors.connectors);
if (genAiConnectors.loading) {
return undefined;
@@ -35,8 +37,8 @@ export function useAIFeatures() {
const couldBeEnabled = Boolean(
license?.hasAtLeast('enterprise') && core.application.capabilities.actions?.save
);
- const isManagedAIConnector = genAiConnectors.selectedConnector
- ? INTERNAL_INFERENCE_CONNECTORS.includes(genAiConnectors.selectedConnector)
+ const isManagedAIConnector = elasticManagedLlmConnector
+ ? elasticManagedLlmConnector.id === genAiConnectors.selectedConnector
: false;
return {
@@ -44,8 +46,8 @@ export function useAIFeatures() {
couldBeEnabled,
genAiConnectors,
isManagedAIConnector,
- hasAcknowledgedAdditionalCharges,
- acknowledgeAdditionalCharges,
+ hasAcknowledgedAdditionalCharges: tourCalloutDismissed,
+ acknowledgeAdditionalCharges: setTourCalloutDismissed,
};
}