# Kaman Chatbot Component

A React-based chatbot component with a 3-panel layout for chat history, messages, and artifacts. Built with Vite, TypeScript, and Tailwind CSS 4.

## Features

- 🔀 **Three-panel layout**: History sidebar, main chat interface, and artifact panel
- 🎨 **Customizable theming**: Pass in custom colors and styling options
- � **File attachment support**: Upload and share files in the chat
- 📊 **Artifact display**: Show images, tables, code blocks, and documents
- 🧩 **React component or Web Component**: Use in any framework
- 🛡️ **CSS isolation**: Doesn't affect parent application styling
- 🔄 **Compatible with React 16+**: Works with a wide range of React versions

## Installation

```bash
npm install @yoctotta/chatbot
# or
yarn add @yoctotta/chatbot
```

## Usage

### As a React Component

```jsx
import React from 'react';
import Chatbot from '@yoctotta/chatbot';

function App() {
  // Option 1: Provide a custom message handler
  const handleSendMessage = async (message, attachments) => {
    console.log('Message sent:', message, attachments);
    // Make API call to your backend
    const response = await api.sendMessage(message, attachments);
    return {
      content: response.text,
      artifact: response.artifact // Optional
    };
  };

  return (
    <div style={{ height: '600px', width: '100%', maxWidth: '1200px' }}>
      {/* Option 1: Use custom message handler */}
      <Chatbot 
        onSendMessage={handleSendMessage}
        theme={{
          primaryColor: '#10b981', // Green
          secondaryColor: '#34d399',
          textColor: '#1f2937',
          backgroundColor: '#f9fafb',
        }}
      />
      
      {/* Option 2: Use built-in ChatAPI with SSE streaming */}
      <Chatbot 
        apiKey="your-api-key" // Authentication for backend
        baseUrl="/api/chat" // Optional, defaults to /api/chat
        theme={{
          primaryColor: '#4f46e5', // Purple
          secondaryColor: '#6366f1',
          textColor: '#1f2937',
          backgroundColor: '#f9fafb',
          borderColor: '#d1d5db',
          borderRadius: '8px',
        }}
        onSendMessage={handleSendMessage}
      />
    </div>
  );
```

### As a Web Component

Include the script in your HTML:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@yoctotta/chatbot/dist/kaman-chatbot.es.js"></script>

<!-- Option 1: Use the built-in ChatAPI with SSE streaming -->
<kaman-chatbot 
  api-key="your-api-key"
  base-url="/api/chat"
  theme='{"primaryColor":"#4f46e5","secondaryColor":"#6366f1"}'
></kaman-chatbot>

<!-- Option 2: Handle messages manually with your own implementation -->
<kaman-chatbot id="custom-chatbot"
  theme='{"primaryColor":"#10b981","secondaryColor":"#34d399"}'
></kaman-chatbot>

<script>
  // Option 2: Listen for messages and handle them manually
  document.querySelector('#custom-chatbot').addEventListener('kaman-chatbot-message', async (e) => {
    console.log('Message sent:', e.detail.message, e.detail.attachments);
    
    try {
      // Make your API call
      const response = await fetch('/your-api/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message: e.detail.message })
      });
      
      const data = await response.json();
      
      // Return the response to the chatbot
      return {
        content: data.text,
        artifact: data.artifact
      };
    } catch (error) {
      console.error('Error:', error);
      return {
        content: 'Sorry, an error occurred while processing your request.',
        artifact: null
      };
    }
  });
</script>
```

## API

### Props

| Prop | Type | Description |
|------|------|-------------|
| `apiKey` | string | API key for authentication with the backend |
| `baseUrl` | string | Base URL for API endpoints (defaults to `/api/chat`) |
| `token` | string | Auth token for JWT-based authentication |
| `mockSSE` | boolean | Enable mock SSE mode for development and testing |
| `theme` | object | Theme customization options |
| `onSendMessage` | function | Optional custom message handler, if not provided the built-in ChatAPI will be used |

### Theme Object

| Property | Type | Description |
|----------|------|-------------|
| `primaryColor` | string | Primary color for buttons and accents |
| `secondaryColor` | string | Secondary color for hover states |
| `textColor` | string | Main text color |
| `backgroundColor` | string | Background color |
| `fontFamily` | string | Font family |
| `borderColor` | string | Color for borders |
| `borderRadius` | string | Border radius for components |

### Response Object

| Property | Type | Description |
|----------|------|-------------|
| `content` | string | Text response to display |
| `artifact` | object | Optional artifact to display in the right panel |

### Artifact Object

The artifact object can be one of the following types:

#### Image
```js
{
  type: 'image',
  url: 'https://example.com/image.jpg',
  alt: 'Description', // optional
  caption: 'Image caption' // optional
}
```

#### Table
```js
{
  type: 'table',
  headers: ['Column 1', 'Column 2'],
  rows: [
    ['Value 1', 'Value 2'],
    ['Value 3', 'Value 4']
  ]
}
```

#### Code
```js
{
  type: 'code',
  language: 'javascript', // optional
  code: 'function hello() { console.log("Hello world!"); }'
}
```

#### Document
```js
{
  type: 'document',
  name: 'document.pdf',
  url: 'https://example.com/document.pdf'
}
```

## Backend Integration

The chatbot can be integrated with the backend using Server-Sent Events (SSE) for streaming responses.

### SSE Integration

When using the built-in ChatAPI (by providing `apiKey` and optionally `baseUrl`), the component will:

1. Send the user message to the backend endpoint (`/api/chat/:sessionId`)
2. Establish an SSE connection to receive streaming responses
3. Update the UI in real-time as the responses arrive
4. Display any artifacts included in the response

The backend API should:

1. Accept POST requests to `/api/chat/:sessionId`
2. Set appropriate SSE headers:
   - `Content-Type: text/event-stream`
   - `Cache-Control: no-cache`
   - `Connection: keep-alive`
3. Send SSE formatted data: `data: {"content": "partial response", "artifact": null}\n\n`
4. Stream multiple messages as the response is generated
5. End the connection when the full response is sent

### Custom Message Handler

Alternatively, you can provide your own message handler through the `onSendMessage` prop. This function should:

1. Accept the message string and optional attachments array
2. Return a promise that resolves to an object with:
   - `content`: The response text
   - `artifact`: (Optional) An object representing any artifact to display

## CSS Isolation

The chatbot is designed to not affect the styles of the parent application. It uses:

1. CSS custom properties (variables) scoped to the component
2. Shadow DOM when used as a Web Component
3. Prefixed class names to avoid conflicts
4. Scoped Tailwind preflight reset that only applies within the component

## Development

```bash
# Start development server
npm run dev

# Run Storybook for component development
npm run storybook

# Build the component library
npm run build
```

## Browser Compatibility

Compatible with all modern browsers. For older browser support (IE11, etc.), you'll need to add appropriate polyfills.

## License

MIT
