@hachther/akilio-widget 1.0.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/dist/style.css CHANGED
@@ -1484,7 +1484,7 @@
1484
1484
  border: 0;
1485
1485
  border-radius: 999px;
1486
1486
  background: var(--akilio-primary);
1487
- color: #fff;
1487
+ color: #fff !important;
1488
1488
  cursor: pointer;
1489
1489
  padding: 0;
1490
1490
  transition:
@@ -2022,6 +2022,8 @@
2022
2022
  min-height: 480px;
2023
2023
  }
2024
2024
  .akilio-panel--inline {
2025
+ width: 100%;
2026
+ height: 100%;
2025
2027
  min-height: 480px;
2026
2028
  border-radius: 16px;
2027
2029
  }
@@ -2893,7 +2895,7 @@
2893
2895
  background: transparent;
2894
2896
  color: var(--akilio-primary);
2895
2897
  padding: 2px 6px;
2896
- font-size: 9px;
2898
+ font-size: 9px !important;
2897
2899
  font-weight: 750;
2898
2900
  text-decoration: none;
2899
2901
  cursor: pointer;
@@ -3437,7 +3439,19 @@
3437
3439
  .akilio-product-variants > div {
3438
3440
  display: flex;
3439
3441
  flex-wrap: wrap;
3440
- gap: 6px;
3442
+ gap: 4px;
3443
+ }
3444
+
3445
+ .akilio-product-variants legend {
3446
+ position: absolute;
3447
+ width: 1px;
3448
+ height: 1px;
3449
+ padding: 0;
3450
+ margin: -1px;
3451
+ overflow: hidden;
3452
+ clip-path: inset(50%);
3453
+ white-space: nowrap;
3454
+ border: 0;
3441
3455
  }
3442
3456
 
3443
3457
  .akilio-product-variant-option {
@@ -3446,9 +3460,14 @@
3446
3460
  background: #fff;
3447
3461
  color: #334155;
3448
3462
  cursor: pointer;
3449
- padding: 4px 8px;
3463
+ padding: 2px 6px !important;
3450
3464
  font: inherit;
3451
- font-size: 11px;
3465
+ font-size: 11px !important;
3466
+ line-height: 1.4 !important;
3467
+ max-width: 100%;
3468
+ overflow: hidden;
3469
+ text-overflow: ellipsis;
3470
+ white-space: nowrap;
3452
3471
  }
3453
3472
 
3454
3473
  .akilio-product-variant-option--selected {
@@ -3457,6 +3476,24 @@
3457
3476
  color: var(--akilio-primary);
3458
3477
  }
3459
3478
 
3479
+ .akilio-product-variant-option:focus-visible,
3480
+ .akilio-product-variant-select:focus-visible {
3481
+ outline: 2px solid var(--akilio-primary);
3482
+ outline-offset: 2px;
3483
+ }
3484
+
3485
+ .akilio-product-variant-select {
3486
+ width: 100%;
3487
+ max-width: 100%;
3488
+ padding: 8px;
3489
+ border: 1px solid #cbd5e1;
3490
+ border-radius: 8px;
3491
+ background: transparent;
3492
+ color: inherit;
3493
+ font: inherit;
3494
+ font-size: 12px;
3495
+ }
3496
+
3460
3497
  .akilio-product-variant-option:disabled {
3461
3498
  opacity: 0.45;
3462
3499
  cursor: not-allowed;
@@ -3961,3 +3998,71 @@
3961
3998
  width: 30px !important;
3962
3999
  height: 30px !important;
3963
4000
  }
