@smooai/chat-widget 0.11.0 → 0.13.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/README.md +1 -0
- package/dist/chat-widget.global.js +473 -21
- package/dist/chat-widget.global.js.map +1 -1
- package/dist/index.d.ts +333 -236
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +454 -18
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/config.ts +11 -0
- package/src/conversation.ts +205 -3
- package/src/element.ts +315 -18
- package/src/index.ts +2 -0
- package/src/styles.ts +53 -2
package/dist/index.d.ts
CHANGED
|
@@ -134,245 +134,19 @@ interface ChatWidgetConfig {
|
|
|
134
134
|
* `require*` flags are ignored and the pre-chat form is skipped.
|
|
135
135
|
*/
|
|
136
136
|
allowAnonymous?: boolean;
|
|
137
|
-
/** Theme overrides. */
|
|
138
|
-
theme?: ChatWidgetTheme;
|
|
139
|
-
}
|
|
140
|
-
//#endregion
|
|
141
|
-
//#region src/element.d.ts
|
|
142
|
-
declare const ELEMENT_TAG = "smooth-agent-chat";
|
|
143
|
-
declare class SmoothAgentChatElement extends HTMLElement {
|
|
144
|
-
static get observedAttributes(): readonly string[];
|
|
145
|
-
private readonly root;
|
|
146
|
-
private controller;
|
|
147
|
-
private overrides;
|
|
148
|
-
private open;
|
|
149
|
-
private messages;
|
|
150
|
-
private status;
|
|
151
|
-
private mounted;
|
|
152
|
-
/** True once the visitor has cleared the pre-chat identity gate (or it's not needed). */
|
|
153
|
-
private userInfoSatisfied;
|
|
154
|
-
/** True after the visitor has sent their first message (hides starter chips). */
|
|
155
|
-
private hasSent;
|
|
156
|
-
/** Starter prompts shown as chips in the empty state. */
|
|
157
|
-
private examplePrompts;
|
|
158
|
-
/** Whether mid-conversation suggested-reply chips are shown (config). */
|
|
159
|
-
private showSuggestedReplies;
|
|
160
|
-
/** Resolved greeting text, cached so async (rAF) renders can reuse it. */
|
|
161
|
-
private greeting;
|
|
162
|
-
/** Current mid-turn interrupt (OTP / tool-confirmation), or null. */
|
|
163
|
-
private interrupt;
|
|
164
|
-
private interruptEl;
|
|
165
|
-
/** Cross-device "restore my chats" flow state (ADR-048 §c). */
|
|
166
|
-
private identityRestore;
|
|
167
|
-
/** Whether the cross-device restore affordance is offered (config). */
|
|
168
|
-
private allowChatRestore;
|
|
169
|
-
/** True while the pre-chat identity gate is showing (blocks premature connect). */
|
|
170
|
-
private gating;
|
|
171
|
-
private panelEl;
|
|
172
|
-
private launcherEl;
|
|
173
|
-
private messagesEl;
|
|
174
|
-
private statusEl;
|
|
175
|
-
private dotEl;
|
|
176
|
-
private inputEl;
|
|
177
|
-
private sendBtn;
|
|
178
|
-
private suggestionsEl;
|
|
179
|
-
/** The live streaming assistant bubble whose textContent the rAF loop drives. */
|
|
180
|
-
private streamBubbleEl;
|
|
181
|
-
/** Message id the reveal is bound to (guards against stale frames after rebuilds). */
|
|
182
|
-
private streamMsgId;
|
|
183
|
-
/** Full buffered target text for the streaming message (grows as tokens arrive). */
|
|
184
|
-
private streamTarget;
|
|
185
|
-
/** How many chars of {@link streamTarget} are currently shown. */
|
|
186
|
-
private displayedLength;
|
|
187
|
-
private rafId;
|
|
188
|
-
constructor();
|
|
189
|
-
connectedCallback(): void;
|
|
190
|
-
disconnectedCallback(): void;
|
|
191
|
-
attributeChangedCallback(): void;
|
|
192
137
|
/**
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*/
|
|
196
|
-
configure(config: Partial<ChatWidgetConfig>): void;
|
|
197
|
-
/** Open the chat panel. */
|
|
198
|
-
openChat(): void;
|
|
199
|
-
/** Collapse the chat panel back to the launcher. */
|
|
200
|
-
closeChat(): void;
|
|
201
|
-
private readConfig;
|
|
202
|
-
private render;
|
|
203
|
-
/**
|
|
204
|
-
* Render (or clear) the mid-turn interrupt overlay above the composer:
|
|
205
|
-
* an OTP code prompt or a tool-write confirmation. Server-supplied text is
|
|
206
|
-
* set via `textContent` (never innerHTML); only static icons use innerHTML.
|
|
207
|
-
*/
|
|
208
|
-
private renderInterrupt;
|
|
209
|
-
/**
|
|
210
|
-
* Build the cross-device "Restore my chats" card (ADR-048 §c). Reuses the
|
|
211
|
-
* same overlay slot + visual language as the OTP interrupt. All server-supplied
|
|
212
|
-
* strings (masked destination, conversation previews) are set via `textContent`
|
|
213
|
-
* — never innerHTML — so they can't inject markup; only the static lock icon
|
|
214
|
-
* uses innerHTML.
|
|
215
|
-
*/
|
|
216
|
-
private buildRestoreCard;
|
|
217
|
-
/** Format an ISO timestamp as a short, locale-aware label (best-effort). */
|
|
218
|
-
private formatWhen;
|
|
219
|
-
/**
|
|
220
|
-
* Wire as-you-type formatting + an inline validity hint onto the pre-chat
|
|
221
|
-
* phone input (libphonenumber-js, US default region). Autofill is preserved:
|
|
222
|
-
* the input keeps its `type="tel"` + `autocomplete="tel"` + implicit <label>,
|
|
223
|
-
* and we also reformat on `change` so a browser-autofilled value gets
|
|
224
|
-
* formatted/validated too.
|
|
138
|
+
* Show the agent's tool activity (grep / read_file / bash / knowledge_search…)
|
|
139
|
+
* as inline chips interleaved with its prose, mirroring the smooth daemon SPA.
|
|
225
140
|
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
* formatting characters works naturally.
|
|
231
|
-
*/
|
|
232
|
-
private wirePhoneField;
|
|
233
|
-
/** Collect identity + consent from the pre-chat form, then drop into the chat view. */
|
|
234
|
-
private handlePrechatSubmit;
|
|
235
|
-
/** Send a starter prompt (from a chip click). */
|
|
236
|
-
private submitPrompt;
|
|
237
|
-
private syncOpenState;
|
|
238
|
-
/** Grow the textarea with its content, up to the CSS max-height. */
|
|
239
|
-
private autosize;
|
|
240
|
-
/**
|
|
241
|
-
* Receive a new message snapshot from the controller and update the view.
|
|
242
|
-
*
|
|
243
|
-
* `onMessages` fires on *every* `stream_token` delta. Rebuilding the whole
|
|
244
|
-
* list each frame is wasteful and fights the smooth reveal, so we take the
|
|
245
|
-
* cheap path when the only change is the trailing streaming assistant message
|
|
246
|
-
* growing: just bump the reveal *target* (the rAF loop drains it). Any
|
|
247
|
-
* structural change (new message, finalize, citations) triggers a full
|
|
248
|
-
* rebuild via {@link renderMessages}.
|
|
249
|
-
*/
|
|
250
|
-
private handleMessages;
|
|
251
|
-
private renderMessages;
|
|
252
|
-
/**
|
|
253
|
-
* Render (or clear) the mid-conversation suggested-reply chips under the
|
|
254
|
-
* composer. Shown ONLY when: the feature is enabled, no interrupt / restore
|
|
255
|
-
* overlay is active (those reuse the slot above the composer), and the LATEST
|
|
256
|
-
* message is a finalized assistant turn that carried suggestions. A new turn
|
|
257
|
-
* (agent or the visitor typing) appends messages, so the latest is no longer
|
|
258
|
-
* that assistant message and the chips clear on the next render. Chips reuse
|
|
259
|
-
* the empty-state `.prompts`/`.chip` styling and send via the same path.
|
|
260
|
-
*/
|
|
261
|
-
private renderSuggestions;
|
|
262
|
-
/** True when the host/user prefers reduced motion (snap, no typewriter). */
|
|
263
|
-
private prefersReducedMotion;
|
|
264
|
-
/**
|
|
265
|
-
* Bind the rAF typewriter to a freshly built streaming bubble. Preserves the
|
|
266
|
-
* already-revealed prefix across rebuilds (so a structural rebuild mid-stream
|
|
267
|
-
* doesn't restart the reveal from zero), then resumes the loop.
|
|
268
|
-
*/
|
|
269
|
-
private bindReveal;
|
|
270
|
-
/** Start the rAF loop if it isn't already running. */
|
|
271
|
-
private ensureRevealLoop;
|
|
272
|
-
/**
|
|
273
|
-
* One animation frame of the reveal. Advances `displayedLength` toward the
|
|
274
|
-
* buffered target at an ADAPTIVE rate — the deeper the backlog, the more
|
|
275
|
-
* chars per frame — so the reveal stays smooth yet never falls behind the
|
|
276
|
-
* network. Updates ONLY the bound bubble's textContent (no list rebuild).
|
|
277
|
-
*/
|
|
278
|
-
private tickReveal;
|
|
279
|
-
/** Snap the bound bubble to the full buffered text immediately (reduced-motion / no-rAF). */
|
|
280
|
-
private snapReveal;
|
|
281
|
-
/**
|
|
282
|
-
* Full-page sizing probe: decide whether the host's container gives it a
|
|
283
|
-
* real box. With the `.wrap` flex chain hidden, `height: 100%` of a SIZED
|
|
284
|
-
* container still resolves (clientHeight > 0), while an auto-height parent
|
|
285
|
-
* (e.g. mounted straight into `<body>`) collapses to ~0. Only the latter
|
|
286
|
-
* gets `data-viewport-fallback`, whose CSS applies `min-height: 100dvh` —
|
|
287
|
-
* so an embed inside a fixed-height box never overflows it (the composer
|
|
288
|
-
* stays visible), and a bare full-page route still fills the viewport.
|
|
289
|
-
*/
|
|
290
|
-
private syncViewportFallback;
|
|
291
|
-
/** Cancel any in-flight reveal loop and clear its state (called on full rebuild). */
|
|
292
|
-
private resetReveal;
|
|
293
|
-
/**
|
|
294
|
-
* Auto-scroll the message list to the bottom — but don't fight a visitor who
|
|
295
|
-
* has scrolled up to read history. When `force` (a structural rebuild) we
|
|
296
|
-
* always pin to bottom; during the streaming reveal we only follow if the
|
|
297
|
-
* viewport is already near the bottom.
|
|
298
|
-
*/
|
|
299
|
-
private scrollToBottom;
|
|
300
|
-
/** Wrap a bubble in a `.row`, prefixing assistant rows with a mini avatar. */
|
|
301
|
-
private buildRow;
|
|
302
|
-
private greetingBubble;
|
|
303
|
-
private typingDot;
|
|
304
|
-
/**
|
|
305
|
-
* Build the collapsible "Sources (N)" block for an assistant message's
|
|
306
|
-
* citations. Title/snippet are set via `textContent` (never innerHTML) so
|
|
307
|
-
* citation text can't inject markup; only the static chevron + numeric count
|
|
308
|
-
* use innerHTML.
|
|
141
|
+
* Defaults to **`false`**: for a customer-facing support widget, surfacing raw
|
|
142
|
+
* tool calls to an end-user is usually undesirable, so tool activity is hidden
|
|
143
|
+
* and only the assistant's prose renders. Enable it for internal / power-user
|
|
144
|
+
* surfaces where seeing what the agent did mid-turn is valuable.
|
|
309
145
|
*/
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
private submit;
|
|
146
|
+
showToolActivity?: boolean;
|
|
147
|
+
/** Theme overrides. */
|
|
148
|
+
theme?: ChatWidgetTheme;
|
|
314
149
|
}
|
|
315
|
-
/** Register the custom element once. Safe to call multiple times. */
|
|
316
|
-
declare function defineChatWidget(): void;
|
|
317
|
-
/**
|
|
318
|
-
* Programmatically create, configure, and append a widget to the page.
|
|
319
|
-
* Returns the element so the host can drive `openChat()` / `closeChat()`.
|
|
320
|
-
*/
|
|
321
|
-
declare function mountChatWidget(config: ChatWidgetConfig, target?: HTMLElement): SmoothAgentChatElement;
|
|
322
|
-
/**
|
|
323
|
-
* Ergonomic helper for the full-page layout: mounts a `<smooth-agent-chat>` in
|
|
324
|
-
* `mode: "fullpage"` (no launcher — the chat fills its container/viewport with a
|
|
325
|
-
* Smooth-branded header, a scrollable message list, and an input bar) and
|
|
326
|
-
* returns the element.
|
|
327
|
-
*
|
|
328
|
-
* `target` defaults to `document.body`; pass a sized container to embed the
|
|
329
|
-
* full-page chat inside a layout region (e.g. a `/chat` route shell or an
|
|
330
|
-
* iframe). The `mode` is forced to `"fullpage"` regardless of the passed config.
|
|
331
|
-
*
|
|
332
|
-
* ```ts
|
|
333
|
-
* mountFullPageChat({ endpoint: 'wss://…/ws', agentId: '…', agentName: 'Support' });
|
|
334
|
-
* ```
|
|
335
|
-
*/
|
|
336
|
-
declare function mountFullPageChat(config: Omit<ChatWidgetConfig, 'mode'>, target?: HTMLElement): SmoothAgentChatElement;
|
|
337
|
-
//#endregion
|
|
338
|
-
//#region src/loader-core.d.ts
|
|
339
|
-
/**
|
|
340
|
-
* Tiny, dependency-free deferred loader for `@smooai/chat-widget`.
|
|
341
|
-
*
|
|
342
|
-
* The recommended embed: a host includes this *small* script eagerly, and it
|
|
343
|
-
* defers injecting the real (heavier) `chat-widget.global.js` module until the
|
|
344
|
-
* page is past its critical render — so the widget never competes with the host
|
|
345
|
-
* page's LCP/TBT. It triggers the real load on the **first** of:
|
|
346
|
-
*
|
|
347
|
-
* - `window` `load` → `requestIdleCallback` (idle time), or
|
|
348
|
-
* - user intent (`pointerdown` / `keydown` / `scroll`), or
|
|
349
|
-
* - an 8s fallback.
|
|
350
|
-
*
|
|
351
|
-
* After the module loads (which registers `<smooth-agent-chat>` and exposes
|
|
352
|
-
* `window.SmoothAgentChat`), it mounts the widget with the host's config.
|
|
353
|
-
*
|
|
354
|
-
* Deliberately imports nothing from the widget itself — this file must stay a
|
|
355
|
-
* few hundred bytes so including it eagerly is free.
|
|
356
|
-
*
|
|
357
|
-
* ## Config
|
|
358
|
-
* Set a global before/with the loader (any `ChatWidgetConfig`, plus an optional
|
|
359
|
-
* `src` pointing at the module bundle):
|
|
360
|
-
*
|
|
361
|
-
* ```html
|
|
362
|
-
* <script>window.SmoothAgentChatConfig = { endpoint: 'wss://…/ws', agentId: '…' };</script>
|
|
363
|
-
* <script src="https://cdn/…/chat-widget-loader.global.js" async></script>
|
|
364
|
-
* ```
|
|
365
|
-
*
|
|
366
|
-
* Or, for the simplest installs, `data-*` attributes on the loader's own tag
|
|
367
|
-
* (`data-endpoint`, `data-agent-id`, `data-primary`, `data-mode`, `data-src`).
|
|
368
|
-
* If no config is found, the module is still loaded (registering the element) so
|
|
369
|
-
* a `<smooth-agent-chat …>` placed directly in markup upgrades itself.
|
|
370
|
-
*/
|
|
371
|
-
/**
|
|
372
|
-
* Install the deferred loader. Idempotent per call; the IIFE entry
|
|
373
|
-
* (`loader.ts`) invokes it once on script execution.
|
|
374
|
-
*/
|
|
375
|
-
declare function initChatWidgetLoader(): void;
|
|
376
150
|
//#endregion
|
|
377
151
|
//#region src/persistence.d.ts
|
|
378
152
|
/** Current persisted-shape version. Bump when the shape below changes incompatibly. */
|
|
@@ -455,6 +229,36 @@ declare function createWidgetStore(agentId: string): StoreApi<WidgetStore>;
|
|
|
455
229
|
*/
|
|
456
230
|
declare function httpBaseFromWsEndpoint(endpoint: string): string | null;
|
|
457
231
|
type Role = 'user' | 'assistant';
|
|
232
|
+
/**
|
|
233
|
+
* One tool invocation within an assistant turn. Mirrors the smooth daemon SPA's
|
|
234
|
+
* `ToolCall` (`crates/smooth-web/web/src/operator.ts`): opens `done: false` on the
|
|
235
|
+
* tool call and resolves on the tool result.
|
|
236
|
+
*/
|
|
237
|
+
interface ToolCall {
|
|
238
|
+
/** Stable id for keyed rendering (assigned when the call opens). */
|
|
239
|
+
id: string;
|
|
240
|
+
name: string;
|
|
241
|
+
/** Raw arguments, JSON-stringified. */
|
|
242
|
+
args: string;
|
|
243
|
+
/** Present once the tool resolves. */
|
|
244
|
+
result?: string;
|
|
245
|
+
isError?: boolean;
|
|
246
|
+
done: boolean;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* One ordered segment of an assistant turn: a run of prose, or a tool call.
|
|
250
|
+
* Preserves the interleave order the model produced (say a bit → call a tool →
|
|
251
|
+
* say a bit → …) so the UI can render tool chips INLINE where the model called
|
|
252
|
+
* them. Mirrors the daemon SPA's `MessageBlock`. Only populated when the widget
|
|
253
|
+
* is configured with `showToolActivity: true`.
|
|
254
|
+
*/
|
|
255
|
+
type MessageBlock = {
|
|
256
|
+
kind: 'text';
|
|
257
|
+
text: string;
|
|
258
|
+
} | {
|
|
259
|
+
kind: 'tool';
|
|
260
|
+
tool: ToolCall;
|
|
261
|
+
};
|
|
458
262
|
interface ChatMessage {
|
|
459
263
|
id: string;
|
|
460
264
|
role: Role;
|
|
@@ -462,6 +266,12 @@ interface ChatMessage {
|
|
|
462
266
|
text: string;
|
|
463
267
|
/** True while an assistant message is still streaming. */
|
|
464
268
|
streaming: boolean;
|
|
269
|
+
/**
|
|
270
|
+
* Ordered text + tool segments, interleaved as the model produced them. Present
|
|
271
|
+
* only on assistant messages when `showToolActivity` is enabled (absent
|
|
272
|
+
* otherwise — the default popover renders `text` alone, byte-for-byte unchanged).
|
|
273
|
+
*/
|
|
274
|
+
blocks?: MessageBlock[];
|
|
465
275
|
/**
|
|
466
276
|
* Sources that grounded an assistant answer, when the terminal
|
|
467
277
|
* `eventual_response` carried any. Optional + back-compatible: absent when
|
|
@@ -485,6 +295,9 @@ type ConnectionStatus = 'idle' | 'connecting' | 'ready' | 'error' | 'closed';
|
|
|
485
295
|
* Resume with {@link ConversationController.verifyOtp}.
|
|
486
296
|
* - `confirm` — the agent wants to run a state-mutating tool and needs approval.
|
|
487
297
|
* Resume with {@link ConversationController.confirmTool}.
|
|
298
|
+
* - `interaction` — the agent raised a Rich Interaction (structured card, e.g.
|
|
299
|
+
* identity intake). Resume with {@link ConversationController.submitInteraction}
|
|
300
|
+
* or {@link ConversationController.declineInteraction}.
|
|
488
301
|
*/
|
|
489
302
|
type Interrupt = {
|
|
490
303
|
kind: 'otp';
|
|
@@ -501,6 +314,16 @@ type Interrupt = {
|
|
|
501
314
|
kind: 'confirm';
|
|
502
315
|
toolId?: string;
|
|
503
316
|
actionDescription?: string;
|
|
317
|
+
} | {
|
|
318
|
+
kind: 'interaction'; /** Server-generated interaction instance id (echoed on submit). */
|
|
319
|
+
interactionId: string; /** The Rich Interaction kind (e.g. `identity_intake`) — selects the card. */
|
|
320
|
+
interactionKind: string; /** Kind-specific render spec (identity_intake: `{ fields: [...] }`). */
|
|
321
|
+
spec: Record<string, unknown>; /** Why the agent raised it (card header copy). */
|
|
322
|
+
reason?: string; /** Per-field server-side validation errors (from `interaction_invalid`). */
|
|
323
|
+
errors?: {
|
|
324
|
+
field: string;
|
|
325
|
+
message: string;
|
|
326
|
+
}[];
|
|
504
327
|
};
|
|
505
328
|
interface UserInfo {
|
|
506
329
|
name?: string;
|
|
@@ -578,6 +401,9 @@ declare class ConversationController {
|
|
|
578
401
|
/** requestId of the in-flight turn — used to resume OTP / tool confirmations. */
|
|
579
402
|
private activeRequestId;
|
|
580
403
|
private interrupt;
|
|
404
|
+
/** Values from the last interaction submit, merged into the persisted
|
|
405
|
+
* identity (identity_intake only) once the server acks them. */
|
|
406
|
+
private pendingInteractionValues;
|
|
581
407
|
private identityRestore;
|
|
582
408
|
/**
|
|
583
409
|
* True once the resume probe (persisted-pointer get_session OR the
|
|
@@ -612,6 +438,16 @@ declare class ConversationController {
|
|
|
612
438
|
verifyOtp(code: string): void;
|
|
613
439
|
/** Approve or reject a pending tool write to resume the paused turn. */
|
|
614
440
|
confirmTool(approved: boolean): void;
|
|
441
|
+
/**
|
|
442
|
+
* Submit a Rich Interaction card to resume the parked turn. The server
|
|
443
|
+
* routes to the kind's validator: invalid values come back as an
|
|
444
|
+
* `interaction_invalid` event (the card re-renders with per-field errors —
|
|
445
|
+
* the turn stays parked); a valid submit is acked and the turn resumes.
|
|
446
|
+
* No-op if not awaiting an interaction.
|
|
447
|
+
*/
|
|
448
|
+
submitInteraction(values: Record<string, unknown>): void;
|
|
449
|
+
/** Decline the pending Rich Interaction; the agent continues without it. */
|
|
450
|
+
declineInteraction(): void;
|
|
615
451
|
private nextId;
|
|
616
452
|
private setStatus;
|
|
617
453
|
private emitMessages;
|
|
@@ -705,6 +541,267 @@ declare class ConversationController {
|
|
|
705
541
|
disconnect(): void;
|
|
706
542
|
}
|
|
707
543
|
//#endregion
|
|
544
|
+
//#region src/element.d.ts
|
|
545
|
+
declare const ELEMENT_TAG = "smooth-agent-chat";
|
|
546
|
+
declare class SmoothAgentChatElement extends HTMLElement {
|
|
547
|
+
static get observedAttributes(): readonly string[];
|
|
548
|
+
private readonly root;
|
|
549
|
+
private controller;
|
|
550
|
+
private overrides;
|
|
551
|
+
private open;
|
|
552
|
+
private messages;
|
|
553
|
+
private status;
|
|
554
|
+
private mounted;
|
|
555
|
+
/** True once the visitor has cleared the pre-chat identity gate (or it's not needed). */
|
|
556
|
+
private userInfoSatisfied;
|
|
557
|
+
/** True after the visitor has sent their first message (hides starter chips). */
|
|
558
|
+
private hasSent;
|
|
559
|
+
/** Starter prompts shown as chips in the empty state. */
|
|
560
|
+
private examplePrompts;
|
|
561
|
+
/** Whether mid-conversation suggested-reply chips are shown (config). */
|
|
562
|
+
private showSuggestedReplies;
|
|
563
|
+
/** Resolved greeting text, cached so async (rAF) renders can reuse it. */
|
|
564
|
+
private greeting;
|
|
565
|
+
/** Current mid-turn interrupt (OTP / tool-confirmation), or null. */
|
|
566
|
+
private interrupt;
|
|
567
|
+
private interruptEl;
|
|
568
|
+
/** Cross-device "restore my chats" flow state (ADR-048 §c). */
|
|
569
|
+
private identityRestore;
|
|
570
|
+
/** Whether the cross-device restore affordance is offered (config). */
|
|
571
|
+
private allowChatRestore;
|
|
572
|
+
/** True while the pre-chat identity gate is showing (blocks premature connect). */
|
|
573
|
+
private gating;
|
|
574
|
+
private panelEl;
|
|
575
|
+
private launcherEl;
|
|
576
|
+
private messagesEl;
|
|
577
|
+
private statusEl;
|
|
578
|
+
private dotEl;
|
|
579
|
+
private inputEl;
|
|
580
|
+
private sendBtn;
|
|
581
|
+
private suggestionsEl;
|
|
582
|
+
/** The live streaming assistant bubble whose textContent the rAF loop drives. */
|
|
583
|
+
private streamBubbleEl;
|
|
584
|
+
/** Message id the reveal is bound to (guards against stale frames after rebuilds). */
|
|
585
|
+
private streamMsgId;
|
|
586
|
+
/** Full buffered target text for the streaming message (grows as tokens arrive). */
|
|
587
|
+
private streamTarget;
|
|
588
|
+
/** How many chars of {@link streamTarget} are currently shown. */
|
|
589
|
+
private displayedLength;
|
|
590
|
+
private rafId;
|
|
591
|
+
/** Block structure signature of the last-rendered streaming message (tool chips
|
|
592
|
+
* only — text growth doesn't change it), so a chip add/resolve forces a rebuild
|
|
593
|
+
* while plain trailing-text growth stays on the fast reveal path. */
|
|
594
|
+
private prevBlockSig;
|
|
595
|
+
constructor();
|
|
596
|
+
connectedCallback(): void;
|
|
597
|
+
disconnectedCallback(): void;
|
|
598
|
+
attributeChangedCallback(): void;
|
|
599
|
+
/**
|
|
600
|
+
* Programmatically merge config overrides (endpoint, agentId, theme, …). Values
|
|
601
|
+
* set here take precedence over HTML attributes. Re-renders the widget.
|
|
602
|
+
*/
|
|
603
|
+
configure(config: Partial<ChatWidgetConfig>): void;
|
|
604
|
+
/** Open the chat panel. */
|
|
605
|
+
openChat(): void;
|
|
606
|
+
/** Collapse the chat panel back to the launcher. */
|
|
607
|
+
closeChat(): void;
|
|
608
|
+
private readConfig;
|
|
609
|
+
private render;
|
|
610
|
+
/**
|
|
611
|
+
* Render (or clear) the mid-turn interrupt overlay above the composer:
|
|
612
|
+
* an OTP code prompt or a tool-write confirmation. Server-supplied text is
|
|
613
|
+
* set via `textContent` (never innerHTML); only static icons use innerHTML.
|
|
614
|
+
*/
|
|
615
|
+
private renderInterrupt;
|
|
616
|
+
/**
|
|
617
|
+
* Build the cross-device "Restore my chats" card (ADR-048 §c). Reuses the
|
|
618
|
+
* same overlay slot + visual language as the OTP interrupt. All server-supplied
|
|
619
|
+
* strings (masked destination, conversation previews) are set via `textContent`
|
|
620
|
+
* — never innerHTML — so they can't inject markup; only the static lock icon
|
|
621
|
+
* uses innerHTML.
|
|
622
|
+
*/
|
|
623
|
+
private buildRestoreCard;
|
|
624
|
+
/** Format an ISO timestamp as a short, locale-aware label (best-effort). */
|
|
625
|
+
private formatWhen;
|
|
626
|
+
/**
|
|
627
|
+
* Wire as-you-type formatting + an inline validity hint onto the pre-chat
|
|
628
|
+
* phone input (libphonenumber-js, US default region). Autofill is preserved:
|
|
629
|
+
* the input keeps its `type="tel"` + `autocomplete="tel"` + implicit <label>,
|
|
630
|
+
* and we also reformat on `change` so a browser-autofilled value gets
|
|
631
|
+
* formatted/validated too.
|
|
632
|
+
*
|
|
633
|
+
* As-you-type caret note: `AsYouType` reformats the entire string, which
|
|
634
|
+
* moves the caret to the end on a mid-string edit. To avoid fighting the
|
|
635
|
+
* user, we only rewrite the value when the caret is at the end (the typical
|
|
636
|
+
* append-a-digit case) and never on a deletion — so backspacing the
|
|
637
|
+
* formatting characters works naturally.
|
|
638
|
+
*/
|
|
639
|
+
private wirePhoneField;
|
|
640
|
+
/** Collect identity + consent from the pre-chat form, then drop into the chat view. */
|
|
641
|
+
private handlePrechatSubmit;
|
|
642
|
+
/** Send a starter prompt (from a chip click). */
|
|
643
|
+
private submitPrompt;
|
|
644
|
+
private syncOpenState;
|
|
645
|
+
/** Grow the textarea with its content, up to the CSS max-height. */
|
|
646
|
+
private autosize;
|
|
647
|
+
/**
|
|
648
|
+
* Receive a new message snapshot from the controller and update the view.
|
|
649
|
+
*
|
|
650
|
+
* `onMessages` fires on *every* `stream_token` delta. Rebuilding the whole
|
|
651
|
+
* list each frame is wasteful and fights the smooth reveal, so we take the
|
|
652
|
+
* cheap path when the only change is the trailing streaming assistant message
|
|
653
|
+
* growing: just bump the reveal *target* (the rAF loop drains it). Any
|
|
654
|
+
* structural change (new message, finalize, citations) triggers a full
|
|
655
|
+
* rebuild via {@link renderMessages}.
|
|
656
|
+
*/
|
|
657
|
+
private handleMessages;
|
|
658
|
+
/** True when an assistant message's turn invoked at least one tool. */
|
|
659
|
+
private hasToolBlocks;
|
|
660
|
+
/** Signature that changes only when a tool chip is added or resolved (text growth is 'x'). */
|
|
661
|
+
private blockSig;
|
|
662
|
+
/** The live (last) text block for a tool turn, else the whole message text. */
|
|
663
|
+
private tailText;
|
|
664
|
+
/** Reveal-binding key — composite for a tool-turn tail (so a new trailing block rebinds), else msg id. */
|
|
665
|
+
private tailKey;
|
|
666
|
+
private renderMessages;
|
|
667
|
+
/**
|
|
668
|
+
* Render (or clear) the mid-conversation suggested-reply chips under the
|
|
669
|
+
* composer. Shown ONLY when: the feature is enabled, no interrupt / restore
|
|
670
|
+
* overlay is active (those reuse the slot above the composer), and the LATEST
|
|
671
|
+
* message is a finalized assistant turn that carried suggestions. A new turn
|
|
672
|
+
* (agent or the visitor typing) appends messages, so the latest is no longer
|
|
673
|
+
* that assistant message and the chips clear on the next render. Chips reuse
|
|
674
|
+
* the empty-state `.prompts`/`.chip` styling and send via the same path.
|
|
675
|
+
*/
|
|
676
|
+
private renderSuggestions;
|
|
677
|
+
/** True when the host/user prefers reduced motion (snap, no typewriter). */
|
|
678
|
+
private prefersReducedMotion;
|
|
679
|
+
/**
|
|
680
|
+
* Bind the rAF typewriter to a freshly built streaming bubble. Preserves the
|
|
681
|
+
* already-revealed prefix across rebuilds (so a structural rebuild mid-stream
|
|
682
|
+
* doesn't restart the reveal from zero), then resumes the loop.
|
|
683
|
+
*/
|
|
684
|
+
private bindReveal;
|
|
685
|
+
/**
|
|
686
|
+
* Render a tool-activity assistant turn as an ordered strip: prose bubbles and
|
|
687
|
+
* inline tool chips in the order the model produced them (mirrors the daemon
|
|
688
|
+
* SPA's `blocks`). The live trailing text block (while streaming) binds to the
|
|
689
|
+
* rAF reveal; earlier/finalized text blocks render as sanitized markdown.
|
|
690
|
+
*/
|
|
691
|
+
private renderAssistantBlocks;
|
|
692
|
+
/**
|
|
693
|
+
* A single tool-activity chip: icon + tool name + status (running… / done / error),
|
|
694
|
+
* with a truncated args preview. Tool name/args are set via `textContent` so a
|
|
695
|
+
* tool payload can never inject markup.
|
|
696
|
+
*/
|
|
697
|
+
private buildToolChip;
|
|
698
|
+
/** Start the rAF loop if it isn't already running. */
|
|
699
|
+
private ensureRevealLoop;
|
|
700
|
+
/**
|
|
701
|
+
* One animation frame of the reveal. Advances `displayedLength` toward the
|
|
702
|
+
* buffered target at an ADAPTIVE rate — the deeper the backlog, the more
|
|
703
|
+
* chars per frame — so the reveal stays smooth yet never falls behind the
|
|
704
|
+
* network. Updates ONLY the bound bubble's textContent (no list rebuild).
|
|
705
|
+
*/
|
|
706
|
+
private tickReveal;
|
|
707
|
+
/** Snap the bound bubble to the full buffered text immediately (reduced-motion / no-rAF). */
|
|
708
|
+
private snapReveal;
|
|
709
|
+
/**
|
|
710
|
+
* Full-page sizing probe: decide whether the host's container gives it a
|
|
711
|
+
* real box. With the `.wrap` flex chain hidden, `height: 100%` of a SIZED
|
|
712
|
+
* container still resolves (clientHeight > 0), while an auto-height parent
|
|
713
|
+
* (e.g. mounted straight into `<body>`) collapses to ~0. Only the latter
|
|
714
|
+
* gets `data-viewport-fallback`, whose CSS applies `min-height: 100dvh` —
|
|
715
|
+
* so an embed inside a fixed-height box never overflows it (the composer
|
|
716
|
+
* stays visible), and a bare full-page route still fills the viewport.
|
|
717
|
+
*/
|
|
718
|
+
private syncViewportFallback;
|
|
719
|
+
/** Cancel any in-flight reveal loop and clear its state (called on full rebuild). */
|
|
720
|
+
private resetReveal;
|
|
721
|
+
/**
|
|
722
|
+
* Auto-scroll the message list to the bottom — but don't fight a visitor who
|
|
723
|
+
* has scrolled up to read history. When `force` (a structural rebuild) we
|
|
724
|
+
* always pin to bottom; during the streaming reveal we only follow if the
|
|
725
|
+
* viewport is already near the bottom.
|
|
726
|
+
*/
|
|
727
|
+
private scrollToBottom;
|
|
728
|
+
/** Wrap a bubble in a `.row`, prefixing assistant rows with a mini avatar. */
|
|
729
|
+
private buildRow;
|
|
730
|
+
private greetingBubble;
|
|
731
|
+
private typingDot;
|
|
732
|
+
/**
|
|
733
|
+
* Build the collapsible "Sources (N)" block for an assistant message's
|
|
734
|
+
* citations. Title/snippet are set via `textContent` (never innerHTML) so
|
|
735
|
+
* citation text can't inject markup; only the static chevron + numeric count
|
|
736
|
+
* use innerHTML.
|
|
737
|
+
*/
|
|
738
|
+
private renderSources;
|
|
739
|
+
private renderStatus;
|
|
740
|
+
private renderComposerState;
|
|
741
|
+
private submit;
|
|
742
|
+
}
|
|
743
|
+
/** Register the custom element once. Safe to call multiple times. */
|
|
744
|
+
declare function defineChatWidget(): void;
|
|
745
|
+
/**
|
|
746
|
+
* Programmatically create, configure, and append a widget to the page.
|
|
747
|
+
* Returns the element so the host can drive `openChat()` / `closeChat()`.
|
|
748
|
+
*/
|
|
749
|
+
declare function mountChatWidget(config: ChatWidgetConfig, target?: HTMLElement): SmoothAgentChatElement;
|
|
750
|
+
/**
|
|
751
|
+
* Ergonomic helper for the full-page layout: mounts a `<smooth-agent-chat>` in
|
|
752
|
+
* `mode: "fullpage"` (no launcher — the chat fills its container/viewport with a
|
|
753
|
+
* Smooth-branded header, a scrollable message list, and an input bar) and
|
|
754
|
+
* returns the element.
|
|
755
|
+
*
|
|
756
|
+
* `target` defaults to `document.body`; pass a sized container to embed the
|
|
757
|
+
* full-page chat inside a layout region (e.g. a `/chat` route shell or an
|
|
758
|
+
* iframe). The `mode` is forced to `"fullpage"` regardless of the passed config.
|
|
759
|
+
*
|
|
760
|
+
* ```ts
|
|
761
|
+
* mountFullPageChat({ endpoint: 'wss://…/ws', agentId: '…', agentName: 'Support' });
|
|
762
|
+
* ```
|
|
763
|
+
*/
|
|
764
|
+
declare function mountFullPageChat(config: Omit<ChatWidgetConfig, 'mode'>, target?: HTMLElement): SmoothAgentChatElement;
|
|
765
|
+
//#endregion
|
|
766
|
+
//#region src/loader-core.d.ts
|
|
767
|
+
/**
|
|
768
|
+
* Tiny, dependency-free deferred loader for `@smooai/chat-widget`.
|
|
769
|
+
*
|
|
770
|
+
* The recommended embed: a host includes this *small* script eagerly, and it
|
|
771
|
+
* defers injecting the real (heavier) `chat-widget.global.js` module until the
|
|
772
|
+
* page is past its critical render — so the widget never competes with the host
|
|
773
|
+
* page's LCP/TBT. It triggers the real load on the **first** of:
|
|
774
|
+
*
|
|
775
|
+
* - `window` `load` → `requestIdleCallback` (idle time), or
|
|
776
|
+
* - user intent (`pointerdown` / `keydown` / `scroll`), or
|
|
777
|
+
* - an 8s fallback.
|
|
778
|
+
*
|
|
779
|
+
* After the module loads (which registers `<smooth-agent-chat>` and exposes
|
|
780
|
+
* `window.SmoothAgentChat`), it mounts the widget with the host's config.
|
|
781
|
+
*
|
|
782
|
+
* Deliberately imports nothing from the widget itself — this file must stay a
|
|
783
|
+
* few hundred bytes so including it eagerly is free.
|
|
784
|
+
*
|
|
785
|
+
* ## Config
|
|
786
|
+
* Set a global before/with the loader (any `ChatWidgetConfig`, plus an optional
|
|
787
|
+
* `src` pointing at the module bundle):
|
|
788
|
+
*
|
|
789
|
+
* ```html
|
|
790
|
+
* <script>window.SmoothAgentChatConfig = { endpoint: 'wss://…/ws', agentId: '…' };</script>
|
|
791
|
+
* <script src="https://cdn/…/chat-widget-loader.global.js" async></script>
|
|
792
|
+
* ```
|
|
793
|
+
*
|
|
794
|
+
* Or, for the simplest installs, `data-*` attributes on the loader's own tag
|
|
795
|
+
* (`data-endpoint`, `data-agent-id`, `data-primary`, `data-mode`, `data-src`).
|
|
796
|
+
* If no config is found, the module is still loaded (registering the element) so
|
|
797
|
+
* a `<smooth-agent-chat …>` placed directly in markup upgrades itself.
|
|
798
|
+
*/
|
|
799
|
+
/**
|
|
800
|
+
* Install the deferred loader. Idempotent per call; the IIFE entry
|
|
801
|
+
* (`loader.ts`) invokes it once on script execution.
|
|
802
|
+
*/
|
|
803
|
+
declare function initChatWidgetLoader(): void;
|
|
804
|
+
//#endregion
|
|
708
805
|
//#region src/fingerprint.d.ts
|
|
709
806
|
/**
|
|
710
807
|
* Browser fingerprint — a stable, privacy-light identifier used by the
|
|
@@ -752,5 +849,5 @@ declare function computeFingerprint(): string;
|
|
|
752
849
|
*/
|
|
753
850
|
declare function getOrCreateFingerprint(get: () => string | null, set: (fp: string) => void): string;
|
|
754
851
|
//#endregion
|
|
755
|
-
export { type ChatMessage, type ChatWidgetConfig, type ChatWidgetMode, type ChatWidgetTheme, type Citation, type ConnectionStatus, type ConsentState, ConversationController, type ConversationEvents, ELEMENT_TAG, type IdentityRestore, type IdentityState, PERSIST_VERSION, type PersistedWidgetState, type RestorableConversation, type Role, SmoothAgentChatElement, type UserInfo, type WidgetStore, computeFingerprint, createWidgetStore, defineChatWidget, getOrCreateFingerprint, httpBaseFromWsEndpoint, initChatWidgetLoader, mountChatWidget, mountFullPageChat, storageKey };
|
|
852
|
+
export { type ChatMessage, type ChatWidgetConfig, type ChatWidgetMode, type ChatWidgetTheme, type Citation, type ConnectionStatus, type ConsentState, ConversationController, type ConversationEvents, ELEMENT_TAG, type IdentityRestore, type IdentityState, type MessageBlock, PERSIST_VERSION, type PersistedWidgetState, type RestorableConversation, type Role, SmoothAgentChatElement, type ToolCall, type UserInfo, type WidgetStore, computeFingerprint, createWidgetStore, defineChatWidget, getOrCreateFingerprint, httpBaseFromWsEndpoint, initChatWidgetLoader, mountChatWidget, mountFullPageChat, storageKey };
|
|
756
853
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/config.ts","../src/
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/config.ts","../src/persistence.ts","../src/conversation.ts","../src/element.ts","../src/loader-core.ts","../src/fingerprint.ts"],"mappings":"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"}
|