From 02773ae8c9cced56b4f91c930242a0c269e06f10 Mon Sep 17 00:00:00 2001 From: Songkan Tang Date: Mon, 2 Sep 2024 14:22:15 +0800 Subject: [PATCH 1/9] Add capabilities to check subscription active status to control assistant feature UI Signed-off-by: Songkan Tang --- common/types/config.ts | 12 ++++++++++-- public/plugin.tsx | 11 ++++++++++- public/types.ts | 7 +++++++ server/capabilities.ts | 24 ++++++++++++++++++++++++ server/index.ts | 3 +++ server/plugin.ts | 8 +++----- 6 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 server/capabilities.ts diff --git a/common/types/config.ts b/common/types/config.ts index bf84a8da..ad8e340b 100644 --- a/common/types/config.ts +++ b/common/types/config.ts @@ -6,8 +6,7 @@ import { schema, TypeOf } from '@osd/config-schema'; export const configSchema = schema.object({ - // TODO: add here to prevent this plugin from being loaded - // enabled: schema.boolean({ defaultValue: true }), + enabled: schema.boolean({ defaultValue: true }), chat: schema.object({ enabled: schema.boolean({ defaultValue: false }), }), @@ -17,6 +16,15 @@ export const configSchema = schema.object({ next: schema.object({ enabled: schema.boolean({ defaultValue: false }), }), + text2viz: schema.object({ + enabled: schema.boolean({ defaultValue: false }), + }), + alertInsight: schema.object({ + enabled: schema.boolean({ defaultValue: false }), + }), + smartAnomalyDetector: schema.object({ + enabled: schema.boolean({ defaultValue: false }), + }), }); export type ConfigSchema = TypeOf; diff --git a/public/plugin.tsx b/public/plugin.tsx index a0399e95..83353acf 100644 --- a/public/plugin.tsx +++ b/public/plugin.tsx @@ -104,7 +104,7 @@ export class AssistantPlugin dataSourceManagement: setupDeps.dataSourceManagement, }); - if (this.config.next.enabled) { + if (this.config.text2viz.enabled) { setupDeps.visualizations.registerAlias({ name: 'text2viz', aliasPath: '#/', @@ -199,6 +199,15 @@ export class AssistantPlugin }, chatEnabled: () => this.config.chat.enabled, nextEnabled: () => this.config.next.enabled, + getFeatureStatus: () => { + return { + chat: this.config.chat.enabled, + next: this.config.next.enabled, + text2viz: this.config.text2viz.enabled, + alertInsight: this.config.alertInsight.enabled, + smartAnomalyDetector: this.config.smartAnomalyDetector.enabled, + }; + }, assistantActions, registerIncontextInsight: this.incontextInsightRegistry.register.bind( this.incontextInsightRegistry diff --git a/public/types.ts b/public/types.ts index 538fadff..2b3aa466 100644 --- a/public/types.ts +++ b/public/types.ts @@ -60,6 +60,13 @@ export interface AssistantSetup { * Returns true if contextual assistant is enabled. */ nextEnabled: () => boolean; + getFeatureStatus: () => { + chat: boolean; + next: boolean; + text2viz: boolean; + alertInsight: boolean; + smartAnomalyDetector: boolean; + }; assistantActions: Omit; registerIncontextInsight: IncontextInsightRegistry['register']; renderIncontextInsight: (component: React.ReactNode) => React.ReactNode; diff --git a/server/capabilities.ts b/server/capabilities.ts new file mode 100644 index 00000000..69a8675d --- /dev/null +++ b/server/capabilities.ts @@ -0,0 +1,24 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { CapabilitiesSwitcher } from '../../../src/core/server'; + +export const capabilitiesProvider = () => ({ + observability: { + show: true, + }, + assistant: { + isSubscriptionActive: true, + }, +}); + +// Users can customize the assistant feature UI capabilities here +export const capabilitiesSwitcher: CapabilitiesSwitcher = (request, capabilities) => { + return { + assistant: { + isSubscriptionActive: true, + }, + }; +}; diff --git a/server/index.ts b/server/index.ts index 4a0d1bab..6bbdce05 100644 --- a/server/index.ts +++ b/server/index.ts @@ -12,6 +12,9 @@ export const config: PluginConfigDescriptor = { chat: true, incontextInsight: true, next: true, + text2viz: true, + alertInsight: true, + smartAnomalyDetector: true, }, schema: configSchema, }; diff --git a/server/plugin.ts b/server/plugin.ts index 48777819..4cff0e6d 100644 --- a/server/plugin.ts +++ b/server/plugin.ts @@ -17,6 +17,7 @@ import { BasicInputOutputParser } from './parsers/basic_input_output_parser'; import { VisualizationCardParser } from './parsers/visualization_card_parser'; import { registerChatRoutes } from './routes/chat_routes'; import { registerText2VizRoutes } from './routes/text2viz_routes'; +import { capabilitiesProvider, capabilitiesSwitcher } from './capabilities'; export class AssistantPlugin implements Plugin { private readonly logger: Logger; @@ -53,11 +54,8 @@ export class AssistantPlugin implements Plugin ({ - observability: { - show: true, - }, - })); + core.capabilities.registerProvider(capabilitiesProvider); + core.capabilities.registerSwitcher(capabilitiesSwitcher); const registerMessageParser = (messageParser: MessageParser) => { const findItem = this.messageParsers.find((item) => item.id === messageParser.id); From 5304c8b08e17eab81d5c57dbd1abe917e7561b64 Mon Sep 17 00:00:00 2001 From: Songkan Tang Date: Mon, 2 Sep 2024 14:25:15 +0800 Subject: [PATCH 2/9] Fix text2viz feature flag check in server/plugin.ts Signed-off-by: Songkan Tang --- server/plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/plugin.ts b/server/plugin.ts index 4cff0e6d..01e2d1d2 100644 --- a/server/plugin.ts +++ b/server/plugin.ts @@ -50,7 +50,7 @@ export class AssistantPlugin implements Plugin Date: Tue, 3 Sep 2024 14:30:59 +0800 Subject: [PATCH 3/9] Use assistant isSubscriptionActive capabilities to control text2viz UI Signed-off-by: Songkan Tang --- public/plugin.tsx | 76 ++++++++++++++++++++++++++---------------- server/capabilities.ts | 2 +- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/public/plugin.tsx b/public/plugin.tsx index 83353acf..34bba4c2 100644 --- a/public/plugin.tsx +++ b/public/plugin.tsx @@ -105,28 +105,42 @@ export class AssistantPlugin }); if (this.config.text2viz.enabled) { - setupDeps.visualizations.registerAlias({ - name: 'text2viz', - aliasPath: '#/', - aliasApp: 'text2viz', - title: i18n.translate('dashboardAssistant.feature.text2viz.title', { - defaultMessage: 'Natural language', - }), - description: i18n.translate('dashboardAssistant.feature.text2viz.description', { - defaultMessage: 'Generate visualization with a natural language question.', - }), - icon: 'chatRight', - stage: 'experimental', - promotion: { - buttonText: i18n.translate('dashboardAssistant.feature.text2viz.promotion.buttonText', { - defaultMessage: 'Natural language previewer', - }), - description: i18n.translate('dashboardAssistant.feature.text2viz.promotion.description', { - defaultMessage: - 'Not sure which visualization to choose? Generate visualization previews with a natural language question.', - }), - }, - }); + const checkSubscriptionAndRegisterText2VizButton = async () => { + const [coreStart] = await core.getStartServices(); + const isSubscriptionActive = + coreStart.application.capabilities?.assistant?.isSubscriptionActive === true; + if (isSubscriptionActive) { + setupDeps.visualizations.registerAlias({ + name: 'text2viz', + aliasPath: '#/', + aliasApp: 'text2viz', + title: i18n.translate('dashboardAssistant.feature.text2viz.title', { + defaultMessage: 'Natural language', + }), + description: i18n.translate('dashboardAssistant.feature.text2viz.description', { + defaultMessage: 'Generate visualization with a natural language question.', + }), + icon: 'chatRight', + stage: 'experimental', + promotion: { + buttonText: i18n.translate( + 'dashboardAssistant.feature.text2viz.promotion.buttonText', + { + defaultMessage: 'Natural language previewer', + } + ), + description: i18n.translate( + 'dashboardAssistant.feature.text2viz.promotion.description', + { + defaultMessage: + 'Not sure which visualization to choose? Generate visualization previews with a natural language question.', + } + ), + }, + }); + } + }; + checkSubscriptionAndRegisterText2VizButton(); core.application.register({ id: 'text2viz', @@ -136,12 +150,18 @@ export class AssistantPlugin navLinkStatus: AppNavLinkStatus.hidden, mount: async (params: AppMountParameters) => { const [coreStart, pluginsStart] = await core.getStartServices(); - const { renderText2VizApp } = await import('./text2viz'); - return renderText2VizApp(params, { - ...coreStart, - ...pluginsStart, - setHeaderActionMenu: params.setHeaderActionMenu, - }); + const isSubscriptionActive = + coreStart.application.capabilities?.assistant?.isSubscriptionActive === true; + if (isSubscriptionActive) { + const { renderText2VizApp } = await import('./text2viz'); + return renderText2VizApp(params, { + ...coreStart, + ...pluginsStart, + setHeaderActionMenu: params.setHeaderActionMenu, + }); + } else { + return () => {}; + } }, }); } diff --git a/server/capabilities.ts b/server/capabilities.ts index 69a8675d..50ff0b41 100644 --- a/server/capabilities.ts +++ b/server/capabilities.ts @@ -14,7 +14,7 @@ export const capabilitiesProvider = () => ({ }, }); -// Users can customize the assistant feature UI capabilities here +// Users can customize the logic of flipping assistant feature UI capabilities here export const capabilitiesSwitcher: CapabilitiesSwitcher = (request, capabilities) => { return { assistant: { From e4522882dbe3ddc4046f176555d80f404e9c0c9f Mon Sep 17 00:00:00 2001 From: Songkan Tang Date: Tue, 3 Sep 2024 15:16:15 +0800 Subject: [PATCH 4/9] Add changelog Signed-off-by: Songkan Tang --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e74ad30..8a2ec76c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,4 +25,5 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Add experimental feature to support text to visualization ([#218](https://github.com/opensearch-project/dashboards-assistant/pull/218)) - Be compatible with ML configuration index mapping change ([#239](https://github.com/opensearch-project/dashboards-assistant/pull/239)) - Support context aware alert analysis by reusing incontext insight component([#215](https://github.com/opensearch-project/dashboards-assistant/pull/215)) -Use smaller and compressed variants of buttons and form components ([#250](https://github.com/opensearch-project/dashboards-assistant/pull/250)) \ No newline at end of file +- Use smaller and compressed variants of buttons and form components ([#250](https://github.com/opensearch-project/dashboards-assistant/pull/250)) +- Export assistant feature flags and add assistant isSubscriptionActive capabilities to control rendering component([#267](https://github.com/opensearch-project/dashboards-assistant/pull/267)) \ No newline at end of file From 20a279e7e4f1b0d6d33b85a98d0c5dac17b6018b Mon Sep 17 00:00:00 2001 From: Songkan Tang Date: Tue, 10 Sep 2024 11:49:10 +0800 Subject: [PATCH 5/9] Add default app not activation page for text2viz if subscription is not activated Signed-off-by: Songkan Tang --- public/plugin.tsx | 3 ++- public/text2viz.tsx | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/public/plugin.tsx b/public/plugin.tsx index a7f7af43..01f5a941 100644 --- a/public/plugin.tsx +++ b/public/plugin.tsx @@ -170,7 +170,8 @@ export class AssistantPlugin setHeaderActionMenu: params.setHeaderActionMenu, }); } else { - return () => {}; + const { renderAppNotActivated } = await import('./text2viz'); + return renderAppNotActivated(params); } }, }); diff --git a/public/text2viz.tsx b/public/text2viz.tsx index 5b066d90..cbc55dfb 100644 --- a/public/text2viz.tsx +++ b/public/text2viz.tsx @@ -5,6 +5,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import { EuiEmptyPrompt, EuiPage, EuiPageBody, EuiPageContent, EuiText } from '@elastic/eui'; import { AppMountParameters } from '../../../src/core/public'; import { Text2Viz } from './components/visualization/text2viz'; import { OpenSearchDashboardsContextProvider } from '../../../src/plugins/opensearch_dashboards_react/public'; @@ -24,3 +25,32 @@ export const renderText2VizApp = (params: AppMountParameters, services: StartSer ReactDOM.unmountComponentAtNode(params.element); }; }; + +export const renderAppNotActivated = (params: AppMountParameters) => { + ReactDOM.render( + + + + Application Not Activated} + body={ + +

+ No application was found at this URL. Please check your subscription to enable + this feature. +

+
+ } + /> +
+
+
, + + params.element + ); + return () => { + ReactDOM.unmountComponentAtNode(params.element); + }; +}; From 5fe214d4448d6ae1fafd52b86cd437ff0c232690 Mon Sep 17 00:00:00 2001 From: Songkan Tang Date: Wed, 11 Sep 2024 15:45:02 +0800 Subject: [PATCH 6/9] Rename assistant feature UI capabilities to a more general name Signed-off-by: Songkan Tang --- public/plugin.tsx | 10 ++++------ server/capabilities.ts | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/public/plugin.tsx b/public/plugin.tsx index feeae407..71f50f3c 100644 --- a/public/plugin.tsx +++ b/public/plugin.tsx @@ -127,9 +127,8 @@ export class AssistantPlugin if (this.config.text2viz.enabled) { const checkSubscriptionAndRegisterText2VizButton = async () => { const [coreStart] = await core.getStartServices(); - const isSubscriptionActive = - coreStart.application.capabilities?.assistant?.isSubscriptionActive === true; - if (isSubscriptionActive) { + const assistantEnabled = coreStart.application.capabilities?.assistant?.enabled === true; + if (assistantEnabled) { setupDeps.embeddable.registerEmbeddableFactory( NLQ_VISUALIZATION_EMBEDDABLE_TYPE, new NLQVisualizationEmbeddableFactory() @@ -192,9 +191,8 @@ export class AssistantPlugin navLinkStatus: AppNavLinkStatus.hidden, mount: async (params: AppMountParameters) => { const [coreStart, pluginsStart] = await core.getStartServices(); - const isSubscriptionActive = - coreStart.application.capabilities?.assistant?.isSubscriptionActive === true; - if (isSubscriptionActive) { + const assistantEnabled = coreStart.application.capabilities?.assistant?.enabled === true; + if (assistantEnabled) { params.element.classList.add('text2viz-wrapper'); const { renderText2VizApp } = await import('./text2viz'); const unmount = renderText2VizApp(params, { diff --git a/server/capabilities.ts b/server/capabilities.ts index 50ff0b41..afd590b5 100644 --- a/server/capabilities.ts +++ b/server/capabilities.ts @@ -10,7 +10,7 @@ export const capabilitiesProvider = () => ({ show: true, }, assistant: { - isSubscriptionActive: true, + enabled: true, }, }); @@ -18,7 +18,7 @@ export const capabilitiesProvider = () => ({ export const capabilitiesSwitcher: CapabilitiesSwitcher = (request, capabilities) => { return { assistant: { - isSubscriptionActive: true, + enabled: true, }, }; }; From bbfa6a3d20c627bb1583c8740737b8f3ca184ea0 Mon Sep 17 00:00:00 2001 From: Songkan Tang Date: Wed, 11 Sep 2024 15:47:37 +0800 Subject: [PATCH 7/9] Rename changelog Signed-off-by: Songkan Tang --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d19e9c66..7f6fe1d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,4 +32,4 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Support context aware alert analysis by reusing incontext insight component([#215](https://github.com/opensearch-project/dashboards-assistant/pull/215)) - Use smaller and compressed variants of buttons and form components ([#250](https://github.com/opensearch-project/dashboards-assistant/pull/250)) - Support insight with RAG in alert analysis assistant and refine the UX ([#266](https://github.com/opensearch-project/dashboards-assistant/pull/266)) -- Add assistant isSubscriptionActive capabilities to control rendering component([#267](https://github.com/opensearch-project/dashboards-assistant/pull/267)) \ No newline at end of file +- Add assistant enabled capabilities to control rendering component([#267](https://github.com/opensearch-project/dashboards-assistant/pull/267)) \ No newline at end of file From ea41d06229473657a649fe23368eb933664d7dc8 Mon Sep 17 00:00:00 2001 From: Songkan Tang Date: Wed, 11 Sep 2024 15:55:51 +0800 Subject: [PATCH 8/9] Rephrase app not found page Signed-off-by: Songkan Tang --- public/plugin.tsx | 4 ++-- public/text2viz.tsx | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/public/plugin.tsx b/public/plugin.tsx index 71f50f3c..be9db38d 100644 --- a/public/plugin.tsx +++ b/public/plugin.tsx @@ -206,8 +206,8 @@ export class AssistantPlugin params.element.classList.remove('text2viz-wrapper'); }; } else { - const { renderAppNotActivated } = await import('./text2viz'); - return renderAppNotActivated(params); + const { renderAppNotFound } = await import('./text2viz'); + return renderAppNotFound(params); } }, }); diff --git a/public/text2viz.tsx b/public/text2viz.tsx index 6d95c87b..db849ec4 100644 --- a/public/text2viz.tsx +++ b/public/text2viz.tsx @@ -32,7 +32,7 @@ export const renderText2VizApp = (params: AppMountParameters, services: StartSer }; }; -export const renderAppNotActivated = (params: AppMountParameters) => { +export const renderAppNotFound = (params: AppMountParameters) => { ReactDOM.render( @@ -40,12 +40,12 @@ export const renderAppNotActivated = (params: AppMountParameters) => { Application Not Activated} + title={

Application Not Found

} body={

- No application was found at this URL. Please check your subscription to enable - this feature. + No application was found at this URL. Please check your app status to enable this + feature.

} From adb23a756e7da272e6456ddf7e7951b7e65248b0 Mon Sep 17 00:00:00 2001 From: Songkan Tang Date: Wed, 11 Sep 2024 16:56:28 +0800 Subject: [PATCH 9/9] Remove switcher registration in favor of developers adding it per their requirement Signed-off-by: Songkan Tang --- server/capabilities.ts | 11 ----------- server/plugin.ts | 3 +-- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/server/capabilities.ts b/server/capabilities.ts index afd590b5..81c03596 100644 --- a/server/capabilities.ts +++ b/server/capabilities.ts @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { CapabilitiesSwitcher } from '../../../src/core/server'; - export const capabilitiesProvider = () => ({ observability: { show: true, @@ -13,12 +11,3 @@ export const capabilitiesProvider = () => ({ enabled: true, }, }); - -// Users can customize the logic of flipping assistant feature UI capabilities here -export const capabilitiesSwitcher: CapabilitiesSwitcher = (request, capabilities) => { - return { - assistant: { - enabled: true, - }, - }; -}; diff --git a/server/plugin.ts b/server/plugin.ts index 5eb71db7..a0636ad2 100644 --- a/server/plugin.ts +++ b/server/plugin.ts @@ -22,7 +22,7 @@ import { registerAgentRoutes } from './routes/agent_routes'; import { registerSummaryAssistantRoutes } from './routes/summary_routes'; import { capabilitiesProvider as visNLQCapabilitiesProvider } from './vis_type_nlq/capabilities_provider'; import { visNLQSavedObjectType } from './vis_type_nlq/saved_object_type'; -import { capabilitiesProvider, capabilitiesSwitcher } from './capabilities'; +import { capabilitiesProvider } from './capabilities'; export class AssistantPlugin implements Plugin { private readonly logger: Logger; @@ -72,7 +72,6 @@ export class AssistantPlugin implements Plugin { const findItem = this.messageParsers.find((item) => item.id === messageParser.id);