@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 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
+ [![npm](https://img.shields.io/npm/v/@smooai/chat-widget?color=00a6a6&label=npm)](https://www.npmjs.com/package/@smooai/chat-widget)
10
+ [![CI](https://github.com/SmooAI/chat-widget/actions/workflows/ci.yml/badge.svg)](https://github.com/SmooAI/chat-widget/actions/workflows/ci.yml)
11
+ [![bundle](https://img.shields.io/badge/gzip-~19%20kB-4f8bff)](https://github.com/SmooAI/chat-widget)
12
+ [![license](https://img.shields.io/badge/license-MIT-8b5cf6)](./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)