Skip to content

Commit

Permalink
[AI Assistant] Add setting for preferred type
Browse files Browse the repository at this point in the history
  • Loading branch information
dgieselaar committed Mar 25, 2024
1 parent 084af44 commit c97d92f
Show file tree
Hide file tree
Showing 18 changed files with 299 additions and 42 deletions.
3 changes: 3 additions & 0 deletions config/serverless.oblt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ xpack.apm.featureFlags.migrationToFleetAvailable: false
xpack.apm.featureFlags.sourcemapApiAvailable: false
xpack.apm.featureFlags.storageExplorerAvailable: false

## Set the AI Assistant type
aiAssistantManagementSelection.preferredAIAssistantType: "observability"

# Specify in telemetry the project type
telemetry.labels.serverless: observability

Expand Down
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 enum AIAssistantType {
Security = 'security',
Observability = 'observability',
Default = 'default',
Never = 'never',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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 PREFERRED_AI_ASSISTANT_TYPE_SETTING_KEY = 'aiAssistant:preferredAIAssistantType';
9 changes: 6 additions & 3 deletions src/plugins/ai_assistant_management/selection/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
"owner": "@elastic/obs-knowledge-team",
"plugin": {
"id": "aiAssistantManagementSelection",
"server": false,
"server": true,
"browser": true,
"requiredPlugins": ["management"],
"optionalPlugins": ["home", "serverless"],
"requiredBundles": ["kibanaReact"]
}
"requiredBundles": ["kibanaReact"],
"configPath": [
"aiAssistantManagementSelection"
],
},
}
23 changes: 16 additions & 7 deletions src/plugins/ai_assistant_management/selection/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@
* Side Public License, v 1.
*/

import { AiAssistantManagementPlugin } from './plugin';
import type { PluginInitializer } from '@kbn/core/public';
import { AIAssistantManagementPlugin } from './plugin';

