Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AI Assistant Management Plugin + Knowledge Base Management #171933

Merged
merged 63 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
f20145c
First pass of AI Assistant Management plugin
CoenWarmer Oct 31, 2023
39858cd
Second pass of AI Assistant Settings plugin
CoenWarmer Nov 7, 2023
673e7b4
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Nov 7, 2023
18e41d7
Add settings config for Serverless
CoenWarmer Nov 7, 2023
37af159
Dont register AI Assistant Management Selector plugin when in Serverless
CoenWarmer Nov 7, 2023
1930ed2
Move connector and knowledge base routes to management plugin
CoenWarmer Nov 10, 2023
1d9b252
Start of Knowledge Base tab
CoenWarmer Nov 10, 2023
252999a
Reorg api routes to where they belong
CoenWarmer Nov 13, 2023
7e7967d
Add UI to edit and delete
CoenWarmer Nov 13, 2023
16f71e4
Add Bulk import
CoenWarmer Nov 14, 2023
60b42f1
Allow setting up of gen ai connector via TriggersActionsUi flyout
CoenWarmer Nov 21, 2023
cacddb2
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Nov 24, 2023
d8e5339
Clean up things
CoenWarmer Nov 24, 2023
9e1a427
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Nov 24, 2023
70192d6
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Nov 24, 2023
697d003
[CI] Auto-commit changed files from 'node scripts/generate codeowners'
kibanamachine Nov 24, 2023
dc0caff
Clean up
CoenWarmer Nov 24, 2023
a0af4bd
Merge branch 'feat/obs-aiassistant-settings-page' of github.com:CoenW…
CoenWarmer Nov 24, 2023
335a5a1
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Nov 24, 2023
6d3c427
Clean up
CoenWarmer Nov 24, 2023
4a29f8b
Merge branch 'feat/obs-aiassistant-settings-page' of github.com:CoenW…
CoenWarmer Nov 24, 2023
af33c66
[CI] Auto-commit changed files from 'node scripts/build_plugin_list_d…
kibanamachine Nov 24, 2023
2d8e02a
Clean up
CoenWarmer Nov 24, 2023
92a9b94
Update limits
CoenWarmer Nov 24, 2023
6219d5e
Fix translations
CoenWarmer Nov 24, 2023
fccf171
Another fix
CoenWarmer Nov 25, 2023
31451eb
Fix FTRs
CoenWarmer Nov 25, 2023
1248f64
[CI] Auto-commit changed files from 'node scripts/build_plugin_list_d…
kibanamachine Nov 25, 2023
a165700
Reorder limits
CoenWarmer Nov 26, 2023
1240e21
Filter Management apps that do not have a title
CoenWarmer Nov 26, 2023
f29d509
Merge branch 'feat/obs-aiassistant-settings-page' of github.com:CoenW…
CoenWarmer Nov 26, 2023
b7acf29
Better filtering of management apps from sidebar
CoenWarmer Nov 27, 2023
9b3e529
Update link to Connectors
CoenWarmer Nov 27, 2023
3cf5d31
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Nov 27, 2023
47e97ec
Open link in external target
CoenWarmer Nov 27, 2023
8300589
Wait when deleting
CoenWarmer Nov 27, 2023
93d0d77
Correctly categorize agent summarizations
CoenWarmer Nov 27, 2023
f1b5154
Further feedback
CoenWarmer Nov 28, 2023
ddf13fc
Further feedback
CoenWarmer Nov 28, 2023
02c4a9b
Address feedback
CoenWarmer Nov 28, 2023
ddf45e6
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Nov 28, 2023
1b29ab2
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Nov 28, 2023
d086763
Address feedback
CoenWarmer Nov 30, 2023
3e33fdf
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Nov 30, 2023
18945d2
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Nov 30, 2023
0cdada6
Update component template
CoenWarmer Nov 30, 2023
cd73b82
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Nov 30, 2023
2cc60e9
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Dec 1, 2023
d99318c
Merge branch 'feat/obs-aiassistant-settings-page' of github.com:CoenW…
CoenWarmer Dec 1, 2023
72e2af3
Add unit tests, typesafe routing
CoenWarmer Dec 1, 2023
de302c2
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Dec 1, 2023
21a9d51
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Dec 1, 2023
6502283
Add tests
CoenWarmer Dec 1, 2023
0d20035
Merge branch 'feat/obs-aiassistant-settings-page' of github.com:CoenW…
CoenWarmer Dec 1, 2023
077dc82
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Dec 1, 2023
9218318
Fix tests
CoenWarmer Dec 4, 2023
5e47fbf
Add not enabled FTR API tests for Knowledge Base
CoenWarmer Dec 4, 2023
e4a86ad
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Dec 4, 2023
9ddb0d2
Fix error in log explorer
CoenWarmer Dec 5, 2023
366531d
Merge branch 'main' of github.com:elastic/kibana into feat/obs-aiassi…
CoenWarmer Dec 5, 2023
71464a1
Fix error in log explorer
CoenWarmer Dec 5, 2023
3fa6e52
Merge branch 'main' into feat/obs-aiassistant-settings-page
kibanamachine Dec 5, 2023
e99b539
Add QueryClient provider to Synthetics
CoenWarmer Dec 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,7 @@ module.exports = {
'x-pack/plugins/profiling/**/*.tsx',
'x-pack/plugins/synthetics/**/*.tsx',
'x-pack/plugins/ux/**/*.tsx',
'src/plugins/ai_assistant_management/**/*.tsx',
],
rules: {
'@kbn/telemetry/event_generating_elements_should_be_instrumented': 'error',
Expand All @@ -938,6 +939,7 @@ module.exports = {
'x-pack/plugins/profiling/**/!(*.stories.tsx|*.test.tsx|*.storybook_decorator.tsx|*.mock.tsx)',
'x-pack/plugins/synthetics/**/!(*.stories.tsx|*.test.tsx|*.storybook_decorator.tsx|*.mock.tsx)',
'x-pack/plugins/ux/**/!(*.stories.tsx|*.test.tsx|*.storybook_decorator.tsx|*.mock.tsx)',
'src/plugins/ai_assistant_management/**/!(*.stories.tsx|*.test.tsx|*.storybook_decorator.tsx|*.mock.tsx)',
],
rules: {
'@kbn/i18n/strings_should_be_translated_with_i18n': 'warn',
Expand Down
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ packages/kbn-ace @elastic/platform-deployment-management
x-pack/plugins/actions @elastic/response-ops
x-pack/test/alerting_api_integration/common/plugins/actions_simulators @elastic/response-ops
src/plugins/advanced_settings @elastic/appex-sharedux @elastic/platform-deployment-management
src/plugins/ai_assistant_management/observability @elastic/obs-knowledge-team
src/plugins/ai_assistant_management/selection @elastic/obs-knowledge-team
x-pack/packages/ml/aiops_components @elastic/ml-ui
x-pack/plugins/aiops @elastic/ml-ui
x-pack/packages/ml/aiops_utils @elastic/ml-ui
Expand Down
2 changes: 2 additions & 0 deletions .i18nrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"paths": {
"advancedSettings": "src/plugins/advanced_settings",
"aiAssistantManagementSelection": "src/plugins/ai_assistant_management/selection",
"aiAssistantManagementObservability": "src/plugins/ai_assistant_management/observability",
"alerts": "packages/kbn-alerts/src",
"alertsUIShared": "packages/kbn-alerts-ui-shared/src",
"apmOss": "src/plugins/apm_oss",
Expand Down
8 changes: 8 additions & 0 deletions docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ allowing users to configure their advanced settings, also known
as uiSettings within the code.


|{kib-repo}blob/{branch}/src/plugins/ai_assistant_management/observability/README.md[aiAssistantManagementObservability]
|The aiAssistantManagementObservability plugin manages the Ai Assistant for Observability management section.


|{kib-repo}blob/{branch}/src/plugins/ai_assistant_management/selection/README.md[aiAssistantManagementSelection]
|The aiAssistantManagementSelection plugin manages the Ai Assistant management section.
miltonhultgren marked this conversation as resolved.
Show resolved Hide resolved


|{kib-repo}blob/{branch}/src/plugins/bfetch/README.md[bfetch]
|bfetch allows to batch HTTP requests and streams responses back.

Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@
"@kbn/actions-plugin": "link:x-pack/plugins/actions",
"@kbn/actions-simulators-plugin": "link:x-pack/test/alerting_api_integration/common/plugins/actions_simulators",
"@kbn/advanced-settings-plugin": "link:src/plugins/advanced_settings",
"@kbn/ai-assistant-management-observability-plugin": "link:src/plugins/ai_assistant_management/observability",
"@kbn/ai-assistant-management-plugin": "link:src/plugins/ai_assistant_management/selection",
"@kbn/aiops-components": "link:x-pack/packages/ml/aiops_components",
"@kbn/aiops-plugin": "link:x-pack/plugins/aiops",
"@kbn/aiops-utils": "link:x-pack/packages/ml/aiops_utils",
Expand Down
2 changes: 2 additions & 0 deletions packages/deeplinks/management/deep_links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export type IntegrationsDeepLinkId = IntegrationsAppId | FleetAppId | OsQueryApp
// Management
export type ManagementAppId = typeof MANAGEMENT_APP_ID;
export type ManagementId =
| 'aiAssistantManagementSelection'
| 'aiAssistantManagementObservability'
| 'api_keys'
| 'cases'
| 'cross_cluster_replication'
Expand Down
3 changes: 3 additions & 0 deletions packages/default-nav/management/default_navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ export const defaultNavigation: ManagementNodeDefinition = {
{
link: 'management:dataViews',
},
{
link: 'management:aiAssistantManagementSelection',
},
{
// Saved objects
link: 'management:objects',
Expand Down
2 changes: 2 additions & 0 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pageLoadAssetSize:
actions: 20000
advancedSettings: 27596
aiAssistantManagementObservability: 19279
aiAssistantManagementSelection: 19146
aiops: 10000
alerting: 106936
apm: 64385
Expand Down
2 changes: 2 additions & 0 deletions packages/shared-ux/chrome/navigation/mocks/src/navlinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const allNavLinks: AppDeepLinkId[] = [
'fleet',
'integrations',
'management',
'management:aiAssistantManagementSelection',
'management:aiAssistantManagementObservability',
'management:api_keys',
'management:cases',
'management:cross_cluster_replication',
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/ai_assistant_management/observability/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# `aiAssistantManagementObservability` plugin

The `aiAssistantManagementObservability` plugin manages the `Ai Assistant for Observability` management section.
18 changes: 18 additions & 0 deletions src/plugins/ai_assistant_management/observability/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

module.exports = {
preset: '@kbn/test',
rootDir: '../../../..',
roots: ['<rootDir>/src/plugins/ai_assistant_management/observability'],
coverageDirectory: '<rootDir>/target/kibana-coverage/jest/src/plugins/ai_assistant_management',
coverageReporters: ['text', 'html'],
collectCoverageFrom: [
'<rootDir>/src/plugins/ai_assistant_management/observability/{common,public,server}/**/*.{ts,tsx}',
],
};
13 changes: 13 additions & 0 deletions src/plugins/ai_assistant_management/observability/kibana.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"type": "plugin",
"id": "@kbn/ai-assistant-management-observability-plugin",
"owner": "@elastic/obs-knowledge-team",
"plugin": {
"id": "aiAssistantManagementObservability",
"server": false,
"browser": true,
"requiredPlugins": ["management"],
"optionalPlugins": ["actions", "home", "observabilityAIAssistant", "serverless"],
"requiredBundles": ["kibanaReact"]
}
}
79 changes: 79 additions & 0 deletions src/plugins/ai_assistant_management/observability/public/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React from 'react';
import ReactDOM from 'react-dom';
import { RouteRenderer, RouterProvider } from '@kbn/typed-react-router-config';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { I18nProvider } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { CoreSetup } from '@kbn/core/public';
import { wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import { ManagementAppMountParams } from '@kbn/management-plugin/public';
import { StartDependencies, AiAssistantManagementObservabilityPluginStart } from './plugin';
import { aIAssistantManagementObservabilityRouter } from './routes/config';
import { RedirectToHomeIfUnauthorized } from './routes/components/redirect_to_home_if_unauthorized';
import { AppContextProvider } from './context/app_context';

interface MountParams {
core: CoreSetup<StartDependencies, AiAssistantManagementObservabilityPluginStart>;
mountParams: ManagementAppMountParams;
}

export const mountManagementSection = async ({ core, mountParams }: MountParams) => {
const [coreStart, startDeps] = await core.getStartServices();

if (!startDeps.observabilityAIAssistant) return () => {};

const { element, history, setBreadcrumbs } = mountParams;
const { theme$ } = core.theme;

coreStart.chrome.docTitle.change(
i18n.translate('aiAssistantManagementObservability.app.titleBar', {
defaultMessage: 'AI Assistant for Observability Settings',
})
);

const queryClient = new QueryClient();

ReactDOM.render(
wrapWithTheme(
<RedirectToHomeIfUnauthorized coreStart={coreStart}>
<I18nProvider>
<AppContextProvider
value={{
application: coreStart.application,
http: coreStart.http,
notifications: coreStart.notifications,
observabilityAIAssistant: startDeps.observabilityAIAssistant,
uiSettings: coreStart.uiSettings,
serverless: startDeps.serverless,
setBreadcrumbs,
}}
>
<QueryClientProvider client={queryClient}>
<RouterProvider
history={history}
router={aIAssistantManagementObservabilityRouter as any}
>
<RouteRenderer />
</RouterProvider>
</QueryClientProvider>
</AppContextProvider>
</I18nProvider>
</RedirectToHomeIfUnauthorized>,
theme$
),
element
);

return () => {
coreStart.chrome.docTitle.reset();
ReactDOM.unmountComponentAtNode(element);
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export const REACT_QUERY_KEYS = {
CoenWarmer marked this conversation as resolved.
Show resolved Hide resolved
GET_GENAI_CONNECTORS: 'get_genai_connectors',
GET_KB_ENTRIES: 'get_kb_entries',
CREATE_KB_ENTRIES: 'create_kb_entry',
IMPORT_KB_ENTRIES: 'import_kb_entry',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React, { createContext } from 'react';
import type { ChromeBreadcrumb } from '@kbn/core-chrome-browser';
import type { CoreStart, HttpSetup } from '@kbn/core/public';
import type { ObservabilityAIAssistantPluginStart } from '@kbn/observability-ai-assistant-plugin/public';
import type { StartDependencies } from '../plugin';

export interface ContextValue extends StartDependencies {
application: CoreStart['application'];
http: HttpSetup;
notifications: CoreStart['notifications'];
observabilityAIAssistant: ObservabilityAIAssistantPluginStart;
setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void;
uiSettings: CoreStart['uiSettings'];
}

export const AppContext = createContext<ContextValue>(null as any);

export const AppContextProvider = ({
children,
value,
}: {
value: ContextValue;
children: React.ReactNode;
}) => {
return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import type { KnowledgeBaseEntry } from '@kbn/observability-ai-assistant-plugin/common/types';

export interface KnowledgeBaseEntryCategory {
'@timestamp': string;
categoryName: string;
entries: KnowledgeBaseEntry[];
}

export function categorizeEntries({ entries }: { entries: KnowledgeBaseEntry[] }) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about lodash.groupBy(entry, 'categoryName')?

return entries.reduce((acc, entry) => {
const categoryName = entry.labels.category ?? entry.id;

const index = acc.findIndex((item) => item.categoryName === categoryName);

if (index > -1) {
acc[index].entries.push(entry);
return acc;
} else {
return acc.concat({ categoryName, entries: [entry], '@timestamp': entry['@timestamp'] });
}
}, [] as Array<{ categoryName: string; entries: KnowledgeBaseEntry[]; '@timestamp': string }>);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React from 'react';
import { createMemoryHistory } from 'history';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { render as testLibRender } from '@testing-library/react';
import { coreMock } from '@kbn/core/public/mocks';
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
import translations from '@kbn/translations-plugin/translations/ja-JP.json';

import { mockObservabilityAIAssistantService } from '@kbn/observability-ai-assistant-plugin/public';
import { RouterProvider } from '@kbn/typed-react-router-config';
import { AppContextProvider } from '../context/app_context';
import { RedirectToHomeIfUnauthorized } from '../routes/components/redirect_to_home_if_unauthorized';
import { aIAssistantManagementObservabilityRouter } from '../routes/config';

export const coreStart = coreMock.createStart();

const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
logger: {
// eslint-disable-next-line no-console
log: console.log,
// eslint-disable-next-line no-console
warn: console.warn,
error: () => {},
},
});

export const render = (component: React.ReactNode, params?: { show: boolean }) => {
const history = createMemoryHistory();

return testLibRender(
// @ts-ignore
<IntlProvider locale="en-US" messages={translations.messages}>
<RedirectToHomeIfUnauthorized
coreStart={{
application: {
...coreStart.application,
capabilities: {
// @ts-ignore
management: { show: true },
observabilityAIAssistant: {
show: params?.show ?? true,
},
},
},
}}
>
<AppContextProvider
value={{
http: coreStart.http,
application: coreStart.application,
notifications: coreStart.notifications,
observabilityAIAssistant: {
service: mockObservabilityAIAssistantService,
useGenAIConnectors: () => ({
loading: false,
selectConnector: () => {},
reloadConnectors: () => {},
}),
},
uiSettings: coreStart.uiSettings,
setBreadcrumbs: () => {},
}}
>
<QueryClientProvider client={queryClient}>
<RouterProvider
history={history}
router={aIAssistantManagementObservabilityRouter as any}
>
{component}
</RouterProvider>
</QueryClientProvider>
</AppContextProvider>
</RedirectToHomeIfUnauthorized>
</IntlProvider>
);
};
Loading