4001
+
4002
+ .akilio-voice-input {
4003
+ display: flex;
4004
+ align-items: center;
4005
+ gap: 8px;
4006
+ flex: 1;
4007
+ min-width: 0;
4008
+ min-height: 48px;
4009
+ font-size: 12px;
4010
+ color: inherit;
4011
+ }
4012
+ .akilio-voice-input [role='status'] { flex: 1; }
4013
+ .akilio-voice-input audio { width: 100%; min-width: 0; height: 36px; }
4014
+ .akilio-voice-dot { width: 8px; height: 8px; border-radius: 50%; background: #ef4444; flex-shrink: 0; }
4015
+ .akilio-voice-dot--waiting { background: var(--akilio-primary); }
4016
+ .akilio-voice-duration { font-variant-numeric: tabular-nums; }
4017
+ .akilio-voice-error { padding: 6px 12px; font-size: 12px; }
4018
+ .akilio-composer-box { align-items: center; }
4019
+ .akilio-composer textarea { min-width: 0; }
4020
+ .akilio-composer-submit:focus-visible { outline: 2px solid var(--akilio-primary); outline-offset: 3px; }
4021
+
4022
+
4023
+ /* Customer verification uses the host theme without interrupting the conversation. */
4024
+ .akilio-identity-card {
4025
+ margin: 8px 14px 4px;
4026
+ padding: 18px;
4027
+ border: 1px solid color-mix(in srgb, currentColor 12%, transparent);
4028
+ border-radius: 16px;
4029
+ background: color-mix(in srgb, var(--akilio-primary) 4%, transparent);
4030
+ color: inherit;
4031
+ flex-shrink: 0;
4032
+ max-height: 56vh;
4033
+ overflow: auto;
4034
+ }
4035
+ .akilio-identity-heading { display: flex; align-items: flex-start; gap: 12px; }
4036
+ .akilio-identity-icon { display: grid; place-items: center; width: 36px; height: 36px; flex-shrink: 0; border-radius: 11px; color: var(--akilio-primary); background: color-mix(in srgb, var(--akilio-primary) 12%, transparent); }
4037
+ .akilio-identity-card h3 { margin: 0; font-size: 14px; font-weight: 650; line-height: 1.5; }
4038
+ .akilio-identity-description, .akilio-identity-hint { margin: 4px 0 0; font-size: 12px; line-height: 1.6; color: color-mix(in srgb, currentColor 75%, transparent); }
4039
+ .akilio-identity-card form { display: grid; gap: 8px; margin: 16px 0 0; }
4040
+ .akilio-identity-card label { font-size: 12px; font-weight: 600; }
4041
+ .akilio-identity-card input { width: 100%; min-width: 0; box-sizing: border-box; padding: 12px 14px; border: 1px solid color-mix(in srgb, currentColor 25%, transparent); border-radius: 10px; font: inherit; font-size: 16px; color: inherit; background: color-mix(in srgb, currentColor 3%, transparent); transition: border-color .15s ease, box-shadow .15s ease; }
4042
+ .akilio-identity-card input::placeholder { color: color-mix(in srgb, currentColor 50%, transparent); }
4043
+ .akilio-identity-card input:focus { border-color: var(--akilio-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--akilio-primary) 15%, transparent); }
4044
+ .akilio-identity-card input.akilio-identity-code { font-variant-numeric: tabular-nums; letter-spacing: .18em; }
4045
+ .akilio-identity-card button { cursor: pointer; font: inherit; }
4046
+ .akilio-root .akilio-identity-primary, .akilio-identity-primary { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; min-height: 44px; margin-top: 4px; padding: 10px 14px; border: 0; border-radius: 10px; font-size: 13px; font-weight: 600; background: var(--akilio-primary); color: var(--akilio-primary-foreground); transition: background .15s ease; }
4047
+ .akilio-identity-primary:hover:not(:disabled) { background: var(--akilio-primary-hover); }
4048
+ .akilio-identity-card button:disabled { opacity: .55; cursor: default; }
4049
+ .akilio-identity-actions { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 4px 12px; margin-top: 10px; }
4050
+ .akilio-identity-link, .akilio-identity-dismiss { padding: 8px 0; border: 0; background: transparent; color: inherit; font-size: 12px !important; text-underline-offset: 3px; }
4051
+ .akilio-identity-link:hover:not(:disabled), .akilio-identity-dismiss:hover { text-decoration: underline; }
4052
+ .akilio-identity-dismiss { display: block; margin: 8px auto -4px; color: color-mix(in srgb, currentColor 75%, transparent); }
4053
+ .akilio-identity-card :focus-visible, .akilio-identity-entry :focus-visible { outline: 2px solid var(--akilio-primary); outline-offset: 3px; }
4054
+ .akilio-identity-delivery { margin: 14px 0 0; font-size: 13px; line-height: 1.6; overflow-wrap: anywhere; }
4055
+ .akilio-identity-notice { margin: 12px 0 0; padding: 10px 12px; border-radius: 10px; background: color-mix(in srgb, currentColor 6%, transparent); font-size: 12px; line-height: 1.6; }
4056
+ .akilio-identity-entry { padding: 4px 16px; }
4057
+ .akilio-identity-entry button { display: flex; align-items: center; gap: 8px; padding: 8px 0; border: 0; background: transparent; color: inherit; font-size: 12px; cursor: pointer; }
4058
+ .akilio-identity-entry svg, .akilio-identity-status svg { width: 16px; height: 16px; flex-shrink: 0; }
4059
+ .akilio-identity-chevron { font-size: 18px; opacity: .6; }
4060
+ .akilio-identity-status { display: flex; align-items: center; gap: 7px; padding: 8px 16px; font-size: 12px; color: inherit; }
4061
+ .akilio-identity-spinner { width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: akilio-identity-spin .8s linear infinite; }
4062
+ @keyframes akilio-identity-spin { to { transform: rotate(360deg); } }
4063
+ @media (prefers-reduced-motion: reduce) { .akilio-identity-spinner { animation: none; } .akilio-identity-card input, .akilio-identity-primary { transition: none; } }
4064
+ @media (max-width: 380px) { .akilio-identity-card { margin-inline: 10px; padding: 14px; } }
4065
+
4066
+ .akilio-identity-methods { display: flex; gap: 4px; padding: 4px; margin-top: 14px; border-radius: 10px; background: color-mix(in srgb, currentColor 6%, transparent); }
4067
+ .akilio-identity-methods button { flex: 1; padding: 8px; border: 1px solid transparent; border-radius: 7px; background: transparent; color: inherit; font-size: 12px; }
4068
+ .akilio-identity-methods button[aria-pressed='true'] { border-color: color-mix(in srgb, var(--akilio-primary) 40%, transparent); background: color-mix(in srgb, var(--akilio-primary) 10%, transparent); }
package/dist/types.d.ts CHANGED
@@ -60,6 +60,40 @@ export interface AkilioThemeConfig {
60
60
  color_mode?: AkilioColorMode;
61
61
  launcher_position?: AkilioLauncherPosition;
62
62
  }
