Skip to content

Commit

Permalink
Merge pull request #14 from dgieselaar/obs-ai-assistant-conversation-…
Browse files Browse the repository at this point in the history
…page
  • Loading branch information
dgieselaar committed Jul 26, 2023
2 parents 11a3b34 + a650125 commit 4cd509b
Show file tree
Hide file tree
Showing 16 changed files with 406 additions and 76 deletions.
2 changes: 1 addition & 1 deletion x-pack/plugins/observability_ai_assistant/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"server": true,
"browser": true,
"configPath": ["xpack", "observabilityAIAssistant"],
"requiredPlugins": ["triggersActionsUi", "actions", "security"],
"requiredPlugins": ["triggersActionsUi", "actions", "security", "observabilityShared"],
"requiredBundles": ["kibanaReact"],
"optionalPlugins": [],
"extraPublicDirs": []
Expand Down
58 changes: 58 additions & 0 deletions x-pack/plugins/observability_ai_assistant/public/application.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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 { EuiErrorBoundary } from '@elastic/eui';
import type { CoreStart, CoreTheme } from '@kbn/core/public';
import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
import { RouteRenderer, RouterProvider } from '@kbn/typed-react-router-config';
import type { History } from 'history';
import React from 'react';
import type { Observable } from 'rxjs';
import { ObservabilityAIAssistantProvider } from './context/observability_ai_assistant_provider';
import { observabilityAIAssistantRouter } from './routes/config';
import type {
ObservabilityAIAssistantPluginStartDependencies,
ObservabilityAIAssistantService,
} from './types';

