From f1a9942f997e148f4e24800fa7c94bd7162a1344 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 4 Sep 2023 15:13:06 +0100 Subject: [PATCH 1/8] skip flaky suite (#165511) --- .../api_integration/test_suites/common/scripted_fields.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test_serverless/api_integration/test_suites/common/scripted_fields.ts b/x-pack/test_serverless/api_integration/test_suites/common/scripted_fields.ts index f3969e07eea7e..7cc4089814c77 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/scripted_fields.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/scripted_fields.ts @@ -13,7 +13,8 @@ export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); - describe('scripted fields disabled', function () { + // FLAKY: https://github.com/elastic/kibana/issues/165511 + describe.skip('scripted fields disabled', function () { before(async () => { await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index'); }); From 771609d6e103a2dd7e9b5d664f9f0f8846997d98 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 4 Sep 2023 15:51:28 +0100 Subject: [PATCH 2/8] skip flaky suite (#165608) --- test/examples/unified_field_list_examples/field_stats.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/examples/unified_field_list_examples/field_stats.ts b/test/examples/unified_field_list_examples/field_stats.ts index de662e737cb2d..0c1ebca9f3a11 100644 --- a/test/examples/unified_field_list_examples/field_stats.ts +++ b/test/examples/unified_field_list_examples/field_stats.ts @@ -52,7 +52,8 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { await PageObjects.unifiedFieldList.cleanSidebarLocalStorage(); }); - describe('field distribution', () => { + // FLAKY: https://github.com/elastic/kibana/issues/165608 + describe.skip('field distribution', () => { before(async () => { await PageObjects.unifiedFieldList.toggleSidebarSection('empty'); // it will allow to render more fields in Available fields section }); From fa721072e10ab5c4021c5d9acf67700ca5059850 Mon Sep 17 00:00:00 2001 From: Miriam <31922082+MiriamAparicio@users.noreply.github.com> Date: Mon, 4 Sep 2023 16:01:05 +0100 Subject: [PATCH 3/8] [APM] Add visual regression test to service map (#164811) Added visual regression to service map test to be able to test the state of the canvas --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- package.json | 1 + .../cypress/e2e/service_map/service_map.cy.ts | 24 ++++++--- .../apm/ftr_e2e/cypress/support/commands.ts | 1 + .../apm/ftr_e2e/setup_cypress_node_events.ts | 4 ++ .../components/app/service_map/index.tsx | 2 +- yarn.lock | 50 ++++++++++++++++++- 6 files changed, 71 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 86071279c1ce4..06e36a7baf297 100644 --- a/package.json +++ b/package.json @@ -1075,6 +1075,7 @@ "@elastic/synthetics": "^1.3.0", "@emotion/babel-preset-css-prop": "^11.11.0", "@emotion/jest": "^11.11.0", + "@frsource/cypress-plugin-visual-regression-diff": "^3.3.10", "@istanbuljs/nyc-config-typescript": "^1.0.2", "@istanbuljs/schema": "^0.1.2", "@jest/console": "^29.6.1", diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/e2e/service_map/service_map.cy.ts b/x-pack/plugins/apm/ftr_e2e/cypress/e2e/service_map/service_map.cy.ts index 2471617e7b1f4..899ffe9d928b7 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/e2e/service_map/service_map.cy.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/e2e/service_map/service_map.cy.ts @@ -9,7 +9,7 @@ import { synthtrace } from '../../../synthtrace'; import { opbeans } from '../../fixtures/synthtrace/opbeans'; const start = '2021-10-10T00:00:00.000Z'; -const end = '2021-10-10T00:15:00.000Z'; +const end = '2021-10-10T00:01:00.000Z'; const serviceMapHref = url.format({ pathname: '/app/apm/service-map', @@ -29,7 +29,7 @@ const detailedServiceMap = url.format({ }, }); -describe('Service map', () => { +describe('service map', () => { before(() => { synthtrace.index( opbeans({ @@ -47,20 +47,28 @@ describe('Service map', () => { cy.loginAsViewerUser(); }); - describe('When navigating to service map', () => { - it('opens service map', () => { + describe('when navigating to service map', () => { + beforeEach(() => { + cy.intercept('GET', '/internal/apm/service-map?*').as('serviceMap'); cy.visitKibana(serviceMapHref); - cy.contains('h1', 'Services'); + + cy.wait('@serviceMap'); + }); + + it('shows nodes in service map', { retries: 3 }, () => { + cy.wait(500); + cy.getByTestSubj('serviceMap').matchImage(); }); - it('opens detailed service map', () => { + it('shows nodes in detailed service map', () => { cy.visitKibana(detailedServiceMap); cy.contains('h1', 'opbeans-java'); + cy.wait(500); + cy.getByTestSubj('serviceMap').matchImage(); }); - describe('When there is no data', () => { + describe('when there is no data', () => { it('shows empty state', () => { - cy.visitKibana(serviceMapHref); // we need to dismiss the service-group call out first cy.contains('Dismiss').click(); cy.getByTestSubj('apmUnifiedSearchBar').type('_id : foo{enter}'); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts b/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts index c191a9add4e96..204d05255ac58 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/support/commands.ts @@ -8,6 +8,7 @@ import 'cypress-real-events/support'; import { Interception } from 'cypress/types/net-stubbing'; import 'cypress-axe'; import moment from 'moment'; +import '@frsource/cypress-plugin-visual-regression-diff'; import { AXE_CONFIG, AXE_OPTIONS } from '@kbn/axe-config'; import { ApmUsername } from '../../../server/test_helpers/create_apm_users/authentication'; diff --git a/x-pack/plugins/apm/ftr_e2e/setup_cypress_node_events.ts b/x-pack/plugins/apm/ftr_e2e/setup_cypress_node_events.ts index 5194a7aa549b2..9fe1c8608fad2 100644 --- a/x-pack/plugins/apm/ftr_e2e/setup_cypress_node_events.ts +++ b/x-pack/plugins/apm/ftr_e2e/setup_cypress_node_events.ts @@ -10,6 +10,8 @@ import { LogLevel, } from '@kbn/apm-synthtrace'; import { createEsClientForTesting } from '@kbn/test'; +// eslint-disable-next-line @kbn/imports/no_unresolvable_imports +import { initPlugin } from '@frsource/cypress-plugin-visual-regression-diff/plugins'; import del from 'del'; import { some } from 'lodash'; import { Readable } from 'stream'; @@ -35,6 +37,8 @@ export function setupNodeEvents( synthtraceEsClient.pipeline(synthtraceEsClient.getDefaultPipeline(false)); + initPlugin(on, config); + on('task', { // send logs to node process log(message) { diff --git a/x-pack/plugins/apm/public/components/app/service_map/index.tsx b/x-pack/plugins/apm/public/components/app/service_map/index.tsx index d3422fac11546..b9a286ac05187 100644 --- a/x-pack/plugins/apm/public/components/app/service_map/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_map/index.tsx @@ -213,7 +213,7 @@ export function ServiceMap({
diff --git a/yarn.lock b/yarn.lock index e1dc303ef252a..47f2d2206ecd9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2193,6 +2193,24 @@ resolved "https://registry.yarnpkg.com/@foliojs-fork/restructure/-/restructure-2.0.2.tgz#73759aba2aff1da87b7c4554e6839c70d43c92b4" integrity sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA== +"@frsource/base64@1.0.17": + version "1.0.17" + resolved "https://registry.yarnpkg.com/@frsource/base64/-/base64-1.0.17.tgz#b5a37e2ffab4f7fc9ef2e9f660dd3f38ccb05ff4" + integrity sha512-QyMv52jCRIMUIlDM6ysSVPc6Cp3KCTu6/YeLUyJpTEhleXssYB3CT5PqmQijGGwu4819qvan8Eu4PWJRAW5Akg== + +"@frsource/cypress-plugin-visual-regression-diff@^3.3.10": + version "3.3.10" + resolved "https://registry.yarnpkg.com/@frsource/cypress-plugin-visual-regression-diff/-/cypress-plugin-visual-regression-diff-3.3.10.tgz#f8c42d457409c4ac3868814085894db705026e97" + integrity sha512-ZjfOpdmXUgNRfLpsbrYiDujUzNEgLx+3dMtvMJHO3d+Yri0wniMB3mukf5+58QUMXuw8mr1cLoBkeWr1UxCOpA== + dependencies: + "@frsource/base64" "1.0.17" + glob "8.1.0" + meta-png "1.0.6" + move-file "2.1.0" + pixelmatch "5.3.0" + pngjs "7.0.0" + sharp "0.32.1" + "@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" @@ -17407,6 +17425,17 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" +glob@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + glob@^10.2.2: version "10.2.7" resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.7.tgz#9dd2828cd5bc7bd861e7738d91e7113dda41d7d8" @@ -21795,6 +21824,11 @@ merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +meta-png@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/meta-png/-/meta-png-1.0.6.tgz#34d78a403cc1c809978d3e9f89485a2700daafce" + integrity sha512-eQtEi5E9axqwqA/sDK1dyhX9kYHCUe2m+45aQ3JHrozjGPs+/ab+hdhPp7A3GUNW+ZAbavrsg5xQ4r5jkGDX+A== + methods@^1.1.2, methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -22378,6 +22412,13 @@ move-concurrently@^1.0.1: rimraf "^2.5.4" run-queue "^1.0.3" +move-file@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/move-file/-/move-file-2.1.0.tgz#3bec9d34fbe4832df6865f112cda4492b56e8507" + integrity sha512-i9qLW6gqboJ5Ht8bauZi7KlTnQ3QFpBCvMvFfEcHADKgHGeJ9BZMO7SFCTwHPV9Qa0du9DYY1Yx3oqlGt30nXA== + dependencies: + path-exists "^4.0.0" + mri@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.4.tgz#7cb1dd1b9b40905f1fac053abe25b6720f44744a" @@ -23947,7 +23988,7 @@ piscina@^3.2.0: optionalDependencies: nice-napi "^1.0.2" -pixelmatch@^5.3.0: +pixelmatch@5.3.0, pixelmatch@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-5.3.0.tgz#5e5321a7abedfb7962d60dbf345deda87cb9560a" integrity sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q== @@ -24043,6 +24084,11 @@ png-js@^1.0.0: resolved "https://registry.yarnpkg.com/png-js/-/png-js-1.0.0.tgz#e5484f1e8156996e383aceebb3789fd75df1874d" integrity sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g== +pngjs@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-7.0.0.tgz#a8b7446020ebbc6ac739db6c5415a65d17090e26" + integrity sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow== + pngjs@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" @@ -27012,7 +27058,7 @@ shallowequal@^1.1.0: resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== -sharp@^0.32.0: +sharp@0.32.1, sharp@^0.32.0: version "0.32.1" resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.32.1.tgz#41aa0d0b2048b2e0ee453d9fcb14ec1f408390fe" integrity sha512-kQTFtj7ldpUqSe8kDxoGLZc1rnMFU0AO2pqbX6pLy3b7Oj8ivJIdoKNwxHVQG2HN6XpHPJqCSM2nsma2gOXvOg== From b7fe71d6a1437819d7763383756b13c6a6baaa74 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Mon, 4 Sep 2023 17:20:23 +0200 Subject: [PATCH 4/8] [Observability AI Assistant] Prompt tweaks (#165591) --- .../get_apm_timeseries.tsx | 10 ++---- .../get_apm_timeseries/index.ts | 3 +- .../common/types.ts | 7 ++-- .../public/functions/index.ts | 5 ++- .../public/functions/lens.tsx | 2 +- .../public/functions/recall.ts | 33 ++++++++++--------- .../public/hooks/use_timeline.test.ts | 19 ++++++++--- .../public/hooks/use_timeline.ts | 9 ++--- .../public/service/create_chat_service.ts | 6 ++-- .../public/types.ts | 11 ++++--- .../public/utils/storybook_decorator.tsx | 11 ++++--- .../server/routes/chat/route.ts | 10 +++--- .../server/service/client/index.ts | 14 ++++++-- 13 files changed, 81 insertions(+), 59 deletions(-) diff --git a/x-pack/plugins/apm/public/assistant_functions/get_apm_timeseries.tsx b/x-pack/plugins/apm/public/assistant_functions/get_apm_timeseries.tsx index 9bdfd4b4789d8..56269d884ad84 100644 --- a/x-pack/plugins/apm/public/assistant_functions/get_apm_timeseries.tsx +++ b/x-pack/plugins/apm/public/assistant_functions/get_apm_timeseries.tsx @@ -140,9 +140,8 @@ export function registerGetApmTimeseriesFunction({ description: 'The name of the service', }, 'service.environment': { - ...NON_EMPTY_STRING, description: - 'The environment that the service is running in.', + 'The environment that the service is running in. If undefined, all environments will be included. Only use this if you have confirmed the environment that the service is running in.', }, filter: { type: 'string', @@ -160,12 +159,7 @@ export function registerGetApmTimeseriesFunction({ 'The offset. Right: 15m. 8h. 1d. Wrong: -15m. -8h. -1d.', }, }, - required: [ - 'service.name', - 'service.environment', - 'timeseries', - 'title', - ], + required: ['service.name', 'timeseries', 'title'], }, }, }, diff --git a/x-pack/plugins/apm/server/routes/assistant_functions/get_apm_timeseries/index.ts b/x-pack/plugins/apm/server/routes/assistant_functions/get_apm_timeseries/index.ts index 0c95cf0231368..7d0b4e2c3a434 100644 --- a/x-pack/plugins/apm/server/routes/assistant_functions/get_apm_timeseries/index.ts +++ b/x-pack/plugins/apm/server/routes/assistant_functions/get_apm_timeseries/index.ts @@ -14,7 +14,6 @@ import { environmentQuery } from '../../../../common/utils/environment_query'; import { getBucketSize } from '../../../../common/utils/get_bucket_size'; import { termQuery } from '../../../../common/utils/term_query'; import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; -import { environmentRt } from '../../default_api_types'; import { getErrorEventRate } from './get_error_event_rate'; import { getExitSpanFailureRate } from './get_exit_span_failure_rate'; import { getExitSpanLatency } from './get_exit_span_latency'; @@ -37,7 +36,6 @@ export const getApmTimeseriesRt = t.type({ stats: t.array( t.intersection([ t.type({ - 'service.environment': environmentRt.props.environment, 'service.name': t.string, title: t.string, timeseries: t.union([ @@ -85,6 +83,7 @@ export const getApmTimeseriesRt = t.type({ t.partial({ filter: t.string, offset: t.string, + 'service.environment': t.string, }), ]) ), diff --git a/x-pack/plugins/observability_ai_assistant/common/types.ts b/x-pack/plugins/observability_ai_assistant/common/types.ts index 1d8be57fd53b3..b14137dbaebf5 100644 --- a/x-pack/plugins/observability_ai_assistant/common/types.ts +++ b/x-pack/plugins/observability_ai_assistant/common/types.ts @@ -88,7 +88,7 @@ interface FunctionOptions = ( - options: { arguments: TArguments }, + options: { arguments: TArguments; messages: Message[] }, signal: AbortSignal ) => Promise; @@ -99,7 +99,10 @@ type RenderFunction = (options: export interface FunctionDefinition { options: FunctionOptions; - respond: (options: { arguments: any }, signal: AbortSignal) => Promise; + respond: ( + options: { arguments: any; messages: Message[] }, + signal: AbortSignal + ) => Promise; render?: RenderFunction; } diff --git a/x-pack/plugins/observability_ai_assistant/public/functions/index.ts b/x-pack/plugins/observability_ai_assistant/public/functions/index.ts index 85d3d50d35fd0..fd2e3b9c6bca2 100644 --- a/x-pack/plugins/observability_ai_assistant/public/functions/index.ts +++ b/x-pack/plugins/observability_ai_assistant/public/functions/index.ts @@ -49,7 +49,10 @@ export async function registerFunctions({ In KQL, escaping happens with double quotes, not single quotes. Some characters that need escaping are: ':()\\\ /\". Always put a field value in double quotes. Best: service.name:\"opbeans-go\". Wrong: service.name:opbeans-go. This is very important! - You can use Github-flavored Markdown in your responses. If a function returns an array, consider using a Markdown table to format the response.` + You can use Github-flavored Markdown in your responses. If a function returns an array, consider using a Markdown table to format the response. + + If multiple functions are suitable, use the most specific and easy one. E.g., when the user asks to visualise APM data, use the APM functions (if available) rather than Lens. + ` ); if (isReady) { diff --git a/x-pack/plugins/observability_ai_assistant/public/functions/lens.tsx b/x-pack/plugins/observability_ai_assistant/public/functions/lens.tsx index c99ecd0521674..efacbe07816e1 100644 --- a/x-pack/plugins/observability_ai_assistant/public/functions/lens.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/functions/lens.tsx @@ -148,7 +148,7 @@ export function registerLensFunction({ name: 'lens', contexts: ['core'], description: - "Use this function to create custom visualizations, using Lens, that can be saved to dashboards. When using this function, make sure to use the recall function to get more information about how to use it, with how you want to use it. Make sure the query also contains information about the user's request. The visualisation is displayed to the user above your reply, DO NOT try to generate or display an image yourself.", + "Use this function to create custom visualizations, using Lens, that can be saved to dashboards. This function does not return data to the assistant, it only shows it to the user. When using this function, make sure to use the recall function to get more information about how to use it, with how you want to use it. Make sure the query also contains information about the user's request. The visualisation is displayed to the user above your reply, DO NOT try to generate or display an image yourself.", descriptionForUser: 'Use this function to create custom visualizations, using Lens, that can be saved to dashboards.', parameters: { diff --git a/x-pack/plugins/observability_ai_assistant/public/functions/recall.ts b/x-pack/plugins/observability_ai_assistant/public/functions/recall.ts index 9fb387dc7d917..f07cf43e1c282 100644 --- a/x-pack/plugins/observability_ai_assistant/public/functions/recall.ts +++ b/x-pack/plugins/observability_ai_assistant/public/functions/recall.ts @@ -6,7 +6,7 @@ */ import type { Serializable } from '@kbn/utility-types'; -import type { RegisterFunctionDefinition } from '../../common/types'; +import { MessageRole, RegisterFunctionDefinition } from '../../common/types'; import type { ObservabilityAIAssistantService } from '../types'; export function registerRecallFunction({ @@ -20,24 +20,19 @@ export function registerRecallFunction({ { name: 'recall', contexts: ['core'], - description: `Use this function to recall earlier learnings. Anything you will summarize can be retrieved again later via this function. This is semantic/vector search so there's no need for an exact match. + description: `Use this function to recall earlier learnings. Anything you will summarize can be retrieved again later via this function. Make sure the query covers the following aspects: - - The user's prompt, verbatim - Anything you've inferred from the user's request, but is not mentioned in the user's request - The functions you think might be suitable for answering the user's request. If there are multiple functions that seem suitable, create multiple queries. Use the function name in the query. + + DO NOT include the user's request. It will be added internally. - Q: "can you visualise the average request duration for opbeans-go over the last 7 days?" - A: -"can you visualise the average request duration for opbeans-go over the last 7 days?" + The user asks: "can you visualise the average request duration for opbeans-go over the last 7 days?" + You recall: - "APM service" - "lens function usage" - - "get_apm_timeseries function usage" - - Q: "what alerts are active?" - A: - "what alerts are active?" - - "alerts function usage" - - `, + - "get_apm_timeseries function usage"`, descriptionForUser: 'This function allows the assistant to recall previous learnings.', parameters: { type: 'object', @@ -53,15 +48,21 @@ export function registerRecallFunction({ }, }, }, - required: ['queries' as const], - }, + required: ['queries'], + } as const, }, - ({ arguments: { queries } }, signal) => { + ({ arguments: { queries }, messages }, signal) => { + const userMessages = messages.filter((message) => message.message.role === MessageRole.User); + + const userPrompt = userMessages[userMessages.length - 1]?.message.content; + + const queriesWithUserPrompt = userPrompt ? [userPrompt, ...queries] : queries; + return service .callApi('POST /internal/observability_ai_assistant/functions/recall', { params: { body: { - queries, + queries: queriesWithUserPrompt, }, }, signal, diff --git a/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.test.ts b/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.test.ts index 3284cdf66e99f..829594b8261d8 100644 --- a/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.test.ts +++ b/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.test.ts @@ -434,11 +434,20 @@ describe('useTimeline', () => { expect(props.onChatComplete).not.toHaveBeenCalled(); - expect(props.chatService.executeFunction).toHaveBeenCalledWith( - 'my_function', - '{}', - expect.any(Object) - ); + expect(props.chatService.executeFunction).toHaveBeenCalledWith({ + name: 'my_function', + args: '{}', + messages: [ + { + '@timestamp': expect.any(String), + message: { + content: 'Hello', + role: 'user', + }, + }, + ], + signal: expect.any(Object), + }); act(() => { subject.next({ diff --git a/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.ts b/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.ts index 77c7a202754d9..3182fe5c19535 100644 --- a/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.ts +++ b/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.ts @@ -182,11 +182,12 @@ export function useTimeline({ const name = lastMessage.message.function_call.name; try { - const message = await chatService!.executeFunction( + const message = await chatService!.executeFunction({ name, - lastMessage.message.function_call.arguments, - controller.signal - ); + args: lastMessage.message.function_call.arguments, + messages: messagesAfterChat.slice(0, -1), + signal: controller.signal, + }); return await chat( messagesAfterChat.concat({ diff --git a/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts b/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts index 7f04c25ac0b01..1c109be6baaf2 100644 --- a/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts +++ b/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts @@ -74,7 +74,7 @@ export async function createChatService({ }; const registerFunction: RegisterFunctionDefinition = (def, respond, render) => { - validators.set(def.name, new Validator(def.parameters as Schema, '2020-12', false)); + validators.set(def.name, new Validator(def.parameters as Schema, '2020-12', true)); functionRegistry.set(def.name, { options: def, respond, render }); }; @@ -112,7 +112,7 @@ export async function createChatService({ } return { - executeFunction: async (name, args, signal) => { + executeFunction: async ({ name, args, signal, messages }) => { const fn = functionRegistry.get(name); if (!fn) { @@ -123,7 +123,7 @@ export async function createChatService({ validate(name, parsedArguments); - return await fn.respond({ arguments: parsedArguments }, signal); + return await fn.respond({ arguments: parsedArguments, messages }, signal); }, renderFunction: (name, args, response) => { const fn = functionRegistry.get(name); diff --git a/x-pack/plugins/observability_ai_assistant/public/types.ts b/x-pack/plugins/observability_ai_assistant/public/types.ts index 6883a33309fcb..d1a71f6933126 100644 --- a/x-pack/plugins/observability_ai_assistant/public/types.ts +++ b/x-pack/plugins/observability_ai_assistant/public/types.ts @@ -65,11 +65,12 @@ export interface ObservabilityAIAssistantChatService { getContexts: () => ContextDefinition[]; getFunctions: (options?: { contexts?: string[]; filter?: string }) => FunctionDefinition[]; hasRenderFunction: (name: string) => boolean; - executeFunction: ( - name: string, - args: string | undefined, - signal: AbortSignal - ) => Promise<{ content?: Serializable; data?: Serializable }>; + executeFunction: ({}: { + name: string; + args: string | undefined; + messages: Message[]; + signal: AbortSignal; + }) => Promise<{ content?: Serializable; data?: Serializable }>; renderFunction: ( name: string, args: string | undefined, diff --git a/x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx b/x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx index 657de54b11f3f..3c4dc569ab5e5 100644 --- a/x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/utils/storybook_decorator.tsx @@ -25,11 +25,12 @@ const chatService: ObservabilityAIAssistantChatService = { chat: (options: { messages: Message[]; connectorId: string }) => new Observable(), getContexts: () => [], getFunctions: () => [buildFunctionElasticsearch(), buildFunctionServiceSummary()], - executeFunction: async ( - name: string, - args: string | undefined, - signal: AbortSignal - ): Promise<{ content?: Serializable; data?: Serializable }> => ({}), + executeFunction: async ({}: { + name: string; + args: string | undefined; + messages: Message[]; + signal: AbortSignal; + }): Promise<{ content?: Serializable; data?: Serializable }> => ({}), renderFunction: (name: string, args: string | undefined, response: {}) => (
Hello! {name}
), diff --git a/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts b/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts index 2d44307147a52..6716da98d78a5 100644 --- a/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts +++ b/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts @@ -4,12 +4,12 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import * as t from 'io-ts'; -import { IncomingMessage } from 'http'; import { notImplemented } from '@hapi/boom'; +import { IncomingMessage } from 'http'; +import * as t from 'io-ts'; +import { MessageRole } from '../../../common'; import { createObservabilityAIAssistantServerRoute } from '../create_observability_ai_assistant_server_route'; import { messageRt } from '../runtime_types'; -import { MessageRole } from '../../../common'; const chatRoute = createObservabilityAIAssistantServerRoute({ endpoint: 'POST /internal/observability_ai_assistant/chat', @@ -47,13 +47,15 @@ const chatRoute = createObservabilityAIAssistantServerRoute({ const isRecallFunctionAvailable = functions.some((fn) => fn.name === 'recall') === true; + const willUseRecall = isStartOfConversation && isRecallFunctionAvailable; + return client.chat({ messages, connectorId, ...(functions.length ? { functions, - functionCall: isStartOfConversation && isRecallFunctionAvailable ? 'recall' : undefined, + functionCall: willUseRecall ? 'recall' : undefined, } : {}), }); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts index 263f6bdd21aa4..ce3f3c39ad1a9 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts @@ -246,9 +246,17 @@ export class ObservabilityAIAssistantClient { }); if ('object' in response && response.object === 'chat.completion') { - const title = - response.choices[0].message?.content?.slice(1, -1) || - `Conversation on ${conversation['@timestamp']}`; + const input = + response.choices[0].message?.content || `Conversation on ${conversation['@timestamp']}`; + + // This regular expression captures a string enclosed in single or double quotes. + // It extracts the string content without the quotes. + // Example matches: + // - "Hello, World!" => Captures: Hello, World! + // - 'Another Example' => Captures: Another Example + // - JustTextWithoutQuotes => Captures: JustTextWithoutQuotes + const match = input.match(/^["']?([^"']+)["']?$/); + const title = match ? match[1] : input; const updatedConversation: Conversation = merge( {}, From be3f9bc85e944ebec24f43d0b09257c7b91a5fbd Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Mon, 4 Sep 2023 17:59:58 +0200 Subject: [PATCH 5/8] [CM] Change network mode to behave correctly (#165593) ## Summary Fixes #165323 This was a tricky one-liner fix: Lens/Maps/Discover/Visualize List are all using the DataViews service, which in turns is leveraging the ContentManagement plugin to get the default DataView in Kibana. The ContentManagement plugin is using a third party library `react-query`, which by default behaves in [`"online"` Network mode](https://tanstack.com/query/v4/docs/react/guides/network-mode), which it means that in case of offline sets in pause all requests optimistically waiting for the connection to get back. This has the side effect of producing a `Promise` which remains in `pending` state forever in an air-gapped environment. ```mermaid sequenceDiagram participant Apps as "Lens/Discover/etc" participant DataViews participant ContentManagement participant lib as "react-query" Apps->>DataViews: getDefaultDataView() DataViews->>ContentManagement: client.get(id) ContentManagement->>lib: fetchFn lib-->>ContentManagement: Promise Note over lib, ContentManagement: Promise will be pending forever ``` The solution is to force the `"always"` Network mode which is what it regularly happens without any smart handling. --- .../content_management/public/content_client/content_client.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/content_management/public/content_client/content_client.tsx b/src/plugins/content_management/public/content_client/content_client.tsx index e1d148b74760a..caf7181472f03 100644 --- a/src/plugins/content_management/public/content_client/content_client.tsx +++ b/src/plugins/content_management/public/content_client/content_client.tsx @@ -96,7 +96,7 @@ export class ContentClient { private readonly crudClientProvider: (contentType?: string) => CrudClient, private readonly contentTypeRegistry: ContentTypeRegistry ) { - this.queryClient = new QueryClient(); + this.queryClient = new QueryClient({ defaultOptions: { queries: { networkMode: 'always' } } }); this.queryOptionBuilder = createQueryOptionBuilder({ crudClientProvider: this.crudClientProvider, contentTypeRegistry: this.contentTypeRegistry, From 63b7227250a362053d5df1ff980921820a0d6d7a Mon Sep 17 00:00:00 2001 From: Coen Warmer Date: Mon, 4 Sep 2023 18:15:36 +0200 Subject: [PATCH 6/8] Assorted Tweaks + Telemetry (#165604) --- .../action_menu_item/action_menu_item.tsx | 1 + .../buttons/ask_assistant_button.tsx | 19 +++++++++-- .../hide_expand_conversation_list_button.tsx | 7 +++- .../components/buttons/new_chat_button.tsx | 7 +++- .../buttons/regenerate_response_button.tsx | 7 +++- .../components/buttons/start_chat_button.tsx | 8 ++++- .../buttons/stop_generating_button.tsx | 8 ++++- .../components/chat/chat_actions_menu.tsx | 10 +++++- .../public/components/chat/chat_flyout.tsx | 6 +++- .../components/chat/chat_item_actions.tsx | 3 ++ .../components/chat/chat_prompt_editor.tsx | 32 +++++++++++++++---- .../components/chat/chat_timeline.stories.tsx | 1 + .../components/chat/chat_welcome_panel.tsx | 1 + .../chat/experimental_feature_banner.tsx | 7 +++- .../components/chat/function_list_popover.tsx | 1 + .../chat/incorrect_license_panel.tsx | 12 +++++-- .../components/chat/initial_setup_panel.tsx | 8 ++++- .../chat/knowledge_base_callout.tsx | 1 + .../public/components/feedback_buttons.tsx | 2 ++ .../components/insight/insight_base.tsx | 1 + .../components/insight/insight_error.tsx | 6 +++- .../missing_credentials_callout.tsx | 7 +++- 22 files changed, 132 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/observability_ai_assistant/public/components/action_menu_item/action_menu_item.tsx b/x-pack/plugins/observability_ai_assistant/public/components/action_menu_item/action_menu_item.tsx index 226c919d28fc1..ca47c242df495 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/action_menu_item/action_menu_item.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/action_menu_item/action_menu_item.tsx @@ -49,6 +49,7 @@ export function ObservabilityAIAssistantActionMenuItem() { <> { setIsOpen(() => true); }} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/buttons/ask_assistant_button.tsx b/x-pack/plugins/observability_ai_assistant/public/components/buttons/ask_assistant_button.tsx index c8125cd91b5fc..f3ac2d2a735ad 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/buttons/ask_assistant_button.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/buttons/ask_assistant_button.tsx @@ -56,14 +56,26 @@ export function AskAssistantButton({ switch (variant) { case 'basic': return ( - + {buttonLabel} ); case 'empty': return ( - + {buttonLabel} ); @@ -89,8 +101,9 @@ export function AskAssistantButton({ defaultMessage: 'Elastic Assistant', } )} - iconType="sparkles" + data-test-subj="observabilityAiAssistantAskAssistantButtonButtonIcon" display={fill ? 'fill' : 'base'} + iconType="sparkles" size={size} style={{ minWidth: 'auto' }} onClick={onClick} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/buttons/hide_expand_conversation_list_button.tsx b/x-pack/plugins/observability_ai_assistant/public/components/buttons/hide_expand_conversation_list_button.tsx index b23e4a9abb713..8347298161dd3 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/buttons/hide_expand_conversation_list_button.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/buttons/hide_expand_conversation_list_button.tsx @@ -14,7 +14,12 @@ export type HideExpandConversationListButtonProps = React.ComponentProps + {props.isExpanded ? i18n.translate('xpack.observabilityAiAssistant.hideExpandConversationButton.hide', { defaultMessage: 'Hide chats', diff --git a/x-pack/plugins/observability_ai_assistant/public/components/buttons/new_chat_button.tsx b/x-pack/plugins/observability_ai_assistant/public/components/buttons/new_chat_button.tsx index 453c8da351119..d11451c78eaba 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/buttons/new_chat_button.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/buttons/new_chat_button.tsx @@ -10,7 +10,12 @@ import { i18n } from '@kbn/i18n'; export function NewChatButton(props: React.ComponentProps) { return ( - + {i18n.translate('xpack.observabilityAiAssistant.newChatButton', { defaultMessage: 'New chat', })} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/buttons/regenerate_response_button.tsx b/x-pack/plugins/observability_ai_assistant/public/components/buttons/regenerate_response_button.tsx index b0439c854e2ca..77d66081f7868 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/buttons/regenerate_response_button.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/buttons/regenerate_response_button.tsx @@ -11,7 +11,12 @@ import { i18n } from '@kbn/i18n'; export function RegenerateResponseButton(props: Partial) { return ( - + {i18n.translate('xpack.observabilityAiAssistant.regenerateResponseButtonLabel', { defaultMessage: 'Regenerate', })} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/buttons/start_chat_button.tsx b/x-pack/plugins/observability_ai_assistant/public/components/buttons/start_chat_button.tsx index dedbc827af4b2..15042a251302e 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/buttons/start_chat_button.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/buttons/start_chat_button.tsx @@ -10,7 +10,13 @@ import { i18n } from '@kbn/i18n'; export function StartChatButton(props: React.ComponentProps) { return ( - + {i18n.translate('xpack.observabilityAiAssistant.insight.response.startChat', { defaultMessage: 'Start chat', })} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/buttons/stop_generating_button.tsx b/x-pack/plugins/observability_ai_assistant/public/components/buttons/stop_generating_button.tsx index 3008ee884ae64..41023e276fcc5 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/buttons/stop_generating_button.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/buttons/stop_generating_button.tsx @@ -11,7 +11,13 @@ import { i18n } from '@kbn/i18n'; export function StopGeneratingButton(props: Partial) { return ( - + {i18n.translate('xpack.observabilityAiAssistant.stopGeneratingButtonLabel', { defaultMessage: 'Stop generating', })} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_actions_menu.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_actions_menu.tsx index 773428f7a891a..d33d622d4a0f8 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_actions_menu.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_actions_menu.tsx @@ -57,6 +57,7 @@ export function ChatActionsMenu({ isOpen={isOpen} button={ - + {i18n.translate( 'xpack.observabilityAiAssistant.chatHeader.actions.connectorManagement', { diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx index 023370999b470..ef4635d873e8a 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_flyout.tsx @@ -78,6 +78,7 @@ export function ChatFlyout({ > {conversationId ? ( ) : ( - + {i18n.translate('xpack.observabilityAiAssistant.conversationListDeepLinkLabel', { defaultMessage: 'Go to conversations', })} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_actions.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_actions.tsx index 79240a03bb314..64585d2f52ecc 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_actions.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_actions.tsx @@ -53,6 +53,7 @@ export function ChatItemActions({ } )} color="text" + data-test-subj="observabilityAiAssistantChatItemActionsEditPromptButton" display={editing ? 'fill' : 'empty'} iconType="documentEdit" onClick={onToggleEdit} @@ -68,6 +69,7 @@ export function ChatItemActions({ } )} color="text" + data-test-subj="observabilityAiAssistantChatItemActionsInspectPromptButton" display={expanded ? 'fill' : 'empty'} iconType={expanded ? 'eyeClosed' : 'eye'} onClick={onToggleExpand} @@ -85,6 +87,7 @@ export function ChatItemActions({ } )} color="text" + data-test-subj="observabilityAiAssistantChatItemActionsCopyMessageButton" iconType="copyClipboard" display={isPopoverOpen === 'copy' ? 'fill' : 'empty'} onClick={() => { diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor.tsx index 174a2048bf290..7033e1b48c47c 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_prompt_editor.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { EuiButtonEmpty, EuiButtonIcon, @@ -18,7 +19,6 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { CodeEditor } from '@kbn/kibana-react-plugin/public'; -import React, { useCallback, useEffect, useRef, useState } from 'react'; import { MessageRole, type Message } from '../../../common'; import { useJsonEditorModel } from '../../hooks/use_json_editor_model'; import { FunctionListPopover } from './function_list_popover'; @@ -51,6 +51,7 @@ export function ChatPromptEditor({ const [functionPayload, setFunctionPayload] = useState( initialFunctionPayload ); + const [functionEditorLineCount, setFunctionEditorLineCount] = useState(0); const { model, initialJsonString } = useJsonEditorModel({ functionName: selectedFunctionName, @@ -59,9 +60,12 @@ export function ChatPromptEditor({ const textAreaRef = useRef(null); - useEffect(() => { - setFunctionPayload(initialJsonString); - }, [initialJsonString, selectedFunctionName]); + const recalculateFunctionEditorLineCount = useCallback(() => { + const newLineCount = model?.getLineCount() || 0; + if (newLineCount !== functionEditorLineCount) { + setFunctionEditorLineCount(newLineCount); + } + }, [functionEditorLineCount, model]); const handleChange = (event: React.ChangeEvent) => { setPrompt(event.currentTarget.value); @@ -69,6 +73,7 @@ export function ChatPromptEditor({ const handleChangeFunctionPayload = (params: string) => { setFunctionPayload(params); + recalculateFunctionEditorLineCount(); }; const handleClearSelection = () => { @@ -91,7 +96,7 @@ export function ChatPromptEditor({ }; const handleSubmit = useCallback(async () => { - if (loading) { + if (loading || !prompt?.trim()) { return; } const currentPrompt = prompt; @@ -129,6 +134,14 @@ export function ChatPromptEditor({ } }, [functionPayload, loading, onSubmit, prompt, selectedFunctionName]); + useEffect(() => { + setFunctionPayload(initialJsonString); + }, [initialJsonString, selectedFunctionName]); + + useEffect(() => { + recalculateFunctionEditorLineCount(); + }, [model, recalculateFunctionEditorLineCount]); + useEffect(() => { const keyboardListener = (event: KeyboardEvent) => { if (!event.shiftKey && event.key === keys.ENTER && (prompt || selectedFunctionName)) { @@ -174,6 +187,7 @@ export function ChatPromptEditor({ {selectedFunctionName ? ( 8 ? '200px' : '120px'} languageId="json" isCopyable languageConfiguration={{ @@ -238,6 +253,8 @@ export function ChatPromptEditor({ ) : ( = (props: ChatTimelineProps) => setCount(count >= 0 && count < props.items.length - 1 ? count + 1 : 0)} > Add message diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_welcome_panel.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_welcome_panel.tsx index 3525758da810f..8240c6fef4054 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_welcome_panel.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_welcome_panel.tsx @@ -51,6 +51,7 @@ export function ChatWelcomePanel({ knowledgeBase }: { knowledgeBase: UseKnowledg {!knowledgeBase.status.value?.ready ? ( - + {i18n.translate( 'xpack.observabilityAiAssistant.experimentalFunctionBanner.feedbackButton', { defaultMessage: 'Give feedback' } diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx index f0684daece223..72dac17c71c2a 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx @@ -109,6 +109,7 @@ export function FunctionListPopover({ anchorPosition="downLeft" button={ - + {i18n.translate( 'xpack.observabilityAiAssistant.incorrectLicense.subscriptionPlansButton', { @@ -63,7 +68,10 @@ export function IncorrectLicensePanel() { - + {i18n.translate('xpack.observabilityAiAssistant.incorrectLicense.manageLicense', { defaultMessage: 'Manage license', })} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/initial_setup_panel.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/initial_setup_panel.tsx index ef492be652b38..281cf46c972bb 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/initial_setup_panel.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/initial_setup_panel.tsx @@ -101,6 +101,7 @@ export function InitialSetupPanel({ /> ) : ( + {i18n.translate( 'xpack.observabilityAiAssistant.initialSetupPanel.setupConnector.buttonLabel', { diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/knowledge_base_callout.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/knowledge_base_callout.tsx index b8f3b8bd7ef82..36d6842286aa8 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/knowledge_base_callout.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/knowledge_base_callout.tsx @@ -89,6 +89,7 @@ export function KnowledgeBaseCallout({ knowledgeBase }: { knowledgeBase: UseKnow } else if (!knowledgeBase.status.value?.ready && !knowledgeBase.status.error) { content = ( { knowledgeBase.install(); }} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/feedback_buttons.tsx b/x-pack/plugins/observability_ai_assistant/public/components/feedback_buttons.tsx index 08b58a85bfadf..2b55e3d8cac35 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/feedback_buttons.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/feedback_buttons.tsx @@ -32,6 +32,7 @@ export function FeedbackButtons({ onClickFeedback }: FeedbackButtonsProps) { - + {i18n.translate('xpack.observabilityAiAssistant.insight.error.buttonLabel', { defaultMessage: 'Regenerate', })} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/missing_credentials_callout.tsx b/x-pack/plugins/observability_ai_assistant/public/components/missing_credentials_callout.tsx index 20c8257b8721f..3cf5511a042e2 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/missing_credentials_callout.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/missing_credentials_callout.tsx @@ -29,7 +29,12 @@ export function MissingCredentialsCallout(props: Props) { - + {i18n.translate('xpack.observabilityAiAssistant.missingCredentialsCallout.buttonLabel', { defaultMessage: 'Connect Assistant', })} From 0edc23e02aa2fdca8b9065225a945ef2a32ff17a Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Mon, 4 Sep 2023 18:29:16 +0200 Subject: [PATCH 7/8] [Ops] Skip buildkite hooks for non kibana jobs (#165597) ## Summary Kibana's build jobs work on a different subset of executors than the buildkite pipelines defined in `catalog-info.yaml`. The former jobs require a set of `pre_command` / `post_command` steps to prepare the jobs for building/testing kibana. The latter don't have access rights to certain vault secrets (and possibly other missing config from the Kibana world), but for now, they're also not building Kibana, they just trigger other jobs, so we can just skip the problematic hooks. ~~A probably good indicator I found for deciding whether we need the kibana-related `pre_command` is the `BUILDKITE_AGENT_META_DATA_AGENT_MANAGER` flag, that's set to `"kibana"` in the case of the kibana executors.~~ We can try to match on the agent names for the CI-systems agents. They seem to be starting with `bk-agent`. This should allow for the [kibana-tests](https://buildkite.com/elastic/kibana-tests) job to run. Split from: https://github.com/elastic/kibana/pull/165346 --------- Co-authored-by: Tiago Costa --- .buildkite/hooks/post-command | 6 +++++- .buildkite/hooks/pre-command | 6 +++++- .../quality-gates/pipeline.tests-production.yaml | 11 +++++++++++ .../pipelines/quality-gates/pipeline.tests-qa.yaml | 11 +++++++++++ .../quality-gates/pipeline.tests-staging.yaml | 11 +++++++++++ .buildkite/scripts/lifecycle/pre_command.sh | 5 ----- 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/.buildkite/hooks/post-command b/.buildkite/hooks/post-command index d9a8ad668da0b..13e0f4d795828 100755 --- a/.buildkite/hooks/post-command +++ b/.buildkite/hooks/post-command @@ -1,3 +1,7 @@ #!/usr/bin/env bash -.buildkite/scripts/lifecycle/post_command.sh +if [[ "$BUILDKITE_AGENT_NAME" =~ ^bk-agent ]]; then + echo "Pipeline file triggered from outside the kibana executors, skipping post_command" +else + .buildkite/scripts/lifecycle/post_command.sh +fi diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 58a2c5f0b499d..95e2975d094c3 100644 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -1,3 +1,7 @@ #!/usr/bin/env bash -source .buildkite/scripts/lifecycle/pre_command.sh +if [[ "$BUILDKITE_AGENT_NAME" =~ ^bk-agent ]]; then + echo "Pipeline file triggered from outside the kibana executors, skipping pre_command" +else + source .buildkite/scripts/lifecycle/pre_command.sh +fi diff --git a/.buildkite/pipelines/quality-gates/pipeline.tests-production.yaml b/.buildkite/pipelines/quality-gates/pipeline.tests-production.yaml index 5a0738ead7d9c..f2a96d0e23f92 100644 --- a/.buildkite/pipelines/quality-gates/pipeline.tests-production.yaml +++ b/.buildkite/pipelines/quality-gates/pipeline.tests-production.yaml @@ -1,3 +1,7 @@ +env: + TEAM_CHANNEL: "#kibana-serverless-release" + ENVIRONMENT: "production" + steps: - label: ":pipeline::fleet::seedling: Trigger Observability Kibana Tests for ${ENVIRONMENT}" command: echo "replace me with Observability specific Kibana tests" @@ -8,3 +12,10 @@ steps: command: echo "replace me with Security specific Kibana tests" agent: image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364" + + - wait: ~ + + - label: ":judge::seedling: Trigger Manual Tests Phase" + command: "make -C /agent trigger-manual-verification-phase" + agents: + image: "docker.elastic.co/ci-agent-images/manual-verification-agent:0.0.1" diff --git a/.buildkite/pipelines/quality-gates/pipeline.tests-qa.yaml b/.buildkite/pipelines/quality-gates/pipeline.tests-qa.yaml index 669b306bc2ceb..1c9047c38ae92 100644 --- a/.buildkite/pipelines/quality-gates/pipeline.tests-qa.yaml +++ b/.buildkite/pipelines/quality-gates/pipeline.tests-qa.yaml @@ -1,3 +1,7 @@ +env: + TEAM_CHANNEL: "#kibana-serverless-release" + ENVIRONMENT: "qa" + steps: - label: ":pipeline::kibana::seedling: Trigger Kibana Tests for ${ENVIRONMENT}" command: echo "replace me with Kibana specific tests" @@ -18,3 +22,10 @@ steps: command: echo "replace me with Control Plane specific Kibana tests" agent: image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364" + + - wait: ~ + + - label: ":judge::seedling: Trigger Manual Tests Phase" + command: "make -C /agent trigger-manual-verification-phase" + agents: + image: "docker.elastic.co/ci-agent-images/manual-verification-agent:0.0.1" diff --git a/.buildkite/pipelines/quality-gates/pipeline.tests-staging.yaml b/.buildkite/pipelines/quality-gates/pipeline.tests-staging.yaml index 5a0738ead7d9c..bb2381df1fd28 100644 --- a/.buildkite/pipelines/quality-gates/pipeline.tests-staging.yaml +++ b/.buildkite/pipelines/quality-gates/pipeline.tests-staging.yaml @@ -1,3 +1,7 @@ +env: + TEAM_CHANNEL: "#kibana-serverless-release" + ENVIRONMENT: "staging" + steps: - label: ":pipeline::fleet::seedling: Trigger Observability Kibana Tests for ${ENVIRONMENT}" command: echo "replace me with Observability specific Kibana tests" @@ -8,3 +12,10 @@ steps: command: echo "replace me with Security specific Kibana tests" agent: image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364" + + - wait: ~ + + - label: ":judge::seedling: Trigger Manual Tests Phase" + command: "make -C /agent trigger-manual-verification-phase" + agents: + image: "docker.elastic.co/ci-agent-images/manual-verification-agent:0.0.1" diff --git a/.buildkite/scripts/lifecycle/pre_command.sh b/.buildkite/scripts/lifecycle/pre_command.sh index cf31fc95bcb5a..b945f08d1dfd9 100755 --- a/.buildkite/scripts/lifecycle/pre_command.sh +++ b/.buildkite/scripts/lifecycle/pre_command.sh @@ -2,11 +2,6 @@ set -euo pipefail -if [[ "$BUILDKITE_COMMAND" =~ ^"buildkite-agent pipeline upload" ]]; then - echo "Skipped pre-command when running the Upload pipeline" - exit 0 -fi - source .buildkite/scripts/common/util.sh echo '--- Setup environment vars' From 6e7624f064c39b857fec0c9f0d77f956b2c6a74f Mon Sep 17 00:00:00 2001 From: amyjtechwriter <61687663+amyjtechwriter@users.noreply.github.com> Date: Mon, 4 Sep 2023 18:20:40 +0100 Subject: [PATCH 8/8] [DOCS] Adds the 8.9.2 release notes. (#165370) ## Summary Adds the 8.9.2 release notes. --- docs/CHANGELOG.asciidoc | 270 ++++------------------------------------ 1 file changed, 21 insertions(+), 249 deletions(-) diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 5e3394b9add9f..f3e74bb49ab0d 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -10,7 +10,8 @@ Review important information about the {kib} 8.x releases. -* <> + +* <> * <> * <> * <> @@ -47,268 +48,39 @@ Review important information about the {kib} 8.x releases. * <> -- -[[release-notes-8.10.0]] -== {kib} 8.10.0 - -coming::[8.10.0] - -For information about the {kib} 8.10.0 release, review the following information. - -[float] -[[breaking-changes-8.10.0]] -=== Breaking changes - -Breaking changes can prevent your application from optimal operation and performance. -Before you upgrade to 8.10.0, review the breaking changes, then mitigate the impact to your application. - -[discrete] -[[breaking-162665]] -.New summary search capabilities -[%collapsible] -==== -*Details* + -New summary search capabilities introduce breaking changes in various places, and we have decided to not handle backward compatibility: - -* SLO find API body parameters have changed -* The index mapping used by the rollup data has changed, and we have added a summary index that becomes the new source of truth for search -* The rollup transform have been updated, but existing SLO with their transform won't be updated. - -If some SLOs have been installed in a prior version at 8.10, the user will need to remove them manually from the UI, or by deleting the Saved Object and the associated Transform. -==== - -[discrete] -[[breaking-162506]] -.Get case metrics APIs now internal -[%collapsible] -==== -*Details* + -The get case metrics APIs are now internal. For more information, refer to ({kibana-pull}162506[#162506]). -==== - -[discrete] -[[breaking-162492]] -.Case limits -[%collapsible] -==== -*Details* + -Limits are now imposed on the number of objects cases can process or the amount of data those objects can store. -//// -For example: -* Updating a case comment is now included in the 10000 user actions restriction. ({kibana-pull}163150[#163150]) -* Updating a case now fails if the operation makes it reach more than 10000 user actions. ({kibana-pull}161848[#161848]) -* The total number of characters per comment is limited to 30000. ({kibana-pull}161357[#161357]) -* The getConnectors API now limits the number of supported connectors returned to 1000. ({kibana-pull}161282[#161282]) -* There are new limits and restrictions when retrieving cases. ({kibana-pull}162411[#162411]), ({kibana-pull}162245[#162245]), ({kibana-pull}161111[#161111]), ({kibana-pull}160705[#160705]) -* A case can now only have 100 external references and persistable state(excluding files) attachments combined. ({kibana-pull}162071[#162071]). -* New limits on titles, descriptions, tags and category. ({kibana-pull}160844[#160844]). -* The maximum number of cases that can be updated simultaneously is now 100. The minimum is 1. ({kibana-pull}161076[#161076]). -* The Delete cases API now limits the number of cases to be deleted to 100.({kibana-pull}160846[#160846]). -//// -For the full list, refer to {kib-issue}146945[#146945]. -==== - -[discrete] -[[breaking-159041]] -.`addProcessorDefinition` is removed -[%collapsible] -==== -*Details* + -The function `addProcessorDefinition` is removed from the Console plugin start contract (server side). For more information, refer to ({kibana-pull}159041[#159041]). -==== - -[float] -[[deprecations-8.10.0]] -=== Deprecations - -The following functionality is deprecated in 8.10.0, and will be removed in 9.0.0. -Deprecated functionality does not have an immediate impact on your application, but we strongly recommend -you make the necessary updates after you upgrade to 8.10.0. - -[discrete] -[[deprecation-161136]] -.Action variables in the UI and in tests that were no longer used have been replaced -[%collapsible] -==== -*Details* + -The following rule action variables have been deprecated; use the recommended variables (in parentheses) instead: - -* alertActionGroup (alert.actionGroup) -* alertActionGroupName (alert.actionGroupName) -* alertActionSubgroup (alert.actionSubgroup) -* alertId (rule.id) -* alertInstanceId (alert.id) -* alertName (rule.name) -* params (rule.params) -* spaceId (rule.spaceId) -* tags (rule.tags) - -For more information, refer to ({kibana-pull}161136[#161136]). -==== - -[float] -[[features-8.10.0]] -=== Features -{kib} 8.10.0 adds the following new and notable features. - -Alerting:: -* Adds support for self-signed SSL certificate authentication in webhook connector ({kibana-pull}161894[#161894]). -* Allow runtime fields to be selected for {es} query rule type 'group by' or 'aggregate over' options ({kibana-pull}160319[#160319]). -APM:: -* Adds KQL filtering in APM rules ({kibana-pull}163825[#163825]). -* Make service group saved objects exportable ({kibana-pull}163569[#163569]). -* Added ability to manage Cross-Cluster API keys ({kibana-pull}162363[#162363]). -* Enable Trace Explorer by default ({kibana-pull}162308[#162308]). -* Adds error.grouping_name to group alerts in Error Count rule ({kibana-pull}161810[#161810]). -* Adds query to check for overflow bucket in service groups ({kibana-pull}159990[#159990]). -Elastic Security:: -For the Elastic Security 8.10.0 release information, refer to {security-guide}/release-notes.html[_Elastic Security Solution Release Notes_]. -Enterprise Search:: -For the Elastic Enterprise Search 8.10.0 release information, refer to {enterprise-search-ref}/changelog.html[_Elastic Enterprise Search Documentation Release notes_]. -Fleet:: -* Only enable secret storage once all fleet servers are above 8.10.0 ({kibana-pull}163627[#163627]). -* Kafka integration API ({kibana-pull}159110[#159110]). -Machine Learning:: -* AIOps: Adds/edits change point charts embeddable from the Dashboard app ({kibana-pull}163694[#163694]). -* AIOps: Adds change point detection charts embeddable ({kibana-pull}162796[#162796]). -* Adds ability to deploy trained models for data frame analytics jobs ({kibana-pull}162537[#162537]). -* Adds map view for models in Trained Models and expands support for models in Analytics map ({kibana-pull}162443[#162443]). -* Adds new Data comparison view ({kibana-pull}161365[#161365]). -Management:: -* Added ability to create a remote cluster with the API key based security model ({kibana-pull}161836[#161836]). -* REST endpoint for swapping saved object references ({kibana-pull}157665[#157665]). -Maps:: -* Maps tracks layer now uses group by time series logic ({kibana-pull}159267[#159267]). -Observability:: -* SLO definition and computed values are now summarized periodically into a summary search index, allowing users to search by name, tags, SLO budgeting type or time window, and even by and sort by error budget consumed, error budget remaining, SLI value or status ({kibana-pull}162665[#162665]). -* Adds indicator to support histogram fields ({kibana-pull}161582[#161582]). - -For more information about the features introduced in 8.10.0, refer to <>. - -[[enhancements-and-bug-fixes-v8.10.0]] -=== Enhancements and bug fixes +[[release-notes-8.9.2]] +== {kib} 8.9.2 -For detailed information about the 8.10.0 release, review the enhancements and bug fixes. +Review the following information about the {kib} 8.9.2 release. [float] -[[enhancement-v8.10.0]] +[[enhancement-v8.9.2]] === Enhancements -Alerting:: -* Fixes the event log data stream to use Data stream lifecycle instead of Index Lifecycle Management. If you had previously customized the Kibana event log ILM policy, you should now update the lifecycle of the event log data stream itself. ({kibana-pull}163210[#163210]). -* KQL search bar for Rules page ({kibana-pull}158106[#158106]). -APM:: -* Lens function ({kibana-pull}163872[#163872]). -* Adds several function implementations to the AI Assistant ({kibana-pull}163764[#163764]). -* Feature controls ({kibana-pull}163232[#163232]). -* Added improved JVM runtime metrics dashboard ({kibana-pull}162460[#162460]). -* Move to new plugin, update design and use connectors ({kibana-pull}162243[#162243]). -* Adding endpoint to upload android map files ({kibana-pull}161252[#161252]). -* Navigate from the transaction details view into the Profiling ({kibana-pull}159686[#159686]). -Dashboard:: -* Change badge color in options list ({kibana-pull}161401[#161401]). -* Edit title, description, and tags from dashboard listing page ({kibana-pull}161399[#161399]). -* Editing toolbar update ({kibana-pull}154966[#154966]). -Discover:: -* Inline shard failures warnings ({kibana-pull}161271[#161271]). -* Improve shard error message formatting ({kibana-pull}161098[#161098]). -Elastic Security:: -For the Elastic Security 8.10.0 release information, refer to {security-guide}/release-notes.html[_Elastic Security Solution Release Notes_]. -Enterprise Search:: -For the Elastic Enterprise Search 8.10.0 release information, refer to {enterprise-search-ref}/changelog.html[_Elastic Enterprise Search Documentation Release notes_]. + Fleet:: -* Adds support for runtime fields ({kibana-pull}161129[#161129]). -Lens & Visualizations:: -* Migrate range slider to `EuiDualRange` and make styling consistent across all controls ({kibana-pull}162651[#162651]). -* Introduce new duration formatter in *Lens* ({kibana-pull}162246[#162246]). -* Create a filter with field:value when last value metric is used on a data table in *Lens* ({kibana-pull}160509[#160509]). -* Adds tooltip for partition and heatmap filtering ({kibana-pull}162716[#162716]). -Machine Learning:: -* Hides paging controls in anomaly swim lane if only one page is available ({kibana-pull}163931[#163931]). -* Adds a throughput description in the Trained Models Deployment stats table ({kibana-pull}163481[#163481]). -* Provides hints for empty fields in dropdown options in Anomaly detection & Transform creation wizards, Change point detection view ({kibana-pull}163371[#163371]). -* AIOps: Adds dip support to log rate analysis in ML AIOps Labs ({kibana-pull}163100[#163100]). -* AIOps: Improves table hovering for log rate analysis ({kibana-pull}162941[#162941]). -* AIOps: Adds dip support for log rate analysis in observability alert details page ({kibana-pull}162476[#162476]). -* Adds validation of field selected for log pattern analysis ({kibana-pull}162319[#162319]). -* AIOps: Renames Explain Log Rate Spikes to Log Rate Analysis ({kibana-pull}161764[#161764]). -* Adds new Data comparison view ({kibana-pull}161365[#161365]). -* Adds test UI for text expansion models ({kibana-pull}159150[#159150]). -* Adds update index mappings step to ML pipeline config workflow ({kibana-pull}163723[#163723]). -Management:: -* Adds multiple formats for geo_point fields and make geo conversion tools part of field_format/common/utils ({kibana-pull}147272[#147272]). -Maps:: -* Support time series split for top hits per entity source ({kibana-pull}161799[#161799]). -Observability:: -* Adds support for group by to SLO burn rate rule ({kibana-pull}163434[#163434]). -* Applying consistent design to Histogram and Custom Metric forms ({kibana-pull}162083[#162083]). -* Adds preview chart to custom metric indicator ({kibana-pull}161597[#161597]). -* Support filters for good/total custom metrics ({kibana-pull}161308[#161308]). -Reporting:: -* Increase max size bytes default to 250mb ({kibana-pull}161318[#161318]). -Security:: -* Change the default value of `session.idleTimeout` from 8 hours to 3 days ({kibana-pull}162313[#162313]). -* User roles displayed on the user profile page ({kibana-pull}161375[#161375]). -Uptime:: -* Implement private location run once ({kibana-pull}162582[#162582]). +* Adds the configuration setting `xpack.fleet.packageVerification.gpgKeyPath` as an environment variable in the {kib} container ({kibana-pull}163783[#163783]). [float] -[[fixes-v8.10.0]] +[[fixes-v8.9.2]] === Bug Fixes -APM:: -* Fixes styling and port issue with new onboarding ({kibana-pull}163922[#163922]). -* Fixes missing alert index issue ({kibana-pull}163600[#163600]). -* Fixes trace waterfall loading logic to handle empty scenarios ({kibana-pull}163397[#163397]). -* Fixes the action menu overlapping the 'Create custom link' flyout ({kibana-pull}162664[#162664]). -* Improve service groups error messages and validations ({kibana-pull}162556[#162556]). -* Fixes throwing appropriate error when user is missing necessary permission ({kibana-pull}162466[#162466]). -* Hide components when there is no support from agents ({kibana-pull}161970[#161970]). -* Fixes link to onboarding page in the Observability Onboarding plugin ({kibana-pull}161847[#161847]). + Dashboard:: -* Disables top navigation actions when cloning or overlay is showing ({kibana-pull}162091[#162091]). -Discover:: -* Fixes document failing to load when the ID contains a slash ({kibana-pull}160239[#160239]). -* Fixes NoData screen in alignment with Dashboard and Lends behavior ({kibana-pull}160747[#160747]). +* Fixes missing state on short URLs could be lost on an alias match redirect ({kibana-pull}163658[#163658]). +* Fixes 'Download CSV' returning no data when panel has custom time range outside the time range of the global time picker ({kibana-pull}163887[#163887]). +* Fixes **Dashboard** getting stuck at loading in {kib} when Controls is used and mapping changed from integer to keyword ({kibana-pull}163529[#163529]). Elastic Security:: -For the Elastic Security 8.10.0 release information, refer to {security-guide}/release-notes.html[_Elastic Security Solution Release Notes_]. -Enterprise Search:: -For the Elastic Enterprise Search 8.10.0 release information, refer to {enterprise-search-ref}/changelog.html[_Elastic Enterprise Search Documentation Release notes_]. -Fleet:: -* Only show agent dashboard links if there is more than one non-server agent and if the dashboards exist ({kibana-pull}164469[#164469]). -* Exclude Synthetics from per-policy-outputs ({kibana-pull}161949[#161949]). -* Fixing the path for hint templates for auto-discover ({kibana-pull}161075[#161075]). +For the Elastic Security 8.9.2 release information, refer to {security-guide}/release-notes.html[_Elastic Security Solution Release Notes_]. Lens & Visualizations:: -* Fixes params._interval conversion to Lens formula ({kibana-pull}164150[#164150]). -* Fixes issues with field name that contains the `:` character in it in *Lens* ({kibana-pull}163626[#163626]). -* Fixes other request merge behavior when empty string key is retrieved ({kibana-pull}163187[#163187]). -* Fixes editing of multi values filters when adding a custom item ({kibana-pull}161940[#161940]). -* Allow setting custom colors to be collapsed by slices pie's multiple metrics in *Lens* ({kibana-pull}160592[#160592]). -* Fixes data table sorting for keyword values in *Lens* ({kibana-pull}160163[#160163]). -* Fixes override parameter when creating data views ({kibana-pull}160953[#160953]). -Logs:: -* Amend lazy imports in logs_shared plugin ({kibana-pull}164102[#164102]). +* Allow removing temporary data view from event annotation group in *Lens* ({kibana-pull}163976[#163976]). Machine Learning:: -* Fixes Trained models list crashes on browser refresh if not on page 1 ({kibana-pull}164163[#164163]). -* Fixes query bar not switching from KQL to Lucene and vice versa in Anomaly explorer ({kibana-pull}163625[#163625]). -* Data Frame Analytics creation wizard: ensures validation works correctly ({kibana-pull}163446[#163446]). -* Fixes capabilities polling in manage page ({kibana-pull}163399[#163399]). -* Fixes unhandled promise rejection from ML plugin ({kibana-pull}163129[#163129]). -* AIOps: Uses Kibana's http service instead of fetch and fixes throttling ({kibana-pull}162335[#162335]). -* Uses model supplied mask token for testing trained models ({kibana-pull}162168[#162168]). +* Anomaly detection wizard: ensure custom URLs test functionality works as expected ({kibana-pull}165055[#165055]). +* Fixes anomaly detection module manifest queries for {kib} sample data sets, so cold and frozen tiers are not queried ({kibana-pull}164332[#164332]). Management:: -* Fixes how a bulk request body with variables are processed in Console ({kibana-pull}162745[#162745]). -* Improves a way of variable substitution and its documentation in Console ({kibana-pull}162382[#162382]). -* Transforms: Reduces rerenders and multiple fetches of source index on transform wizard load ({kibana-pull}160979[#160979]). -Maps:: -* Fixes Map layer preview blocks adding layer until all tiles are loaded ({kibana-pull}161994[#161994]). -Monitoring:: -* Rewrite CPU usage rule to improve accuracy ({kibana-pull}159351[#159351]). -Observability:: -* Fixes email connector rule URL ({kibana-pull}162954[#162954]). -* Disable the 'View rule details' option from the Alert Details' Actions list when the rule is deleted ({kibana-pull}163183[#163183]). +* Transforms: Fixes privileges check ({kibana-pull}163687[#163687]). +Operations:: +* Fixes an issue where {kib} did not start on CentOS/RHEL 7 ({kibana-pull}165151[#165151]). Reporting:: -* Fixes a bug where Kibana Reporting would not work in Elastic Docker without adding a special setting in kibana.yml to disable the Chromium sandbox. ({kibana-pull}149080[#149080]). -* Fixes an issue where certain international characters would not appear correctly in the contents of a print-optimized PDF report of a dashboard ({kibana-pull}161825[#161825]). -Uptime:: -* Fixes auto-expand feature for failed step detail ({kibana-pull}162747[#162747]). +* Allow custom roles to use image reporting in **Dashboard** ({kibana-pull}163873[#163873]). [[release-notes-8.9.1]] == {kib} 8.9.1