Skip to content

Commit

Permalink
feat: chatbot docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Fernando Pauer committed Nov 25, 2024
1 parent 9466499 commit 0fe7e11
Show file tree
Hide file tree
Showing 2 changed files with 278 additions and 0 deletions.
152 changes: 152 additions & 0 deletions packages/doc-site/stories/assistant/components/Chatbot.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { Canvas, Meta, Story, Source, Markdown } from '@storybook/blocks';
import * as ChatbotStories from './Chatbot1.stories';

# Chatbot

An AI-powered chatbot component powered by [IoT Sitewise Assistant](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/assistant-get-started.html) pre-trained on large volumes of industrial data and using a large language model (LLM).

The chatbot allows users like plant managers, quality engineers, and maintenance technicians to gain insights, dive deep on question to solve problems, and get directions how to act directly from their operational and enterprise data.

<Canvas sourceState="hidden" story={{ height : '500px' }} of={ChatbotStories.Standard} />

<Meta of={ChatbotStories} />

## Chatbot Properties

The Chatbot component contains the following customizable properties.

#### messages
##### (array, required)
This specifies a list of messages to visualize in the chatbot. The messages can be harded code or retrieved using useAssistant hooks, learn more about [useAssistant hook](/docs/hooks-useassistant--docs).

Array of chat messages to display

Example for messages data.
<Source dark="true" code={`
<AssistantChatbot
messages={[
{
content: 'Hello, I am your AWS IoT SiteWise Assistant. Please ask me anything about your data.',
sender: 'assistant',
type: MessageType.TEXT,
id: uuid(),
loading: false,
},
{
content:
'Processing assistant response, please wait..',
sender: 'assistant',
type: MessageType.TEXT,
id: crypto.randomUUID(),
loading: true,
},
]}
/>
`} />

#### height
##### (number, required)
This defines a fixed height for the Chatbot. Default behavior is to use 100% of the avaliable height of the parent component.

#### visible
##### (boolean, optional)
This defines the visible state of the chatbot, this can be used to display or not the chatbot depending on the use case. Default to `true`.

onSubmit: (utterance: string) => void;
header?: ChatbotHeaderProps;

/**
* Props interface for the Chatbot component
* @interface ChatbotProps
* @property {string} [className] - Optional CSS class name for styling
* @property {string} [placeholder] - Placeholder text for the input field
* @property {boolean} [loading] - Whether the chatbot is in a loading state
* @property {string} [error] - Error message to display
* @property {string} [inputValue] - Controlled input value
* @property {(value: string) => void} [onInputChange] - Handler for input changes
* @property {() => void} [onSubmit] - Handler for form submission
* @property {ChatMessage[]} [messages] - Array of chat messages to display
* @property {ReactNode} [header] - Custom header content
*/

/**
* Chatbot component that provides a conversational interface
*
* @component
* @example
* ```jsx
* <Chatbot
* placeholder="Type a message..."
* messages={[
* { role: 'user', content: 'Hello!' },
* { role: 'assistant', content: 'Hi there! How can I help?' }
* ]}
* onSubmit={() => handleSubmit()}
* />
* ```
*/
// packages/react-components/stories/assistant-chatbot/assistant-chatbot.stories.tsx
/**
* @fileoverview Storybook stories for the Chatbot component
*/
/**
* Basic usage example showing a simple chat interface
*/
export const Basic = {
args: {
placeholder: 'Type your message...',
messages: [
{ role: 'assistant', content: 'Hello! How can I help you today?' },
{ role: 'user', content: 'Hi! I have a question.' }
]
}
};
/**
* Example showing loading state while waiting for response
*/
export const Loading = {
args: {
loading: true,
messages: [
{ role: 'user', content: 'Processing request...' }
]
}
};
/**
* Example showing error state
*/
export const Error = {
args: {
error: 'Failed to send message. Please try again.',
messages: [
{ role: 'user', content: 'This message failed to send' }
]
}
};
/**
* Example with custom header and footer
*/
export const CustomHeaderFooter = {
args: {
header: <div>Custom Header</div>,
footer: <div>Custom Footer</div>,
messages: []
}
};
/**
* Example showing controlled input
*/
export const ControlledInput = {
args: {
inputValue: 'Controlled input text',
onInputChange: (value) => console.log('Input changed:', value),
messages: []
}
};
126 changes: 126 additions & 0 deletions packages/doc-site/stories/assistant/components/Chatbot1.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/* eslint-disable */
// @ts-nocheck
import { useEffect } from 'react';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import { AssistantChatbot } from '../../src/components/assistant-chatbot';
import { useAssistant } from '../../src/hooks/useAssistant/useAssistant';
import { IoTSitewiseAssistantClient } from '@iot-app-kit/core-util';
import '@cloudscape-design/global-styles/index.css';
import { MessageType } from '../../src/hooks/useAssistant/types';
import { MockInvokeAssistant } from '../../mockAssistantAPI';

