From 309f513b6e1dfd699eeb2e5c46a7da1761033f49 Mon Sep 17 00:00:00 2001 From: Ievgen Sorokopud Date: Tue, 4 Mar 2025 13:05:51 +0100 Subject: [PATCH] [Bug] [Assistant API] - Do not allow empty conversation ID in chat/complete route (#11783) (#213049) ## Summary BUG: https://github.com/elastic/security-team/issues/11783 This PR fixes the behaviour of the `/api/security_ai_assistant/chat/complete` route where the `conversationId` can be passed as an empty string. This may lead to unexpected results described in https://github.com/elastic/security-team/issues/11783#issuecomment-2696529040. ### Expected behaviour We should throw a bad request (400) http error when empty `conversationId` has been passed. ### Testing * Use this `curl` command to test the endpoint. ``` curl --location 'http://localhost:5601/api/security_ai_assistant/chat/complete' \ --header 'kbn-xsrf: true' \ --header 'Content-Type: application/json' \ --data '{ "connectorId": "{{my-gpt4o-ai}}", "conversationId": "", "isStream": false, "messages": [ { "content": "Follow up", "role": "user" } ], "persist": true }' ``` You should see next error as a response: ``` { "statusCode": 400, "error": "Bad Request", "message": "[request body]: conversationId: String must contain at least 1 character(s), conversationId: No empty strings allowed" } ``` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> (cherry picked from commit 7db897a5393f2d776eca1d9760801dc2fa72ad9d) --- oas_docs/output/kibana.serverless.yaml | 2 +- oas_docs/output/kibana.yaml | 2 +- .../ess/elastic_assistant_api_2023_10_31.bundled.schema.yaml | 2 +- .../elastic_assistant_api_2023_10_31.bundled.schema.yaml | 2 +- .../impl/schemas/chat/post_chat_complete_route.gen.ts | 4 +++- .../impl/schemas/chat/post_chat_complete_route.schema.yaml | 4 ++-- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index 787aab237db04..9bcda120baaf5 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -42966,7 +42966,7 @@ components: connectorId: type: string conversationId: - type: string + $ref: '#/components/schemas/Security_AI_Assistant_API_NonEmptyString' isStream: type: boolean langSmithApiKey: diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index b76e478c009bf..5ecd9c32b94d7 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -34580,7 +34580,7 @@ components: connectorId: type: string conversationId: - type: string + $ref: '#/components/schemas/Security_AI_Assistant_API_NonEmptyString' isStream: type: boolean langSmithApiKey: diff --git a/x-pack/packages/kbn-elastic-assistant-common/docs/openapi/ess/elastic_assistant_api_2023_10_31.bundled.schema.yaml b/x-pack/packages/kbn-elastic-assistant-common/docs/openapi/ess/elastic_assistant_api_2023_10_31.bundled.schema.yaml index 19faddceb894f..85b5f6e83fe76 100644 --- a/x-pack/packages/kbn-elastic-assistant-common/docs/openapi/ess/elastic_assistant_api_2023_10_31.bundled.schema.yaml +++ b/x-pack/packages/kbn-elastic-assistant-common/docs/openapi/ess/elastic_assistant_api_2023_10_31.bundled.schema.yaml @@ -731,7 +731,7 @@ components: connectorId: type: string conversationId: - type: string + $ref: '#/components/schemas/NonEmptyString' isStream: type: boolean langSmithApiKey: diff --git a/x-pack/packages/kbn-elastic-assistant-common/docs/openapi/serverless/elastic_assistant_api_2023_10_31.bundled.schema.yaml b/x-pack/packages/kbn-elastic-assistant-common/docs/openapi/serverless/elastic_assistant_api_2023_10_31.bundled.schema.yaml index fc507ff95f19b..598ed39df7d59 100644 --- a/x-pack/packages/kbn-elastic-assistant-common/docs/openapi/serverless/elastic_assistant_api_2023_10_31.bundled.schema.yaml +++ b/x-pack/packages/kbn-elastic-assistant-common/docs/openapi/serverless/elastic_assistant_api_2023_10_31.bundled.schema.yaml @@ -731,7 +731,7 @@ components: connectorId: type: string conversationId: - type: string + $ref: '#/components/schemas/NonEmptyString' isStream: type: boolean langSmithApiKey: diff --git a/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.gen.ts b/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.gen.ts index cd43bda23faf4..a21c6efe9922b 100644 --- a/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.gen.ts +++ b/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.gen.ts @@ -16,6 +16,8 @@ import { z } from '@kbn/zod'; +import { NonEmptyString } from '../common_attributes.gen'; + export type RootContext = z.infer; export const RootContext = z.literal('security'); @@ -52,7 +54,7 @@ export const ChatMessage = z.object({ export type ChatCompleteProps = z.infer; export const ChatCompleteProps = z.object({ - conversationId: z.string().optional(), + conversationId: NonEmptyString.optional(), promptId: z.string().optional(), isStream: z.boolean().optional(), responseLanguage: z.string().optional(), diff --git a/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.schema.yaml b/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.schema.yaml index 53392e63413af..93f93ed5ab2f3 100644 --- a/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.schema.yaml +++ b/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/chat/post_chat_complete_route.schema.yaml @@ -83,7 +83,7 @@ components: type: object properties: conversationId: - type: string + $ref: '../common_attributes.schema.yaml#/components/schemas/NonEmptyString' promptId: type: string isStream: @@ -103,7 +103,7 @@ components: messages: type: array items: - $ref: '#/components/schemas/ChatMessage' + $ref: '#/components/schemas/ChatMessage' required: - messages - persist