@smooai/chat-widget 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +237 -0
- package/dist/chat-widget.global.js +1802 -0
- package/dist/chat-widget.global.js.map +1 -0
- package/dist/index.d.ts +278 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1296 -0
- package/dist/index.js.map +1 -0
- package/package.json +80 -0
- package/src/config.ts +160 -0
- package/src/conversation.ts +321 -0
- package/src/element.ts +563 -0
- package/src/index.ts +37 -0
- package/src/logo.ts +9 -0
- package/src/standalone.ts +33 -0
- package/src/styles.ts +518 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Smoo AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# @smooai/chat-widget
|
|
4
|
+
|
|
5
|
+
### Embeddable AI chat as a framework-light web component.
|
|
6
|
+
|
|
7
|
+
**Streaming replies · grounded sources · popover or full-page · inherits _your_ brand color.**
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@smooai/chat-widget)
|
|
10
|
+
[](https://github.com/SmooAI/chat-widget/actions/workflows/ci.yml)
|
|
11
|
+
[](https://github.com/SmooAI/chat-widget)
|
|
12
|
+
[](./LICENSE)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
`<smooth-agent-chat>` is a self-contained chat web component for the
|
|
19
|
+
[smooth-operator](https://github.com/SmooAI/smooth-operator) protocol. Drop in one
|
|
20
|
+
`<script>` tag (or import the ESM module) and you get a polished, streaming,
|
|
21
|
+
shadow-DOM-isolated chat experience — **the "Aurora Glass" design** — that adapts
|
|
22
|
+
to any host brand from a single accent color.
|
|
23
|
+
|
|
24
|
+
No React on the host page. No CSS to import. ~19 kB gzipped, protocol client included.
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<script src="https://unpkg.com/@smooai/chat-widget/dist/chat-widget.global.js"></script>
|
|
28
|
+
<smooth-agent-chat endpoint="wss://your-host/ws" agent-id="…" agent-name="Support"></smooth-agent-chat>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> **Live demo:** open [`index.html`](./index.html) (it runs entirely in the browser
|
|
32
|
+
> against an in-page mock of the protocol — no backend needed).
|
|
33
|
+
|
|
34
|
+
## Why this widget
|
|
35
|
+
|
|
36
|
+
- **Aurora Glass design** — a spring launcher with a live presence pulse, a
|
|
37
|
+
glass-depth panel, gradient brand avatar + status dot, an animated typing
|
|
38
|
+
indicator, message rise-in, refined source cards, and an icon composer.
|
|
39
|
+
- **Brand-adaptive** — pass one `primary` color and the gradients, bubbles, glow,
|
|
40
|
+
and depth shades derive themselves. Works light or dark.
|
|
41
|
+
- **Streaming + sources** — token-by-token replies with a typing indicator and a
|
|
42
|
+
collapsible "Sources" disclosure for knowledge-grounded answers.
|
|
43
|
+
- **Popover or full-page** — a floating launcher, or a full-bleed `/chat` surface.
|
|
44
|
+
Same component, one attribute.
|
|
45
|
+
- **Framework-light & isolated** — a standard custom element with Shadow-DOM style
|
|
46
|
+
isolation. Use it with React, Vue, Svelte, Astro, or no framework at all.
|
|
47
|
+
- **Secure by construction** — message + citation text is rendered via
|
|
48
|
+
`textContent`, and citation links are restricted to `http(s)` (no
|
|
49
|
+
`javascript:`/`data:` XSS).
|
|
50
|
+
|
|
51
|
+
## Install
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pnpm add @smooai/chat-widget
|
|
55
|
+
# or: npm i @smooai/chat-widget · yarn add @smooai/chat-widget
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`@smooai/smooth-operator` (the protocol client) is a runtime dependency and is
|
|
59
|
+
installed automatically.
|
|
60
|
+
|
|
61
|
+
## Quick start
|
|
62
|
+
|
|
63
|
+
### 1. Declarative — a `<script>` tag + the element
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<script src="https://unpkg.com/@smooai/chat-widget/dist/chat-widget.global.js"></script>
|
|
67
|
+
|
|
68
|
+
<smooth-agent-chat
|
|
69
|
+
endpoint="wss://your-host/ws"
|
|
70
|
+
agent-id="11111111-1111-4111-8111-111111111111"
|
|
71
|
+
agent-name="Support"
|
|
72
|
+
greeting="Hi! How can I help?"
|
|
73
|
+
></smooth-agent-chat>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The IIFE bundle auto-registers the element on load.
|
|
77
|
+
|
|
78
|
+
### 2. Programmatic — bundler / ESM
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { mountChatWidget } from '@smooai/chat-widget';
|
|
82
|
+
|
|
83
|
+
const widget = mountChatWidget({
|
|
84
|
+
endpoint: 'wss://your-host/ws',
|
|
85
|
+
agentId: '11111111-1111-4111-8111-111111111111',
|
|
86
|
+
agentName: 'Support',
|
|
87
|
+
theme: { primary: '#8b5cf6' },
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Drive it imperatively:
|
|
91
|
+
widget.openChat();
|
|
92
|
+
widget.closeChat();
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Or register the element and place it yourself:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { defineChatWidget } from '@smooai/chat-widget';
|
|
99
|
+
defineChatWidget(); // now <smooth-agent-chat> works anywhere in your markup
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Theming
|
|
103
|
+
|
|
104
|
+
Every color is a CSS custom property under the hood, so the simplest possible
|
|
105
|
+
theme is a single `primary` — the launcher gradient, send button, user bubbles,
|
|
106
|
+
ambient glow, and derived depth shades all follow from it.
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
mountChatWidget({
|
|
110
|
+
endpoint, agentId,
|
|
111
|
+
theme: {
|
|
112
|
+
primary: '#ff5d6e', // the one color most brands need to set
|
|
113
|
+
background: '#ffffff', // light panel
|
|
114
|
+
text: '#1f2430',
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
| Token | Drives | Default |
|
|
120
|
+
| ---------------------- | --------------------------------------------------- | ------------------ |
|
|
121
|
+
| `primary` | Launcher, send button, user bubble, glow, avatar | `#00a6a6` |
|
|
122
|
+
| `primaryText` | Text/icon on top of `primary` | `#f8fafc` |
|
|
123
|
+
| `background` | Panel background | `#040d30` |
|
|
124
|
+
| `text` | Foreground text + derived inset surfaces | `#f8fafc` |
|
|
125
|
+
| `assistantBubble` | Inbound (assistant) bubble background | `#06134b` |
|
|
126
|
+
| `assistantBubbleText` | Inbound bubble text | `#f8fafc` |
|
|
127
|
+
| `userBubble` | Outbound (user) bubble background | `primary` |
|
|
128
|
+
| `userBubbleText` | Outbound bubble text | `primaryText` |
|
|
129
|
+
| `border` | Panel + input hairline | `rgba(255,255,255,.1)` |
|
|
130
|
+
|
|
131
|
+
Two further tokens — a darker `primary-2` (gradient depth) and a `surface-2`
|
|
132
|
+
inset wash — are **derived in CSS** from `primary`/`text`, so you never have to
|
|
133
|
+
supply them and they adapt automatically to light or dark themes.
|
|
134
|
+
|
|
135
|
+
> **Dashboard parity:** the theme also accepts the SmooAI agent dashboard's
|
|
136
|
+
> 10-color model — `secondary` plus `chatBubbleInbound` / `chatBubbleInboundText`
|
|
137
|
+
> / `chatBubbleOutbound` / `chatBubbleOutboundText` (aliases that win over the
|
|
138
|
+
> canonical keys) — so a config exported from the dashboard themes the widget
|
|
139
|
+
> directly.
|
|
140
|
+
|
|
141
|
+
## Visitor identity & starter prompts
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
mountChatWidget({
|
|
145
|
+
endpoint, agentId,
|
|
146
|
+
examplePrompts: ['How do I get started?', 'Do you integrate with HubSpot?'],
|
|
147
|
+
requireName: true,
|
|
148
|
+
requireEmail: true, // gate the chat behind a pre-chat form…
|
|
149
|
+
// allowAnonymous: true, // …or let visitors skip it entirely
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
- **`examplePrompts`** render as clickable chips in the empty state (max 5).
|
|
154
|
+
- **`requireName` / `requireEmail` / `requirePhone`** show a styled pre-chat form;
|
|
155
|
+
the collected name/email are attached to the conversation session (phone rides
|
|
156
|
+
session metadata). Set **`allowAnonymous: true`** to skip the form.
|
|
157
|
+
|
|
158
|
+
### OTP & tool confirmation (programmatic)
|
|
159
|
+
|
|
160
|
+
The `ConversationController` surfaces mid-turn pauses via an `onInterrupt`
|
|
161
|
+
callback — `otp_verification_required` and `write_confirmation_required` — and
|
|
162
|
+
resumes them with `verifyOtp(code)` / `confirmTool(approved)`. (A built-in dialog
|
|
163
|
+
UI for these is on the roadmap; the protocol plumbing ships today.)
|
|
164
|
+
|
|
165
|
+
## Full-page mode
|
|
166
|
+
|
|
167
|
+
Render the chat as a full-bleed surface (a `/chat` route, a docs sidebar, an
|
|
168
|
+
iframe) instead of a floating launcher:
|
|
169
|
+
|
|
170
|
+
```html
|
|
171
|
+
<smooth-agent-chat mode="fullpage" endpoint="wss://…/ws" agent-id="…"></smooth-agent-chat>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import { mountFullPageChat } from '@smooai/chat-widget';
|
|
176
|
+
mountFullPageChat({ endpoint, agentId, agentName: 'Support' }, document.getElementById('chat'));
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Configuration
|
|
180
|
+
|
|
181
|
+
Declarative attributes mirror the programmatic [`ChatWidgetConfig`](./src/config.ts):
|
|
182
|
+
|
|
183
|
+
| Attribute | Config key | Notes |
|
|
184
|
+
| --------------- | ---------------- | -------------------------------------------------- |
|
|
185
|
+
| `endpoint` | `endpoint` | **Required.** smooth-operator WebSocket URL. |
|
|
186
|
+
| `agent-id` | `agentId` | **Required.** UUID of the agent. |
|
|
187
|
+
| `agent-name` | `agentName` | Header label + monogram. Default `Assistant`. |
|
|
188
|
+
| `placeholder` | `placeholder` | Composer placeholder. |
|
|
189
|
+
| `greeting` | `greeting` | Shown before the first message. |
|
|
190
|
+
| `mode` | `mode` | `popover` (default) or `fullpage`. |
|
|
191
|
+
| `start-open` | `startOpen` | Open the panel immediately (no launcher click). |
|
|
192
|
+
| — | `theme` | Brand colors (see [Theming](#theming)). |
|
|
193
|
+
| — | `userName` / `userEmail` | Optional participant identity. |
|
|
194
|
+
|
|
195
|
+
### Programmatic API
|
|
196
|
+
|
|
197
|
+
`mountChatWidget(config, target?)` and `mountFullPageChat(config, target?)` return
|
|
198
|
+
the element, which exposes:
|
|
199
|
+
|
|
200
|
+
- `configure(partialConfig)` — merge overrides (e.g. live theme tweaks) and re-render.
|
|
201
|
+
- `openChat()` / `closeChat()` — toggle the popover panel.
|
|
202
|
+
|
|
203
|
+
## How it works
|
|
204
|
+
|
|
205
|
+
The widget is pure view + a thin `ConversationController` that speaks the
|
|
206
|
+
smooth-operator protocol via [`@smooai/smooth-operator`](https://github.com/SmooAI/smooth-operator):
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
connect() → WebSocket + create_conversation_session
|
|
210
|
+
send(text) → send_message → stream_token … (live) … → eventual_response (+ citations)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The wire protocol is owned by smooth-operator; this package only renders it. That
|
|
214
|
+
keeps one source of truth for the protocol and lets the widget stay tiny.
|
|
215
|
+
|
|
216
|
+
## Browser support
|
|
217
|
+
|
|
218
|
+
Evergreen browsers (Chrome/Edge 111+, Safari 16.4+, Firefox 113+). The design uses
|
|
219
|
+
`color-mix()` to derive brand shades and `::part()` for host-side customization.
|
|
220
|
+
|
|
221
|
+
## Local development
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
pnpm install
|
|
225
|
+
pnpm build # tsdown → dist/ (ESM + IIFE)
|
|
226
|
+
pnpm typecheck # tsc --noEmit
|
|
227
|
+
pnpm test # vitest (jsdom) unit + render smoke tests
|
|
228
|
+
pnpm check # typecheck + test + build
|
|
229
|
+
pnpm test:e2e # Playwright live e2e (gated — see e2e/)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Open `index.html` (e.g. `pnpm dlx serve .`) after a build for the interactive,
|
|
233
|
+
backend-free showcase.
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
MIT © [SmooAI](https://github.com/SmooAI)
|