<div align="center">

# @ddrinnova/agentsgt-widget

**Drop-in chat widget for [AgentsGT](https://agentsgt.com) AI agents.**

Embed a fully-featured AI assistant on any website with a single script tag.

[![npm version](https://img.shields.io/npm/v/@ddrinnova/agentsgt-widget.svg?style=flat&colorA=18181b&colorB=FBB76B)](https://www.npmjs.com/package/@ddrinnova/agentsgt-widget)
[![bundle size](https://img.shields.io/bundlephobia/minzip/@ddrinnova/agentsgt-widget?style=flat&colorA=18181b&colorB=FBB76B)](https://bundlephobia.com/package/@ddrinnova/agentsgt-widget)
[![license](https://img.shields.io/npm/l/@ddrinnova/agentsgt-widget?style=flat&colorA=18181b&colorB=FBB76B)](https://github.com/ddrinnova/agentsgt-widget/blob/main/LICENSE)

</div>

---

## Features

- **3 display modes** &mdash; Popup bubble, sidebar panel, or inline chat
- **Streaming responses** &mdash; Real-time AI output via Vercel AI SDK
- **Markdown rendering** &mdash; Rich text, code blocks, tables, and lists
- **Tool display** &mdash; Web search results, image generation, document lookup
- **Multi-language** &mdash; Auto-detects agent language (EN, ES, FR, DE, PT, IT)
- **Session persistence** &mdash; Conversations survive page refreshes
- **Theming** &mdash; Customize colors to match your brand
- **Lightweight** &mdash; ~150 KB gzipped, zero external CSS conflicts

---

## Quick Start

### Script Tag

The fastest way to add an agent to any site:

```html
<div id="agent-chat"></div>

<script src="https://unpkg.com/@ddrinnova/agentsgt-widget/dist/widget.umd.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@ddrinnova/agentsgt-widget/dist/widget.css" />

<script>
  AgentSGTWidget.mountApp(document.getElementById('agent-chat'), {
    runtimeUrl: 'https://agentsgt.com/api/v1/agents/chat/YOUR_AGENT_ID',
    apiKey: 'pk_xxx:sk_xxx',
  });
</script>
```

### npm Install

```bash
npm install @ddrinnova/agentsgt-widget
```

```tsx
import { mountApp } from '@ddrinnova/agentsgt-widget';
import '@ddrinnova/agentsgt-widget/dist/widget.css';

const unmount = mountApp(document.getElementById('agent-chat')!, {
  runtimeUrl: 'https://agentsgt.com/api/v1/agents/chat/YOUR_AGENT_ID',
  apiKey: 'pk_xxx:sk_xxx',
  uiMode: 'popup',
});

// Call unmount() to remove the widget later
```

### React Component

```tsx
import App from '@ddrinnova/agentsgt-widget';
import '@ddrinnova/agentsgt-widget/dist/widget.css';

function MyPage() {
  return (
    <App
      runtimeUrl="https://agentsgt.com/api/v1/agents/chat/YOUR_AGENT_ID"
      apiKey="pk_xxx:sk_xxx"
      uiMode="popup"
      title="Support"
      initialMessage="Hi! How can I help you today?"
      theme={{ primaryColor: '#7C3AED' }}
    />
  );
}
```

### Loader (dynamically load widget assets)

```html
<div id="agent-widget"></div>

<script>
  window.onload = function () {
    if (window.AgentSGTWidgetLoader) {
      AgentSGTWidgetLoader.load('agent-widget', {
        runtimeUrl: 'https://agentsgt.com/api/v1/agents/chat/YOUR_AGENT_ID',
        apiKey: 'pk_xxx:sk_xxx',
        name: 'My Assistant',
        uiMode: 'popup',
        theme: { primaryColor: '#FBB76B' },
      });
    }
  };
</script>
<script src="https://unpkg.com/@ddrinnova/agentsgt-widget/dist/loader.umd.js"></script>
```

---

## Options

### Core

| Option | Type | Default | Description |
|:---|:---|:---|:---|
| **`runtimeUrl`** | `string` | *required* | Full URL to the agent chat endpoint |
| **`apiKey`** | `string` | *required* | API key in `pk_xxx:sk_xxx` format |
| `uiMode` | `"popup"` \| `"sidebar"` \| `"chat"` | `"popup"` | Display mode |
| `title` | `string` | Agent name | Header title |
| `initialMessage` | `string` | `"Need any help?"` | Greeting shown on first visit |
| `identifier` | `string` | &mdash; | External user ID for conversation tracking |

### `theme` (since 0.2.0)

| Option | Type | Default | Description |
|:---|:---|:---|:---|
| `theme.primaryColor` | `string` | `#FBB76B` | Accent color (CTAs, link hover, focus ring) |
| `theme.accent` | `string` | derived | Secondary accent |
| `theme.surface` | `string` | `#ffffff` | Widget background |
| `theme.textColor` | `string` | `#1f2937` | Primary text color |
| `theme.radius` | `"sm"` \| `"md"` \| `"lg"` \| `"xl"` \| `number` | `"lg"` | Corner radius preset, or px value |
| `theme.shadow` | `"none"` \| `"sm"` \| `"md"` \| `"lg"` | `"md"` | Drop-shadow strength |
| `theme.mode` | `"light"` \| `"dark"` \| `"auto"` | `"light"` | `"auto"` follows the user's `prefers-color-scheme` |
| `theme.fontFamily` | `string` | system stack | Custom font family |

### `branding` (since 0.2.0)

| Option | Type | Default | Description |
|:---|:---|:---|:---|
| `branding.title` | `string` | &mdash; | Header title (overrides top-level `title`) |
| `branding.avatarUrl` | `string` | letter circle | Header avatar image |
| `branding.logoUrl` | `string` | chat icon | Image inside the launcher button |
| `branding.poweredBy` | `boolean` | `true` | Show the "Powered by AgentsGT" footer |
| `branding.suggestedPrompts` | `string[]` | &mdash; | Chip row above the input on the empty state (max 6 shown) |

---

## Display Modes

### `"popup"` &nbsp;*(default)*
Floating chat bubble in the bottom-right corner. Click to open a 400 &times; 520 chat window. Best for **customer support overlays**.

### `"sidebar"`
Full-height panel that slides in from the right. Great for **dashboards and admin panels**.

### `"chat"`
Inline chat that fills its parent container. Use when **embedding directly into your page layout**.

---

## Theming

### Quick &mdash; via prop

```js
{ theme: { primaryColor: '#7C3AED' } }
```

### Full control &mdash; via CSS custom properties

The widget defines its CSS variables on its own wrappers (`.agt-popup`, `.agt-sidebar`, `.agt-trigger`, `.agt-widget`), so they never leak onto the host page. Override them by targeting the same selectors:

```css
.agt-popup,
.agt-sidebar,
.agt-trigger,
.agt-widget {
  --agt-primary: #FBB76B;
  --agt-accent: #f59e3a;
  --agt-bg: #ffffff;
  --agt-surface: #ffffff;
  --agt-text: #1f2937;
  --agt-text-secondary: #6b7280;
  --agt-text-on-primary: #1f2937;
  --agt-border: #e5e7eb;
  --agt-muted: #f3f4f6;
  --agt-user-bg: rgba(251, 183, 107, 0.14);
  --agt-assistant-bg: #f3f4f6;
  --agt-radius: 1rem;
  --agt-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
}
```

Dark mode uses the same vars under `[data-agt-theme="dark"]`. Set `theme.mode: "auto"` to follow the user's system preference.

---

## API Keys

1. Open the [AgentsGT dashboard](https://agentsgt.com)
2. Navigate to **Settings &rarr; API Keys**
3. Create a new key pair &mdash; you'll get a `pk_xxx:sk_xxx` string
4. Pass it as the `apiKey` prop

> API keys used in client-side widgets are visible to end users. Enable **domain whitelisting** in your dashboard to restrict usage to your domains.

---

## Development

```bash
git clone https://github.com/ddrinnova/agentsgt-widget.git
cd agentsgt-widget
npm install
npm run dev            # Start dev server at localhost:5173
npm run build          # Production build → dist/
npm run lint
```

## Releasing

Releases are published to npm by **GitHub Actions** on tag push &mdash; no local `npm publish`.

```bash
# 1. Bump the version in package.json (patch / minor / major as appropriate)
npm version patch          # writes 0.2.x → 0.2.(x+1), creates a v0.2.(x+1) git tag

# 2. Push the commit and the tag
git push origin main --follow-tags
```

The workflow at `.github/workflows/publish.yml` runs on tags matching `v*.*.*`:

1. Installs dependencies, lints, builds.
2. Verifies `package.json` `version` matches the pushed tag (fails the run otherwise).
3. Publishes with `npm publish --access public --provenance`.
4. Creates a GitHub Release with auto-generated notes.

**One-time setup:** add an `NPM_TOKEN` repo secret with publish rights to `@ddrinnova/agentsgt-widget`.

---

<div align="center">

**Built with [Vercel AI SDK](https://sdk.vercel.ai) + React**

[agentsgt.com](https://agentsgt.com) &nbsp;&bull;&nbsp; [GitHub](https://github.com/ddrinnova/agentsgt-widget) &nbsp;&bull;&nbsp; [npm](https://www.npmjs.com/package/@ddrinnova/agentsgt-widget)

</div>