63
+ /** Widget presentation settings persisted by Akilio. Brand identity lives in
64
+ * the business profile; host applications may still use AkilioThemeConfig
65
+ * props for explicit one-off visual overrides. */
66
+ export type AkilioWidgetThemeConfig = Omit<AkilioThemeConfig, 'primary_color' | 'accent_color' | 'logo_url' | 'brand_name'> & {
67
+ widget_mode?: AkilioMode;
68
+ launcher_experience?: 'adaptive' | 'static';
69
+ enable_tour?: boolean;
70
+ tour_delay_ms?: number;
71
+ allow_color_mode_toggle?: boolean;
72
+ enable_response_sound?: boolean;
73
+ response_sound_volume?: number;
74
+ contextual_prompt_enabled?: boolean;
75
+ contextual_prompt_threshold?: number;
76
+ contextual_prompt_placeholder?: string;
77
+ contextual_prompt_dismissible?: boolean;
78
+ };
79
+ export interface AkilioPublicBusinessBrand {
80
+ display_name: string;
81
+ tagline: string;
82
+ logo_url: string;
83
+ primary_color: string;
84
+ secondary_color: string;
85
+ }
86
+ export interface AkilioPublicBusinessProfile {
87
+ name: string;
88
+ description: string;
89
+ website: string;
90
+ industry: string | null;
91
+ brand: AkilioPublicBusinessBrand | null;
92
+ languages: Array<{
93
+ language: string;
94
+ is_default: boolean;
95
+ }>;
96
+ }
63
97
  export interface AkilioPageContext {
64
98
  url?: string;
65
99
  title?: string;
@@ -162,9 +196,7 @@ export interface AkilioProductVariant {
162
196
  compare_at_price?: string | null;
163
197
  currency?: string;
164
198
  inventory_quantity?: number;
165
- options?: {
166
- Size?: string;
167
- };
199
+ options?: Record<string, string>;
168
200
  available: boolean;
169
201
  }
170
202
  export interface AkilioProductAttribute {
@@ -173,6 +205,7 @@ export interface AkilioProductAttribute {
173
205
  value: string;
174
206
  }
175
207
  export interface AkilioProduct {
208
+ cart_provider?: 'shopify' | null;
176
209
  id: string;
177
210
  external_id: string;
178
211
  title: string;
@@ -202,6 +235,8 @@ export interface AkilioCommerceCapability {
202
235
  display?: 'list' | 'detail';
203
236
  }
204
237
  export interface AkilioCommercePublicAction {
238
+ /** Direct storefront action; the customer's button click supplies consent. */
239
+ storefront?: 'shopify';
205
240
  type: AkilioCommerceActionType;
206
241
  product_id?: string;
207
242
  variant_id?: string;
@@ -317,6 +352,7 @@ export interface AkilioCurrentCartResponse {
317
352
  cart: AkilioCart | null;
318
353
  }
319
354
  export interface AkilioProjectConfig {
355
+ identity_verification_methods?: ('email' | 'phone')[];
320
356
  project_key: string;
321
357
  name: string;
322
358
  slug: string;
@@ -324,7 +360,8 @@ export interface AkilioProjectConfig {
324
360
  placeholder: string;
325
361
  starter_questions: string[];
326
362
  welcome_message?: string;
327
- theme_config: AkilioThemeConfig;
363
+ theme_config: AkilioWidgetThemeConfig;
364
+ business_profile?: AkilioPublicBusinessProfile;
328
365
  default_language: string;
329
366
  supported_languages: string[];
330
367
  widget_policy?: AkilioWidgetPolicy;
@@ -429,10 +466,14 @@ export interface AkilioWidgetPolicy {
429
466
  assistant_mode: AkilioAssistantMode;
430
467
  /** Whether product results and commerce events may be used. */
431
468
  commerce_enabled: boolean;
469
+ /** Whether the workspace plan allows voice input. */
470
+ audio_enabled?: boolean;
432
471
  /** Branding treatment the widget must apply. */
433
472
  branding: AkilioWidgetBranding;
434
473
  }
435
474
  export interface AkilioChatRequest {
475
+ external_resume_token?: string;
476
+ voice_transcription_id?: string;
436
477
  project_key: string;
437
478
  conversation_id?: string;
438
479
  context_id?: string;
@@ -489,8 +530,14 @@ export interface AkilioCustomerServiceToolResponse {
489
530
  result: unknown;
490
531
  }
491
532
  export interface AkilioAgentTool {
533
+ resume_token?: string;
492
534
  tool_id: string;
493
535
  requires_confirmation?: boolean;
536
+ confirmation_id?: string;
537
+ error?: string;
538
+ expires_at?: string;
539
+ question?: string;
540
+ entry_context?: AkilioEntryContext;
494
541
  action?: 'confirm_human_request' | 'start_contact_request' | string;
495
542
  payload?: Record<string, unknown>;
496
543
  result?: {
@@ -520,7 +567,7 @@ export interface AkilioClarificationField {
520
567
  }
521
568
  export interface AkilioClarification {
522
569
  question: string;
523
- submission_template: string;
570
+ submission_template?: string | null;
524
571
  reason?: string;
525
572
  missing_entities?: string[];
526
573
  fields?: AkilioClarificationField[];
@@ -530,7 +577,30 @@ export interface AkilioClarificationResponse {
530
577
  source_message_id: string;
531
578
  values: Record<string, string>;
532
579
  }
580
+ export interface AkilioIdentityVerification {
581
+ identifier_type?: 'email' | 'phone';
582
+ verification_id: string;
583
+ status: string;
584
+ masked_identifier: string;
585
+ expires_at: string;
586
+ }
587
+ export interface AkilioIdentitySession {
588
+ authenticated: boolean;
589
+ identity_id: string | null;
590
+ assurance_level: string | null;
591
+ verified_at: string | null;
592
+ expires_at: string | null;
593
+ }
594
+ export interface AkilioIdentityRequirement {
595
+ methods: string[];
596
+ purpose?: 'identity' | 'step_up';
597
+ }
533
598
  export interface AkilioChatResponse {
599
+ external_operation_resume?: {
600
+ token: string;
601
+ question: string;
602
+ };
603
+ identity_verification_required?: AkilioIdentityRequirement;
534
604
  schema_version?: string;
535
605
  conversation_id: string;
536
606
  context_id: string;
@@ -655,6 +725,33 @@ export interface AkilioChatMessage {
655
725
  intentDecision?: AkilioIntentDecision;
656
726
  }
657
727
  export interface AkilioCopyOverrides {
728
+ identityTitle?: string;
729
+ identityEmail?: string;
730
+ identityCode?: string;
731
+ identitySend?: string;
732
+ identityConfirm?: string;
733
+ identityResend?: string;
734
+ identityCancel?: string;
735
+ identitySent?: string;
736
+ identityVerified?: string;
737
+ identityInvalid?: string;
738
+ identityExpired?: string;
739
+ identityUnavailable?: string;
740
+ identityLimited?: string;
741
+ identityChangeEmail?: string;
742
+ identityBusy?: string;
743
+ identityGenericTitle?: string;
744
+ identityPhone?: string;
745
+ identityPhoneHint?: string;
746
+ identityPhoneSent?: string;
747
+ identityPhoneCodeTitle?: string;
748
+ identityPhoneCodeHint?: string;
749
+ identityPhoneVerified?: string;
750
+ identityChangePhone?: string;
751
+ identityCodeTitle?: string;
752
+ identityDescription?: string;
753
+ identityCodeHint?: string;
754
+ identitySending?: string;
658
755
  launcher?: string;
659
756
  title?: string;
660
757
  description?: string;
@@ -707,6 +804,13 @@ export interface AkilioCopyOverrides {
707
804
  humanRequestSuccess?: string;
708
805
  clarificationNeeded?: string;
709
806
  clarificationSubmit?: string;
807
+ recordVoice?: string;
808
+ stopVoice?: string;
809
+ sendVoice?: string;
810
+ cancelVoice?: string;
811
+ voiceTranscribing?: string;
812
+ voiceFailure?: string;
813
+ voicePermissionError?: string;
710
814
  voteUp?: string;
711
815
  voteDown?: string;
712
816
  requestFailed?: string;
@@ -823,7 +927,10 @@ export interface AkilioWidgetProps {
823
927
  /** Initial prompts. An empty list hides prompts; capability actions remain available. */
824
928
  starterPrompts?: string[];
825
929
  apiBaseUrl?: string;
826
- projectKey: string;
930
+ /** Installation public key. */
931
+ widgetKey?: string;
932
+ /** @deprecated Use widgetKey; existing installations remain supported. */
933
+ projectKey?: string;
827
934
  locale?: AkilioLocale;
828
935
  /** Per-widget language dictionaries, also accepted by Akilio.mount(). */
829
936
  translations?: AkilioTranslations;
@@ -889,11 +996,18 @@ export interface AkilioWidgetProps {
889
996
  className?: string;
890
997
  onOpenChange?: (open: boolean) => void;
891
998
  onMessage?: (message: AkilioChatMessage) => void;
999
+ /** Final canonical response for host diagnostics; never changes widget rendering. */
1000
+ onResponse?: (response: AkilioChatResponse) => void;
1001
+ /** Disable cached configuration in authenticated previews that switch versions. */
1002
+ cacheProjectConfig?: boolean;
1003
+ /** Optional host transport; defaults to the browser fetch implementation. */
1004
+ fetchImpl?: typeof fetch;
892
1005
  onProductClick?: (product: AkilioProduct, variant?: AkilioProductVariant) => void;
893
1006
  onError?: (error: Error) => void;
894
1007
  integration?: IntegrationType;
895
1008
  }
896
1009
  export interface ChatPanelProps {
1010
+ identityVerification?: ReactNode;
897
1011
  panelId: string;
898
1012
  open: boolean;
899
1013
  isDesktop: boolean;
@@ -921,10 +1035,12 @@ export interface ChatPanelProps {
921
1035
  onToggleColorMode: () => void;
922
1036
  onClear: () => void;
923
1037
  onSubmit: (query: string) => Promise<AkilioChatResponse>;
1038
+ onVoiceSubmit?: (audio: Blob, signal: AbortSignal) => Promise<void>;
924
1039
  onDraftChange?: (draft: string, manual: boolean) => void;
925
1040
  onFeedback: (message: AkilioChatMessage, rating: AkilioFeedbackRating) => void;
926
1041
  contactRequestCapability?: AkilioContactRequestCapability;
927
1042
  onContactRequest: (request: AkilioContactRequest, actionType: AkilioCustomerActionType) => Promise<AkilioContactRequestResponse>;
1043
+ onConfirmExternalOperation?: (message: AkilioChatMessage, tool: AkilioAgentTool) => Promise<void>;
928
1044
  onConfirmHumanRequest: (message: AkilioChatMessage, tool: AkilioAgentTool, request: AkilioContactRequest) => Promise<void>;
929
1045
  onClarificationSubmit: (message: AkilioChatMessage, values: Record<string, string>, submission: string) => Promise<void>;
930
1046
  onSuggestion: (suggestion: string) => void;
@@ -1,8 +1,8 @@
1
1
  {
2
- "version": "1.0.0",
2
+ "version": "1.1.0",
3
3
  "loader": "loader.js",
4
- "release": "releases/1.0.0/akilio-widget.min.js",
4
+ "release": "releases/1.1.0/akilio-widget.min.js",
5
5
  "compatibility": "akilio-widget.min.js",
6
- "sha256": "acae3bde3798bb1cd6919849048eba27bb1a98bc04c5663cd036cf2625ab75fc",
7
- "size": 719047
6
+ "sha256": "fcb3c58c4477c179e2a2262810c021e09627c344cb1fae2efeeb5a027e96ac84",
7
+ "size": 751685
8
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachther/akilio-widget",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Embeddable React AI assistant widget for Akilio backend.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",