@akropolys/kiku 1.7.16 → 1.7.19
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 +31 -28
- package/dist/index.d.mts +111 -41
- package/dist/index.d.ts +111 -41
- package/dist/index.js +46 -3312
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +46 -3279
- package/dist/index.mjs.map +1 -1
- package/dist/kiku.iife.global.js +107 -0
- package/dist/kiku.iife.global.js.map +1 -0
- package/dist/kiku.iife.js +107 -0
- package/dist/kiku.iife.js.map +1 -0
- package/dist/shopify.global.js +107 -0
- package/dist/shopify.global.js.map +1 -0
- package/dist/shopify.js +107 -0
- package/dist/shopify.js.map +1 -0
- package/dist/styles.css +1 -4047
- package/dist/styles.css.map +1 -1
- package/package.json +68 -68
- package/shopify/README.md +71 -0
- package/shopify/blocks/kiku-button.liquid +121 -0
- package/shopify/snippets/kiku-embed.liquid +45 -0
package/README.md
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
# @akropolys/kiku
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Pre-built, blindly agnostic multi-modal conversational AI widget with duplex Live Voice, Computer Vision, and real-time comparative tables for any website or transactional platform.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@akropolys/kiku) [](https://opensource.org/licenses/MIT) [](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Install
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
```bash
|
|
12
|
+
npm install @akropolys/kiku @akropolys/sdk
|
|
13
|
+
# or
|
|
14
|
+
pnpm add @akropolys/kiku @akropolys/sdk
|
|
15
|
+
```
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Usage (React / Next.js)
|
|
14
20
|
|
|
15
21
|
```tsx
|
|
16
22
|
import { AkropolysProvider } from '@akropolys/sdk';
|
|
@@ -20,41 +26,38 @@ import '@akropolys/kiku/styles.css';
|
|
|
20
26
|
export default function App() {
|
|
21
27
|
return (
|
|
22
28
|
<AkropolysProvider
|
|
23
|
-
siteId={process.env.NEXT_PUBLIC_AKROPOLYS_SITE_ID}
|
|
24
|
-
|
|
29
|
+
siteId={process.env.NEXT_PUBLIC_AKROPOLYS_SITE_ID!}
|
|
30
|
+
apiUrl={process.env.NEXT_PUBLIC_AKROPOLYS_API_URL!}
|
|
31
|
+
apiToken={process.env.NEXT_PUBLIC_AKROPOLYS_API_KEY!}
|
|
25
32
|
>
|
|
26
|
-
<KikuButton
|
|
33
|
+
<KikuButton
|
|
34
|
+
label="Ask me anything"
|
|
35
|
+
enableVoice={true}
|
|
36
|
+
enableVision={true}
|
|
37
|
+
enableAudioResponse={true}
|
|
38
|
+
theme={{
|
|
39
|
+
borderRadius: "24px",
|
|
40
|
+
}}
|
|
41
|
+
/>
|
|
27
42
|
</AkropolysProvider>
|
|
28
43
|
);
|
|
29
44
|
}
|
|
30
45
|
```
|
|
31
46
|
|
|
47
|
+
---
|
|
48
|
+
|
|
32
49
|
## Components
|
|
33
50
|
|
|
34
|
-
| Component |
|
|
51
|
+
| Component | Description |
|
|
35
52
|
|---|---|
|
|
36
|
-
| `<KikuButton />` | Floating
|
|
37
|
-
| `<KikuChat />` |
|
|
38
|
-
| `<
|
|
39
|
-
| `<
|
|
40
|
-
| `<ComparisonMatrix />` | Side-by-side product comparison |
|
|
41
|
-
| `<VoiceButton />` | Speak a query instead of typing it |
|
|
42
|
-
| `<VisualSearch />` | Search by uploading a photo |
|
|
43
|
-
|
|
44
|
-
## Install
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
npm install @akropolys/kiku @akropolys/sdk
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
```ts
|
|
51
|
-
import '@akropolys/kiku/styles.css';
|
|
52
|
-
```
|
|
53
|
+
| `<KikuButton />` | Floating trigger button and full-screen modal with multi-modal voice & vision. |
|
|
54
|
+
| `<KikuChat />` | Embedded inline conversational chat container. |
|
|
55
|
+
| `<VoiceOverlay />` | Duplex live spoken voice assistant with Apple Siri chromatic animation and real-time audio visualization. |
|
|
56
|
+
| `<LiveTable />` | High-precision comparative financial and sports odds table. |
|
|
53
57
|
|
|
54
|
-
[Read the full docs →](https://akropolys.io/docs)
|
|
55
58
|
|
|
56
59
|
---
|
|
57
60
|
|
|
58
61
|
## License
|
|
59
62
|
|
|
60
|
-
MIT © Akropolys
|
|
63
|
+
MIT © [Akropolys](https://akropolys.cloud)
|
package/dist/index.d.mts
CHANGED
|
@@ -4,7 +4,6 @@ import { SearchResult, AkropolysTheme, ChatSource, Product, VisualSearchResponse
|
|
|
4
4
|
interface SearchBarProps {
|
|
5
5
|
placeholder?: string;
|
|
6
6
|
limit?: number;
|
|
7
|
-
/** Debounce in ms — default 150 for instant type-ahead */
|
|
8
7
|
debounceMs?: number;
|
|
9
8
|
onSelect?: (result: SearchResult) => void;
|
|
10
9
|
className?: string;
|
|
@@ -36,17 +35,22 @@ interface ChatWidgetProps {
|
|
|
36
35
|
input?: string;
|
|
37
36
|
};
|
|
38
37
|
onSelectSource?: (source: ChatSource) => void;
|
|
39
|
-
/** Enable 🎙️ voice input via browser Web Speech API (free) */
|
|
40
38
|
enableVoice?: boolean;
|
|
41
|
-
/** Enable 📷 visual style-match search
|
|
39
|
+
/** Enable 📷 visual style-match search */
|
|
42
40
|
enableVision?: boolean;
|
|
43
|
-
/** Optional category hint for visual search (e.g. 'dress', 'curtains') */
|
|
44
41
|
visionCategoryHint?: string;
|
|
42
|
+
/** Enable 🔊 TTS voice audio responses from AI */
|
|
43
|
+
enableAudioResponse?: boolean;
|
|
44
|
+
/** Optional AI voice preset */
|
|
45
|
+
ttsVoice?: string;
|
|
46
|
+
autoSpeakResponses?: boolean;
|
|
45
47
|
}
|
|
46
|
-
declare function ChatWidget({ title, placeholder, emptyStateText, emptyStateSuggestions, defaultCurrency, className, theme, classNames, onSelectSource, enableVoice, enableVision, visionCategoryHint }: ChatWidgetProps): React.JSX.Element;
|
|
48
|
+
declare function ChatWidget({ title, placeholder, emptyStateText, emptyStateSuggestions, defaultCurrency, className, theme, classNames, onSelectSource, enableVoice, enableVision, visionCategoryHint, enableAudioResponse, ttsVoice, autoSpeakResponses }: ChatWidgetProps): React.JSX.Element;
|
|
47
49
|
|
|
48
50
|
interface KikuButtonProps {
|
|
49
|
-
label?:
|
|
51
|
+
label?: React.ReactNode;
|
|
52
|
+
children?: React.ReactNode;
|
|
53
|
+
icon?: React.ReactNode;
|
|
50
54
|
title?: string;
|
|
51
55
|
placeholder?: string;
|
|
52
56
|
backdropColor?: string;
|
|
@@ -63,29 +67,24 @@ interface KikuButtonProps {
|
|
|
63
67
|
input?: string;
|
|
64
68
|
sendButton?: string;
|
|
65
69
|
};
|
|
66
|
-
/** Enable 🎙️ voice input via browser Web Speech API (free) */
|
|
67
70
|
enableVoice?: boolean;
|
|
68
|
-
/** BCP-47 tag for voice transcription (e.g. 'sw-KE', 'fr-FR'). Defaults to
|
|
69
|
-
the page's <html lang>, then the browser language. */
|
|
70
71
|
voiceLang?: string;
|
|
71
|
-
/** Enable 📷 visual style-match search via Gemini (requires backend GEMINI_API_KEY) */
|
|
72
72
|
enableVision?: boolean;
|
|
73
|
-
/** Optional category hint for visual search (e.g. 'dress', 'curtains') */
|
|
74
73
|
visionCategoryHint?: string;
|
|
74
|
+
/** Enable 🔊 TTS voice audio responses from AI */
|
|
75
|
+
enableAudioResponse?: boolean;
|
|
76
|
+
ttsVoice?: string;
|
|
77
|
+
autoSpeakResponses?: boolean;
|
|
75
78
|
}
|
|
76
|
-
declare function KikuButton({ label, title, placeholder, backdropColor, backdropBlur, className, onSelectSource, defaultCurrency, chips, theme, classNames, enableVoice, voiceLang, enableVision, visionCategoryHint, }: KikuButtonProps): React.JSX.Element;
|
|
79
|
+
declare function KikuButton({ label, children, icon, title, placeholder, backdropColor, backdropBlur, className, onSelectSource, defaultCurrency, chips, theme, classNames, enableVoice, voiceLang, enableVision, visionCategoryHint, enableAudioResponse, ttsVoice, autoSpeakResponses, }: KikuButtonProps): React.JSX.Element;
|
|
77
80
|
|
|
78
81
|
interface SparkleProps {
|
|
79
82
|
productName: string;
|
|
80
83
|
limit?: number;
|
|
81
84
|
onResult?: (results: SearchResult[]) => void;
|
|
82
|
-
/** Override the backdrop colour (any CSS colour/gradient) */
|
|
83
85
|
backdropColor?: string;
|
|
84
|
-
/** Override backdrop blur — e.g. "8px" or 8 */
|
|
85
86
|
backdropBlur?: string | number;
|
|
86
|
-
/** Extra classes on the trigger button */
|
|
87
87
|
className?: string;
|
|
88
|
-
/** Called when user clicks a result — return false to prevent default navigation */
|
|
89
88
|
onNavigate?: (result: SearchResult) => boolean | void;
|
|
90
89
|
theme?: AkropolysTheme;
|
|
91
90
|
classNames?: {
|
|
@@ -99,29 +98,20 @@ interface SparkleProps {
|
|
|
99
98
|
}
|
|
100
99
|
declare function Sparkle({ productName, limit, onResult, backdropColor, backdropBlur, className, onNavigate, theme, classNames, product, children, }: SparkleProps): React.JSX.Element;
|
|
101
100
|
|
|
102
|
-
interface ComparisonMatrixProps {
|
|
103
|
-
sources: ChatSource[];
|
|
104
|
-
defaultCurrency?: string;
|
|
105
|
-
displayConfig?: Record<string, string>;
|
|
106
|
-
}
|
|
107
|
-
declare function ComparisonMatrix({ sources, defaultCurrency, displayConfig }: ComparisonMatrixProps): React.JSX.Element | null;
|
|
108
|
-
|
|
109
101
|
interface VoiceButtonProps {
|
|
110
102
|
onTranscript: (text: string) => void;
|
|
111
103
|
onInterim?: (text: string) => void;
|
|
112
|
-
/** BCP-47
|
|
104
|
+
/** BCP-47 tag. Defaults to the page's <html lang>, then the browser language. */
|
|
113
105
|
lang?: string;
|
|
114
106
|
className?: string;
|
|
115
107
|
disabled?: boolean;
|
|
108
|
+
/** Raw SpeechRecognition error code — 'not-allowed', 'audio-capture', etc. */
|
|
109
|
+
onError?: (code: string) => void;
|
|
116
110
|
}
|
|
117
111
|
/**
|
|
118
|
-
* VoiceButton —
|
|
119
|
-
* No API key, no backend call, no cost.
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* <VoiceButton onTranscript={(text) => setQuery(text)} />
|
|
112
|
+
* VoiceButton — speech to text input with pause-based utterance detection.
|
|
123
113
|
*/
|
|
124
|
-
declare function VoiceButton({ onTranscript, onInterim, lang, className, disabled, }: VoiceButtonProps): React.JSX.Element | null;
|
|
114
|
+
declare function VoiceButton({ onTranscript, onInterim, lang, className, disabled, onError, }: VoiceButtonProps): React.JSX.Element | null;
|
|
125
115
|
|
|
126
116
|
interface VisualSearchProps {
|
|
127
117
|
/** Called with search results + the base64 preview when Gemini responds. */
|
|
@@ -136,17 +126,97 @@ interface VisualSearchProps {
|
|
|
136
126
|
disabled?: boolean;
|
|
137
127
|
}
|
|
138
128
|
/**
|
|
139
|
-
* VisualSearch — camera/image-upload button
|
|
140
|
-
*
|
|
141
|
-
* User picks a photo → it's base64-encoded in-browser → sent to POST /search/visual
|
|
142
|
-
* → Gemini Flash extracts Style DNA → results returned via onResults().
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
* <VisualSearch
|
|
146
|
-
* categoryHint="dress"
|
|
147
|
-
* onResults={(res, preview) => setVisualResults(res)}
|
|
148
|
-
* />
|
|
129
|
+
* VisualSearch — camera/image-upload button for style-match search.
|
|
149
130
|
*/
|
|
150
131
|
declare function VisualSearch({ onResults, onError, categoryHint, className, disabled, }: VisualSearchProps): React.JSX.Element;
|
|
151
132
|
|
|
152
|
-
|
|
133
|
+
interface ShopifyProduct {
|
|
134
|
+
id?: number | string;
|
|
135
|
+
title?: string;
|
|
136
|
+
name?: string;
|
|
137
|
+
handle?: string;
|
|
138
|
+
url?: string;
|
|
139
|
+
price?: number | string;
|
|
140
|
+
compare_at_price?: number | string;
|
|
141
|
+
price_min?: number | string;
|
|
142
|
+
featured_image?: string;
|
|
143
|
+
images?: string[] | {
|
|
144
|
+
src: string;
|
|
145
|
+
}[];
|
|
146
|
+
image?: string;
|
|
147
|
+
type?: string;
|
|
148
|
+
product_type?: string;
|
|
149
|
+
category?: string;
|
|
150
|
+
vendor?: string;
|
|
151
|
+
brand?: string;
|
|
152
|
+
tags?: string[] | string;
|
|
153
|
+
description?: string;
|
|
154
|
+
body_html?: string;
|
|
155
|
+
variants?: Array<{
|
|
156
|
+
id: number | string;
|
|
157
|
+
title?: string;
|
|
158
|
+
price?: number | string;
|
|
159
|
+
sku?: string;
|
|
160
|
+
available?: boolean;
|
|
161
|
+
}>;
|
|
162
|
+
available?: boolean;
|
|
163
|
+
[key: string]: any;
|
|
164
|
+
}
|
|
165
|
+
interface StandaloneConfig {
|
|
166
|
+
siteId?: string;
|
|
167
|
+
apiToken?: string;
|
|
168
|
+
apiUrl?: string;
|
|
169
|
+
vertical?: string;
|
|
170
|
+
shopperId?: string;
|
|
171
|
+
theme?: 'dark' | 'light' | any;
|
|
172
|
+
buttonLabel?: string;
|
|
173
|
+
title?: string;
|
|
174
|
+
placeholder?: string;
|
|
175
|
+
defaultCurrency?: string;
|
|
176
|
+
chips?: string[];
|
|
177
|
+
enableVoice?: boolean;
|
|
178
|
+
voiceLang?: string;
|
|
179
|
+
enableVision?: boolean;
|
|
180
|
+
visionCategoryHint?: string;
|
|
181
|
+
enableAudioResponse?: boolean;
|
|
182
|
+
ttsVoice?: string;
|
|
183
|
+
autoSpeakResponses?: boolean;
|
|
184
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'inline' | 'hidden' | 'custom';
|
|
185
|
+
containerId?: string;
|
|
186
|
+
containerSelector?: string;
|
|
187
|
+
dockable?: boolean;
|
|
188
|
+
product?: ShopifyProduct;
|
|
189
|
+
onAddToCart?: (items: ChatSource[]) => void;
|
|
190
|
+
onAction?: (action: any) => void;
|
|
191
|
+
[key: string]: any;
|
|
192
|
+
}
|
|
193
|
+
declare global {
|
|
194
|
+
interface Window {
|
|
195
|
+
AkropolysConfig?: StandaloneConfig;
|
|
196
|
+
Kiku?: {
|
|
197
|
+
version: string;
|
|
198
|
+
open: () => void;
|
|
199
|
+
close: () => void;
|
|
200
|
+
toggle: () => void;
|
|
201
|
+
ingest: (product: ShopifyProduct) => Promise<void>;
|
|
202
|
+
resetPosition: () => void;
|
|
203
|
+
getClient: () => any;
|
|
204
|
+
config: StandaloneConfig;
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Normalizes a Shopify product object into Akropolys entity format.
|
|
210
|
+
*/
|
|
211
|
+
declare function normalizeShopifyProduct(p: ShopifyProduct): Record<string, any>;
|
|
212
|
+
/**
|
|
213
|
+
* Native Shopify Cart Integration.
|
|
214
|
+
*/
|
|
215
|
+
declare function shopifyAddToCart(items: ChatSource[]): Promise<any>;
|
|
216
|
+
/**
|
|
217
|
+
* Native Shopify Get Cart.
|
|
218
|
+
*/
|
|
219
|
+
declare function shopifyGetCart(): Promise<any>;
|
|
220
|
+
declare function initKiku(customConfig?: StandaloneConfig): void;
|
|
221
|
+
|
|
222
|
+
export { ChatWidget, type ChatWidgetProps, KikuButton, type KikuButtonProps, ChatWidget as KikuChat, type ChatWidgetProps as KikuChatProps, SearchBar, type SearchBarProps, type ShopifyProduct, Sparkle, type StandaloneConfig, VisualSearch, type VisualSearchProps, VoiceButton, type VoiceButtonProps, initKiku, normalizeShopifyProduct, shopifyAddToCart, shopifyGetCart };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { SearchResult, AkropolysTheme, ChatSource, Product, VisualSearchResponse
|
|
|
4
4
|
interface SearchBarProps {
|
|
5
5
|
placeholder?: string;
|
|
6
6
|
limit?: number;
|
|
7
|
-
/** Debounce in ms — default 150 for instant type-ahead */
|
|
8
7
|
debounceMs?: number;
|
|
9
8
|
onSelect?: (result: SearchResult) => void;
|
|
10
9
|
className?: string;
|
|
@@ -36,17 +35,22 @@ interface ChatWidgetProps {
|
|
|
36
35
|
input?: string;
|
|
37
36
|
};
|
|
38
37
|
onSelectSource?: (source: ChatSource) => void;
|
|
39
|
-
/** Enable 🎙️ voice input via browser Web Speech API (free) */
|
|
40
38
|
enableVoice?: boolean;
|
|
41
|
-
/** Enable 📷 visual style-match search
|
|
39
|
+
/** Enable 📷 visual style-match search */
|
|
42
40
|
enableVision?: boolean;
|
|
43
|
-
/** Optional category hint for visual search (e.g. 'dress', 'curtains') */
|
|
44
41
|
visionCategoryHint?: string;
|
|
42
|
+
/** Enable 🔊 TTS voice audio responses from AI */
|
|
43
|
+
enableAudioResponse?: boolean;
|
|
44
|
+
/** Optional AI voice preset */
|
|
45
|
+
ttsVoice?: string;
|
|
46
|
+
autoSpeakResponses?: boolean;
|
|
45
47
|
}
|
|
46
|
-
declare function ChatWidget({ title, placeholder, emptyStateText, emptyStateSuggestions, defaultCurrency, className, theme, classNames, onSelectSource, enableVoice, enableVision, visionCategoryHint }: ChatWidgetProps): React.JSX.Element;
|
|
48
|
+
declare function ChatWidget({ title, placeholder, emptyStateText, emptyStateSuggestions, defaultCurrency, className, theme, classNames, onSelectSource, enableVoice, enableVision, visionCategoryHint, enableAudioResponse, ttsVoice, autoSpeakResponses }: ChatWidgetProps): React.JSX.Element;
|
|
47
49
|
|
|
48
50
|
interface KikuButtonProps {
|
|
49
|
-
label?:
|
|
51
|
+
label?: React.ReactNode;
|
|
52
|
+
children?: React.ReactNode;
|
|
53
|
+
icon?: React.ReactNode;
|
|
50
54
|
title?: string;
|
|
51
55
|
placeholder?: string;
|
|
52
56
|
backdropColor?: string;
|
|
@@ -63,29 +67,24 @@ interface KikuButtonProps {
|
|
|
63
67
|
input?: string;
|
|
64
68
|
sendButton?: string;
|
|
65
69
|
};
|
|
66
|
-
/** Enable 🎙️ voice input via browser Web Speech API (free) */
|
|
67
70
|
enableVoice?: boolean;
|
|
68
|
-
/** BCP-47 tag for voice transcription (e.g. 'sw-KE', 'fr-FR'). Defaults to
|
|
69
|
-
the page's <html lang>, then the browser language. */
|
|
70
71
|
voiceLang?: string;
|
|
71
|
-
/** Enable 📷 visual style-match search via Gemini (requires backend GEMINI_API_KEY) */
|
|
72
72
|
enableVision?: boolean;
|
|
73
|
-
/** Optional category hint for visual search (e.g. 'dress', 'curtains') */
|
|
74
73
|
visionCategoryHint?: string;
|
|
74
|
+
/** Enable 🔊 TTS voice audio responses from AI */
|
|
75
|
+
enableAudioResponse?: boolean;
|
|
76
|
+
ttsVoice?: string;
|
|
77
|
+
autoSpeakResponses?: boolean;
|
|
75
78
|
}
|
|
76
|
-
declare function KikuButton({ label, title, placeholder, backdropColor, backdropBlur, className, onSelectSource, defaultCurrency, chips, theme, classNames, enableVoice, voiceLang, enableVision, visionCategoryHint, }: KikuButtonProps): React.JSX.Element;
|
|
79
|
+
declare function KikuButton({ label, children, icon, title, placeholder, backdropColor, backdropBlur, className, onSelectSource, defaultCurrency, chips, theme, classNames, enableVoice, voiceLang, enableVision, visionCategoryHint, enableAudioResponse, ttsVoice, autoSpeakResponses, }: KikuButtonProps): React.JSX.Element;
|
|
77
80
|
|
|
78
81
|
interface SparkleProps {
|
|
79
82
|
productName: string;
|
|
80
83
|
limit?: number;
|
|
81
84
|
onResult?: (results: SearchResult[]) => void;
|
|
82
|
-
/** Override the backdrop colour (any CSS colour/gradient) */
|
|
83
85
|
backdropColor?: string;
|
|
84
|
-
/** Override backdrop blur — e.g. "8px" or 8 */
|
|
85
86
|
backdropBlur?: string | number;
|
|
86
|
-
/** Extra classes on the trigger button */
|
|
87
87
|
className?: string;
|
|
88
|
-
/** Called when user clicks a result — return false to prevent default navigation */
|
|
89
88
|
onNavigate?: (result: SearchResult) => boolean | void;
|
|
90
89
|
theme?: AkropolysTheme;
|
|
91
90
|
classNames?: {
|
|
@@ -99,29 +98,20 @@ interface SparkleProps {
|
|
|
99
98
|
}
|
|
100
99
|
declare function Sparkle({ productName, limit, onResult, backdropColor, backdropBlur, className, onNavigate, theme, classNames, product, children, }: SparkleProps): React.JSX.Element;
|
|
101
100
|
|
|
102
|
-
interface ComparisonMatrixProps {
|
|
103
|
-
sources: ChatSource[];
|
|
104
|
-
defaultCurrency?: string;
|
|
105
|
-
displayConfig?: Record<string, string>;
|
|
106
|
-
}
|
|
107
|
-
declare function ComparisonMatrix({ sources, defaultCurrency, displayConfig }: ComparisonMatrixProps): React.JSX.Element | null;
|
|
108
|
-
|
|
109
101
|
interface VoiceButtonProps {
|
|
110
102
|
onTranscript: (text: string) => void;
|
|
111
103
|
onInterim?: (text: string) => void;
|
|
112
|
-
/** BCP-47
|
|
104
|
+
/** BCP-47 tag. Defaults to the page's <html lang>, then the browser language. */
|
|
113
105
|
lang?: string;
|
|
114
106
|
className?: string;
|
|
115
107
|
disabled?: boolean;
|
|
108
|
+
/** Raw SpeechRecognition error code — 'not-allowed', 'audio-capture', etc. */
|
|
109
|
+
onError?: (code: string) => void;
|
|
116
110
|
}
|
|
117
111
|
/**
|
|
118
|
-
* VoiceButton —
|
|
119
|
-
* No API key, no backend call, no cost.
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* <VoiceButton onTranscript={(text) => setQuery(text)} />
|
|
112
|
+
* VoiceButton — speech to text input with pause-based utterance detection.
|
|
123
113
|
*/
|
|
124
|
-
declare function VoiceButton({ onTranscript, onInterim, lang, className, disabled, }: VoiceButtonProps): React.JSX.Element | null;
|
|
114
|
+
declare function VoiceButton({ onTranscript, onInterim, lang, className, disabled, onError, }: VoiceButtonProps): React.JSX.Element | null;
|
|
125
115
|
|
|
126
116
|
interface VisualSearchProps {
|
|
127
117
|
/** Called with search results + the base64 preview when Gemini responds. */
|
|
@@ -136,17 +126,97 @@ interface VisualSearchProps {
|
|
|
136
126
|
disabled?: boolean;
|
|
137
127
|
}
|
|
138
128
|
/**
|
|
139
|
-
* VisualSearch — camera/image-upload button
|
|
140
|
-
*
|
|
141
|
-
* User picks a photo → it's base64-encoded in-browser → sent to POST /search/visual
|
|
142
|
-
* → Gemini Flash extracts Style DNA → results returned via onResults().
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
* <VisualSearch
|
|
146
|
-
* categoryHint="dress"
|
|
147
|
-
* onResults={(res, preview) => setVisualResults(res)}
|
|
148
|
-
* />
|
|
129
|
+
* VisualSearch — camera/image-upload button for style-match search.
|
|
149
130
|
*/
|
|
150
131
|
declare function VisualSearch({ onResults, onError, categoryHint, className, disabled, }: VisualSearchProps): React.JSX.Element;
|
|
151
132
|
|
|
152
|
-
|
|
133
|
+
interface ShopifyProduct {
|
|
134
|
+
id?: number | string;
|
|
135
|
+
title?: string;
|
|
136
|
+
name?: string;
|
|
137
|
+
handle?: string;
|
|
138
|
+
url?: string;
|
|
139
|
+
price?: number | string;
|
|
140
|
+
compare_at_price?: number | string;
|
|
141
|
+
price_min?: number | string;
|
|
142
|
+
featured_image?: string;
|
|
143
|
+
images?: string[] | {
|
|
144
|
+
src: string;
|
|
145
|
+
}[];
|
|
146
|
+
image?: string;
|
|
147
|
+
type?: string;
|
|
148
|
+
product_type?: string;
|
|
149
|
+
category?: string;
|
|
150
|
+
vendor?: string;
|
|
151
|
+
brand?: string;
|
|
152
|
+
tags?: string[] | string;
|
|
153
|
+
description?: string;
|
|
154
|
+
body_html?: string;
|
|
155
|
+
variants?: Array<{
|
|
156
|
+
id: number | string;
|
|
157
|
+
title?: string;
|
|
158
|
+
price?: number | string;
|
|
159
|
+
sku?: string;
|
|
160
|
+
available?: boolean;
|
|
161
|
+
}>;
|
|
162
|
+
available?: boolean;
|
|
163
|
+
[key: string]: any;
|
|
164
|
+
}
|
|
165
|
+
interface StandaloneConfig {
|
|
166
|
+
siteId?: string;
|
|
167
|
+
apiToken?: string;
|
|
168
|
+
apiUrl?: string;
|
|
169
|
+
vertical?: string;
|
|
170
|
+
shopperId?: string;
|
|
171
|
+
theme?: 'dark' | 'light' | any;
|
|
172
|
+
buttonLabel?: string;
|
|
173
|
+
title?: string;
|
|
174
|
+
placeholder?: string;
|
|
175
|
+
defaultCurrency?: string;
|
|
176
|
+
chips?: string[];
|
|
177
|
+
enableVoice?: boolean;
|
|
178
|
+
voiceLang?: string;
|
|
179
|
+
enableVision?: boolean;
|
|
180
|
+
visionCategoryHint?: string;
|
|
181
|
+
enableAudioResponse?: boolean;
|
|
182
|
+
ttsVoice?: string;
|
|
183
|
+
autoSpeakResponses?: boolean;
|
|
184
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'inline' | 'hidden' | 'custom';
|
|
185
|
+
containerId?: string;
|
|
186
|
+
containerSelector?: string;
|
|
187
|
+
dockable?: boolean;
|
|
188
|
+
product?: ShopifyProduct;
|
|
189
|
+
onAddToCart?: (items: ChatSource[]) => void;
|
|
190
|
+
onAction?: (action: any) => void;
|
|
191
|
+
[key: string]: any;
|
|
192
|
+
}
|
|
193
|
+
declare global {
|
|
194
|
+
interface Window {
|
|
195
|
+
AkropolysConfig?: StandaloneConfig;
|
|
196
|
+
Kiku?: {
|
|
197
|
+
version: string;
|
|
198
|
+
open: () => void;
|
|
199
|
+
close: () => void;
|
|
200
|
+
toggle: () => void;
|
|
201
|
+
ingest: (product: ShopifyProduct) => Promise<void>;
|
|
202
|
+
resetPosition: () => void;
|
|
203
|
+
getClient: () => any;
|
|
204
|
+
config: StandaloneConfig;
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Normalizes a Shopify product object into Akropolys entity format.
|
|
210
|
+
*/
|
|
211
|
+
declare function normalizeShopifyProduct(p: ShopifyProduct): Record<string, any>;
|
|
212
|
+
/**
|
|
213
|
+
* Native Shopify Cart Integration.
|
|
214
|
+
*/
|
|
215
|
+
declare function shopifyAddToCart(items: ChatSource[]): Promise<any>;
|
|
216
|
+
/**
|
|
217
|
+
* Native Shopify Get Cart.
|
|
218
|
+
*/
|
|
219
|
+
declare function shopifyGetCart(): Promise<any>;
|
|
220
|
+
declare function initKiku(customConfig?: StandaloneConfig): void;
|
|
221
|
+
|
|
222
|
+
export { ChatWidget, type ChatWidgetProps, KikuButton, type KikuButtonProps, ChatWidget as KikuChat, type ChatWidgetProps as KikuChatProps, SearchBar, type SearchBarProps, type ShopifyProduct, Sparkle, type StandaloneConfig, VisualSearch, type VisualSearchProps, VoiceButton, type VoiceButtonProps, initKiku, normalizeShopifyProduct, shopifyAddToCart, shopifyGetCart };
|