export type {
AiAssistantManagementSelectionPluginSetup,
AiAssistantManagementSelectionPluginStart,
import type {
AIAssistantManagementSelectionPluginPublicSetup,
AIAssistantManagementSelectionPluginPublicStart,
} from './plugin';

export function plugin() {
return new AiAssistantManagementPlugin();
}
export { AIAssistantType } from '../common/ai_assistant_type';

export type {
AIAssistantManagementSelectionPluginPublicSetup,
AIAssistantManagementSelectionPluginPublicStart,
};

export const plugin: PluginInitializer<
AIAssistantManagementSelectionPluginPublicSetup,
AIAssistantManagementSelectionPluginPublicStart
> = () => new AIAssistantManagementPlugin();
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ import ReactDOM from 'react-dom';
import { RouteRenderer, RouterProvider } from '@kbn/typed-react-router-config';
import { I18nProvider } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { CoreSetup } from '@kbn/core/public';
import type { CoreSetup } from '@kbn/core/public';
import { wrapWithTheme } from '@kbn/kibana-react-plugin/public';
import { ManagementAppMountParams } from '@kbn/management-plugin/public';
import { StartDependencies, AiAssistantManagementSelectionPluginStart } from '../plugin';
import type { ManagementAppMountParams } from '@kbn/management-plugin/public';
import type { StartDependencies, AIAssistantManagementSelectionPluginPublicStart } from '../plugin';
import { aIAssistantManagementSelectionRouter } from '../routes/config';
import { RedirectToHomeIfUnauthorized } from '../routes/components/redirect_to_home_if_unauthorized';
import { AppContextProvider } from '../app_context';

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

Expand Down
46 changes: 31 additions & 15 deletions src/plugins/ai_assistant_management/selection/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@
*/

import { i18n } from '@kbn/i18n';
import { CoreSetup, Plugin } from '@kbn/core/public';
import { ManagementSetup } from '@kbn/management-plugin/public';
import { HomePublicPluginSetup } from '@kbn/home-plugin/public';
import { ServerlessPluginSetup } from '@kbn/serverless/public';
import { type CoreSetup, Plugin, type CoreStart } from '@kbn/core/public';
import type { ManagementSetup } from '@kbn/management-plugin/public';
import type { HomePublicPluginSetup } from '@kbn/home-plugin/public';
import type { ServerlessPluginSetup } from '@kbn/serverless/public';
import { BehaviorSubject, Observable } from 'rxjs';
import { AIAssistantType } from '../common/ai_assistant_type';
import { PREFERRED_AI_ASSISTANT_TYPE_SETTING_KEY } from '../common/ui_setting_keys';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface AiAssistantManagementSelectionPluginSetup {}
export interface AIAssistantManagementSelectionPluginPublicSetup {}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface AiAssistantManagementSelectionPluginStart {}
export interface AIAssistantManagementSelectionPluginPublicStart {
aiAssistantType$: Observable<AIAssistantType>;
}

export interface SetupDependencies {
management: ManagementSetup;
Expand All @@ -27,20 +31,24 @@ export interface SetupDependencies {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface StartDependencies {}

export class AiAssistantManagementPlugin
export class AIAssistantManagementPlugin
implements
Plugin<
AiAssistantManagementSelectionPluginSetup,
AiAssistantManagementSelectionPluginStart,
AIAssistantManagementSelectionPluginPublicSetup,
AIAssistantManagementSelectionPluginPublicStart,
SetupDependencies,
StartDependencies
>
{
constructor() {}

public setup(
core: CoreSetup<StartDependencies, AiAssistantManagementSelectionPluginStart>,
core: CoreSetup<StartDependencies, AIAssistantManagementSelectionPluginPublicStart>,
{ home, management, serverless }: SetupDependencies
): AiAssistantManagementSelectionPluginSetup {
if (serverless) return {};
): AIAssistantManagementSelectionPluginPublicSetup {
if (serverless) {
return {};
}

if (home) {
home.featureCatalogue.register({
Expand Down Expand Up @@ -77,7 +85,15 @@ export class AiAssistantManagementPlugin
return {};
}

public start() {
return {};
public start(coreStart: CoreStart) {
const preferredAIAssistantType: AIAssistantType = coreStart.uiSettings.get(
PREFERRED_AI_ASSISTANT_TYPE_SETTING_KEY
);

const aiAssistantType$ = new BehaviorSubject(preferredAIAssistantType);

return {
aiAssistantType$: aiAssistantType$.asObservable(),
};
}
}
13 changes: 13 additions & 0 deletions src/plugins/ai_assistant_management/selection/public/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 { AIAssistantType } from '../common/ai_assistant_type';

export interface ConfigSchema {
preferredAIAssistantType: AIAssistantType;
}
33 changes: 33 additions & 0 deletions src/plugins/ai_assistant_management/selection/server/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 { schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core-plugins-server';
import { AIAssistantType } from '../common/ai_assistant_type';

const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
preferredAIAssistantType: schema.oneOf(
[
schema.literal(AIAssistantType.Default),
schema.literal(AIAssistantType.Never),
schema.literal(AIAssistantType.Observability),
schema.literal(AIAssistantType.Security),
],
{ defaultValue: AIAssistantType.Default }
),
});

export type AIAssistantManagementSelectionConfig = TypeOf<typeof configSchema>;

export const config: PluginConfigDescriptor<AIAssistantManagementSelectionConfig> = {
schema: configSchema,
exposeToBrowser: {
preferredAIAssistantType: true,
},
};
16 changes: 16 additions & 0 deletions src/plugins/ai_assistant_management/selection/server/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* 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 { PluginInitializerContext } from '@kbn/core/server';

export { config } from './config';

export const plugin = async (initContext: PluginInitializerContext) => {
const { AIAssistantManagementSelectionPlugin } = await import('./plugin');
return new AIAssistantManagementSelectionPlugin(initContext);
};
90 changes: 90 additions & 0 deletions src/plugins/ai_assistant_management/selection/server/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* 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 { i18n } from '@kbn/i18n';

import type { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '@kbn/core/server';
import { schema } from '@kbn/config-schema';
import type { AIAssistantManagementSelectionConfig } from './config';
import type {
AIAssistantManagementSelectionPluginServerSetup,
AIAssistantManagementSelectionPluginServerStart,
} from './types';
import { AIAssistantType } from '../common/ai_assistant_type';
import { PREFERRED_AI_ASSISTANT_TYPE_SETTING_KEY } from '../common/ui_setting_keys';

export class AIAssistantManagementSelectionPlugin
implements
Plugin<
AIAssistantManagementSelectionPluginServerSetup,
AIAssistantManagementSelectionPluginServerStart
>
{
private readonly config: AIAssistantManagementSelectionConfig;

constructor(initializerContext: PluginInitializerContext) {
this.config = initializerContext.config.get();
}

public setup(core: CoreSetup) {
core.uiSettings.register({
[PREFERRED_AI_ASSISTANT_TYPE_SETTING_KEY]: {
name: i18n.translate('aiAssistantManagementSelection.preferredAIAssistantTypeSettingName', {
defaultMessage: 'AI Assistant type',
}),
value: this.config.preferredAIAssistantType,
description: i18n.translate(
'aiAssistantManagementSelection.preferredAIAssistantTypeSettingDescription',
{ defaultMessage: 'Select an AI Assistant to use, or disable it entirely' }
),
schema: schema.oneOf(
[
schema.literal(AIAssistantType.Default),
schema.literal(AIAssistantType.Observability),
schema.literal(AIAssistantType.Security),
schema.literal(AIAssistantType.Never),
],
{ defaultValue: this.config.preferredAIAssistantType }
),
options: [
AIAssistantType.Default,
AIAssistantType.Observability,
AIAssistantType.Security,
AIAssistantType.Never,
],
type: 'select',
optionLabels: {
[AIAssistantType.Default]: i18n.translate(
'aiAssistantManagementSelection.preferredAIAssistantTypeSettingValueDefault',
{ defaultMessage: 'Default' }
),
[AIAssistantType.Observability]: i18n.translate(
'aiAssistantManagementSelection.preferredAIAssistantTypeSettingValueObservability',
{ defaultMessage: 'Observability' }
),
[AIAssistantType.Security]: i18n.translate(
'aiAssistantManagementSelection.preferredAIAssistantTypeSettingValueSecurity',
{ defaultMessage: 'Security' }
),
[AIAssistantType.Never]: i18n.translate(
'aiAssistantManagementSelection.preferredAIAssistantTypeSettingValueNever',
{ defaultMessage: 'Disable everywhere' }
),
},
requiresPageReload: true,
},
});

return {};
}

public start(core: CoreStart) {
return {};
}

public stop() {}
}
18 changes: 18 additions & 0 deletions src/plugins/ai_assistant_management/selection/server/types.ts
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.
*/

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface AIAssistantManagementSelectionPluginServerDependenciesStart {}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface AIAssistantManagementSelectionPluginServerDependenciesSetup {}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface AIAssistantManagementSelectionPluginServerStart {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface AIAssistantManagementSelectionPluginServerSetup {}
4 changes: 3 additions & 1 deletion src/plugins/ai_assistant_management/selection/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"@kbn/i18n-react",
"@kbn/core-chrome-browser",
"@kbn/typed-react-router-config",
"@kbn/serverless"
"@kbn/serverless",
"@kbn/config-schema",
"@kbn/core-plugins-server"
],
"exclude": ["target/**/*"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"browser": true,
"configPath": ["xpack", "observabilityAIAssistantApp"],
"requiredPlugins": [
"aiAssistantManagementSelection",
"observabilityAIAssistant",
"observabilityShared",
"actions",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
import React, { useEffect, useRef, useState } from 'react';
import { AssistantAvatar, useAbortableAsync } from '@kbn/observability-ai-assistant-plugin/public';
import { EuiButton } from '@elastic/eui';
import { EuiButton, EuiLoadingSpinner } from '@elastic/eui';
import { css } from '@emotion/react';
import { v4 } from 'uuid';
import useObservable from 'react-use/lib/useObservable';
Expand Down Expand Up @@ -92,7 +92,7 @@ export function NavControl({}: {}) {
fullWidth={false}
minWidth={0}
>
<AssistantAvatar size="xs" />
{chatService.loading ? <EuiLoadingSpinner size="s" /> : <AssistantAvatar size="xs" />}
</EuiButton>
{chatService.value ? (
<ObservabilityAIAssistantChatServiceContext.Provider value={chatService.value}>
Expand Down
Loading

0 comments on commit c97d92f

Please sign in to comment.