From 588704b2d12193a011cdca0096ad3510ff89ab1a Mon Sep 17 00:00:00 2001 From: Kenneth Kreindler <42113355+KDKHD@users.noreply.github.com> Date: Thu, 10 Jul 2025 14:18:43 +0100 Subject: [PATCH] [Security Solution] [AI Assistant] Remove advanced esql generation feature flag (#226740) ## Summary Summarize your PR. If it involves visual changes include a screenshot or gif. Remove feature flag for advanced ESQL generation. This will enable ESQL generation with validation in the Security AI assistant. ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [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/src/platform/packages/shared/kbn-i18n/README.md) - [X] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [X] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [X] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [X] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [X] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [X] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [X] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ... --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine (cherry picked from commit 2928bdf1cb5f8fd648c6a46a52ae3f96b4b01a70) # Conflicts: # x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/capabilities/index.ts --- .../impl/capabilities/index.ts | 1 - .../assistant_provider.test.tsx | 1 - .../lib/telemetry/event_based_telemetry.ts | 12 ++- .../common/experimental_features.ts | 5 -- .../tools/esql/ask_about_esql_tool.ts | 9 +- .../tools/esql/generate_esql_tool.ts | 3 +- .../assistant/tools/esql/nl_to_esql_tool.ts | 87 ------------------- .../server/assistant/tools/index.ts | 2 - .../security_solution/server/plugin.ts | 1 - 9 files changed, 13 insertions(+), 108 deletions(-) delete mode 100644 x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/nl_to_esql_tool.ts diff --git a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/capabilities/index.ts b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/capabilities/index.ts index 2bda440886bde..0e204b4b949ea 100644 --- a/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/capabilities/index.ts +++ b/x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/capabilities/index.ts @@ -21,5 +21,4 @@ export type AssistantFeatureKey = keyof AssistantFeatures; export const defaultAssistantFeatures = Object.freeze({ assistantModelEvaluation: false, defendInsights: false, - advancedEsqlGeneration: false, }); diff --git a/x-pack/solutions/security/plugins/elastic_assistant/public/src/context/assistant_context/assistant_provider.test.tsx b/x-pack/solutions/security/plugins/elastic_assistant/public/src/context/assistant_context/assistant_provider.test.tsx index 2bed09bd68558..d47f792ee0b03 100644 --- a/x-pack/solutions/security/plugins/elastic_assistant/public/src/context/assistant_context/assistant_provider.test.tsx +++ b/x-pack/solutions/security/plugins/elastic_assistant/public/src/context/assistant_context/assistant_provider.test.tsx @@ -69,7 +69,6 @@ describe('AssistantProvider', () => { isStarterPromptsEnabled: expect.any(Boolean), }), assistantFeatures: expect.objectContaining({ - advancedEsqlGeneration: expect.any(Boolean), assistantModelEvaluation: expect.any(Boolean), defendInsights: expect.any(Boolean), }), diff --git a/x-pack/solutions/security/plugins/elastic_assistant/server/lib/telemetry/event_based_telemetry.ts b/x-pack/solutions/security/plugins/elastic_assistant/server/lib/telemetry/event_based_telemetry.ts index d5685bf3ab610..c0a74f9cd72cd 100644 --- a/x-pack/solutions/security/plugins/elastic_assistant/server/lib/telemetry/event_based_telemetry.ts +++ b/x-pack/solutions/security/plugins/elastic_assistant/server/lib/telemetry/event_based_telemetry.ts @@ -79,7 +79,8 @@ export const INVOKE_ASSISTANT_SUCCESS_EVENT: EventTypeOpts<{ durationMs: number; toolsInvoked: { AlertCountsTool?: number; - NaturalLanguageESQLTool?: number; + GenerateESQLTool?: number; + AskAboutESQLTool?: number; KnowledgeBaseRetrievalTool?: number; KnowledgeBaseWriteTool?: number; OpenAndAcknowledgedAlertsTool?: number; @@ -139,7 +140,14 @@ export const INVOKE_ASSISTANT_SUCCESS_EVENT: EventTypeOpts<{ optional: true, }, }, - NaturalLanguageESQLTool: { + GenerateESQLTool: { + type: 'long', + _meta: { + description: 'Number of times tool was invoked.', + optional: true, + }, + }, + AskAboutESQLTool: { type: 'long', _meta: { description: 'Number of times tool was invoked.', diff --git a/x-pack/solutions/security/plugins/security_solution/common/experimental_features.ts b/x-pack/solutions/security/plugins/security_solution/common/experimental_features.ts index 7b02f852586d5..bf6e80cf066a1 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/experimental_features.ts @@ -103,11 +103,6 @@ export const allowedExperimentalValues = Object.freeze({ */ assistantModelEvaluation: false, - /** - * Enables advanced ESQL generation for the Assistant. - */ - advancedEsqlGeneration: false, - /** * Enables the Managed User section inside the new user details flyout. */ diff --git a/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/ask_about_esql_tool.ts b/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/ask_about_esql_tool.ts index bcedca300c5fd..8055e20f4059a 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/ask_about_esql_tool.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/ask_about_esql_tool.ts @@ -16,7 +16,7 @@ import { getPromptSuffixForOssModel } from './utils/common'; export type ESQLToolParams = Require; -const TOOL_NAME = 'AskAboutEsqlTool'; +const TOOL_NAME = 'AskAboutESQLTool'; const toolDetails = { id: 'ask-about-esql-tool', @@ -40,12 +40,7 @@ export const ASK_ABOUT_ESQL_TOOL: AssistantTool = { sourceRegister: APP_UI_ID, isSupported: (params: AssistantToolParams): params is ESQLToolParams => { const { inference, connectorId, assistantContext } = params; - return ( - inference != null && - connectorId != null && - assistantContext != null && - assistantContext.getRegisteredFeatures('securitySolutionUI').advancedEsqlGeneration - ); + return inference != null && connectorId != null && assistantContext != null; }, async getTool(params: AssistantToolParams) { if (!this.isSupported(params)) return null; diff --git a/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/generate_esql_tool.ts b/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/generate_esql_tool.ts index 1b417bbb61a52..c4f519996bcba 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/generate_esql_tool.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/generate_esql_tool.ts @@ -22,7 +22,7 @@ export type GenerateEsqlParams = Require< const TOOL_NAME = 'GenerateESQLTool'; const toolDetails = { - id: 'gnerate-esql-tool', + id: 'generate-esql-tool', name: TOOL_NAME, // note: this description is overwritten when `getTool` is called // local definitions exist ../elastic_assistant/server/lib/prompt/tool_prompts.ts @@ -43,7 +43,6 @@ export const GENERATE_ESQL_TOOL: AssistantTool = { inference != null && connectorId != null && assistantContext != null && - assistantContext.getRegisteredFeatures('securitySolutionUI').advancedEsqlGeneration && createLlmInstance != null ); }, diff --git a/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/nl_to_esql_tool.ts b/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/nl_to_esql_tool.ts deleted file mode 100644 index 0af8c46dbf3ec..0000000000000 --- a/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/esql/nl_to_esql_tool.ts +++ /dev/null @@ -1,87 +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 { tool } from '@langchain/core/tools'; -import type { AssistantTool, AssistantToolParams } from '@kbn/elastic-assistant-plugin/server'; -import { lastValueFrom } from 'rxjs'; -import { naturalLanguageToEsql } from '@kbn/inference-plugin/server'; -import { z } from '@kbn/zod'; -import type { Require } from '@kbn/elastic-assistant-plugin/server/types'; -import { APP_UI_ID } from '../../../../common'; -import { getPromptSuffixForOssModel } from './utils/common'; - -// select only some properties of AssistantToolParams - -export type ESQLToolParams = Require; - -const TOOL_NAME = 'NaturalLanguageESQLTool'; - -const toolDetails = { - id: 'nl-to-esql-tool', - name: TOOL_NAME, - // note: this description is overwritten when `getTool` is called - // local definitions exist ../elastic_assistant/server/lib/prompt/tool_prompts.ts - // local definitions can be overwritten by security-ai-prompt integration definitions - description: `You MUST use the "${TOOL_NAME}" function when the user wants to: - - breakdown or filter ES|QL queries that are displayed on the current page - - convert queries from another language to ES|QL - - asks general questions about ES|QL - - ALWAYS use this tool to generate ES|QL queries or explain anything about the ES|QL query language rather than coming up with your own answer.`, -}; - -export const NL_TO_ESQL_TOOL: AssistantTool = { - ...toolDetails, - sourceRegister: APP_UI_ID, - isSupported: (params: AssistantToolParams): params is ESQLToolParams => { - const { inference, connectorId, assistantContext } = params; - return ( - inference != null && - connectorId != null && - assistantContext != null && - !assistantContext.getRegisteredFeatures('securitySolutionUI').advancedEsqlGeneration - ); - }, - async getTool(params: AssistantToolParams) { - if (!this.isSupported(params)) return null; - - const { connectorId, inference, logger, request, isOssModel } = params as ESQLToolParams; - if (inference == null || connectorId == null) return null; - - const callNaturalLanguageToEsql = async (question: string) => { - return lastValueFrom( - naturalLanguageToEsql({ - client: inference.getClient({ request }), - connectorId, - input: question, - functionCalling: 'auto', - logger, - }) - ); - }; - - return tool( - async (input) => { - const generateEvent = await callNaturalLanguageToEsql(input.question); - const answer = generateEvent.content ?? 'An error occurred in the tool'; - - logger.debug(`Received response from NL to ESQL tool: ${answer}`); - return answer; - }, - { - name: toolDetails.name, - description: - (params.description || toolDetails.description) + - (isOssModel ? getPromptSuffixForOssModel(TOOL_NAME) : ''), - schema: z.object({ - question: z.string().describe(`The user's exact question about ESQL`), - }), - tags: ['esql', 'query-generation', 'knowledge-base'], - } - ); - }, -}; diff --git a/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/index.ts b/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/index.ts index 4e55e97ceb455..ffed96f0b68a5 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/assistant/tools/index.ts @@ -8,7 +8,6 @@ import { PRODUCT_DOCUMENTATION_TOOL } from './product_docs/product_documentation_tool'; import { GENERATE_ESQL_TOOL } from './esql/generate_esql_tool'; import { ASK_ABOUT_ESQL_TOOL } from './esql/ask_about_esql_tool'; -import { NL_TO_ESQL_TOOL } from './esql/nl_to_esql_tool'; import { ALERT_COUNTS_TOOL } from './alert_counts/alert_counts_tool'; import { OPEN_AND_ACKNOWLEDGED_ALERTS_TOOL } from './open_and_acknowledged_alerts/open_and_acknowledged_alerts_tool'; import { DEFEND_INSIGHTS_TOOL } from './defend_insights'; @@ -25,7 +24,6 @@ export const assistantTools = [ KNOWLEDGE_BASE_WRITE_TOOL, GENERATE_ESQL_TOOL, ASK_ABOUT_ESQL_TOOL, - NL_TO_ESQL_TOOL, OPEN_AND_ACKNOWLEDGED_ALERTS_TOOL, PRODUCT_DOCUMENTATION_TOOL, SECURITY_LABS_KNOWLEDGE_BASE_TOOL, diff --git a/x-pack/solutions/security/plugins/security_solution/server/plugin.ts b/x-pack/solutions/security/plugins/security_solution/server/plugin.ts index b13498debf7d3..77626376f9432 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/plugin.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/plugin.ts @@ -599,7 +599,6 @@ export class Plugin implements ISecuritySolutionPlugin { plugins.elasticAssistant.registerTools(APP_UI_ID, assistantTools); const features = { assistantModelEvaluation: config.experimentalFeatures.assistantModelEvaluation, - advancedEsqlGeneration: config.experimentalFeatures.advancedEsqlGeneration, }; plugins.elasticAssistant.registerFeatures(APP_UI_ID, features); plugins.elasticAssistant.registerFeatures('management', features);