@hachther/akilio-widget 0.7.0 → 1.1.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 +331 -26
- package/dist/_headers +16 -0
- package/dist/akilio-widget.min.js +45 -44
- package/dist/assets/EmailIcon.d.ts +2 -0
- package/dist/assets/FormIcon.d.ts +2 -0
- package/dist/assets/PhoneIcon.d.ts +2 -0
- package/dist/components/BrandLogo.d.ts +7 -1
- package/dist/components/CartPanel.d.ts +13 -0
- package/dist/components/CommerceActions.d.ts +11 -0
- package/dist/components/Composer.d.ts +7 -1
- package/dist/components/ContactActions.d.ts +2 -2
- package/dist/components/EmptyState.d.ts +3 -7
- package/dist/components/Icons.d.ts +3 -0
- package/dist/components/IdentityVerification.d.ts +14 -0
- package/dist/components/InlineDecisionCard.d.ts +2 -0
- package/dist/components/Launcher.d.ts +6 -1
- package/dist/components/MessageBubble.d.ts +9 -2
- package/dist/components/MessageList.d.ts +1 -1
- package/dist/components/ProductCard.d.ts +4 -2
- package/dist/components/ProductCards.d.ts +6 -1
- package/dist/components/ProductDetail.d.ts +12 -0
- package/dist/components/ProductVariantSelector.d.ts +9 -0
- package/dist/components/SectionPrompt.d.ts +2 -0
- package/dist/components/TextSelectionPrompt.d.ts +2 -0
- package/dist/components/VoiceRecorder.d.ts +11 -0
- package/dist/hooks/current-cart.d.ts +14 -0
- package/dist/hooks/proactive-summary.d.ts +1 -0
- package/dist/hooks/storage.d.ts +2 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.min.js +10412 -7169
- package/dist/index.umd.min.cjs +37 -36
- package/dist/lib/cart-capabilities.d.ts +4 -0
- package/dist/lib/client.d.ts +35 -2
- package/dist/lib/copy.d.ts +8 -2
- package/dist/lib/storefront-cart.d.ts +5 -0
- package/dist/loader.js +46 -0
- package/dist/locales/en.d.ts +161 -0
- package/dist/locales/fr.d.ts +161 -0
- package/dist/locales/index.d.ts +3 -0
- package/dist/releases/1.1.0/akilio-widget.min.js +46 -0
- package/dist/style.css +1842 -81
- package/dist/types.d.ts +569 -31
- package/dist/vanilla.d.ts +1 -0
- package/dist/widget-manifest.json +8 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -63,10 +63,7 @@ placed at the bottom-left or displayed as a vertical tab in the middle of the
|
|
|
63
63
|
right viewport edge:
|
|
64
64
|
|
|
65
65
|
```tsx
|
|
66
|
-
<AkilioWidget
|
|
67
|
-
projectKey='your-project-key'
|
|
68
|
-
launcherPosition='right-middle'
|
|
69
|
-
/>
|
|
66
|
+
<AkilioWidget projectKey='your-project-key' launcherPosition='right-middle' />
|
|
70
67
|
```
|
|
71
68
|
|
|
72
69
|
Supported values are `bottom-right`, `bottom-left`, and `right-middle`. The
|
|
@@ -76,6 +73,22 @@ the compact bottom-right launcher and the normal mobile presentation.
|
|
|
76
73
|
|
|
77
74
|
The standalone equivalent is `data-launcher-position="right-middle"`.
|
|
78
75
|
|
|
76
|
+
## Adaptive launcher
|
|
77
|
+
|
|
78
|
+
The built-in launcher defaults to Akilio’s compact adaptive experience: it
|
|
79
|
+
appears as an icon, expands once with a page-aware invitation, then stays quiet.
|
|
80
|
+
It can show a single answer-ready signal when a response completes while chat is
|
|
81
|
+
closed. Discovery and dismissal are remembered per project, and motion is
|
|
82
|
+
automatically reduced for visitors who request it.
|
|
83
|
+
|
|
84
|
+
Use the original persistent label while validating the new experience:
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
<AkilioWidget launcherExperience='static' />
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Standalone scripts use `data-launcher-experience="static"`.
|
|
91
|
+
|
|
79
92
|
## Page-end contextual prompt
|
|
80
93
|
|
|
81
94
|
Documentation pages can show a compact “Ask about this page” input when the
|
|
@@ -181,11 +194,7 @@ and is dismissed when the visitor closes it, opens the widget, or presses
|
|
|
181
194
|
Escape. Dismissal is stored per project and tour version.
|
|
182
195
|
|
|
183
196
|
```tsx
|
|
184
|
-
<AkilioWidget
|
|
185
|
-
enableTour
|
|
186
|
-
tourDelayMs={3000}
|
|
187
|
-
tourVersion="v1"
|
|
188
|
-
/>
|
|
197
|
+
<AkilioWidget enableTour tourDelayMs={3000} tourVersion='v1' />
|
|
189
198
|
```
|
|
190
199
|
|
|
191
200
|
Standalone attributes are `data-enable-tour`, `data-tour-delay-ms`, and
|
|
@@ -203,12 +212,14 @@ preferences.
|
|
|
203
212
|
## Capability-driven chat actions
|
|
204
213
|
|
|
205
214
|
The widget reads `capabilities.chat` from the public project configuration. An
|
|
206
|
-
enabled `summarize_page` intent that supports the `widget` surface is shown
|
|
207
|
-
an
|
|
208
|
-
available. Selecting it sends `intent: "summarize_page"` and the current
|
|
209
|
-
context to the chat endpoint. Unsupported, disabled, wrong-surface, or
|
|
210
|
-
unmet-requirement actions are not displayed.
|
|
211
|
-
|
|
215
|
+
enabled `summarize_page` intent that supports the `widget` surface is shown in
|
|
216
|
+
an action tray immediately above the composer when its `page.url` requirement
|
|
217
|
+
is available. Selecting it sends `intent: "summarize_page"` and the current
|
|
218
|
+
page context to the chat endpoint. Unsupported, disabled, wrong-surface, or
|
|
219
|
+
unmet-requirement actions are not displayed. The action tray remains available
|
|
220
|
+
throughout the conversation and is temporarily hidden while a response streams.
|
|
221
|
+
Older API responses without the capability catalog retain the previous
|
|
222
|
+
suggestion behavior.
|
|
212
223
|
|
|
213
224
|
An enabled `contact` intent adds a “Contact the team” action. Contact responses
|
|
214
225
|
can display validated `email`, `phone`, and `form` links from `contact_options`.
|
|
@@ -245,7 +256,11 @@ dist/index.min.js
|
|
|
245
256
|
dist/index.umd.min.cjs
|
|
246
257
|
dist/index.d.ts
|
|
247
258
|
dist/style.css
|
|
259
|
+
dist/loader.js
|
|
260
|
+
dist/widget-manifest.json
|
|
261
|
+
dist/releases/0.7.0/akilio-widget.min.js
|
|
248
262
|
dist/akilio-widget.min.js
|
|
263
|
+
dist/_headers
|
|
249
264
|
```
|
|
250
265
|
|
|
251
266
|
## React
|
|
@@ -315,10 +330,13 @@ The token resolver is evaluated for every request, so a host application can rot
|
|
|
315
330
|
|
|
316
331
|
## Standalone script
|
|
317
332
|
|
|
333
|
+
For production websites, use the stable loader URL:
|
|
334
|
+
|
|
318
335
|
```html
|
|
319
336
|
<script
|
|
320
337
|
data-akilio-widget
|
|
321
|
-
|
|
338
|
+
data-cfasync="false"
|
|
339
|
+
src="https://cdn.example.com/widget/loader.js"
|
|
322
340
|
data-api-base-url="https://api.akilio-ai.com"
|
|
323
341
|
data-project-key="ask_pk_xxx"
|
|
324
342
|
data-mode="floating"
|
|
@@ -334,19 +352,76 @@ For an inline widget:
|
|
|
334
352
|
|
|
335
353
|
```html
|
|
336
354
|
<div id="support-assistant" style="height: 680px"></div>
|
|
337
|
-
<script
|
|
355
|
+
<script
|
|
356
|
+
src="https://cdn.example.com/widget/loader.js"
|
|
357
|
+
data-akilio-widget
|
|
358
|
+
data-auto-init="false"
|
|
359
|
+
></script>
|
|
338
360
|
<script>
|
|
339
|
-
window.
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
361
|
+
window.addEventListener('akilio:loader-ready', () => {
|
|
362
|
+
window.Akilio.mount({
|
|
363
|
+
target: '#support-assistant',
|
|
364
|
+
apiBaseUrl: 'https://api.akilio-ai.com',
|
|
365
|
+
projectKey: 'ask_pk_xxx',
|
|
366
|
+
mode: 'inline',
|
|
367
|
+
colorMode: 'system',
|
|
368
|
+
accessToken: 'short-lived-widget-token',
|
|
369
|
+
});
|
|
346
370
|
});
|
|
347
371
|
</script>
|
|
348
372
|
```
|
|
349
373
|
|
|
374
|
+
`loader.js` is revalidated by the browser and loads the immutable release file
|
|
375
|
+
for the current package version. Deploy the complete `dist` directory without
|
|
376
|
+
deleting earlier `dist/releases/*` versions. Each build also keeps
|
|
377
|
+
`akilio-widget.min.js` as a non-immutable compatibility file.
|
|
378
|
+
|
|
379
|
+
For optional Cloudflare Pages deployments, the generated `dist/_headers` requires browser and edge
|
|
380
|
+
revalidation for `loader.js` and `widget-manifest.json`. Files under
|
|
381
|
+
`releases/*` receive a one-year immutable browser and edge cache. Configure
|
|
382
|
+
Cloudflare Browser Cache TTL to **Respect Existing Headers** for this path so a
|
|
383
|
+
cache rule does not keep the loader stale.
|
|
384
|
+
|
|
385
|
+
Cloudflare R2 does not use `_headers`; the R2 deployment command writes the
|
|
386
|
+
equivalent `Cache-Control` metadata on each uploaded object.
|
|
387
|
+
|
|
388
|
+
Publishing a new package version updates only the loader and manifest pointers;
|
|
389
|
+
existing embed snippets do not change and a manual cache purge is not normally
|
|
390
|
+
required. The manifest includes the active version, release path, byte size,
|
|
391
|
+
and SHA-256 digest for deployment verification.
|
|
392
|
+
|
|
393
|
+
### Deploy to Cloudflare R2
|
|
394
|
+
|
|
395
|
+
Set the R2 bucket name in your local `.env` or shell environment:
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
CLOUDFLARE_R2_BUCKET=your-r2-bucket
|
|
399
|
+
# Optional folder within the bucket:
|
|
400
|
+
CLOUDFLARE_R2_PREFIX=widget
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Then validate, build, and publish the CDN assets with:
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
npm run deploy:r2
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
You can also provide the target without storing it in `.env`:
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
npm run deploy:r2 -- --bucket your-r2-bucket --prefix widget
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Wrangler uses an existing local Cloudflare login. In CI, provide
|
|
416
|
+
`CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` as protected environment
|
|
417
|
+
variables. Never commit a Cloudflare API token.
|
|
418
|
+
|
|
419
|
+
The deploy command uploads the immutable versioned bundle first, followed by
|
|
420
|
+
the compatibility bundle, manifest, and finally `loader.js`. The versioned file
|
|
421
|
+
receives a one-year immutable cache policy. Stable files receive
|
|
422
|
+
`max-age=0, must-revalidate`, so the CDN entry point can discover each release.
|
|
423
|
+
Add `--dry-run` to build and inspect the target object paths without uploading.
|
|
424
|
+
|
|
350
425
|
The standalone API can hide the launcher and control the chat imperatively:
|
|
351
426
|
|
|
352
427
|
```js
|
|
@@ -476,7 +551,10 @@ The package itself is now safe to import in an SSR module. The component must st
|
|
|
476
551
|
|
|
477
552
|
## Ecommerce responses
|
|
478
553
|
|
|
479
|
-
When the chat API returns a `commerce` capability, the widget
|
|
554
|
+
When the chat API returns a `commerce` capability, the widget renders a compact
|
|
555
|
+
commerce surface inside the assistant message. Direct matches, recommendations,
|
|
556
|
+
comparisons, compatible products, bundles, upsells, and cross-sells receive
|
|
557
|
+
capability-aware headings and layouts.
|
|
480
558
|
|
|
481
559
|
```tsx
|
|
482
560
|
<AkilioWidget
|
|
@@ -488,7 +566,42 @@ When the chat API returns a `commerce` capability, the widget automatically disp
|
|
|
488
566
|
/>
|
|
489
567
|
```
|
|
490
568
|
|
|
491
|
-
Product links open
|
|
569
|
+
Product links open through the existing product callback. Trusted
|
|
570
|
+
`commerce.actions` are matched only to products returned in the same response.
|
|
571
|
+
`add_to_cart` proposals require a second explicit confirmation, then use the
|
|
572
|
+
backend's one-time capability-confirmation flow and an idempotency key before a
|
|
573
|
+
cart tool is executed. The provider cart ID is retained in `sessionStorage` for
|
|
574
|
+
subsequent additions during the same browser session. The widget also records
|
|
575
|
+
authenticated commerce events.
|
|
576
|
+
|
|
577
|
+
The widget refreshes `GET /commerce/cart/current/` whenever its chat panel is
|
|
578
|
+
opened. The header cart control shows the returned line items and only exposes a
|
|
579
|
+
checkout link supplied by the backend. A chat response with `cart_state` causes
|
|
580
|
+
an immediate refresh, ensuring the local cart display follows server-side cart
|
|
581
|
+
changes without treating the compact summary as the source of truth.
|
|
582
|
+
|
|
583
|
+
### `/chat/` response contract
|
|
584
|
+
|
|
585
|
+
`AkilioChatResponse` follows the public OpenAPI `ChatResponse` schema. It
|
|
586
|
+
supports documented conversation context, answer content, citations, commerce,
|
|
587
|
+
suggestions, warnings, market resolution, grounding/refusal flags, escalation,
|
|
588
|
+
contact options, customer actions, agent tools, and intent decisions. Commerce
|
|
589
|
+
products and actions are runtime-validated before they are rendered because the
|
|
590
|
+
OpenAPI schema deliberately leaves those objects extensible.
|
|
591
|
+
|
|
592
|
+
The documented response does not include top-level `images`, `rich_actions`,
|
|
593
|
+
`forms`, or `cart` fields. The widget does not treat those fields as part of its
|
|
594
|
+
public chat contract. Add them to the backend OpenAPI schema before introducing
|
|
595
|
+
matching widget rendering.
|
|
596
|
+
|
|
597
|
+
## Human handoff
|
|
598
|
+
|
|
599
|
+
When a configured contact action is submitted, the widget sends its consented
|
|
600
|
+
request to `POST /chat/contact-requests/` with the conversation and assistant
|
|
601
|
+
message that offered the action. `POST /chat/handoffs/` is an equivalent backend
|
|
602
|
+
alias. The backend derives the conversation summary, intent, customer context,
|
|
603
|
+
and action context from the validated conversation. The widget renders the
|
|
604
|
+
browser-safe handoff delivery status returned by the API.
|
|
492
605
|
|
|
493
606
|
## Assistant mode
|
|
494
607
|
|
|
@@ -519,3 +632,195 @@ For the standalone build:
|
|
|
519
632
|
## Follow-up suggestions
|
|
520
633
|
|
|
521
634
|
When `/api/v1/chat/` returns a `suggestions` array, the widget displays accessible suggestion chips under that assistant response. Selecting a chip sends it as the next user message. Suggestions are retained in local history and restored from server conversation message metadata or structured content when supplied by the API.
|
|
635
|
+
|
|
636
|
+
## Widget Core (AKI-WIDGET-001)
|
|
637
|
+
|
|
638
|
+
Built-in interface translations cover English and French (including regional
|
|
639
|
+
locales such as `fr-CA`). Supply `locale` and `copy` for other languages; missing
|
|
640
|
+
translations fall back to English. The widget sets its language and direction
|
|
641
|
+
for common right-to-left locales. The standalone script reads the page language.
|
|
642
|
+
The backend receives the requested locale for generated responses.
|
|
643
|
+
|
|
644
|
+
White-label policy hides Akilio marks in the launcher, discovery tip, header,
|
|
645
|
+
messages, and confirmation cards. Default text becomes neutral; explicitly
|
|
646
|
+
configured project titles and copy remain under the integrator's control.
|
|
647
|
+
|
|
648
|
+
History, preferences, configuration, and anonymous continuation credentials use
|
|
649
|
+
browser storage with an in-memory fallback when storage is blocked or full.
|
|
650
|
+
Persistent storage is required to resume after a full page reload; memory-only
|
|
651
|
+
sessions remain usable during the current visit. History is scoped by project
|
|
652
|
+
and locale and retains the latest 60 messages.
|
|
653
|
+
|
|
654
|
+
Mobile forms use 16px inputs and main controls have 44px touch targets, alongside
|
|
655
|
+
viewport sizing and safe-area padding. Physical-device keyboard testing and live
|
|
656
|
+
backend acceptance testing are still required before production sign-off.
|
|
657
|
+
|
|
658
|
+
## Adding languages
|
|
659
|
+
|
|
660
|
+
Translations live in `src/locales/en.ts` and `src/locales/fr.ts`. To ship a new
|
|
661
|
+
built-in language:
|
|
662
|
+
|
|
663
|
+
1. Copy `en.ts` to a new file such as `es.ts` and rename the export to `es`.
|
|
664
|
+
2. Translate every message, the starter questions, and the `whiteLabel` wording.
|
|
665
|
+
Preserve placeholders such as `{seconds}`. Set `direction` to `ltr` or `rtl`.
|
|
666
|
+
3. Import the pack in `src/locales/index.ts` and add it to `builtInLanguages`.
|
|
667
|
+
4. Run `npm run typecheck`, `npm test`, and `npm run build`.
|
|
668
|
+
|
|
669
|
+
Each complete pack uses `satisfies AkilioLanguagePack`, so missing translation
|
|
670
|
+
keys are reported by TypeScript when the interface grows.
|
|
671
|
+
|
|
672
|
+
You can also add languages without rebuilding the widget using the `translations`
|
|
673
|
+
option. Partial packs are supported; untranslated text falls back to English:
|
|
674
|
+
|
|
675
|
+
```tsx
|
|
676
|
+
import type { AkilioTranslations } from '@hachther/akilio-widget';
|
|
677
|
+
|
|
678
|
+
const translations = {
|
|
679
|
+
es: {
|
|
680
|
+
direction: 'ltr',
|
|
681
|
+
messages: {
|
|
682
|
+
title: 'Asistente',
|
|
683
|
+
launcher: 'Hacer una pregunta',
|
|
684
|
+
submit: 'Enviar',
|
|
685
|
+
placeholder: 'Escribe tu pregunta...',
|
|
686
|
+
suggestions: ['¿Cómo puedo contactar con el equipo?'],
|
|
687
|
+
},
|
|
688
|
+
whiteLabel: {
|
|
689
|
+
title: 'Asistente',
|
|
690
|
+
launcher: 'Hacer una pregunta',
|
|
691
|
+
configFailed: 'No se puede cargar la configuración.',
|
|
692
|
+
},
|
|
693
|
+
},
|
|
694
|
+
} satisfies AkilioTranslations;
|
|
695
|
+
|
|
696
|
+
<AkilioWidget
|
|
697
|
+
projectKey='your-project-key'
|
|
698
|
+
locale='es-MX'
|
|
699
|
+
translations={translations}
|
|
700
|
+
/>;
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
The same dictionary works with `window.Akilio.mount({ projectKey: 'your-project-key',
|
|
704
|
+
locale: 'es-MX', translations })`. For script integrations, use programmatic mounting
|
|
705
|
+
with auto-init disabled when supplying dictionaries.
|
|
706
|
+
|
|
707
|
+
Locale matching ignores case and accepts underscores. The fallback order is the
|
|
708
|
+
most specific locale, then its parent language/script, then English. For example,
|
|
709
|
+
`zh-Hant-TW` inherits from `zh-Hant`, `zh`, and `en`. Custom dictionaries override
|
|
710
|
+
built-ins at the same locale. Existing project title, placeholder, and starter
|
|
711
|
+
questions still take precedence; the `copy` prop remains the final text override.
|
|
712
|
+
White-label wording is stored separately from branded defaults. Dictionaries are
|
|
713
|
+
scoped to each widget, so one integration cannot change another's translations.
|
|
714
|
+
|
|
715
|
+
Changing `locale` or `translations` props updates React UI copy. The requested
|
|
716
|
+
locale is still sent to the backend; adding UI translations does not configure
|
|
717
|
+
backend response languages. This framework uses plain text messages and existing
|
|
718
|
+
named placeholders, not ICU plural rules.
|
|
719
|
+
|
|
720
|
+
## Business branding (AKI-WIDGET-002)
|
|
721
|
+
|
|
722
|
+
```tsx
|
|
723
|
+
<AkilioWidget
|
|
724
|
+
projectKey='your-project-key'
|
|
725
|
+
agentName='Alex'
|
|
726
|
+
welcomeMessage='Welcome to Acme. How can I help?'
|
|
727
|
+
starterPrompts={['Explore our services', 'Contact the team']}
|
|
728
|
+
launcherPosition='bottom-left'
|
|
729
|
+
theme={{
|
|
730
|
+
logo_url: 'https://example.com/logo.png',
|
|
731
|
+
brand_name: 'Acme',
|
|
732
|
+
primary_color: '#123456',
|
|
733
|
+
primary_dark_color: '#102030',
|
|
734
|
+
primary_foreground_color: '#ffffff',
|
|
735
|
+
}}
|
|
736
|
+
/>
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
Business logos appear in the launcher, discovery tip, header, empty state,
|
|
740
|
+
assistant answers, and human-help confirmation cards. HTTP(S) and relative image
|
|
741
|
+
URLs are accepted. Failed or invalid images fall back to the Akilio mark when
|
|
742
|
+
branding is enabled, or a neutral icon when branding is hidden. Required
|
|
743
|
+
“Powered by Akilio” attribution remains visible with a business logo.
|
|
744
|
+
|
|
745
|
+
Name priority: `copy.title`, `agentName`, host `theme.brand_name`, server
|
|
746
|
+
`theme_config.brand_name`, server `title`, then language defaults. Welcome text
|
|
747
|
+
uses `copy.emptyState`, `welcomeMessage`, server `welcome_message`, then language
|
|
748
|
+
defaults. The welcome message appears before the first conversation message.
|
|
749
|
+
|
|
750
|
+
Before configuration arrives, starter prompts use `starterPrompts` and then
|
|
751
|
+
language suggestions. Once available, `starter_questions` from the public
|
|
752
|
+
configuration endpoint is authoritative, including an explicit empty array that
|
|
753
|
+
hides prompts. Up to four are shown; server-advertised capability actions remain
|
|
754
|
+
independent of starter prompts.
|
|
755
|
+
|
|
756
|
+
Standalone embeds accept the same options via `Akilio.mount()` or these attributes:
|
|
757
|
+
|
|
758
|
+
```html
|
|
759
|
+
<script
|
|
760
|
+
src="https://your-cdn.example/widget/loader.js"
|
|
761
|
+
data-akilio-widget
|
|
762
|
+
data-project-key="your-project-key"
|
|
763
|
+
data-agent-name="Alex"
|
|
764
|
+
data-brand-name="Acme"
|
|
765
|
+
data-logo-url="https://example.com/logo.png"
|
|
766
|
+
data-welcome-message="Welcome to Acme. How can I help?"
|
|
767
|
+
data-starter-prompts='["Explore our services", "Contact the team"]'
|
|
768
|
+
data-theme='{"primary_color":"#123456"}'
|
|
769
|
+
data-launcher-position="bottom-left"
|
|
770
|
+
></script>
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
Use `data-starter-prompts='[]'` to hide prompts. Dedicated logo/name attributes
|
|
774
|
+
override corresponding values in `data-theme`. Malformed prompt JSON falls back
|
|
775
|
+
to configuration defaults. Custom React launchers and external HTML buttons using
|
|
776
|
+
`launcher: 'hidden'` with `open()`, `close()`, or `toggle()` remain supported.
|
|
777
|
+
### Direct product-card cart actions
|
|
778
|
+
|
|
779
|
+
Product cards and product details expose Add to cart automatically when backend
|
|
780
|
+
capability discovery includes executable `commerce.add_to_cart`. Available
|
|
781
|
+
variants receive direct actions independent of the LLM response. Clicking the
|
|
782
|
+
button supplies consent; backend capability confirmation is still executed.
|
|
783
|
+
Shopify products on their own storefront use the Shopify adapter. The selected variant is added through
|
|
784
|
+
the Shopify Ajax Cart API, sharing the website's browser cart, without a chat or
|
|
785
|
+
LLM round trip. Cards retain their variant selector, display update feedback,
|
|
786
|
+
and link to the storefront cart after success. Themes can listen for the
|
|
787
|
+
`akilio:cart-updated` window event to refresh their cart counter or drawer.
|
|
788
|
+
|
|
789
|
+
The backend product payload supplies `cart_provider: "shopify"` to select the
|
|
790
|
+
native adapter when applicable. Other products execute the advertised backend
|
|
791
|
+
cart capability. Actions are hidden for unavailable products and blocked
|
|
792
|
+
business-rule decisions. A backend-managed cart does not necessarily share the
|
|
793
|
+
website browser cart; direct website-cart adapters beyond Shopify are not implemented.
|
|
794
|
+
|
|
795
|
+
### Voice messages
|
|
796
|
+
|
|
797
|
+
The composer now supports recording, playback preview, send, and cancel on browsers
|
|
798
|
+
with MediaRecorder and microphone permission. HTTPS (or supported localhost access)
|
|
799
|
+
is required. Recording is capped at five minutes and 10 MiB. EN/FR copy can be
|
|
800
|
+
overridden through the existing translation/copy configuration.
|
|
801
|
+
|
|
802
|
+
Sending uploads to the authenticated public chat voice endpoint, polls private
|
|
803
|
+
transcription status, then submits the transcript through normal chat. The backend
|
|
804
|
+
must include the shared voice migrations and a transcription worker (or the existing
|
|
805
|
+
explicit development synchronous-processing mode). Voice input produces text replies;
|
|
806
|
+
this does not enable synthesized voice responses.
|
|
807
|
+
|
|
808
|
+
Voice uploads and polling use the existing widget bearer-token/origin mechanism.
|
|
809
|
+
Microphone capture stops when the panel closes or consent becomes unavailable.
|
|
810
|
+
Update your distributed bundle to make these controls available in deployed widgets.
|
|
811
|
+
|
|
812
|
+
### Email verification
|
|
813
|
+
|
|
814
|
+
Once a conversation exists, the widget offers **Verify your email** above the composer. The inline form requests an email code, displays the server's masked email, confirms the code, and restores the verified badge from the conversation's server session. It supports resend cooldowns, expiry, cancellation, retry limits, unavailable providers, and English/French copy overrides (`identity*` keys).
|
|
815
|
+
|
|
816
|
+
Verification uses the dedicated `/customer-identity/verifications/`, `/{id}/confirm/`, `/{id}/resend/`, and `/customer-identity/session/` routes under `apiBaseUrl`, with the existing widget authentication. Codes are submitted directly as strings and cleared from the input; they are never chat messages or widget analytics events. Challenge IDs and pending questions are held only in memory. The server determines verification and authorization.
|
|
817
|
+
|
|
818
|
+
A chat response (including a streaming final response) may include `identity_verification_required: { methods: ['email'], purpose: 'identity' }` (`step_up` is also supported). This opens the form. On successful confirmation and an authoritative session lookup, the widget submits the paused question once in the same conversation without duplicating the user's chat bubble. Cancel or a new question discards that continuation. This is a new optional response contract; the backend must emit it when protected actions require verification. It does not itself enforce access to protected actions.
|
|
819
|
+
|
|
820
|
+
The actual verification provider remains a backend integration. Until that provider is configured, delivery returns an unavailable message. No eSauti calls or credentials are implemented in the widget.
|
|
821
|
+
|
|
822
|
+
### Multiple widget installations
|
|
823
|
+
|
|
824
|
+
Create installations in Portal → Widget. Each has its own public key, assigned Agent, appearance and allowed domains. Use `widgetKey` with the React component or `data-widget-key` on the script tag. The existing `projectKey` / `data-project-key` spelling remains supported. Keys identify installations; the workspace remains the tenant boundary. New conversations use the assigned Agent, while existing conversations retain their original Agent.
|
|
825
|
+
|
|
826
|
+
Managed installations: omit host text/theme and presentation props to follow published Agent text and widget appearance. Public configuration supplies layout, launcher, tour, sound and contextual-prompt options; explicit host props still take precedence. Existing embeds with inline overrides must remove those overrides or replace their snippet once to follow portal publications.
|
package/dist/_headers
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Cloudflare Pages response headers
|
|
2
|
+
/loader.js
|
|
3
|
+
Cache-Control: public, max-age=0, must-revalidate
|
|
4
|
+
Cloudflare-CDN-Cache-Control: no-cache
|
|
5
|
+
|
|
6
|
+
/widget-manifest.json
|
|
7
|
+
Cache-Control: public, max-age=0, must-revalidate
|
|
8
|
+
Cloudflare-CDN-Cache-Control: no-cache
|
|
9
|
+
|
|
10
|
+
/akilio-widget.min.js
|
|
11
|
+
Cache-Control: public, max-age=0, must-revalidate
|
|
12
|
+
Cloudflare-CDN-Cache-Control: no-cache
|
|
13
|
+
|
|
14
|
+
/releases/*
|
|
15
|
+
Cache-Control: public, max-age=31536000, immutable
|
|
16
|
+
Cloudflare-CDN-Cache-Control: public, max-age=31536000, immutable
|