mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[onechat] Add tools page, show registered tools (#224330)
## Summary Implements the tools page in the Onechat UI and retrieves the registered tools from the Kibana API to display a list of all tools and descriptions — descriptions are truncated at the first `\n` character.  ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] ~[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials~ - [ ] ~[Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios~ - [ ] ~If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~ - [ ] ~This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations.~ - [ ] ~[Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed~ - [ ] ~The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)~ ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. __No risks are introduced in this PR.__ --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
6b452c79ae
commit
37c930a542
28 changed files with 592 additions and 41 deletions
|
@ -8,3 +8,4 @@
|
|||
*/
|
||||
|
||||
export const WORKCHAT_APP_ID = 'workchat';
|
||||
export const ONECHAT_APP_ID = 'onechat';
|
||||
|
|
|
@ -7,10 +7,16 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { WORKCHAT_APP_ID } from './constants';
|
||||
import { ONECHAT_APP_ID, WORKCHAT_APP_ID } from './constants';
|
||||
|
||||
export type WorkchatApp = typeof WORKCHAT_APP_ID;
|
||||
export type OnechatApp = typeof ONECHAT_APP_ID;
|
||||
|
||||
export type WorkchatLinkId = 'agents' | 'integrations';
|
||||
export type OnechatLinkId = 'conversations' | 'tools';
|
||||
|
||||
export type DeepLinkId = WorkchatApp | `${WorkchatApp}:${WorkchatLinkId}`;
|
||||
export type DeepLinkId =
|
||||
| WorkchatApp
|
||||
| `${WorkchatApp}:${WorkchatLinkId}`
|
||||
| OnechatApp
|
||||
| `${OnechatApp}:${OnechatLinkId}`;
|
||||
|
|
|
@ -495,6 +495,14 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
|
|||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
'onechat:ui:enabled': {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
'onechat:tools:enabled': {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
'banners:placement': {
|
||||
type: 'keyword',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
|
|
|
@ -50,6 +50,8 @@ export interface UsageStats {
|
|||
'observability:aiAssistantSimulatedFunctionCalling': boolean;
|
||||
'observability:aiAssistantSearchConnectorIndexPattern': string;
|
||||
'onechat:mcpServer:enabled': boolean;
|
||||
'onechat:ui:enabled': boolean;
|
||||
'onechat:tools:enabled': boolean;
|
||||
'visualization:heatmap:maxBuckets': number;
|
||||
'visualization:regionmap:showWarnings': boolean;
|
||||
'visualization:tileMap:maxPrecision': number;
|
||||
|
|
|
@ -11039,6 +11039,18 @@
|
|||
"description": "Non-default value of setting."
|
||||
}
|
||||
},
|
||||
"onechat:ui:enabled": {
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
"description": "Non-default value of setting."
|
||||
}
|
||||
},
|
||||
"onechat:tools:enabled": {
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
"description": "Non-default value of setting."
|
||||
}
|
||||
},
|
||||
"banners:placement": {
|
||||
"type": "keyword",
|
||||
"_meta": {
|
||||
|
|
|
@ -109,6 +109,7 @@
|
|||
"xpack.observabilityLogsOverview": [
|
||||
"platform/packages/shared/logs-overview/src/components"
|
||||
],
|
||||
"xpack.onechat": ["platform/plugins/shared/onechat"],
|
||||
"xpack.osquery": [
|
||||
"platform/plugins/shared/osquery"
|
||||
],
|
||||
|
|
|
@ -9,3 +9,13 @@
|
|||
* UI Setting ID for enabling / disabling the MCP server
|
||||
*/
|
||||
export const ONECHAT_MCP_SERVER_UI_SETTING_ID = 'onechat:mcpServer:enabled';
|
||||
|
||||
/**
|
||||
* UI Setting ID for enabling / disabling the onechat plugin UI
|
||||
*/
|
||||
export const ONECHAT_UI_SETTING_ID = 'onechat:ui:enabled';
|
||||
|
||||
/**
|
||||
* UI Setting ID for enabling / disabling the tools UI
|
||||
*/
|
||||
export const ONECHAT_TOOLS_UI_SETTING_ID = 'onechat:tools:enabled';
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
|
||||
export const ONECHAT_FEATURE_ID = 'onechat';
|
||||
export const ONECHAT_FEATURE_NAME = 'onechat';
|
||||
export const ONECHAT_APP_ID = 'onechat_app';
|
||||
export const ONECHAT_APP_ID = 'onechat';
|
||||
export const ONECHAT_PATH = '/app/chat';
|
||||
export const ONECHAT_TITLE = 'Chat';
|
||||
|
||||
export const uiPrivileges = {
|
||||
show: 'show',
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"browser": true,
|
||||
"configPath": ["xpack", "onechat"],
|
||||
"requiredPlugins": ["actions", "inference", "features"],
|
||||
"requiredBundles": [],
|
||||
"requiredBundles": ["kibanaReact"],
|
||||
"optionalPlugins": [],
|
||||
"extraPublicDirs": []
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
||||
import React from 'react';
|
||||
import { OnechatToolsTable } from './tools_table';
|
||||
export const OnechatTools = () => {
|
||||
return (
|
||||
<KibanaPageTemplate>
|
||||
<KibanaPageTemplate.Header
|
||||
pageTitle={i18n.translate('xpack.onechat.tools.title', {
|
||||
defaultMessage: 'Tools',
|
||||
})}
|
||||
description={i18n.translate('xpack.onechat.tools.toolsDescription', {
|
||||
defaultMessage:
|
||||
'Functionality used to enhance the capabilities of your AI agents in your chat experience by allowing them to perform specific tasks or access additional information.',
|
||||
})}
|
||||
/>
|
||||
<KibanaPageTemplate.Section>
|
||||
<OnechatToolsTable />
|
||||
</KibanaPageTemplate.Section>
|
||||
</KibanaPageTemplate>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiBadge, EuiBadgeGroup, EuiBasicTable, EuiBasicTableColumn, EuiText } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ToolDescriptor } from '@kbn/onechat-common';
|
||||
import React from 'react';
|
||||
import { useOnechatTools } from '../../hooks/use_tools';
|
||||
|
||||
const parseToolDescription = (description: string): string => {
|
||||
// Truncate at newline
|
||||
const [truncatedDescription] = description.split('\n');
|
||||
return truncatedDescription;
|
||||
};
|
||||
|
||||
const columns: Array<EuiBasicTableColumn<ToolDescriptor>> = [
|
||||
{
|
||||
field: 'id',
|
||||
name: i18n.translate('xpack.onechat.tools.toolIdLabel', { defaultMessage: 'Tool' }),
|
||||
valign: 'top',
|
||||
render: (id: string) => (
|
||||
<EuiText size="s">
|
||||
<strong>{id}</strong>
|
||||
</EuiText>
|
||||
),
|
||||
},
|
||||
{
|
||||
field: 'description',
|
||||
name: i18n.translate('xpack.onechat.tools.toolDescriptionLabel', {
|
||||
defaultMessage: 'Description',
|
||||
}),
|
||||
width: '60%',
|
||||
valign: 'top',
|
||||
render: (description: string) => {
|
||||
return <EuiText size="s">{parseToolDescription(description)}</EuiText>;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'meta.tags',
|
||||
name: i18n.translate('xpack.onechat.tools.tagsLabel', {
|
||||
defaultMessage: 'Tags',
|
||||
}),
|
||||
width: '15%',
|
||||
valign: 'top',
|
||||
render: (tags: string[]) => {
|
||||
return (
|
||||
<EuiBadgeGroup>
|
||||
{tags.map((tag) => (
|
||||
<EuiBadge key={tag} color="primary">
|
||||
{tag}
|
||||
</EuiBadge>
|
||||
))}
|
||||
</EuiBadgeGroup>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const OnechatToolsTable: React.FC = () => {
|
||||
const { tools, isLoading, error } = useOnechatTools();
|
||||
const errorMessage = error
|
||||
? i18n.translate('xpack.onechat.tools.listToolsErrorMessage', {
|
||||
defaultMessage: 'Failed to fetch tools',
|
||||
})
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<EuiBasicTable
|
||||
loading={isLoading}
|
||||
columns={columns}
|
||||
items={tools}
|
||||
itemId="id"
|
||||
noItemsMessage={i18n.translate('xpack.onechat.tools.noToolsMessage', {
|
||||
defaultMessage: 'No tools found',
|
||||
})}
|
||||
error={errorMessage}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { createContext } from 'react';
|
||||
import { OnechatInternalService } from '../../services';
|
||||
|
||||
export const OnechatServicesContext = createContext<OnechatInternalService | undefined>(undefined);
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useEffect, useMemo, useCallback } from 'react';
|
||||
import type { ChromeBreadcrumb } from '@kbn/core/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ONECHAT_APP_ID } from '../../../common/features';
|
||||
import { useKibana } from './use_kibana';
|
||||
|
||||
interface OnechatBreadcrumb {
|
||||
text: string;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
export const useBreadcrumb = (breadcrumbs: OnechatBreadcrumb[]) => {
|
||||
const {
|
||||
services: { chrome, application },
|
||||
} = useKibana();
|
||||
|
||||
const getUrl = useCallback(
|
||||
(path: string) => {
|
||||
return application.getUrlForApp(ONECHAT_APP_ID, { path });
|
||||
},
|
||||
[application]
|
||||
);
|
||||
|
||||
const appUrl = useMemo(() => {
|
||||
return getUrl('');
|
||||
}, [getUrl]);
|
||||
|
||||
const baseCrumbs: ChromeBreadcrumb[] = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
text: i18n.translate('xpack.onechat.breadcrumb.onechat', {
|
||||
defaultMessage: 'OneChat',
|
||||
}),
|
||||
href: appUrl,
|
||||
},
|
||||
];
|
||||
}, [appUrl]);
|
||||
|
||||
useEffect(() => {
|
||||
const additionalCrumbs = breadcrumbs.map<ChromeBreadcrumb>((crumb) => {
|
||||
return {
|
||||
text: crumb.text,
|
||||
href: crumb.path ? getUrl(crumb.path) : undefined,
|
||||
};
|
||||
});
|
||||
|
||||
chrome.setBreadcrumbs([...baseCrumbs, ...additionalCrumbs], {
|
||||
project: { value: additionalCrumbs.length ? additionalCrumbs : baseCrumbs, absolute: true },
|
||||
});
|
||||
return () => {
|
||||
chrome.setBreadcrumbs([]);
|
||||
};
|
||||
}, [chrome, baseCrumbs, breadcrumbs, getUrl]);
|
||||
};
|
|
@ -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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import type { CoreStart } from '@kbn/core/public';
|
||||
import type { OnechatStartDependencies } from '../../types';
|
||||
|
||||
export type StartServices = CoreStart & {
|
||||
plugins: OnechatStartDependencies;
|
||||
};
|
||||
|
||||
const useTypedKibana = () => useKibana<StartServices>();
|
||||
|
||||
export { useTypedKibana as useKibana };
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useContext } from 'react';
|
||||
import { OnechatServicesContext } from '../context/onechat_services_context';
|
||||
|
||||
export const useOnechatServices = () => {
|
||||
const services = useContext(OnechatServicesContext);
|
||||
if (services === undefined) {
|
||||
throw new Error(
|
||||
`OnechatServicesContext not set. Did you wrap your component in <OnechatServicesContext.Provider> ?`
|
||||
);
|
||||
}
|
||||
return services;
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useOnechatServices } from './use_onechat_service';
|
||||
|
||||
export const useOnechatTools = () => {
|
||||
const { toolsService } = useOnechatServices();
|
||||
|
||||
const { data, isLoading, error } = useQuery({
|
||||
queryKey: ['tools', 'list'],
|
||||
queryFn: () => toolsService.list(),
|
||||
});
|
||||
|
||||
return { tools: data?.tools ?? [], isLoading, error };
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export { mountApp } from './mount';
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CoreStart, ScopedHistory } from '@kbn/core/public';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { Router } from '@kbn/shared-ux-router';
|
||||
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
|
||||
import { OnechatRoutes } from './routes';
|
||||
import type { OnechatInternalService } from '../services';
|
||||
import { OnechatStartDependencies } from '../types';
|
||||
import { OnechatServicesContext } from './context/onechat_services_context';
|
||||
|
||||
export const mountApp = async ({
|
||||
core,
|
||||
plugins,
|
||||
element,
|
||||
history,
|
||||
services,
|
||||
}: {
|
||||
core: CoreStart;
|
||||
plugins: OnechatStartDependencies;
|
||||
element: HTMLElement;
|
||||
history: ScopedHistory;
|
||||
services: OnechatInternalService;
|
||||
}) => {
|
||||
const kibanaServices = { ...core, plugins };
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
ReactDOM.render(
|
||||
core.rendering.addContext(
|
||||
<KibanaContextProvider services={kibanaServices}>
|
||||
<I18nProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<OnechatServicesContext.Provider value={services}>
|
||||
<RedirectAppLinks coreStart={core}>
|
||||
<Router history={history}>
|
||||
<OnechatRoutes />
|
||||
</Router>
|
||||
</RedirectAppLinks>
|
||||
</OnechatServicesContext.Provider>
|
||||
</QueryClientProvider>
|
||||
</I18nProvider>
|
||||
</KibanaContextProvider>
|
||||
),
|
||||
element
|
||||
);
|
||||
|
||||
return () => {
|
||||
ReactDOM.unmountComponentAtNode(element);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export const OnechatConversationsPage = () => {
|
||||
return <div>OnechatConversationsPage</div>;
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { OnechatTools } from '../components/tools/tools';
|
||||
import { useBreadcrumb } from '../hooks/use_breadcrumbs';
|
||||
|
||||
export const OnechatToolsPage = () => {
|
||||
useBreadcrumb([
|
||||
{ text: i18n.translate('xpack.onechat.chat.title', { defaultMessage: 'Chat' }) },
|
||||
{ text: i18n.translate('xpack.onechat.tools.title', { defaultMessage: 'Tools' }) },
|
||||
]);
|
||||
return <OnechatTools />;
|
||||
};
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Routes, Route } from '@kbn/shared-ux-router';
|
||||
import React from 'react';
|
||||
import { useUiSetting } from '@kbn/kibana-react-plugin/public';
|
||||
import { OnechatToolsPage } from './pages/tools';
|
||||
import { OnechatConversationsPage } from './pages/chat';
|
||||
import { ONECHAT_TOOLS_UI_SETTING_ID } from '../../common/constants';
|
||||
|
||||
export const OnechatRoutes: React.FC<{}> = () => {
|
||||
const isToolsPageEnabled = useUiSetting<boolean>(ONECHAT_TOOLS_UI_SETTING_ID, false);
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/conversations">
|
||||
<OnechatConversationsPage />
|
||||
</Route>
|
||||
{isToolsPageEnabled && (
|
||||
<Route path="/tools">
|
||||
<OnechatToolsPage />
|
||||
</Route>
|
||||
)}
|
||||
</Routes>
|
||||
);
|
||||
};
|
|
@ -5,8 +5,21 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';
|
||||
import {
|
||||
type CoreSetup,
|
||||
type CoreStart,
|
||||
type Plugin,
|
||||
type PluginInitializerContext,
|
||||
} from '@kbn/core/public';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import { registerApp } from './register';
|
||||
import {
|
||||
AgentService,
|
||||
ChatService,
|
||||
ConversationsService,
|
||||
OnechatInternalService,
|
||||
ToolsService,
|
||||
} from './services';
|
||||
import type {
|
||||
ConfigSchema,
|
||||
OnechatPluginSetup,
|
||||
|
@ -14,13 +27,7 @@ import type {
|
|||
OnechatSetupDependencies,
|
||||
OnechatStartDependencies,
|
||||
} from './types';
|
||||
import {
|
||||
AgentService,
|
||||
ChatService,
|
||||
ConversationsService,
|
||||
ToolsService,
|
||||
OnechatInternalService,
|
||||
} from './services';
|
||||
import { ONECHAT_UI_SETTING_ID } from '../common/constants';
|
||||
|
||||
export class OnechatPlugin
|
||||
implements
|
||||
|
@ -32,16 +39,25 @@ export class OnechatPlugin
|
|||
>
|
||||
{
|
||||
logger: Logger;
|
||||
// @ts-expect-error unused for now
|
||||
private internalServices?: OnechatInternalService;
|
||||
|
||||
constructor(context: PluginInitializerContext<ConfigSchema>) {
|
||||
this.logger = context.logger.get();
|
||||
}
|
||||
setup(
|
||||
coreSetup: CoreSetup<OnechatStartDependencies, OnechatPluginStart>,
|
||||
pluginsSetup: OnechatSetupDependencies
|
||||
): OnechatPluginSetup {
|
||||
setup(core: CoreSetup<OnechatStartDependencies, OnechatPluginStart>): OnechatPluginSetup {
|
||||
const isOnechatUiEnabled = core.uiSettings.get<boolean>(ONECHAT_UI_SETTING_ID, false);
|
||||
|
||||
if (isOnechatUiEnabled) {
|
||||
registerApp({
|
||||
core,
|
||||
getServices: () => {
|
||||
if (!this.internalServices) {
|
||||
throw new Error('getServices called before plugin start');
|
||||
}
|
||||
return this.internalServices;
|
||||
},
|
||||
});
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
60
x-pack/platform/plugins/shared/onechat/public/register.ts
Normal file
60
x-pack/platform/plugins/shared/onechat/public/register.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CoreSetup } from '@kbn/core-lifecycle-browser';
|
||||
import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common';
|
||||
import { AppMountParameters } from '@kbn/core-application-browser';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { OnechatInternalService } from './services';
|
||||
import { OnechatPluginStart } from './types';
|
||||
import { ONECHAT_APP_ID, ONECHAT_PATH, ONECHAT_TITLE } from '../common/features';
|
||||
import { ONECHAT_TOOLS_UI_SETTING_ID } from '../common/constants';
|
||||
|
||||
export const registerApp = ({
|
||||
core,
|
||||
getServices,
|
||||
}: {
|
||||
core: CoreSetup<OnechatPluginStart>;
|
||||
getServices: () => OnechatInternalService;
|
||||
}) => {
|
||||
const isToolsPageEnabled = core.uiSettings.get<boolean>(ONECHAT_TOOLS_UI_SETTING_ID, false);
|
||||
core.application.register({
|
||||
id: ONECHAT_APP_ID,
|
||||
appRoute: ONECHAT_PATH,
|
||||
category: DEFAULT_APP_CATEGORIES.chat,
|
||||
title: ONECHAT_TITLE,
|
||||
euiIconType: 'logoElasticsearch',
|
||||
visibleIn: ['sideNav', 'globalSearch'],
|
||||
deepLinks: [
|
||||
{
|
||||
id: 'conversations',
|
||||
path: '/conversations',
|
||||
title: i18n.translate('xpack.onechat.chat.conversationsTitle', {
|
||||
defaultMessage: 'Conversations',
|
||||
}),
|
||||
},
|
||||
...(isToolsPageEnabled
|
||||
? [
|
||||
{
|
||||
id: 'tools',
|
||||
path: '/tools',
|
||||
title: i18n.translate('xpack.onechat.tools.title', { defaultMessage: 'Tools' }),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
async mount({ element, history }: AppMountParameters) {
|
||||
const { mountApp } = await import('./application');
|
||||
const [coreStart, startPluginDeps] = await core.getStartServices();
|
||||
|
||||
coreStart.chrome.docTitle.change(ONECHAT_TITLE);
|
||||
const services = getServices();
|
||||
|
||||
return mountApp({ core: coreStart, services, element, history, plugins: startPluginDeps });
|
||||
},
|
||||
});
|
||||
};
|
|
@ -5,22 +5,20 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/server';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { OnechatConfig } from './config';
|
||||
import { registerFeatures } from './features';
|
||||
import { registerRoutes } from './routes';
|
||||
import { ServiceManager } from './services';
|
||||
import { registerTools } from './tools';
|
||||
import type {
|
||||
OnechatPluginSetup,
|
||||
OnechatPluginStart,
|
||||
OnechatSetupDependencies,
|
||||
OnechatStartDependencies,
|
||||
} from './types';
|
||||
import { registerRoutes } from './routes';
|
||||
import { ServiceManager } from './services';
|
||||
import { registerFeatures } from './features';
|
||||
import { registerTools } from './tools';
|
||||
import { ONECHAT_MCP_SERVER_UI_SETTING_ID } from '../common/constants';
|
||||
import { registerUISettings } from './ui_settings';
|
||||
|
||||
export class OnechatPlugin
|
||||
implements
|
||||
|
@ -53,20 +51,7 @@ export class OnechatPlugin
|
|||
|
||||
registerTools({ tools: serviceSetups.tools });
|
||||
|
||||
coreSetup.uiSettings.register({
|
||||
[ONECHAT_MCP_SERVER_UI_SETTING_ID]: {
|
||||
description: i18n.translate('onechat.uiSettings.mcpServer.description', {
|
||||
defaultMessage: 'Enables MCP server with access to tools.',
|
||||
}),
|
||||
name: i18n.translate('onechat.uiSettings.mcpServer.name', {
|
||||
defaultMessage: 'MCP Server',
|
||||
}),
|
||||
schema: schema.boolean(),
|
||||
value: false,
|
||||
readonly: true,
|
||||
readonlyMode: 'ui',
|
||||
},
|
||||
});
|
||||
registerUISettings({ uiSettings: coreSetup.uiSettings });
|
||||
|
||||
const router = coreSetup.http.createRouter();
|
||||
registerRoutes({
|
||||
|
|
56
x-pack/platform/plugins/shared/onechat/server/ui_settings.ts
Normal file
56
x-pack/platform/plugins/shared/onechat/server/ui_settings.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { UiSettingsServiceSetup } from '@kbn/core-ui-settings-server';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
ONECHAT_UI_SETTING_ID,
|
||||
ONECHAT_MCP_SERVER_UI_SETTING_ID,
|
||||
ONECHAT_TOOLS_UI_SETTING_ID,
|
||||
} from '../common/constants';
|
||||
|
||||
export const registerUISettings = ({ uiSettings }: { uiSettings: UiSettingsServiceSetup }) => {
|
||||
uiSettings.register({
|
||||
[ONECHAT_MCP_SERVER_UI_SETTING_ID]: {
|
||||
description: i18n.translate('xpack.onechat.uiSettings.mcpServer.description', {
|
||||
defaultMessage: 'Enables MCP server with access to tools.',
|
||||
}),
|
||||
name: i18n.translate('xpack.onechat.uiSettings.mcpServer.name', {
|
||||
defaultMessage: 'MCP Server',
|
||||
}),
|
||||
schema: schema.boolean(),
|
||||
value: false,
|
||||
readonly: true,
|
||||
readonlyMode: 'ui',
|
||||
},
|
||||
[ONECHAT_UI_SETTING_ID]: {
|
||||
description: i18n.translate('xpack.onechat.uiSettings.chatUI.description', {
|
||||
defaultMessage: 'Enables the OneChat chat UI.',
|
||||
}),
|
||||
name: i18n.translate('xpack.onechat.uiSettings.chatUI.name', {
|
||||
defaultMessage: 'OneChat Chat UI',
|
||||
}),
|
||||
schema: schema.boolean(),
|
||||
value: false,
|
||||
readonly: true,
|
||||
readonlyMode: 'ui',
|
||||
},
|
||||
[ONECHAT_TOOLS_UI_SETTING_ID]: {
|
||||
description: i18n.translate('xpack.onechat.uiSettings.toolsPage.description', {
|
||||
defaultMessage: 'Enables the OneChat tools page.',
|
||||
}),
|
||||
name: i18n.translate('xpack.onechat.uiSettings.toolsPage.name', {
|
||||
defaultMessage: 'OneChat Tools Page',
|
||||
}),
|
||||
schema: schema.boolean(),
|
||||
value: false,
|
||||
readonly: true,
|
||||
readonlyMode: 'ui',
|
||||
},
|
||||
});
|
||||
};
|
|
@ -37,6 +37,15 @@
|
|||
"@kbn/features-plugin",
|
||||
"@kbn/core-logging-server-mocks",
|
||||
"@kbn/i18n",
|
||||
"@kbn/onechat-genai-utils"
|
||||
"@kbn/onechat-genai-utils",
|
||||
"@kbn/shared-ux-page-kibana-template",
|
||||
"@kbn/kibana-react-plugin",
|
||||
"@kbn/i18n-react",
|
||||
"@kbn/shared-ux-router",
|
||||
"@kbn/shared-ux-link-redirect-app",
|
||||
"@kbn/core-lifecycle-browser",
|
||||
"@kbn/core-application-common",
|
||||
"@kbn/core-application-browser",
|
||||
"@kbn/core-ui-settings-server"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -30,9 +30,10 @@
|
|||
"serverless",
|
||||
"searchHomepage",
|
||||
"share",
|
||||
"visualizations"
|
||||
"visualizations",
|
||||
],
|
||||
"optionalPlugins": [
|
||||
"onechat",
|
||||
"indexManagement",
|
||||
"contentConnectors",
|
||||
"searchInferenceEndpoints",
|
||||
|
|
|
@ -44,6 +44,20 @@ export const navigationTree = ({ isAppRegistered }: ApplicationStart): Navigatio
|
|||
{
|
||||
link: 'discover',
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.serverlessSearch.nav.chat', {
|
||||
defaultMessage: 'Chat',
|
||||
}),
|
||||
renderAs: 'accordion',
|
||||
children: [
|
||||
{
|
||||
link: 'onechat:conversations',
|
||||
},
|
||||
{
|
||||
link: 'onechat:tools',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
link: 'dashboards',
|
||||
getIsActive: ({ pathNameSerialized, prepend }) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue