# chat-widget

Embeddable AI assistant widget for React applications. The package wraps the AI Chat Widget used in the AI Console projects and exposes both a plug-and-play `<ChatWidget />` component and a lower-level `useChat()` hook for custom UIs. It speaks to a compatible RAG backend, streams responses, surfaces knowledge-base citations, and handles feedback/actions out of the box.

---

## Features

- **Drop-in widget** with launcher button, conversation history, file uploads, and light/dark themes.
- **Auto-configuration** – widget appearance/behavior is loaded from your backend (`/api/widget/:id/config`).
- **Persistent conversations** backed by existing widget sessions and local storage.
- **Agent support** – seamlessly handles widgets with custom actions and follow-up approvals.
- **Hook-first API** for building bespoke chat surfaces while reusing the data flows.
- **Browser friendly** UMD bundle (`window.AIChatWidget.mount`) for non-React hosts.
- **No API key required** – widget ID acts as the access token for simplified integration.

---

## Installation

```bash
# with npm
npm install @chatwidgetai/chat-widget

# or with pnpm / yarn
pnpm add @chatwidgetai/chat-widget
yarn add @chatwidgetai/chat-widget
```

> **Peer dependencies**  
> Your project must provide `react` and `react-dom` (v18 or v19).

---

## Quick start (React)

```tsx
import { ChatWidget } from '@chatwidgetai/chat-widget';

export function SupportChat() {
  return (
    <ChatWidget
      widgetId="64f6e3e4d12b4a9c8f3c1234"
      apiUrl="https://api.my-rag-backend.com"
      position="bottom-right"
      theme="auto"
      onMessage={(message) => console.log('New message:', message)}
      onError={(error) => console.error('Chat error', error)}
    />
  );
}
```

The widget automatically pulls its configuration (branding, behavior, suggestions, etc.) from your backend. Only `widgetId` is required; `apiUrl` defaults to `window.location.origin`.

> **Security Note**: Keep your Widget ID confidential. It acts as the access token for your widget and should not be exposed in public repositories.

---

## Props

| Prop           | Type                                                            | Required | Description                                                                                      |
| -------------- | --------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------ |
| `widgetId`     | `string`                                                        | ✅       | Widget identifier created in the AI Console. Keep this confidential.                             |
| `apiUrl`       | `string`                                                        | ❌       | Base URL of your widget API. Defaults to `window.location.origin`.                               |
| `position`     | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'`  | ❌       | Launcher position (overridden by backend appearance settings).                                   |
| `theme`        | `'light' \| 'dark' \| 'auto'`                                   | ❌       | Force a theme instead of the configured one.                                                     |
| `primaryColor` | `string`                                                        | ❌       | Override the accent color (CSS color string).                                                    |
| `onOpen`       | `() => void`                                                    | ❌       | Fired when the chat window opens.                                                                |
| `onClose`      | `() => void`                                                    | ❌       | Fired when the chat window closes.                                                               |
| `onMessage`    | `(message: ConversationMessage) => void`                        | ❌       | Called for every new message, including the user's own messages.                                 |
| `onError`      | `(error: Error) => void`                                        | ❌       | Called when an API error or transport failure occurs.                                            |

---

## Building your own UI with `useChat`

```tsx
import { useChat } from '@chatwidgetai/chat-widget';

export function CustomChat({ widgetId }: { widgetId: string }) {
  const {
    messages,
    isLoading,
    isTyping,
    error,
    config,
    sendMessage,
    approveAction,
    rejectAction,
    submitFeedback,
  } = useChat({
    widgetId,
    apiUrl: 'https://api.my-rag-backend.com',
  });

  // render messages however you like…
}
```

`useChat` handles configuration, conversation persistence, agent actions, file uploads, and feedback submission. See TypeScript definitions in `@chatwidgetai/chat-widget/dist/index.d.ts` (or `src/hooks/useChat.ts`) for the full return signature and helper types.

---

## Vanilla / script-tag usage

A bundled UMD build is published as `dist/ai-chat-widget.umd.js`. After including the script on a page, a global helper becomes available:

```html
<script src="https://unpkg.com/@chatwidgetai/chat-widget/dist/ai-chat-widget.umd.js"></script>
<script>
  window.AIChatWidget.mount({
    widgetId: '64f6e3e4d12b4a9c8f3c1234',
    apiUrl: 'https://api.my-rag-backend.com',
    position: 'bottom-right',
    theme: 'auto',
  });
</script>
```

You can pass `container` to mount inside an existing element and call the returned `destroy()` method to unmount programmatically.

---

## Styling

Default styles are bundled and injected automatically via Rollup’s PostCSS pipeline. To override the look & feel, update the widget’s appearance in the console or provide a custom `primaryColor`, `fontFamily`, or `borderRadius` from the backend configuration. For heavy customization, define a custom theme in your backend and serve additional CSS through the `customCSS` field—those rules are appended inside the widget root.

---

## Backend contract

The widget expects the following endpoints (see `src/api` for details):

| Endpoint                                        | Purpose                                   |
| ----------------------------------------------- | ----------------------------------------- |
| `GET /api/widget/:widgetId/config`              | Returns appearance/behavior configuration |
| `GET /api/widget/:widgetId/conversation/:id`    | Fetch existing conversation (or create)   |
| `POST /api/widget/:widgetId/chat`               | Standard chat message flow                |
| `POST /api/widget/:widgetId/agent`              | Agent/Tools conversation flow             |
| `POST /api/widget/:widgetId/upload`             | Secure file uploads                       |
| `POST /api/widget/:widgetId/feedback`           | Capture thumbs-up / thumbs-down feedback  |

Adjust the API paths on the client (override `apiUrl`) if your deployment differs.

---

## Development

```bash
pnpm install
pnpm build        # creates CJS, ESM, and UMD bundles in dist/
pnpm lint
pnpm typecheck
```

Rollup outputs:

- `dist/index.js` – CommonJS build (Node/SSR)
- `dist/index.esm.js` – ES module build (modern bundlers)
- `dist/ai-chat-widget.umd.js` – Browser-ready bundle exposing `window.AIChatWidget`

---

## License

MIT © 2024 AI Chat Widget contributors
