mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 10:40:07 -04:00
Add docs for chat/complete public API (#224235)
## 26/06 Edits Following discussion with the team, made the following changes: * Modified curl and request and response examples with more appropriate examples ## 20/06 Edits Following discussion with the team, made the following changes: * Removed `query` parameter from the API, and therefore removed it from docs * Made API return OpenAI format by default * Removed `unredactions` property from public API schema and removed it from docs ## Summary Closes https://github.com/elastic/obs-ai-assistant-team/issues/193 Add docs for chat/complete public API. ## Steps to view documentation 1. checkout branch 2. Install bump-cli if you don't already have it: https://docs.bump.sh/help/continuous-integration/cli/ 3. Go to kibana/oas_docs folder 4. Run `bump preview output/kibana.yaml` or `bump preview output/kibana.serverless.yaml` 5. Go to the url given by the command (it takes a while to load). On the side bar, click on Observability AI Assistant menu item and there you can see the docs :) ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [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)   --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
d049766224
commit
b3573364cf
9 changed files with 812 additions and 76 deletions
|
@ -103,6 +103,12 @@ tags:
|
|||
- description: Machine learning
|
||||
name: ml
|
||||
x-displayName: Machine learning
|
||||
- description: Interact with the Observability AI Assistant resources.
|
||||
externalDocs:
|
||||
description: Observability AI Assistant
|
||||
url: https://www.elastic.co/docs/solutions/observability/observability-ai-assistant
|
||||
name: observability_ai_assistant
|
||||
x-displayName: Observability AI Assistant
|
||||
- name: roles
|
||||
x-displayName: Roles
|
||||
description: Manage the roles that grant Elasticsearch and Kibana privileges.
|
||||
|
@ -41174,6 +41180,107 @@ paths:
|
|||
summary: Add or update a note
|
||||
tags:
|
||||
- Security Timeline API
|
||||
/api/observability_ai_assistant/chat/complete:
|
||||
post:
|
||||
description: |
|
||||
Create a new chat completion by using the Observability AI Assistant.
|
||||
|
||||
The API returns the model's response based on the current conversation context.
|
||||
|
||||
It also handles any tool requests within the conversation, which may trigger multiple calls to the underlying large language model (LLM).
|
||||
|
||||
This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.
|
||||
operationId: observability-ai-assistant-chat-complete
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
examples:
|
||||
chatCompleteRequestExample:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_ChatCompleteRequestExample'
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
actions:
|
||||
items:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_Function'
|
||||
type: array
|
||||
connectorId:
|
||||
description: A unique identifier for the connector.
|
||||
type: string
|
||||
conversationId:
|
||||
description: A unique identifier for the conversation if you are continuing an existing conversation.
|
||||
type: string
|
||||
disableFunctions:
|
||||
description: Flag indicating whether all function calls should be disabled for the conversation. If true, no calls to functions will be made.
|
||||
type: boolean
|
||||
instructions:
|
||||
description: An array of instruction objects, which can be either simple strings or detailed objects.
|
||||
items:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_Instruction'
|
||||
type: array
|
||||
messages:
|
||||
description: An array of message objects containing the conversation history.
|
||||
items:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_Message'
|
||||
type: array
|
||||
persist:
|
||||
description: Indicates whether the conversation should be saved to storage. If true, the conversation will be saved and will be available in Kibana.
|
||||
type: boolean
|
||||
title:
|
||||
description: A title for the conversation.
|
||||
type: string
|
||||
required:
|
||||
- messages
|
||||
- connectorId
|
||||
- persist
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
examples:
|
||||
chatCompleteResponseExample:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_ChatCompleteResponseExample'
|
||||
schema:
|
||||
type: object
|
||||
description: Successful response
|
||||
summary: Generate a chat completion
|
||||
tags:
|
||||
- observability_ai_assistant
|
||||
x-codeSamples:
|
||||
- lang: cURL
|
||||
source: |
|
||||
curl --request POST 'localhost:5601/api/observability_ai_assistant/chat/complete' -u <username>:<password> -H 'kbn-xsrf: true' -H "Content-Type: application/json" --data '
|
||||
{
|
||||
"connectorId": "<connectorId>",
|
||||
"disableFunctions": false,
|
||||
"messages": [
|
||||
{
|
||||
"@timestamp": "2025-06-25T23:45:00.000Z",
|
||||
"message": {
|
||||
"role": "user",
|
||||
"content": "Is my Elasticsearch cluster healthy right now?"
|
||||
}
|
||||
}
|
||||
],
|
||||
"persist": false,
|
||||
"actions": [
|
||||
{
|
||||
"name": "get_cluster_health",
|
||||
"description": "Fetch the current Elasticsearch cluster-health status and key metrics.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"includeShardStats": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"instructions": ["When the user asks about Elasticsearch cluster health, use the get_cluster_health tool to retrieve cluster health, then summarize the response in plain English."]
|
||||
}'
|
||||
x-state: Technical Preview
|
||||
/api/osquery/live_queries:
|
||||
get:
|
||||
description: Get a list of all live queries.
|
||||
|
@ -57321,6 +57428,134 @@ components:
|
|||
$ref: '#/components/schemas/Machine_learning_APIs_mlSyncResponseSuccess'
|
||||
title: Sync API response for trained models
|
||||
type: object
|
||||
Observability_AI_Assistant_API_ChatCompleteRequestExample:
|
||||
summary: Example of completing a chat interaction
|
||||
value: |
|
||||
{
|
||||
"connectorId": "<connectorId>",
|
||||
"disableFunctions": false,
|
||||
"messages": [
|
||||
{
|
||||
"@timestamp": "2025-06-25T23:45:00.000Z",
|
||||
"message": {
|
||||
"role": "user",
|
||||
"content": "Is my Elasticsearch cluster healthy right now?"
|
||||
}
|
||||
}
|
||||
],
|
||||
"persist": false,
|
||||
"actions": [
|
||||
{
|
||||
"name": "get_cluster_health",
|
||||
"description": "Fetch the current Elasticsearch cluster-health status and key metrics.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"includeShardStats": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"instructions": ["When the user asks about Elasticsearch cluster health, use the get_cluster_health tool to retrieve cluster health, then summarize the response in plain English."]
|
||||
}
|
||||
Observability_AI_Assistant_API_ChatCompleteResponseExample:
|
||||
summary: Get a chat completion from the Observability AI Assistant
|
||||
value: |
|
||||
data: {"model":"unknown","choices":[{"delta":{"content":"","function_call":{"name":"get_cluster_health","arguments":"{\"includeShardStats\":true}"}},"finish_reason":null,"index":0}],"created":1750936626911,"id":"9c8eff9b-4fd4-4203-a4ab-2e364688deff","object":"chat.completion.chunk"}
|
||||
|
||||
data: [DONE]
|
||||
Observability_AI_Assistant_API_Function:
|
||||
type: object
|
||||
properties:
|
||||
description:
|
||||
description: The description of the function.
|
||||
type: string
|
||||
name:
|
||||
description: The name of the function.
|
||||
type: string
|
||||
parameters:
|
||||
description: The parameters of the function.
|
||||
type: object
|
||||
Observability_AI_Assistant_API_FunctionCall:
|
||||
description: Details of the function call within the message.
|
||||
type: object
|
||||
properties:
|
||||
arguments:
|
||||
description: The arguments for the function call.
|
||||
type: string
|
||||
name:
|
||||
description: The name of the function.
|
||||
type: string
|
||||
trigger:
|
||||
description: The trigger of the function call.
|
||||
enum:
|
||||
- assistant
|
||||
- user
|
||||
- elastic
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- trigger
|
||||
Observability_AI_Assistant_API_Instruction:
|
||||
oneOf:
|
||||
- description: A simple instruction represented as a string.
|
||||
type: string
|
||||
- description: A detailed instruction with an ID and text.
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
description: A unique identifier for the instruction.
|
||||
type: string
|
||||
text:
|
||||
description: The text of the instruction.
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- text
|
||||
Observability_AI_Assistant_API_Message:
|
||||
name: Message
|
||||
type: object
|
||||
properties:
|
||||
'@timestamp':
|
||||
description: The timestamp when the message was created.
|
||||
type: string
|
||||
message:
|
||||
description: The main content of the message.
|
||||
type: object
|
||||
properties:
|
||||
content:
|
||||
description: The content of the message.
|
||||
type: string
|
||||
data:
|
||||
description: Additional data associated with the message.
|
||||
type: string
|
||||
event:
|
||||
description: The event related to the message.
|
||||
type: string
|
||||
function_call:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_FunctionCall'
|
||||
name:
|
||||
description: The name associated with the message.
|
||||
type: string
|
||||
role:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_MessageRoleEnum'
|
||||
required:
|
||||
- role
|
||||
required:
|
||||
- '@timestamp'
|
||||
- message
|
||||
Observability_AI_Assistant_API_MessageRoleEnum:
|
||||
description: The role of the message sender.
|
||||
enum:
|
||||
- system
|
||||
- assistant
|
||||
- function
|
||||
- user
|
||||
- elastic
|
||||
type: string
|
||||
Security_AI_Assistant_API_AnonymizationFieldCreateProps:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
@ -126,6 +126,12 @@ tags:
|
|||
- description: Machine learning
|
||||
name: ml
|
||||
x-displayName: Machine learning
|
||||
- description: Interact with the Observability AI Assistant resources.
|
||||
externalDocs:
|
||||
description: Observability AI Assistant
|
||||
url: https://www.elastic.co/docs/solutions/observability/observability-ai-assistant
|
||||
name: observability_ai_assistant
|
||||
x-displayName: Observability AI Assistant
|
||||
- name: roles
|
||||
x-displayName: Roles
|
||||
description: Manage the roles that grant Elasticsearch and Kibana privileges.
|
||||
|
@ -43579,6 +43585,107 @@ paths:
|
|||
summary: Add or update a note
|
||||
tags:
|
||||
- Security Timeline API
|
||||
/api/observability_ai_assistant/chat/complete:
|
||||
post:
|
||||
description: |
|
||||
Create a new chat completion by using the Observability AI Assistant.
|
||||
|
||||
The API returns the model's response based on the current conversation context.
|
||||
|
||||
It also handles any tool requests within the conversation, which may trigger multiple calls to the underlying large language model (LLM).
|
||||
|
||||
This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.
|
||||
operationId: observability-ai-assistant-chat-complete
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
examples:
|
||||
chatCompleteRequestExample:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_ChatCompleteRequestExample'
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
actions:
|
||||
items:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_Function'
|
||||
type: array
|
||||
connectorId:
|
||||
description: A unique identifier for the connector.
|
||||
type: string
|
||||
conversationId:
|
||||
description: A unique identifier for the conversation if you are continuing an existing conversation.
|
||||
type: string
|
||||
disableFunctions:
|
||||
description: Flag indicating whether all function calls should be disabled for the conversation. If true, no calls to functions will be made.
|
||||
type: boolean
|
||||
instructions:
|
||||
description: An array of instruction objects, which can be either simple strings or detailed objects.
|
||||
items:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_Instruction'
|
||||
type: array
|
||||
messages:
|
||||
description: An array of message objects containing the conversation history.
|
||||
items:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_Message'
|
||||
type: array
|
||||
persist:
|
||||
description: Indicates whether the conversation should be saved to storage. If true, the conversation will be saved and will be available in Kibana.
|
||||
type: boolean
|
||||
title:
|
||||
description: A title for the conversation.
|
||||
type: string
|
||||
required:
|
||||
- messages
|
||||
- connectorId
|
||||
- persist
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
examples:
|
||||
chatCompleteResponseExample:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_ChatCompleteResponseExample'
|
||||
schema:
|
||||
type: object
|
||||
description: Successful response
|
||||
summary: Generate a chat completion
|
||||
tags:
|
||||
- observability_ai_assistant
|
||||
x-codeSamples:
|
||||
- lang: cURL
|
||||
source: |
|
||||
curl --request POST 'localhost:5601/api/observability_ai_assistant/chat/complete' -u <username>:<password> -H 'kbn-xsrf: true' -H "Content-Type: application/json" --data '
|
||||
{
|
||||
"connectorId": "<connectorId>",
|
||||
"disableFunctions": false,
|
||||
"messages": [
|
||||
{
|
||||
"@timestamp": "2025-06-25T23:45:00.000Z",
|
||||
"message": {
|
||||
"role": "user",
|
||||
"content": "Is my Elasticsearch cluster healthy right now?"
|
||||
}
|
||||
}
|
||||
],
|
||||
"persist": false,
|
||||
"actions": [
|
||||
{
|
||||
"name": "get_cluster_health",
|
||||
"description": "Fetch the current Elasticsearch cluster-health status and key metrics.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"includeShardStats": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"instructions": ["When the user asks about Elasticsearch cluster health, use the get_cluster_health tool to retrieve cluster health, then summarize the response in plain English."]
|
||||
}'
|
||||
x-state: Technical Preview
|
||||
/api/osquery/live_queries:
|
||||
get:
|
||||
description: Get a list of all live queries.
|
||||
|
@ -66670,6 +66777,134 @@ components:
|
|||
$ref: '#/components/schemas/Machine_learning_APIs_mlSyncResponseSuccess'
|
||||
title: Sync API response for trained models
|
||||
type: object
|
||||
Observability_AI_Assistant_API_ChatCompleteRequestExample:
|
||||
summary: Example of completing a chat interaction
|
||||
value: |
|
||||
{
|
||||
"connectorId": "<connectorId>",
|
||||
"disableFunctions": false,
|
||||
"messages": [
|
||||
{
|
||||
"@timestamp": "2025-06-25T23:45:00.000Z",
|
||||
"message": {
|
||||
"role": "user",
|
||||
"content": "Is my Elasticsearch cluster healthy right now?"
|
||||
}
|
||||
}
|
||||
],
|
||||
"persist": false,
|
||||
"actions": [
|
||||
{
|
||||
"name": "get_cluster_health",
|
||||
"description": "Fetch the current Elasticsearch cluster-health status and key metrics.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"includeShardStats": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"instructions": ["When the user asks about Elasticsearch cluster health, use the get_cluster_health tool to retrieve cluster health, then summarize the response in plain English."]
|
||||
}
|
||||
Observability_AI_Assistant_API_ChatCompleteResponseExample:
|
||||
summary: Get a chat completion from the Observability AI Assistant
|
||||
value: |
|
||||
data: {"model":"unknown","choices":[{"delta":{"content":"","function_call":{"name":"get_cluster_health","arguments":"{\"includeShardStats\":true}"}},"finish_reason":null,"index":0}],"created":1750936626911,"id":"9c8eff9b-4fd4-4203-a4ab-2e364688deff","object":"chat.completion.chunk"}
|
||||
|
||||
data: [DONE]
|
||||
Observability_AI_Assistant_API_Function:
|
||||
type: object
|
||||
properties:
|
||||
description:
|
||||
description: The description of the function.
|
||||
type: string
|
||||
name:
|
||||
description: The name of the function.
|
||||
type: string
|
||||
parameters:
|
||||
description: The parameters of the function.
|
||||
type: object
|
||||
Observability_AI_Assistant_API_FunctionCall:
|
||||
description: Details of the function call within the message.
|
||||
type: object
|
||||
properties:
|
||||
arguments:
|
||||
description: The arguments for the function call.
|
||||
type: string
|
||||
name:
|
||||
description: The name of the function.
|
||||
type: string
|
||||
trigger:
|
||||
description: The trigger of the function call.
|
||||
enum:
|
||||
- assistant
|
||||
- user
|
||||
- elastic
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- trigger
|
||||
Observability_AI_Assistant_API_Instruction:
|
||||
oneOf:
|
||||
- description: A simple instruction represented as a string.
|
||||
type: string
|
||||
- description: A detailed instruction with an ID and text.
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
description: A unique identifier for the instruction.
|
||||
type: string
|
||||
text:
|
||||
description: The text of the instruction.
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- text
|
||||
Observability_AI_Assistant_API_Message:
|
||||
name: Message
|
||||
type: object
|
||||
properties:
|
||||
'@timestamp':
|
||||
description: The timestamp when the message was created.
|
||||
type: string
|
||||
message:
|
||||
description: The main content of the message.
|
||||
type: object
|
||||
properties:
|
||||
content:
|
||||
description: The content of the message.
|
||||
type: string
|
||||
data:
|
||||
description: Additional data associated with the message.
|
||||
type: string
|
||||
event:
|
||||
description: The event related to the message.
|
||||
type: string
|
||||
function_call:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_FunctionCall'
|
||||
name:
|
||||
description: The name associated with the message.
|
||||
type: string
|
||||
role:
|
||||
$ref: '#/components/schemas/Observability_AI_Assistant_API_MessageRoleEnum'
|
||||
required:
|
||||
- role
|
||||
required:
|
||||
- '@timestamp'
|
||||
- message
|
||||
Observability_AI_Assistant_API_MessageRoleEnum:
|
||||
description: The role of the message sender.
|
||||
enum:
|
||||
- system
|
||||
- assistant
|
||||
- function
|
||||
- user
|
||||
- elastic
|
||||
type: string
|
||||
Saved_objects_400_response:
|
||||
title: Bad request
|
||||
type: object
|
||||
|
|
|
@ -31,6 +31,7 @@ const { REPO_ROOT } = require('@kbn/repo-info');
|
|||
`${REPO_ROOT}/x-pack/solutions/observability/plugins/apm/docs/openapi/apm/bundled.yaml`,
|
||||
`${REPO_ROOT}/x-pack/solutions/observability/plugins/slo/docs/openapi/slo/bundled.yaml`,
|
||||
`${REPO_ROOT}/x-pack/solutions/observability/plugins/uptime/docs/openapi/uptime_apis.yaml`,
|
||||
`${REPO_ROOT}/x-pack/solutions/observability/plugins/observability_ai_assistant_app/docs/openapi/observability_ai_assistant_app_apis.yaml`,
|
||||
`${REPO_ROOT}/x-pack/solutions/observability/plugins/synthetics/docs/openapi/synthetic_apis.yaml`,
|
||||
|
||||
// Security solution
|
||||
|
|
|
@ -22,6 +22,7 @@ const { REPO_ROOT } = require('@kbn/repo-info');
|
|||
// Observability Solution
|
||||
`${REPO_ROOT}/x-pack/solutions/observability/plugins/apm/docs/openapi/apm/bundled.yaml`,
|
||||
`${REPO_ROOT}/x-pack/solutions/observability/plugins/slo/docs/openapi/slo/bundled.yaml`,
|
||||
`${REPO_ROOT}/x-pack/solutions/observability/plugins/observability_ai_assistant_app/docs/openapi/observability_ai_assistant_app_apis.yaml`,
|
||||
|
||||
// Security solution
|
||||
`${REPO_ROOT}/x-pack/solutions/security/plugins/security_solution/docs/openapi/serverless/*.schema.yaml`,
|
||||
|
|
|
@ -20,35 +20,42 @@ import { withAssistantSpan } from '../../service/util/with_assistant_span';
|
|||
import { recallAndScore } from '../../functions/context/utils/recall_and_score';
|
||||
import { createObservabilityAIAssistantServerRoute } from '../create_observability_ai_assistant_server_route';
|
||||
import { Instruction } from '../../../common/types';
|
||||
import { assistantScopeType, functionRt, messageRt, screenContextRt } from '../runtime_types';
|
||||
import {
|
||||
assistantScopeType,
|
||||
functionRt,
|
||||
messageRt,
|
||||
publicMessageRt,
|
||||
screenContextRt,
|
||||
} from '../runtime_types';
|
||||
import { ObservabilityAIAssistantRouteHandlerResources } from '../types';
|
||||
|
||||
const chatCompleteBaseRt = t.type({
|
||||
body: t.intersection([
|
||||
t.type({
|
||||
messages: t.array(messageRt),
|
||||
connectorId: t.string,
|
||||
persist: toBooleanRt,
|
||||
}),
|
||||
t.partial({
|
||||
conversationId: t.string,
|
||||
title: t.string,
|
||||
disableFunctions: toBooleanRt,
|
||||
instructions: t.array(
|
||||
t.union([
|
||||
t.string,
|
||||
t.type({
|
||||
id: t.string,
|
||||
text: t.string,
|
||||
}),
|
||||
])
|
||||
),
|
||||
}),
|
||||
]),
|
||||
});
|
||||
const chatCompleteBaseRt = (apiType: 'public' | 'internal') =>
|
||||
t.type({
|
||||
body: t.intersection([
|
||||
t.type({
|
||||
messages: t.array(apiType === 'public' ? publicMessageRt : messageRt),
|
||||
connectorId: t.string,
|
||||
persist: toBooleanRt,
|
||||
}),
|
||||
t.partial({
|
||||
conversationId: t.string,
|
||||
title: t.string,
|
||||
disableFunctions: toBooleanRt,
|
||||
instructions: t.array(
|
||||
t.union([
|
||||
t.string,
|
||||
t.type({
|
||||
id: t.string,
|
||||
text: t.string,
|
||||
}),
|
||||
])
|
||||
),
|
||||
}),
|
||||
]),
|
||||
});
|
||||
|
||||
const chatCompleteInternalRt = t.intersection([
|
||||
chatCompleteBaseRt,
|
||||
chatCompleteBaseRt('internal'),
|
||||
t.type({
|
||||
body: t.type({
|
||||
screenContexts: t.array(screenContextRt),
|
||||
|
@ -58,14 +65,11 @@ const chatCompleteInternalRt = t.intersection([
|
|||
]);
|
||||
|
||||
const chatCompletePublicRt = t.intersection([
|
||||
chatCompleteBaseRt,
|
||||
chatCompleteBaseRt('public'),
|
||||
t.partial({
|
||||
body: t.partial({
|
||||
actions: t.array(functionRt),
|
||||
}),
|
||||
query: t.partial({
|
||||
format: t.union([t.literal('default'), t.literal('openai')]),
|
||||
}),
|
||||
}),
|
||||
]);
|
||||
|
||||
|
@ -307,16 +311,16 @@ const publicChatCompleteRoute = createObservabilityAIAssistantServerRoute({
|
|||
},
|
||||
},
|
||||
params: chatCompletePublicRt,
|
||||
options: {
|
||||
tags: ['observability-ai-assistant'],
|
||||
},
|
||||
handler: async (resources): Promise<Readable> => {
|
||||
const { params, logger } = resources;
|
||||
|
||||
const {
|
||||
body: { actions, ...restOfBody },
|
||||
query = {},
|
||||
} = params;
|
||||
|
||||
const { format = 'default' } = query;
|
||||
|
||||
const response$ = await chatComplete({
|
||||
...resources,
|
||||
params: {
|
||||
|
@ -332,9 +336,7 @@ const publicChatCompleteRoute = createObservabilityAIAssistantServerRoute({
|
|||
},
|
||||
});
|
||||
|
||||
return format === 'openai'
|
||||
? observableIntoOpenAIStream(response$, logger)
|
||||
: observableIntoStream(response$);
|
||||
return observableIntoOpenAIStream(response$, logger);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -58,6 +58,40 @@ export const messageRt: t.Type<Message> = t.type({
|
|||
]),
|
||||
});
|
||||
|
||||
export const publicMessageRt: t.Type<Omit<Message, 'unredactions'>> = t.type({
|
||||
'@timestamp': t.string,
|
||||
message: t.intersection([
|
||||
t.type({
|
||||
role: t.union([
|
||||
t.literal(MessageRole.System),
|
||||
t.literal(MessageRole.Assistant),
|
||||
t.literal(MessageRole.Function),
|
||||
t.literal(MessageRole.User),
|
||||
t.literal(MessageRole.Elastic),
|
||||
]),
|
||||
}),
|
||||
t.partial({
|
||||
content: t.string,
|
||||
name: t.string,
|
||||
event: t.string,
|
||||
data: t.string,
|
||||
function_call: t.intersection([
|
||||
t.type({
|
||||
name: t.string,
|
||||
trigger: t.union([
|
||||
t.literal(MessageRole.Assistant),
|
||||
t.literal(MessageRole.User),
|
||||
t.literal(MessageRole.Elastic),
|
||||
]),
|
||||
}),
|
||||
t.partial({
|
||||
arguments: t.string,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
});
|
||||
|
||||
const tokenCountRt = t.type({
|
||||
prompt: t.number,
|
||||
completion: t.number,
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# Observability AI Assistant OpenAPI documentation
|
||||
|
||||
::::{warning}
|
||||
This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.
|
||||
::::
|
||||
|
||||
This directory contains [OpenAPI specifications](https://swagger.io/specification/) for the [Observability AI Assistant API](https://www.elastic.co/docs/solutions/observability/observability-ai-assistant) in Kibana.
|
||||
|
||||
# OpenAPI (Experimental)
|
||||
|
||||
The current self-contained spec file can be used for online tools like those found at https://openapi.tools/. This spec is experimental and may be incomplete or change later.
|
||||
|
||||
A guide about the openApi specification can be found at [https://swagger.io/docs/specification/about/](https://swagger.io/docs/specification/about/).
|
||||
|
||||
These files are joined with the rest of the Kibana APIs per `oas_docs/README.md`
|
|
@ -0,0 +1,252 @@
|
|||
openapi: 3.0.3
|
||||
info:
|
||||
title: Observability AI Assistant API
|
||||
description: Kibana API for the Observability AI Assistant
|
||||
version: '1.0.1'
|
||||
license:
|
||||
name: Elastic License 2.0
|
||||
url: https://www.elastic.co/licensing/elastic-license
|
||||
tags:
|
||||
- name: observability_ai_assistant
|
||||
x-displayName: Observability AI Assistant
|
||||
externalDocs:
|
||||
url: https://www.elastic.co/docs/solutions/observability/observability-ai-assistant
|
||||
description: Observability AI Assistant
|
||||
description: Interact with the Observability AI Assistant resources.
|
||||
servers:
|
||||
- url: /
|
||||
paths:
|
||||
/api/observability_ai_assistant/chat/complete:
|
||||
post:
|
||||
summary: Generate a chat completion
|
||||
operationId: observability-ai-assistant-chat-complete
|
||||
description: |
|
||||
Create a new chat completion by using the Observability AI Assistant.
|
||||
|
||||
The API returns the model's response based on the current conversation context.
|
||||
|
||||
It also handles any tool requests within the conversation, which may trigger multiple calls to the underlying large language model (LLM).
|
||||
|
||||
This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.
|
||||
x-state: Technical Preview
|
||||
x-codeSamples:
|
||||
- lang: cURL
|
||||
source: |
|
||||
curl --request POST 'localhost:5601/api/observability_ai_assistant/chat/complete' -u <username>:<password> -H 'kbn-xsrf: true' -H "Content-Type: application/json" --data '
|
||||
{
|
||||
"connectorId": "<connectorId>",
|
||||
"disableFunctions": false,
|
||||
"messages": [
|
||||
{
|
||||
"@timestamp": "2025-06-25T23:45:00.000Z",
|
||||
"message": {
|
||||
"role": "user",
|
||||
"content": "Is my Elasticsearch cluster healthy right now?"
|
||||
}
|
||||
}
|
||||
],
|
||||
"persist": false,
|
||||
"actions": [
|
||||
{
|
||||
"name": "get_cluster_health",
|
||||
"description": "Fetch the current Elasticsearch cluster-health status and key metrics.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"includeShardStats": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"instructions": ["When the user asks about Elasticsearch cluster health, use the get_cluster_health tool to retrieve cluster health, then summarize the response in plain English."]
|
||||
}'
|
||||
tags:
|
||||
- observability_ai_assistant
|
||||
security:
|
||||
- authz: ['ai_assistant']
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
messages:
|
||||
type: array
|
||||
description: An array of message objects containing the conversation history.
|
||||
items:
|
||||
$ref: '#/components/schemas/Message'
|
||||
connectorId:
|
||||
type: string
|
||||
description: A unique identifier for the connector.
|
||||
conversationId:
|
||||
type: string
|
||||
description: A unique identifier for the conversation if you are continuing an existing conversation.
|
||||
title:
|
||||
type: string
|
||||
description: A title for the conversation.
|
||||
persist:
|
||||
type: boolean
|
||||
description: Indicates whether the conversation should be saved to storage. If true, the conversation will be saved and will be available in Kibana.
|
||||
actions:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Function'
|
||||
disableFunctions:
|
||||
type: boolean
|
||||
description: Flag indicating whether all function calls should be disabled for the conversation. If true, no calls to functions will be made.
|
||||
instructions:
|
||||
type: array
|
||||
description: An array of instruction objects, which can be either simple strings or detailed objects.
|
||||
items:
|
||||
$ref: '#/components/schemas/Instruction'
|
||||
required:
|
||||
- messages
|
||||
- connectorId
|
||||
- persist
|
||||
examples:
|
||||
chatCompleteRequestExample:
|
||||
$ref: '#/components/schemas/ChatCompleteRequestExample'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
examples:
|
||||
chatCompleteResponseExample:
|
||||
$ref: '#/components/schemas/ChatCompleteResponseExample'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Message:
|
||||
type: object
|
||||
name: Message
|
||||
properties:
|
||||
'@timestamp':
|
||||
type: string
|
||||
description: The timestamp when the message was created.
|
||||
message:
|
||||
type: object
|
||||
description: The main content of the message.
|
||||
properties:
|
||||
role:
|
||||
$ref: '#/components/schemas/MessageRoleEnum'
|
||||
content:
|
||||
type: string
|
||||
description: The content of the message.
|
||||
name:
|
||||
type: string
|
||||
description: The name associated with the message.
|
||||
event:
|
||||
type: string
|
||||
description: The event related to the message.
|
||||
data:
|
||||
type: string
|
||||
description: Additional data associated with the message.
|
||||
function_call:
|
||||
$ref: '#/components/schemas/FunctionCall'
|
||||
required:
|
||||
- role
|
||||
required:
|
||||
- '@timestamp'
|
||||
- message
|
||||
MessageRoleEnum:
|
||||
description: The role of the message sender.
|
||||
type: string
|
||||
enum:
|
||||
- system
|
||||
- assistant
|
||||
- function
|
||||
- user
|
||||
- elastic
|
||||
FunctionCall:
|
||||
type: object
|
||||
description: Details of the function call within the message.
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: The name of the function.
|
||||
trigger:
|
||||
type: string
|
||||
enum:
|
||||
- assistant
|
||||
- user
|
||||
- elastic
|
||||
description: The trigger of the function call.
|
||||
arguments:
|
||||
type: string
|
||||
description: The arguments for the function call.
|
||||
required:
|
||||
- name
|
||||
- trigger
|
||||
Function:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: The name of the function.
|
||||
description:
|
||||
type: string
|
||||
description: The description of the function.
|
||||
parameters:
|
||||
type: object
|
||||
description: The parameters of the function.
|
||||
Instruction:
|
||||
oneOf:
|
||||
- type: string
|
||||
description: A simple instruction represented as a string.
|
||||
- type: object
|
||||
description: A detailed instruction with an ID and text.
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: A unique identifier for the instruction.
|
||||
text:
|
||||
type: string
|
||||
description: The text of the instruction.
|
||||
required:
|
||||
- id
|
||||
- text
|
||||
ChatCompleteResponseExample:
|
||||
summary: Get a chat completion from the Observability AI Assistant
|
||||
value: |
|
||||
data: {"model":"unknown","choices":[{"delta":{"content":"","function_call":{"name":"get_cluster_health","arguments":"{\"includeShardStats\":true}"}},"finish_reason":null,"index":0}],"created":1750936626911,"id":"9c8eff9b-4fd4-4203-a4ab-2e364688deff","object":"chat.completion.chunk"}
|
||||
|
||||
data: [DONE]
|
||||
ChatCompleteRequestExample:
|
||||
summary: Example of completing a chat interaction
|
||||
value: |
|
||||
{
|
||||
"connectorId": "<connectorId>",
|
||||
"disableFunctions": false,
|
||||
"messages": [
|
||||
{
|
||||
"@timestamp": "2025-06-25T23:45:00.000Z",
|
||||
"message": {
|
||||
"role": "user",
|
||||
"content": "Is my Elasticsearch cluster healthy right now?"
|
||||
}
|
||||
}
|
||||
],
|
||||
"persist": false,
|
||||
"actions": [
|
||||
{
|
||||
"name": "get_cluster_health",
|
||||
"description": "Fetch the current Elasticsearch cluster-health status and key metrics.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"includeShardStats": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"instructions": ["When the user asks about Elasticsearch cluster health, use the get_cluster_health tool to retrieve cluster health, then summarize the response in plain English."]
|
||||
}
|
|
@ -10,17 +10,12 @@ import {
|
|||
MessageRole,
|
||||
type Message,
|
||||
} from '@kbn/observability-ai-assistant-plugin/common';
|
||||
import {
|
||||
MessageAddEvent,
|
||||
type StreamingChatResponseEvent,
|
||||
} from '@kbn/observability-ai-assistant-plugin/common/conversation_complete';
|
||||
import { type Instruction } from '@kbn/observability-ai-assistant-plugin/common/types';
|
||||
import {
|
||||
createLlmProxy,
|
||||
LlmProxy,
|
||||
} from '../../../../../../observability_ai_assistant_api_integration/common/create_llm_proxy';
|
||||
import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context';
|
||||
import { decodeEvents } from '../utils/conversation';
|
||||
|
||||
export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) {
|
||||
const log = getService('log');
|
||||
|
@ -45,18 +40,15 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
|
|||
async function callPublicChatComplete({
|
||||
actions,
|
||||
instructions,
|
||||
format = 'default',
|
||||
persist = true,
|
||||
}: {
|
||||
actions?: Array<Pick<FunctionDefinition, 'name' | 'description' | 'parameters'>>;
|
||||
instructions?: Array<string | Instruction>;
|
||||
format?: 'openai' | 'default';
|
||||
persist?: boolean;
|
||||
}) {
|
||||
const response = await observabilityAIAssistantAPIClient.admin({
|
||||
endpoint: 'POST /api/observability_ai_assistant/chat/complete 2023-10-31',
|
||||
params: {
|
||||
query: { format },
|
||||
body: {
|
||||
messages,
|
||||
connectorId,
|
||||
|
@ -101,37 +93,6 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
|
|||
llmProxy.clear();
|
||||
});
|
||||
|
||||
describe('after executing an action and closing the stream', () => {
|
||||
let events: StreamingChatResponseEvent[];
|
||||
|
||||
before(async () => {
|
||||
void llmProxy.interceptTitle('My Title');
|
||||
void llmProxy.interceptWithFunctionRequest({
|
||||
name: 'my_action',
|
||||
arguments: () => JSON.stringify({ foo: 'bar' }),
|
||||
});
|
||||
|
||||
const responseBody = await callPublicChatComplete({
|
||||
actions: [action],
|
||||
});
|
||||
|
||||
await llmProxy.waitForAllInterceptorsToHaveBeenCalled();
|
||||
|
||||
events = decodeEvents(responseBody);
|
||||
});
|
||||
|
||||
it('does not persist the conversation (the last event is not a conversationUpdated event)', () => {
|
||||
const lastEvent = events[events.length - 1] as MessageAddEvent;
|
||||
expect(lastEvent.type).to.not.be('conversationUpdate');
|
||||
expect(lastEvent.type).to.be('messageAdd');
|
||||
expect(lastEvent.message.message.function_call).to.eql({
|
||||
name: 'my_action',
|
||||
arguments: JSON.stringify({ foo: 'bar' }),
|
||||
trigger: MessageRole.Assistant,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('after adding an instruction', () => {
|
||||
before(async () => {
|
||||
void llmProxy.interceptWithFunctionRequest({
|
||||
|
@ -161,7 +122,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
|
|||
void llmProxy.interceptTitle('My Title');
|
||||
void llmProxy.interceptWithResponse('Hello');
|
||||
|
||||
responseBody = await callPublicChatComplete({ format: 'openai' });
|
||||
responseBody = await callPublicChatComplete({});
|
||||
|
||||
await llmProxy.waitForAllInterceptorsToHaveBeenCalled();
|
||||
});
|
||||
|
@ -179,7 +140,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
|
|||
return str.split('\n\n').filter(Boolean);
|
||||
}
|
||||
|
||||
it('outputs each line an SSE-compatible format (data: ...)', () => {
|
||||
it('outputs each line in an SSE-compatible format (data: ...)', () => {
|
||||
const lines = getLines(responseBody);
|
||||
|
||||
lines.forEach((line) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue