@accurix/centrinfo-widget 5.1.1 → 5.2.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 CHANGED
@@ -9,6 +9,55 @@ public chat API (see [`.claude/PUBLIC_CHAT.md`](../../../../.claude/PUBLIC_CHAT.
9
9
  for the backend, and [`.claude/PUBLIC_WIDGET_LIBRARY.md`](../../../../.claude/PUBLIC_WIDGET_LIBRARY.md)
10
10
  for the design).
11
11
 
12
+ ## Simple customization
13
+
14
+ Use `branding` and `composer` for common changes. The same options work in the
15
+ floating widget, full-page chat and unified SDK chat mounts.
16
+
17
+ ```ts
18
+ import { createWidget } from '@accurix/centrinfo-widget';
19
+
20
+ const widget = createWidget({
21
+ token: 'pub_...',
22
+ branding: {
23
+ name: 'ShopCo Assistant',
24
+ logo: '/shopco-logo.png',
25
+ color: '#2563eb',
26
+ },
27
+ composer: {
28
+ placeholder: 'Ask about your ShopCo orders...',
29
+ attachments: false,
30
+ voice: false,
31
+ modelSelector: true,
32
+ },
33
+ });
34
+ ```
35
+
36
+ | Option | What it changes |
37
+ | ------------------------ | --------------------------------------------------------------------- |
38
+ | `branding.name` | The displayed assistant name |
39
+ | `branding.logo` | Assistant avatar and floating launcher image |
40
+ | `branding.color` | Main accent color |
41
+ | `composer.placeholder` | Message-box prompt |
42
+ | `composer.attachments` | Show or hide the attachment button; default `true` |
43
+ | `composer.voice` | Set `false` to hide microphone input; default allows configured voice |
44
+ | `composer.modelSelector` | Show or hide the model picker; default `true` |
45
+
46
+ Omit any option to keep the existing behavior. Voice still requires the
47
+ application's voice configuration; the model picker requires permitted models.
48
+ These display options do not change data access or conversation retention.
49
+ In the floating widget, a separately configured voice assistant/call experience
50
+ is independent of the composer's microphone button.
51
+
52
+ For more control, use existing `themeTokens`, `labels`, `locale`, `dir`,
53
+ `theme`, placement and launcher options. Explicit advanced options take priority:
54
+ `agentName`, `agentAvatarUrl`, `launcherIcon`, `accentColor`, `attachments`,
55
+ `showAnalyticsModelSelector` and `labels.composerPlaceholder` override their simple
56
+ equivalents. `themeTokens.accent` also takes priority over `branding.color`.
57
+ Full-page `fullPageLabels.composerPlaceholder` takes priority over the shared
58
+ placeholder. The built-in component arrangement remains fixed; arbitrary
59
+ message renderers, button ordering and custom CSS injection are not provided.
60
+
12
61
  ## Install
13
62
 
14
63
  ### Script tag (any site — WordPress / Webflow / plain HTML)
@@ -51,6 +100,16 @@ const widget = init({ token: 'pub_8f3k…' });
51
100
 
52
101
  ## Config
53
102
 
103
+ Authenticated chat shows a **Data** dropdown by default when analytics models
104
+ are available to the customer's application role. `Automatic` keeps automatic
105
+ routing; selecting a model pins analytics turns and follow-ups to that model.
106
+ Switching models opens a fresh conversation and retains the previous history.
107
+ The backend validates the selected model on every turn.
108
+
109
+ Set `showAnalyticsModelSelector: false` to hide it. Set `analyticsModelId` to
110
+ provide an initial selection; a remembered customer choice takes precedence.
111
+ These options work in both the floating widget and full-page chat SDK.
112
+
54
113
  | Option | Type | Default | Notes |
55
114
  | ------------------------------------------------------------- | ----------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
56
115
  | `token` **(required)** | string | — | The org's `pub_*` token. It _is_ the org identity. |
@@ -66,10 +125,12 @@ const widget = init({ token: 'pub_8f3k…' });
66
125
  | `openByDefault` | boolean | `false` | Open the panel on load. |
67
126
  | `zIndex` | number | very high | Stacking against the host page. |
68
127
  | `demo` | boolean | `false` | Use the built-in mock transport — **no backend/token needed**. |
69
- | `configRefreshSeconds` | number | `30` | While the panel is open, refresh token branding/actions from `bootstrap`; set `0` to disable. |
128
+ | `configRefreshSeconds` | number | `300` | While the panel is open, refresh token branding/actions from `bootstrap`; set `0` to disable. |
70
129
  | `onOpen` / `onClose` / `onMessage` / `onAction` / `onHandoff` | function | — | Event hooks. |
71
130
  | `onOpenAnalyticsSource` | function | — | Receives a cited insight or Liveboard tile from a signed analytics answer. The host must check access before opening it. |
72
131
 
132
+ The widget loads `bootstrap` once on mount. An open panel does not poll live events until the session has conversation activity, and it does not send presence until the visitor has sent a message. During ordinary AI chat it checks for staff events every 30 seconds; during a queued or active human handoff it checks about every 2.2 seconds. Presence renews every 20 seconds only for an open conversation in a visible tab. Closing the panel or hiding the tab stops these checks. `configRefreshSeconds` controls only the separate branding/action refresh.
133
+
73
134
  ```ts
74
135
  init({
75
136
  token: 'pub_8f3k...',
@@ -306,15 +367,29 @@ With the default `persistence: 'local'` the widget keeps, per token and visitor
306
367
  `centrinfo:history:*`):
307
368
 
308
369
  - the session id, the visitor's name/email/phone once given, and a history index;
309
- - a **lean transcript**: message text, ids, sources, suggested replies and
310
- feedback, capped by the token's message cap and retention (30 days by default).
311
-
312
- Analytics results are **not** stored: rows, filters, explanations and chart
313
- data are dropped before writing, and a reloaded answer shows a short "ask again"
314
- note instead. Entries written by older versions are slimmed on the next load.
370
+ - a transcript with message text, analytics answers, chart data, sources, and
371
+ feedback. Anonymous transcripts follow the token's message cap and retention
372
+ (30 days by default). Signed-in transcripts have no automatic local expiry;
373
+ the local cache remains bounded by the message cap and browser storage quota.
374
+
375
+ Conversations bound to a verified signed customer identity do not auto-end
376
+ after inactivity. Their server messages are retained without the anonymous
377
+ TTL or message-cap deletion. A display-only `user` value does not establish
378
+ verified identity: supply `identityToken` or `getIdentityToken`. Explicitly
379
+ ending a conversation, removing it from history, and host logout still work.
380
+ Authentication tokens still expire and must be refreshed normally. The AI
381
+ receives only a bounded recent-message context, not the entire stored history.
382
+
383
+ Analytics answers, including their chart data and explanation, are kept with
384
+ the local transcript so reopening a conversation does not run the query again.
385
+ Authenticated history also restores the retained answer from the backend on a
386
+ new device. Ask the question again when you want current data. Older SDK
387
+ versions may have stored only a result marker; those entries cannot be restored.
315
388
  Writes happen at most once per second (plus on tab hide), and a full or blocked
316
389
  storage only costs the local copy of the chat. Use `persistence: 'none'` to
317
- store nothing.
390
+ keep no transcript on the device. Server retention follows the anonymous
391
+ conversation settings for anonymous sessions; verified customer messages do
392
+ not expire automatically. Previously deleted messages cannot be recovered.
318
393
 
319
394
  ## Lazy files and CSP
320
395