export function Application({
theme$,
history,
coreStart,
pluginsStart,
service,
}: {
theme$: Observable<CoreTheme>;
history: History;
coreStart: CoreStart;
pluginsStart: ObservabilityAIAssistantPluginStartDependencies;
service: ObservabilityAIAssistantService;
}) {
return (
<EuiErrorBoundary>
<KibanaThemeProvider theme$={theme$}>
<KibanaContextProvider
services={{
plugins: {
start: pluginsStart,
},
}}
>
<RedirectAppLinks coreStart={coreStart}>
<coreStart.i18n.Context>
<ObservabilityAIAssistantProvider value={service}>
<RouterProvider history={history} router={observabilityAIAssistantRouter as any}>
<RouteRenderer />
</RouterProvider>
</ObservabilityAIAssistantProvider>
</coreStart.i18n.Context>
</RedirectAppLinks>
</KibanaContextProvider>
</KibanaThemeProvider>
</EuiErrorBoundary>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,25 @@
* 2.0.
*/

import React, { useState } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
EuiFlyout,
EuiFlyoutBody,
EuiFlyoutFooter,
EuiFlyoutHeader,
EuiTitle,
} from '@elastic/eui';
import { EuiFlyout, EuiFlyoutBody, EuiFlyoutFooter, EuiFlyoutHeader } from '@elastic/eui';
import { euiThemeVars } from '@kbn/ui-theme';
import { useChatConversation } from '../../hooks/use_chat_conversation';
import { ChatTimeline } from './chat_timeline';
import React, { useState } from 'react';
import { ConversationCreateRequest } from '../../../common/types';
import { UseGenAIConnectorsResult } from '../../hooks/use_genai_connectors';
import { ChatHeader } from './chat_header';
import { ChatPromptEditor } from './chat_prompt_editor';
import { AssistantAvatar } from '../assistant_avatar';
import { ChatTimeline } from './chat_timeline';

export interface ChatFlyoutProps {
conversationId?: string;
conversation: ConversationCreateRequest;
connectors: UseGenAIConnectorsResult;
}

export function ChatFlyout({ conversationId }: ChatFlyoutProps) {
const { title, messages } = useChatConversation({ conversationId });
export function ChatFlyout({ conversation, connectors }: ChatFlyoutProps) {
const {
conversation: { title },
messages,
} = conversation;

const [isOpen, setIsOpen] = useState(true);

Expand All @@ -35,16 +32,7 @@ export function ChatFlyout({ conversationId }: ChatFlyoutProps) {
return isOpen ? (
<EuiFlyout onClose={() => setIsOpen(false)} size="m">
<EuiFlyoutHeader hasBorder>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<AssistantAvatar size="m" />
</EuiFlexItem>
<EuiFlexItem>
<EuiTitle size="m">
<h2>{title}</h2>
</EuiTitle>
</EuiFlexItem>
</EuiFlexGroup>
<ChatHeader title={title} connectors={connectors} />
</EuiFlyoutHeader>

<EuiFlyoutBody>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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';
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
import { FindActionResult } from '@kbn/actions-plugin/server';
import { EuiPanel } from '@elastic/eui';
import { ChatHeader as Component } from './chat_header';

const meta: ComponentMeta<typeof Component> = {
component: Component,
title: 'app/Molecules/ChatHeader',
};

export default meta;

export const ChatHeaderLoaded: ComponentStoryObj<typeof Component> = {
args: {
title: 'My conversation',
connectors: {
loading: false,
selectedConnector: 'gpt-4',
connectors: [
{ id: 'gpt-4', name: 'OpenAI GPT-4' },
{ id: 'gpt-3.5-turbo', name: 'OpenAI GPT-3.5 Turbo' },
] as FindActionResult[],
selectConnector: () => {},
},
},
render: (props) => {
return (
<EuiPanel hasBorder hasShadow={false}>
<Component {...props} />
</EuiPanel>
);
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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 { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui';
import React from 'react';
import { UseGenAIConnectorsResult } from '../../hooks/use_genai_connectors';
import { AssistantAvatar } from '../assistant_avatar';
import { ConnectorSelectorBase } from '../connector_selector/connector_selector_base';

export function ChatHeader({
title,
connectors,
}: {
title: string;
connectors: UseGenAIConnectorsResult;
}) {
return (
<EuiFlexGroup alignItems="center" gutterSize="l">
<EuiFlexItem grow={false}>
<AssistantAvatar size="l" />
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup direction="column" gutterSize="none" justifyContent="center">
<EuiFlexItem grow={false}>
<EuiTitle size="m">
<h2>{title}</h2>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<ConnectorSelectorBase {...connectors} />
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
import { FindActionResult } from '@kbn/actions-plugin/server';
import { ComponentProps } from 'react';
import { EuiPanel } from '@elastic/eui';
import { ConnectorSelectorBase as Component } from './connector_selector_base';

const meta: ComponentMeta<typeof Component> = {
Expand All @@ -16,6 +18,14 @@ const meta: ComponentMeta<typeof Component> = {

export default meta;

const render = (props: ComponentProps<typeof Component>) => {
return (
<EuiPanel hasBorder hasShadow={false}>
<Component {...props} />
</EuiPanel>
);
};

export const Loaded: ComponentStoryObj<typeof Component> = {
args: {
loading: false,
Expand All @@ -25,24 +35,28 @@ export const Loaded: ComponentStoryObj<typeof Component> = {
{ id: 'gpt-3.5-turbo', name: 'OpenAI GPT-3.5 Turbo' },
] as FindActionResult[],
},
render,
};

export const Loading: ComponentStoryObj<typeof Component> = {
args: {
loading: true,
},
render,
};

export const Empty: ComponentStoryObj<typeof Component> = {
args: {
loading: false,
connectors: [],
},
render,
};

export const FailedToLoad: ComponentStoryObj<typeof Component> = {
args: {
loading: false,
error: new Error('Failed to load connectors'),
},
render,
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const wrapperClassName = css`
border: none;
box-shadow: none;
background: none;
padding-left: 0;
}
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
} from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { css } from '@emotion/css';

interface Props {
error?: Error;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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 { css } from '@emotion/css';
import React from 'react';
import { useKibana } from '../hooks/use_kibana';

const pageSectionClassName = css`
width: 100%;
display: flex;
flex-grow: 1;
`;

export function ObservabilityAIAssistantPageTemplate({ children }: { children: React.ReactNode }) {
const {
services: {
plugins: {
start: { observabilityShared },
},
},
} = useKibana();

const PageTemplate = observabilityShared.navigation.PageTemplate;

return (
<PageTemplate
pageSectionProps={{
alignment: 'horizontalCenter',
restrictWidth: true,
contentProps: {
className: pageSectionClassName,
},
}}
>
{children}
</PageTemplate>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { CoreStart } from '@kbn/core/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { ObservabilityAIAssistantPluginStartDependencies } from '../types';

export type StartServices<AdditionalServices extends object = {}> = CoreStart &
ObservabilityAIAssistantPluginStartDependencies &
AdditionalServices & {};
export type StartServices<AdditionalServices extends object = {}> = CoreStart & {
plugins: { start: ObservabilityAIAssistantPluginStartDependencies };
} & AdditionalServices & {};
const useTypedKibana = <AdditionalServices extends object = {}>() =>
useKibana<StartServices<AdditionalServices>>();

Expand Down
39 changes: 0 additions & 39 deletions x-pack/plugins/observability_ai_assistant/public/plugin.ts

This file was deleted.

Loading

0 comments on commit 4cd509b

Please sign in to comment.