[Security Assistant] Aligning API Schemas (#188704)

## Summary

This PR aims to address https://github.com/elastic/kibana/issues/183825
to ensure all our public API's have a corresponding OpenAPI spec and to
ensure that they are documented as intended.

I've updated the kbn-elastic-assistant-common `yarn openapi:bundle`
script to generate both `ess` and `serverless` artifacts (as per [this
issue](https://github.com/elastic/security-team/issues/9516), which are
now created within the package (instead of `target`), and so are checked
in to `x-pack/packages/kbn-elastic-assistant-common/docs/openapi/`.


This also includes:

- [X] Create OpenAPI specs for the endpoints listed above (see
[issue](https://github.com/elastic/kibana/issues/183825)).
  - They had already existed  
- [X] Check if there are any other public endpoints that you own that
don't have OpenAPI specs and add them to the list above.
- All endpoints (public/internal) had specs, but did need to update the
`path`'s to make sure they were consistent with what was registered.
- [X] Make sure the specs you add are valid OpenAPI documents.
- [X] Make sure the specs you add match the actual API contract defined
in the code.
- [X] Mark the endpoints as available in ESS, or Serverless, or in both
offerings.

---
Initial evaluation of routes listed as missing specs in
https://github.com/elastic/kibana/issues/183825:

- [X] `POST
/api/elastic_assistant/current_user/conversations/{id}/messages`
Latest/Actual Route:
`/internal/elastic_assistant/current_user/conversations/{id}/messages`
Route Handler:
bae84d4569/x-pack/plugins/elastic_assistant/server/routes/user_conversations/append_conversation_messages_route.ts (L22)
Schema:
bae84d4569/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/conversations/crud_conversation_route.schema.yaml (L151-L191)


- [X]  `POST /api/elastic_assistant/current_user/conversations`
Updated Route: `/api/security_ai_assistant/current_user/conversations`
Route Handler:
1d4e9b9b53/x-pack/plugins/elastic_assistant/server/routes/user_conversations/create_route.ts (L21)
Schema:
bae84d4569/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/conversations/crud_conversation_route.schema.yaml (L6-L39)

- [X]  GET /api/elastic_assistant/current_user/conversations/_find
Updated Route:
`/api/security_ai_assistant/current_user/conversations/_find`
Route Handler:
1d4e9b9b53/x-pack/plugins/elastic_assistant/server/routes/user_conversations/find_route.ts (L26)
Schema:
1b872fbf9d/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/conversations/find_conversations_route.schema.yaml (L94-L180)

- [X]  DELETE /api/elastic_assistant/current_user/conversations/{id}
Updated Route:
`/api/security_ai_assistant/current_user/conversations/{id}`
Route Handler:
1d5cf48a97/x-pack/plugins/elastic_assistant/server/routes/user_conversations/delete_route.ts (L19)
Schema:
bae84d4569/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/conversations/crud_conversation_route.schema.yaml (L116-L149)

- [X] GET /api/elastic_assistant/current_user/conversations/{id}
Updated Route:
`/api/security_ai_assistant/current_user/conversations/{id}`
Route Handler:
1d5cf48a97/x-pack/plugins/elastic_assistant/server/routes/user_conversations/read_route.ts (L21)
Schema:
bae84d4569/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/conversations/crud_conversation_route.schema.yaml (L42-L75)

- [X]  PUT /api/elastic_assistant/current_user/conversations/{id}
Updated Route:
`/api/security_ai_assistant/current_user/conversations/{id}`
Route Handler:
1d5cf48a97/x-pack/plugins/elastic_assistant/server/routes/user_conversations/update_route.ts (L24)
Schema:
bae84d4569/x-pack/packages/kbn-elastic-assistant-common/impl/schemas/conversations/crud_conversation_route.schema.yaml (L76-L115)


To continue with remaining public routes....

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Garrett Spong 2024-07-24 08:03:46 -06:00 committed by GitHub
parent 6e09aef3be
commit a51b775391
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 2716 additions and 272 deletions

View file

@ -0,0 +1,114 @@
openapi: 3.0.3
info:
description: Manage and interact with Security Assistant resources.
title: Security AI Assistant API (Elastic Cloud & self-hosted)
version: '2023-10-31'
servers:
- url: 'http://{kibana_host}:{port}'
variables:
kibana_host:
default: localhost
port:
default: '5601'
paths:
/api/security_ai_assistant/chat/complete:
post:
description: Creates a model response for the given chat conversation.
operationId: ChatComplete
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ChatCompleteProps'
required: true
responses:
'200':
content:
application/octet-stream:
schema:
format: binary
type: string
description: Indicates a successful call.
'400':
content:
application/json:
schema:
type: object
properties:
error:
type: string
message:
type: string
statusCode:
type: number
description: Generic Error
summary: Creates a model response for the given chat conversation.
tags:
- Chat Complete API
components:
schemas:
ChatCompleteProps:
type: object
properties:
connectorId:
type: string
conversationId:
type: string
isStream:
type: boolean
langSmithApiKey:
type: string
langSmithProject:
type: string
messages:
items:
$ref: '#/components/schemas/ChatMessage'
type: array
model:
type: string
persist:
type: boolean
promptId:
type: string
responseLanguage:
type: string
required:
- messages
- persist
- connectorId
ChatMessage:
description: AI assistant message.
type: object
properties:
content:
description: Message content.
type: string
data:
$ref: '#/components/schemas/MessageData'
description: ECS object to attach to the context of the message.
fields_to_anonymize:
items:
type: string
type: array
role:
$ref: '#/components/schemas/ChatMessageRole'
description: Message role.
required:
- role
ChatMessageRole:
description: Message role.
enum:
- system
- user
- assistant
type: string
MessageData:
additionalProperties: true
type: object
securitySchemes:
BasicAuth:
scheme: basic
type: http
security:
- BasicAuth: []
tags: !<tag:yaml.org,2002:js/undefined> ''

View file

@ -0,0 +1,114 @@
openapi: 3.0.3
info:
description: Manage and interact with Security Assistant resources.
title: Security AI Assistant API (Elastic Cloud Serverless)
version: '2023-10-31'
servers:
- url: 'http://{kibana_host}:{port}'
variables:
kibana_host:
default: localhost
port:
default: '5601'
paths:
/api/security_ai_assistant/chat/complete:
post:
description: Creates a model response for the given chat conversation.
operationId: ChatComplete
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ChatCompleteProps'
required: true
responses:
'200':
content:
application/octet-stream:
schema:
format: binary
type: string
description: Indicates a successful call.
'400':
content:
application/json:
schema:
type: object
properties:
error:
type: string
message:
type: string
statusCode:
type: number
description: Generic Error
summary: Creates a model response for the given chat conversation.
tags:
- Chat Complete API
components:
schemas:
ChatCompleteProps:
type: object
properties:
connectorId:
type: string
conversationId:
type: string
isStream:
type: boolean
langSmithApiKey:
type: string
langSmithProject:
type: string
messages:
items:
$ref: '#/components/schemas/ChatMessage'
type: array
model:
type: string
persist:
type: boolean
promptId:
type: string
responseLanguage:
type: string
required:
- messages
- persist
- connectorId
ChatMessage:
description: AI assistant message.
type: object
properties:
content:
description: Message content.
type: string
data:
$ref: '#/components/schemas/MessageData'
description: ECS object to attach to the context of the message.
fields_to_anonymize:
items:
type: string
type: array
role:
$ref: '#/components/schemas/ChatMessageRole'
description: Message role.
required:
- role
ChatMessageRole:
description: Message role.
enum:
- system
- user
- assistant
type: string
MessageData:
additionalProperties: true
type: object
securitySchemes:
BasicAuth:
scheme: basic
type: http
security:
- BasicAuth: []
tags: !<tag:yaml.org,2002:js/undefined> ''

View file

@ -5,8 +5,9 @@ info:
paths:
/internal/elastic_assistant/actions/connector/{connectorId}/_execute:
post:
operationId: ExecuteConnector
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: ExecuteConnector
description: Execute Elastic Assistant connector by id
summary: Execute Elastic Assistant connector
tags:

View file

@ -10,7 +10,7 @@
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
*
* info:
* title: Bulk Actions API endpoint
* title: Bulk Anonymization Fields Actions API endpoint
* version: 1
*/
@ -18,14 +18,20 @@ import { z } from 'zod';
import { NonEmptyString } from '../common_attributes.gen';
export type BulkActionSkipReason = z.infer<typeof BulkActionSkipReason>;
export const BulkActionSkipReason = z.literal('ANONYMIZATION_FIELD_NOT_MODIFIED');
export type AnonymizationFieldsBulkActionSkipReason = z.infer<
typeof AnonymizationFieldsBulkActionSkipReason
>;
export const AnonymizationFieldsBulkActionSkipReason = z.literal(
'ANONYMIZATION_FIELD_NOT_MODIFIED'
);
export type BulkActionSkipResult = z.infer<typeof BulkActionSkipResult>;
export const BulkActionSkipResult = z.object({
export type AnonymizationFieldsBulkActionSkipResult = z.infer<
typeof AnonymizationFieldsBulkActionSkipResult
>;
export const AnonymizationFieldsBulkActionSkipResult = z.object({
id: z.string(),
name: z.string().optional(),
skip_reason: BulkActionSkipReason,
skip_reason: AnonymizationFieldsBulkActionSkipReason,
});
export type AnonymizationFieldDetailsInError = z.infer<typeof AnonymizationFieldDetailsInError>;
@ -59,12 +65,14 @@ export const AnonymizationFieldResponse = z.object({
namespace: z.string().optional(),
});
export type BulkCrudActionResults = z.infer<typeof BulkCrudActionResults>;
export const BulkCrudActionResults = z.object({
export type AnonymizationFieldsBulkCrudActionResults = z.infer<
typeof AnonymizationFieldsBulkCrudActionResults
>;
export const AnonymizationFieldsBulkCrudActionResults = z.object({
updated: z.array(AnonymizationFieldResponse),
created: z.array(AnonymizationFieldResponse),
deleted: z.array(z.string()),
skipped: z.array(BulkActionSkipResult),
skipped: z.array(AnonymizationFieldsBulkActionSkipResult),
});
export type BulkCrudActionSummary = z.infer<typeof BulkCrudActionSummary>;
@ -75,14 +83,16 @@ export const BulkCrudActionSummary = z.object({
total: z.number().int(),
});
export type BulkCrudActionResponse = z.infer<typeof BulkCrudActionResponse>;
export const BulkCrudActionResponse = z.object({
export type AnonymizationFieldsBulkCrudActionResponse = z.infer<
typeof AnonymizationFieldsBulkCrudActionResponse
>;
export const AnonymizationFieldsBulkCrudActionResponse = z.object({
success: z.boolean().optional(),
status_code: z.number().int().optional(),
message: z.string().optional(),
anonymization_fields_count: z.number().int().optional(),
attributes: z.object({
results: BulkCrudActionResults,
results: AnonymizationFieldsBulkCrudActionResults,
summary: BulkCrudActionSummary,
errors: z.array(NormalizedAnonymizationFieldError).optional(),
}),
@ -123,4 +133,4 @@ export const PerformBulkActionRequestBody = z.object({
export type PerformBulkActionRequestBodyInput = z.input<typeof PerformBulkActionRequestBody>;
export type PerformBulkActionResponse = z.infer<typeof PerformBulkActionResponse>;
export const PerformBulkActionResponse = BulkCrudActionResponse;
export const PerformBulkActionResponse = AnonymizationFieldsBulkCrudActionResponse;

View file

@ -1,12 +1,13 @@
openapi: 3.0.0
info:
title: Bulk Actions API endpoint
title: Bulk Anonymization Fields Actions API endpoint
version: '1'
paths:
/internal/elastic_assistant/anonymization_fields/_bulk_action:
/api/security_ai_assistant/anonymization_fields/_bulk_action:
post:
operationId: PerformBulkAction
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: PerformBulkAction
summary: Applies a bulk action to multiple anonymization fields
description: The bulk action is applied to all anonymization fields that match the filter or to the list of anonymization fields by their IDs.
tags:
@ -33,7 +34,7 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/BulkCrudActionResponse'
$ref: '#/components/schemas/AnonymizationFieldsBulkCrudActionResponse'
400:
description: Generic Error
content:
@ -50,12 +51,12 @@ paths:
components:
schemas:
BulkActionSkipReason:
AnonymizationFieldsBulkActionSkipReason:
type: string
enum:
- ANONYMIZATION_FIELD_NOT_MODIFIED
BulkActionSkipResult:
AnonymizationFieldsBulkActionSkipResult:
type: object
properties:
id:
@ -63,7 +64,7 @@ components:
name:
type: string
skip_reason:
$ref: '#/components/schemas/BulkActionSkipReason'
$ref: '#/components/schemas/AnonymizationFieldsBulkActionSkipReason'
required:
- id
- skip_reason
@ -124,7 +125,7 @@ components:
type: string
description: Kibana space
BulkCrudActionResults:
AnonymizationFieldsBulkCrudActionResults:
type: object
properties:
updated:
@ -142,7 +143,7 @@ components:
skipped:
type: array
items:
$ref: '#/components/schemas/BulkActionSkipResult'
$ref: '#/components/schemas/AnonymizationFieldsBulkActionSkipResult'
required:
- updated
- created
@ -166,7 +167,7 @@ components:
- succeeded
- total
BulkCrudActionResponse:
AnonymizationFieldsBulkCrudActionResponse:
type: object
properties:
success:
@ -181,7 +182,7 @@ components:
type: object
properties:
results:
$ref: '#/components/schemas/BulkCrudActionResults'
$ref: '#/components/schemas/AnonymizationFieldsBulkCrudActionResults'
summary:
$ref: '#/components/schemas/BulkCrudActionSummary'
errors:

View file

@ -3,10 +3,11 @@ info:
title: Find AnonymizationFields API endpoint
version: '1'
paths:
/internal/elastic_assistant/anonymization_fields/_find:
/api/security_ai_assistant/anonymization_fields/_find:
get:
operationId: FindAnonymizationFields
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: FindAnonymizationFields
description: Finds anonymization fields that match the given query.
summary: Finds anonymization fields that match the given query.
tags:

View file

@ -5,8 +5,9 @@ info:
paths:
/internal/elastic_assistant/attack_discovery/cancel/{connectorId}:
put:
operationId: AttackDiscoveryCancel
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: AttackDiscoveryCancel
description: Cancel relevant data for performing an attack discovery like pending requests
summary: Cancel relevant data for performing an attack discovery
tags:

View file

@ -5,8 +5,9 @@ info:
paths:
/internal/elastic_assistant/attack_discovery/{connectorId}:
get:
operationId: AttackDiscoveryGet
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: AttackDiscoveryGet
description: Get relevant data for performing an attack discovery like pending requests
summary: Get relevant data for performing an attack discovery
tags:

View file

@ -8,8 +8,9 @@ components:
paths:
/internal/elastic_assistant/attack_discovery:
post:
operationId: AttackDiscoveryPost
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: AttackDiscoveryPost
description: Generate attack discoveries from alerts
summary: Generate attack discoveries from alerts via the Elastic Assistant
tags:

View file

@ -5,8 +5,9 @@ info:
paths:
/internal/elastic_assistant/capabilities:
get:
operationId: GetCapabilities
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: GetCapabilities
description: Get Elastic Assistant capabilities for the requesting plugin
summary: Get Elastic Assistant capabilities
tags:

View file

@ -3,10 +3,11 @@ info:
title: Chat Complete API endpoint
version: '2023-10-31'
paths:
/api/elastic_assistant/chat/complete:
/api/security_ai_assistant/chat/complete:
post:
operationId: ChatComplete
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: ChatComplete
description: Creates a model response for the given chat conversation.
summary: Creates a model response for the given chat conversation.
tags:
@ -86,7 +87,7 @@ components:
promptId:
type: string
isStream:
type: boolean
type: boolean
responseLanguage:
type: string
langSmithProject:

View file

@ -10,7 +10,7 @@
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
*
* info:
* title: Bulk Actions API endpoint
* title: Bulk Conversations Actions API endpoint
* version: 1
*/
@ -22,14 +22,14 @@ import {
ConversationResponse,
} from './common_attributes.gen';
export type BulkActionSkipReason = z.infer<typeof BulkActionSkipReason>;
export const BulkActionSkipReason = z.literal('CONVERSATION_NOT_MODIFIED');
export type ConversationsBulkActionSkipReason = z.infer<typeof ConversationsBulkActionSkipReason>;
export const ConversationsBulkActionSkipReason = z.literal('CONVERSATION_NOT_MODIFIED');
export type BulkActionSkipResult = z.infer<typeof BulkActionSkipResult>;
export const BulkActionSkipResult = z.object({
export type ConversationsBulkActionSkipResult = z.infer<typeof ConversationsBulkActionSkipResult>;
export const ConversationsBulkActionSkipResult = z.object({
id: z.string(),
name: z.string().optional(),
skip_reason: BulkActionSkipReason,
skip_reason: ConversationsBulkActionSkipReason,
});
export type ConversationDetailsInError = z.infer<typeof ConversationDetailsInError>;
@ -46,12 +46,12 @@ export const NormalizedConversationError = z.object({
conversations: z.array(ConversationDetailsInError),
});
export type BulkCrudActionResults = z.infer<typeof BulkCrudActionResults>;
export const BulkCrudActionResults = z.object({
export type ConversationsBulkCrudActionResults = z.infer<typeof ConversationsBulkCrudActionResults>;
export const ConversationsBulkCrudActionResults = z.object({
updated: z.array(ConversationResponse),
created: z.array(ConversationResponse),
deleted: z.array(z.string()),
skipped: z.array(BulkActionSkipResult),
skipped: z.array(ConversationsBulkActionSkipResult),
});
export type BulkCrudActionSummary = z.infer<typeof BulkCrudActionSummary>;
@ -62,14 +62,16 @@ export const BulkCrudActionSummary = z.object({
total: z.number().int(),
});
export type BulkCrudActionResponse = z.infer<typeof BulkCrudActionResponse>;
export const BulkCrudActionResponse = z.object({
export type ConversationsBulkCrudActionResponse = z.infer<
typeof ConversationsBulkCrudActionResponse
>;
export const ConversationsBulkCrudActionResponse = z.object({
success: z.boolean().optional(),
status_code: z.number().int().optional(),
message: z.string().optional(),
conversations_count: z.number().int().optional(),
attributes: z.object({
results: BulkCrudActionResults,
results: ConversationsBulkCrudActionResults,
summary: BulkCrudActionSummary,
errors: z.array(NormalizedConversationError).optional(),
}),
@ -96,4 +98,4 @@ export const PerformBulkActionRequestBody = z.object({
export type PerformBulkActionRequestBodyInput = z.input<typeof PerformBulkActionRequestBody>;
export type PerformBulkActionResponse = z.infer<typeof PerformBulkActionResponse>;
export const PerformBulkActionResponse = BulkCrudActionResponse;
export const PerformBulkActionResponse = ConversationsBulkCrudActionResponse;

View file

@ -1,12 +1,13 @@
openapi: 3.0.0
info:
title: Bulk Actions API endpoint
title: Bulk Conversations Actions API endpoint
version: '1'
paths:
/internal/elastic_assistant/conversations/_bulk_action:
/internal/elastic_assistant/current_user/conversations/_bulk_action:
post:
operationId: PerformBulkAction
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: PerformBulkAction
summary: Applies a bulk action to multiple conversations
description: The bulk action is applied to all conversations that match the filter or to the list of conversations by their IDs.
tags:
@ -33,7 +34,7 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/BulkCrudActionResponse'
$ref: '#/components/schemas/ConversationsBulkCrudActionResponse'
400:
description: Generic Error
content:
@ -50,12 +51,12 @@ paths:
components:
schemas:
BulkActionSkipReason:
ConversationsBulkActionSkipReason:
type: string
enum:
- CONVERSATION_NOT_MODIFIED
BulkActionSkipResult:
ConversationsBulkActionSkipResult:
type: object
properties:
id:
@ -63,7 +64,7 @@ components:
name:
type: string
skip_reason:
$ref: '#/components/schemas/BulkActionSkipReason'
$ref: '#/components/schemas/ConversationsBulkActionSkipReason'
required:
- id
- skip_reason
@ -96,7 +97,7 @@ components:
- status_code
- conversations
BulkCrudActionResults:
ConversationsBulkCrudActionResults:
type: object
properties:
updated:
@ -114,7 +115,7 @@ components:
skipped:
type: array
items:
$ref: '#/components/schemas/BulkActionSkipResult'
$ref: '#/components/schemas/ConversationsBulkActionSkipResult'
required:
- updated
- created
@ -138,7 +139,7 @@ components:
- succeeded
- total
BulkCrudActionResponse:
ConversationsBulkCrudActionResponse:
type: object
properties:
success:
@ -153,7 +154,7 @@ components:
type: object
properties:
results:
$ref: '#/components/schemas/BulkCrudActionResults'
$ref: '#/components/schemas/ConversationsBulkCrudActionResults'
summary:
$ref: '#/components/schemas/BulkCrudActionSummary'
errors:
@ -180,4 +181,3 @@ components:
minItems: 1
items:
type: string

View file

@ -3,10 +3,11 @@ info:
title: Create Conversation API endpoint
version: '1'
paths:
/internal/elastic_assistant/conversations:
/api/security_ai_assistant/current_user/conversations:
post:
operationId: CreateConversation
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: CreateConversation
description: Create a conversation
summary: Create a conversation
tags:
@ -38,10 +39,11 @@ paths:
message:
type: string
/internal/elastic_assistant/conversations/{id}:
/api/security_ai_assistant/current_user/conversations/{id}:
get:
operationId: ReadConversation
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: ReadConversation
description: Read a single conversation
summary: Read a single conversation
tags:
@ -74,8 +76,9 @@ paths:
message:
type: string
put:
operationId: UpdateConversation
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: UpdateConversation
description: Update a single conversation
summary: Update a conversation
tags:
@ -114,8 +117,9 @@ paths:
message:
type: string
delete:
operationId: DeleteConversation
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: DeleteConversation
description: Deletes a single conversation using the `id` field.
summary: Deletes a single conversation using the `id` field.
tags:
@ -148,10 +152,11 @@ paths:
message:
type: string
/internal/elastic_assistant/conversations/{id}/messages:
/internal/elastic_assistant/current_user/conversations/{id}/messages:
post:
operationId: AppendConversationMessage
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: AppendConversationMessage
description: Append a message to the conversation
summary: Append a message to the conversation
tags:

View file

@ -63,42 +63,3 @@ export const FindConversationsResponse = z.object({
total: z.number().int(),
data: z.array(ConversationResponse),
});
export type FindCurrentUserConversationsRequestQuery = z.infer<
typeof FindCurrentUserConversationsRequestQuery
>;
export const FindCurrentUserConversationsRequestQuery = z.object({
fields: ArrayFromString(z.string()).optional(),
/**
* Search query
*/
filter: z.string().optional(),
/**
* Field to sort by
*/
sort_field: FindConversationsSortField.optional(),
/**
* Sort order
*/
sort_order: SortOrder.optional(),
/**
* Page number
*/
page: z.coerce.number().int().min(1).optional().default(1),
/**
* Conversations per page
*/
per_page: z.coerce.number().int().min(0).optional().default(20),
});
export type FindCurrentUserConversationsRequestQueryInput = z.input<
typeof FindCurrentUserConversationsRequestQuery
>;
export type FindCurrentUserConversationsResponse = z.infer<
typeof FindCurrentUserConversationsResponse
>;
export const FindCurrentUserConversationsResponse = z.object({
page: z.number().int(),
perPage: z.number().int(),
total: z.number().int(),
data: z.array(ConversationResponse),
});

View file

@ -3,10 +3,11 @@ info:
title: Find Conversations API endpoint
version: '1'
paths:
/internal/elastic_assistant/conversations/_find:
/api/security_ai_assistant/current_user/conversations/_find:
get:
operationId: FindConversations
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: FindConversations
description: Finds conversations that match the given query.
summary: Finds conversations that match the given query.
tags:
@ -91,94 +92,6 @@ paths:
message:
type: string
/internal/elastic_assistant/conversations/current_user/_find:
get:
operationId: FindCurrentUserConversations
x-codegen-enabled: true
description: Finds current user conversations that match the given query.
summary: Finds current user conversations that match the given query.
tags:
- Conversations API
parameters:
- name: 'fields'
in: query
required: false
schema:
type: array
items:
type: string
- name: 'filter'
in: query
description: Search query
required: false
schema:
type: string
- name: 'sort_field'
in: query
description: Field to sort by
required: false
schema:
$ref: '#/components/schemas/FindConversationsSortField'
- name: 'sort_order'
in: query
description: Sort order
required: false
schema:
$ref: '../common_attributes.schema.yaml#/components/schemas/SortOrder'
- name: 'page'
in: query
description: Page number
required: false
schema:
type: integer
minimum: 1
default: 1
- name: 'per_page'
in: query
description: Conversations per page
required: false
schema:
type: integer
minimum: 0
default: 20
responses:
200:
description: Successful response
content:
application/json:
schema:
type: object
properties:
page:
type: integer
perPage:
type: integer
total:
type: integer
data:
type: array
items:
$ref: './common_attributes.schema.yaml#/components/schemas/ConversationResponse'
required:
- page
- perPage
- total
- data
400:
description: Generic Error
content:
application/json:
schema:
type: object
properties:
statusCode:
type: number
error:
type: string
message:
type: string
components:
schemas:
FindConversationsSortField:

View file

@ -5,8 +5,9 @@ info:
paths:
/internal/elastic_assistant/evaluate:
get:
operationId: GetEvaluate
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: GetEvaluate
description: Get relevant data for performing an evaluation like available sample data, agents, and evaluators
summary: Get relevant data for performing an evaluation
tags:

View file

@ -5,8 +5,9 @@ info:
paths:
/internal/elastic_assistant/evaluate:
post:
operationId: PostEvaluate
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: PostEvaluate
description: Perform an evaluation using sample data against a combination of Agents and Connectors
summary: Performs an evaluation of the Elastic Assistant
tags:

View file

@ -11,7 +11,7 @@
*
* info:
* title: Bulk Knowledge Base Actions API endpoint
* version: 2023-10-31
* version: 1
*/
import { z } from 'zod';

View file

@ -1,12 +1,15 @@
openapi: 3.0.0
info:
title: Bulk Knowledge Base Actions API endpoint
version: '2023-10-31'
version: '1'
paths:
/api/elastic_assistant/knowledge_base/entries/_bulk_action:
/internal/elastic_assistant/knowledge_base/entries/_bulk_action:
post:
operationId: PerformKnowledgeBaseEntryBulkAction
x-codegen-enabled: true
# This API is still behind the `assistantKnowledgeBaseByDefault` feature flag
x-internal: true
x-labels: [ess, serverless]
operationId: PerformKnowledgeBaseEntryBulkAction
summary: Applies a bulk action to multiple Knowledge Base Entries
description: The bulk action is applied to all Knowledge Base Entries that match the filter or to the list of Knowledge Base Entries by their IDs
tags:

View file

@ -11,7 +11,7 @@
*
* info:
* title: KnowledgeBase API endpoints
* version: 2023-10-31
* version: 1
*/
import { z } from 'zod';

View file

@ -1,12 +1,13 @@
openapi: 3.0.0
info:
title: KnowledgeBase API endpoints
version: '2023-10-31'
version: '1'
paths:
/internal/elastic_assistant/knowledge_base/{resource}:
post:
operationId: CreateKnowledgeBase
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: CreateKnowledgeBase
summary: Create a KnowledgeBase
description: Create a KnowledgeBase
tags:
@ -38,8 +39,9 @@ paths:
message:
type: string
get:
operationId: ReadKnowledgeBase
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: ReadKnowledgeBase
description: Read a single KB
summary: Read a KnowledgeBase
tags:
@ -82,8 +84,9 @@ paths:
message:
type: string
delete:
operationId: DeleteKnowledgeBase
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: DeleteKnowledgeBase
description: Deletes KnowledgeBase with the `resource` field.
summary: Deletes a KnowledgeBase
tags:

View file

@ -11,7 +11,7 @@
*
* info:
* title: Manage Knowledge Base Entries API endpoint
* version: 2023-10-31
* version: 1
*/
import { z } from 'zod';

View file

@ -1,12 +1,15 @@
openapi: 3.0.0
info:
title: Manage Knowledge Base Entries API endpoint
version: '2023-10-31'
version: '1'
paths:
/api/elastic_assistant/knowledge_base/entries:
/internnal/elastic_assistant/knowledge_base/entries:
post:
operationId: CreateKnowledgeBaseEntry
x-codegen-enabled: true
# This API is still behind the `assistantKnowledgeBaseByDefault` feature flag
x-internal: true
x-labels: [ess, serverless]
operationId: CreateKnowledgeBaseEntry
description: Create a Knowledge Base Entry
summary: Create a Knowledge Base Entry
tags:
@ -31,10 +34,13 @@ paths:
schema:
$ref: './common_attributes.schema.yaml#/components/schemas/KnowledgeBaseEntryErrorSchema'
/api/elastic_assistant/knowledge_base/entries/{id}:
/internal/elastic_assistant/knowledge_base/entries/{id}:
get:
operationId: ReadKnowledgeBaseEntry
x-codegen-enabled: true
# This API is still behind the `assistantKnowledgeBaseByDefault` feature flag
x-internal: true
x-labels: [ess, serverless]
operationId: ReadKnowledgeBaseEntry
description: Read a Knowledge Base Entry
summary: Read a Knowledge Base Entry
tags:
@ -60,8 +66,11 @@ paths:
schema:
$ref: './common_attributes.schema.yaml#/components/schemas/KnowledgeBaseEntryErrorSchema'
put:
operationId: UpdateKnowledgeBaseEntry
x-codegen-enabled: true
# This API is still behind the `assistantKnowledgeBaseByDefault` feature flag
x-internal: true
x-labels: [ess, serverless]
operationId: UpdateKnowledgeBaseEntry
description: Update a Knowledge Base Entry
summary: Update a Knowledge Base Entry
tags:
@ -93,8 +102,11 @@ paths:
schema:
$ref: './common_attributes.schema.yaml#/components/schemas/KnowledgeBaseEntryErrorSchema'
delete:
operationId: DeleteKnowledgeBaseEntry
x-codegen-enabled: true
# This API is still behind the `assistantKnowledgeBaseByDefault` feature flag
x-internal: true
x-labels: [ess, serverless]
operationId: DeleteKnowledgeBaseEntry
description: Deletes a single Knowledge Base Entry using the `id` field
summary: Deletes a single Knowledge Base Entry using the `id` field
tags:

View file

@ -5,8 +5,11 @@ info:
paths:
/internal/elastic_assistant/knowledge_base/entries/_find:
get:
operationId: FindKnowledgeBaseEntries
x-codegen-enabled: true
# This API is still behind the `assistantKnowledgeBaseByDefault` feature flag
x-internal: true
x-labels: [ess, serverless]
operationId: FindKnowledgeBaseEntries
description: Finds Knowledge Base Entries that match the given query.
summary: Finds Knowledge Base Entries that match the given query.
tags:

View file

@ -10,7 +10,7 @@
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
*
* info:
* title: Bulk Actions API endpoint
* title: Bulk Prompts Actions API endpoint
* version: 1
*/
@ -18,14 +18,14 @@ import { z } from 'zod';
import { NonEmptyString, User } from '../common_attributes.gen';
export type BulkActionSkipReason = z.infer<typeof BulkActionSkipReason>;
export const BulkActionSkipReason = z.literal('PROMPT_FIELD_NOT_MODIFIED');
export type PromptsBulkActionSkipReason = z.infer<typeof PromptsBulkActionSkipReason>;
export const PromptsBulkActionSkipReason = z.literal('PROMPT_FIELD_NOT_MODIFIED');
export type BulkActionSkipResult = z.infer<typeof BulkActionSkipResult>;
export const BulkActionSkipResult = z.object({
export type PromptsBulkActionSkipResult = z.infer<typeof PromptsBulkActionSkipResult>;
export const PromptsBulkActionSkipResult = z.object({
id: z.string(),
name: z.string().optional(),
skip_reason: BulkActionSkipReason,
skip_reason: PromptsBulkActionSkipReason,
});
export type PromptDetailsInError = z.infer<typeof PromptDetailsInError>;
@ -73,12 +73,12 @@ export const PromptResponse = z.object({
namespace: z.string().optional(),
});
export type BulkCrudActionResults = z.infer<typeof BulkCrudActionResults>;
export const BulkCrudActionResults = z.object({
export type PromptsBulkCrudActionResults = z.infer<typeof PromptsBulkCrudActionResults>;
export const PromptsBulkCrudActionResults = z.object({
updated: z.array(PromptResponse),
created: z.array(PromptResponse),
deleted: z.array(z.string()),
skipped: z.array(BulkActionSkipResult),
skipped: z.array(PromptsBulkActionSkipResult),
});
export type BulkCrudActionSummary = z.infer<typeof BulkCrudActionSummary>;
@ -89,14 +89,14 @@ export const BulkCrudActionSummary = z.object({
total: z.number().int(),
});
export type BulkCrudActionResponse = z.infer<typeof BulkCrudActionResponse>;
export const BulkCrudActionResponse = z.object({
export type PromptsBulkCrudActionResponse = z.infer<typeof PromptsBulkCrudActionResponse>;
export const PromptsBulkCrudActionResponse = z.object({
success: z.boolean().optional(),
status_code: z.number().int().optional(),
message: z.string().optional(),
prompts_count: z.number().int().optional(),
attributes: z.object({
results: BulkCrudActionResults,
results: PromptsBulkCrudActionResults,
summary: BulkCrudActionSummary,
errors: z.array(NormalizedPromptError).optional(),
}),
@ -146,4 +146,4 @@ export const PerformBulkActionRequestBody = z.object({
export type PerformBulkActionRequestBodyInput = z.input<typeof PerformBulkActionRequestBody>;
export type PerformBulkActionResponse = z.infer<typeof PerformBulkActionResponse>;
export const PerformBulkActionResponse = BulkCrudActionResponse;
export const PerformBulkActionResponse = PromptsBulkCrudActionResponse;

View file

@ -1,12 +1,13 @@
openapi: 3.0.0
info:
title: Bulk Actions API endpoint
title: Bulk Prompts Actions API endpoint
version: '1'
paths:
/internal/elastic_assistant/prompts/_bulk_action:
/api/security_ai_assistant/prompts/_bulk_action:
post:
operationId: PerformBulkAction
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: PerformBulkAction
summary: Applies a bulk action to multiple prompts
description: The bulk action is applied to all prompts that match the filter or to the list of prompts by their IDs.
tags:
@ -33,7 +34,7 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/BulkCrudActionResponse'
$ref: '#/components/schemas/PromptsBulkCrudActionResponse'
400:
description: Generic Error
content:
@ -50,12 +51,12 @@ paths:
components:
schemas:
BulkActionSkipReason:
PromptsBulkActionSkipReason:
type: string
enum:
- PROMPT_FIELD_NOT_MODIFIED
BulkActionSkipResult:
PromptsBulkActionSkipResult:
type: object
properties:
id:
@ -63,7 +64,7 @@ components:
name:
type: string
skip_reason:
$ref: '#/components/schemas/BulkActionSkipReason'
$ref: '#/components/schemas/PromptsBulkActionSkipReason'
required:
- id
- skip_reason
@ -149,7 +150,7 @@ components:
type: string
description: Kibana space
BulkCrudActionResults:
PromptsBulkCrudActionResults:
type: object
properties:
updated:
@ -167,7 +168,7 @@ components:
skipped:
type: array
items:
$ref: '#/components/schemas/BulkActionSkipResult'
$ref: '#/components/schemas/PromptsBulkActionSkipResult'
required:
- updated
- created
@ -191,7 +192,7 @@ components:
- succeeded
- total
BulkCrudActionResponse:
PromptsBulkCrudActionResponse:
type: object
properties:
success:
@ -206,7 +207,7 @@ components:
type: object
properties:
results:
$ref: '#/components/schemas/BulkCrudActionResults'
$ref: '#/components/schemas/PromptsBulkCrudActionResults'
summary:
$ref: '#/components/schemas/BulkCrudActionSummary'
errors:

View file

@ -3,10 +3,11 @@ info:
title: Find Prompts API endpoint
version: '1'
paths:
/internal/elastic_assistant/prompts/_find:
/api/security_ai_assistant/prompts/_find:
get:
operationId: FindPrompts
x-codegen-enabled: true
x-labels: [ess, serverless]
operationId: FindPrompts
description: Finds prompts that match the given query.
summary: Finds prompts that match the given query.
tags:

View file

@ -8,12 +8,38 @@
require('../../../../../src/setup_node_env');
const { bundle } = require('@kbn/openapi-bundler');
// eslint-disable-next-line import/no-nodejs-modules
const { resolve } = require('path');
const { join, resolve } = require('path');
const ELASTIC_ASSISTANT_ROOT = resolve(__dirname, '../..');
bundle({
rootDir: ELASTIC_ASSISTANT_ROOT,
sourceGlob: './impl/schemas/**/*.schema.yaml',
outputFilePath: './target/openapi/elastic_assistant.bundled.schema.yaml',
});
(async () => {
await bundle({
sourceGlob: join(ELASTIC_ASSISTANT_ROOT, 'impl/schemas/**/*.schema.yaml'),
outputFilePath: join(
ELASTIC_ASSISTANT_ROOT,
'docs/openapi/serverless/elastic_assistant_api_{version}.bundled.schema.yaml'
),
options: {
includeLabels: ['serverless'],
specInfo: {
title: 'Security AI Assistant API (Elastic Cloud Serverless)',
description: 'Manage and interact with Security Assistant resources.',
},
},
});
await bundle({
sourceGlob: join(ELASTIC_ASSISTANT_ROOT, 'impl/schemas/**/*.schema.yaml'),
outputFilePath: join(
ELASTIC_ASSISTANT_ROOT,
'docs/openapi/ess/elastic_assistant_api_{version}.bundled.schema.yaml'
),
options: {
includeLabels: ['ess'],
specInfo: {
title: 'Security AI Assistant API (Elastic Cloud & self-hosted)',
description: 'Manage and interact with Security Assistant resources.',
},
},
});
})();

View file

@ -16,9 +16,9 @@ import {
import {
AnonymizationFieldResponse,
BulkActionSkipResult,
BulkCrudActionResponse,
BulkCrudActionResults,
AnonymizationFieldsBulkActionSkipResult,
AnonymizationFieldsBulkCrudActionResponse,
AnonymizationFieldsBulkCrudActionResults,
BulkCrudActionSummary,
PerformBulkActionRequestBody,
PerformBulkActionResponse,
@ -63,9 +63,9 @@ const buildBulkResponse = (
updated?: AnonymizationFieldResponse[];
created?: AnonymizationFieldResponse[];
deleted?: string[];
skipped?: BulkActionSkipResult[];
skipped?: AnonymizationFieldsBulkActionSkipResult[];
}
): IKibanaResponse<BulkCrudActionResponse> => {
): IKibanaResponse<AnonymizationFieldsBulkCrudActionResponse> => {
const numSucceeded = updated.length + created.length + deleted.length;
const numSkipped = skipped.length;
const numFailed = errors.length;
@ -77,7 +77,7 @@ const buildBulkResponse = (
total: numSucceeded + numFailed + numSkipped,
};
const results: BulkCrudActionResults = {
const results: AnonymizationFieldsBulkCrudActionResults = {
updated,
created,
deleted,
@ -85,7 +85,7 @@ const buildBulkResponse = (
};
if (numFailed > 0) {
return response.custom<BulkCrudActionResponse>({
return response.custom<AnonymizationFieldsBulkCrudActionResponse>({
headers: { 'content-type': 'application/json' },
body: {
message: summary.succeeded > 0 ? 'Bulk edit partially failed' : 'Bulk edit failed',
@ -103,7 +103,7 @@ const buildBulkResponse = (
});
}
const responseBody: BulkCrudActionResponse = {
const responseBody: AnonymizationFieldsBulkCrudActionResponse = {
success: true,
anonymization_fields_count: summary.total,
attributes: { results, summary },

View file

@ -16,9 +16,9 @@ import {
import {
PromptResponse,
BulkActionSkipResult,
BulkCrudActionResponse,
BulkCrudActionResults,
PromptsBulkActionSkipResult,
PromptsBulkCrudActionResponse,
PromptsBulkCrudActionResults,
BulkCrudActionSummary,
PerformBulkActionRequestBody,
PerformBulkActionResponse,
@ -60,9 +60,9 @@ const buildBulkResponse = (
updated?: PromptResponse[];
created?: PromptResponse[];
deleted?: string[];
skipped?: BulkActionSkipResult[];
skipped?: PromptsBulkActionSkipResult[];
}
): IKibanaResponse<BulkCrudActionResponse> => {
): IKibanaResponse<PromptsBulkCrudActionResponse> => {
const numSucceeded = updated.length + created.length + deleted.length;
const numSkipped = skipped.length;
const numFailed = errors.length;
@ -74,7 +74,7 @@ const buildBulkResponse = (
total: numSucceeded + numFailed + numSkipped,
};
const results: BulkCrudActionResults = {
const results: PromptsBulkCrudActionResults = {
updated,
created,
deleted,
@ -82,7 +82,7 @@ const buildBulkResponse = (
};
if (numFailed > 0) {
return response.custom<BulkCrudActionResponse>({
return response.custom<PromptsBulkCrudActionResponse>({
headers: { 'content-type': 'application/json' },
body: {
message: summary.succeeded > 0 ? 'Bulk edit partially failed' : 'Bulk edit failed',
@ -100,7 +100,7 @@ const buildBulkResponse = (
});
}
const responseBody: BulkCrudActionResponse = {
const responseBody: PromptsBulkCrudActionResponse = {
success: true,
prompts_count: summary.total,
attributes: { results, summary },

View file

@ -11,9 +11,9 @@ import type { IKibanaResponse, KibanaResponseFactory, Logger } from '@kbn/core/s
import { transformError } from '@kbn/securitysolution-es-utils';
import {
ELASTIC_AI_ASSISTANT_CONVERSATIONS_URL_BULK_ACTION,
BulkActionSkipResult,
BulkCrudActionResponse,
BulkCrudActionResults,
ConversationsBulkActionSkipResult,
ConversationsBulkCrudActionResponse,
ConversationsBulkCrudActionResults,
BulkCrudActionSummary,
PerformBulkActionRequestBody,
PerformBulkActionResponse,
@ -61,9 +61,9 @@ const buildBulkResponse = (
updated?: ConversationResponse[];
created?: ConversationResponse[];
deleted?: string[];
skipped?: BulkActionSkipResult[];
skipped?: ConversationsBulkActionSkipResult[];
}
): IKibanaResponse<BulkCrudActionResponse> => {
): IKibanaResponse<ConversationsBulkCrudActionResponse> => {
const numSucceeded = updated.length + created.length + deleted.length;
const numSkipped = skipped.length;
const numFailed = errors.length;
@ -75,7 +75,7 @@ const buildBulkResponse = (
total: numSucceeded + numFailed + numSkipped,
};
const results: BulkCrudActionResults = {
const results: ConversationsBulkCrudActionResults = {
updated,
created,
deleted,
@ -83,7 +83,7 @@ const buildBulkResponse = (
};
if (numFailed > 0) {
return response.custom<BulkCrudActionResponse>({
return response.custom<ConversationsBulkCrudActionResponse>({
headers: { 'content-type': 'application/json' },
body: {
message: summary.succeeded > 0 ? 'Bulk edit partially failed' : 'Bulk edit failed',
@ -101,7 +101,7 @@ const buildBulkResponse = (
});
}
const responseBody: BulkCrudActionResponse = {
const responseBody: ConversationsBulkCrudActionResponse = {
success: true,
conversations_count: summary.total,
attributes: { results, summary },