export default {
title: 'Assistant/Components/Chatbot',
component: AssistantChatbot,
argTypes: {
accessKeyId: { control: { type: 'string' } },
secretAccessKey: { control: { type: 'string' } },
sessionToken: { control: { type: 'string' } },
containerWidth: { control: { type: 'number' }, defaultValue: 200 },
containerHeight: { control: { type: 'number' }, defaultValue: 200 },
},
parameters: {
layout: 'fullscreen',
},
} as ComponentMeta<typeof AssistantChatbot>;

const conversationId = crypto.randomUUID();
const client = new IoTSitewiseAssistantClient({
iotSiteWiseClient: {
invokeAssistant: MockInvokeAssistant,
},
defaultContext: '',
});

export const Standard: ComponentStory<
typeof AssistantChatbot
> = () => {

const { messages, invokeAssistant, clearAll, setMessages } = useAssistant({
assistantClient: client,
});

useEffect(() => {
clearAll();
setMessages([
{
content:
'Who are you ?',
sender: 'user',
type: MessageType.TEXT,
id: crypto.randomUUID(),
loading: false,
},
{
content:
'Hello, I am your AWS IoT SiteWise Assistant. Please ask me anything about your dashboard.',
sender: 'assistant',
type: MessageType.TEXT,
id: crypto.randomUUID(),
loading: false,
},
]);
}, []);

const handleSubmit = (utterance: string) => {
invokeAssistant({ componentId: '', conversationId, utterance });
};

return (
<div style={{ padding: '0.5rem' }} data-testid='default-chatbot-story'>
<AssistantChatbot
height={500}
messages={messages}
onSubmit={handleSubmit}
onClose={() => {}}
header={{
headerText: 'IoT Sitewise Assistant',
showCloseButton: true,
showResetButton: true,
onReset: () => clearAll(),
onClose: () => {},
}}
/>
</div>
);
};

export const ErrorState: ComponentStory<
typeof AssistantChatbot
> = () => {

const messages = [
{
content:
'Processing assistant response, please wait..',
sender: 'assistant',
type: MessageType.TEXT,
id: crypto.randomUUID(),
loading: true,
},
{
content: 'You do not have the required permissions to use the Sitewise Assistant. Please contact your administrator to request access.',
sender: 'assistant',
type: MessageType.ERROR,
id: crypto.randomUUID(),
loading: false,
payload: {
accessDeniedException: {
name: 'accessDeniedException',
message: 'You do not have the required permissions to use the Sitewise Assistant. Please contact your administrator to request access.',
}
}
}
];

return (
<div style={{ padding: '0.5rem' }} data-testid='error-chatbot-story'>
<AssistantChatbot
height={500}
messages={messages}
onSubmit={() => {}}
onClose={() => {}}
/>
</div>
);
};

0 comments on commit 0fe7e11

Please sign in to comment.