@constructor-io/constructorio-ui-asa 1.8.0 → 1.10.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 +8 -210
- package/dist/constructorio-ui-asa-bundled.js +79 -21
- package/lib/cjs/components/Button/Button.js +22 -3
- package/lib/cjs/components/Chat/AiMessage.css +52 -0
- package/lib/cjs/components/Chat/AiMessage.js +6 -2
- package/lib/cjs/components/Chat/Chat.js +18 -4
- package/lib/cjs/components/Chat/ChatInput.js +3 -3
- package/lib/cjs/hooks/asaStreamHandlers.js +1 -1
- package/lib/cjs/hooks/persistence/backgroundTurns.js +35 -0
- package/lib/cjs/hooks/persistence/useChatPersistence.js +35 -10
- package/lib/cjs/hooks/useAsaResults.js +54 -26
- package/lib/cjs/hooks/useAsaTracking.js +31 -16
- package/lib/cjs/index.js +3 -1
- package/lib/cjs/utils/chatThreads.js +15 -1
- package/lib/cjs/utils/localStoragePersistence.js +110 -19
- package/lib/cjs/utils/markdown.js +60 -0
- package/lib/cjs/version.js +1 -1
- package/lib/mjs/components/Button/Button.js +26 -3
- package/lib/mjs/components/Chat/AiMessage.css +52 -0
- package/lib/mjs/components/Chat/AiMessage.js +6 -2
- package/lib/mjs/components/Chat/Chat.js +18 -4
- package/lib/mjs/components/Chat/ChatInput.js +3 -3
- package/lib/mjs/hooks/asaStreamHandlers.js +1 -1
- package/lib/mjs/hooks/persistence/backgroundTurns.js +35 -1
- package/lib/mjs/hooks/persistence/useChatPersistence.js +35 -11
- package/lib/mjs/hooks/useAsaResults.js +53 -24
- package/lib/mjs/hooks/useAsaTracking.js +40 -16
- package/lib/mjs/index.js +1 -0
- package/lib/mjs/utils/chatThreads.js +12 -0
- package/lib/mjs/utils/localStoragePersistence.js +106 -14
- package/lib/mjs/utils/markdown.js +53 -0
- package/lib/mjs/version.js +1 -1
- package/lib/types/components/Button/Button.d.ts +3 -2
- package/lib/types/components/Chat/Chat.d.ts +13 -1
- package/lib/types/hooks/persistence/backgroundTurns.d.ts +6 -0
- package/lib/types/hooks/persistence/useChatPersistence.d.ts +4 -0
- package/lib/types/hooks/useAsaTracking.d.ts +4 -2
- package/lib/types/index.d.ts +3 -2
- package/lib/types/types.d.ts +57 -8
- package/lib/types/utils/chatThreads.d.ts +4 -0
- package/lib/types/utils/markdown.d.ts +8 -0
- package/lib/types/version.d.ts +1 -1
- package/package.json +6 -2
package/lib/types/types.d.ts
CHANGED
|
@@ -179,12 +179,24 @@ export interface ResultGroup {
|
|
|
179
179
|
searchResultId?: string;
|
|
180
180
|
intentResultId?: string;
|
|
181
181
|
}
|
|
182
|
+
export interface SendMessageOptions {
|
|
183
|
+
/**
|
|
184
|
+
* Conversation to send into, e.g. one started elsewhere on the page. The chat moves to it
|
|
185
|
+
* first: loaded from storage when persistence has it, otherwise continued on the server
|
|
186
|
+
* with an empty screen. Omit to send into the conversation on screen.
|
|
187
|
+
*/
|
|
188
|
+
threadId?: string;
|
|
189
|
+
}
|
|
182
190
|
export interface UseChatReturn {
|
|
183
191
|
messages: ChatMessage[];
|
|
184
|
-
|
|
192
|
+
/** Skipped while another answer streams. */
|
|
193
|
+
sendMessage: (text: string, source?: AssistantSubmitSource, options?: SendMessageOptions) => void;
|
|
185
194
|
/** True while an answer is streaming, here or, with persistence on, in another tab on the same thread. */
|
|
186
195
|
isStreaming: boolean;
|
|
187
|
-
/**
|
|
196
|
+
/**
|
|
197
|
+
* True while `abort` can stop the answer: this tab's own, or, when the store can reach it, one
|
|
198
|
+
* streaming in another tab.
|
|
199
|
+
*/
|
|
188
200
|
canAbort: boolean;
|
|
189
201
|
/**
|
|
190
202
|
* Cancel the in-flight request, keeping the conversation. The partial reply is settled
|
|
@@ -261,6 +273,18 @@ export interface ChatPersistence {
|
|
|
261
273
|
* Returns an unsubscribe function.
|
|
262
274
|
*/
|
|
263
275
|
subscribe?(listener: () => void): () => void;
|
|
276
|
+
/** Optional. Ask the tab streaming `messageId` into `threadId` to stop it. */
|
|
277
|
+
requestAbort?(threadId: string, messageId: string): void;
|
|
278
|
+
/**
|
|
279
|
+
* Optional. Notify when another tab asks to stop an answer, see `requestAbort`. Returns an
|
|
280
|
+
* unsubscribe function. Without both, an answer streaming in another tab cannot be stopped.
|
|
281
|
+
*/
|
|
282
|
+
subscribeAbort?(listener: (request: AbortRequest) => void): () => void;
|
|
283
|
+
}
|
|
284
|
+
/** Another tab asks to stop the answer `messageId` streaming into `threadId`. */
|
|
285
|
+
export interface AbortRequest {
|
|
286
|
+
threadId: string;
|
|
287
|
+
messageId: string;
|
|
264
288
|
}
|
|
265
289
|
/** Which stored history `clearPersistedConversations` deletes; mirror what the provider was given. */
|
|
266
290
|
export interface ClearPersistedConversationsOptions {
|
|
@@ -289,20 +313,44 @@ export interface LocalStoragePersistenceOptions {
|
|
|
289
313
|
/** Storage to use instead of the browser's; takes precedence over `storageArea`. */
|
|
290
314
|
storage?: Storage;
|
|
291
315
|
}
|
|
292
|
-
/**
|
|
293
|
-
|
|
316
|
+
/**
|
|
317
|
+
* How an intent was submitted: typed input, a welcome-screen suggestion chip, a refinement chip,
|
|
318
|
+
* or the host page (`ChatHandle.sendMessage` or the `initialPrompt` prop).
|
|
319
|
+
*/
|
|
320
|
+
export type AssistantSubmitSource = 'input' | 'suggestion' | 'refinement' | 'external';
|
|
294
321
|
/** An item within a viewed/clicked search_result pod. */
|
|
295
322
|
export interface AssistantTrackedItem {
|
|
296
323
|
itemId?: string;
|
|
297
324
|
itemName?: string;
|
|
298
325
|
variationId?: string;
|
|
299
326
|
}
|
|
327
|
+
/** Agent mode a CTA opens or starts. */
|
|
328
|
+
export type AgentButtonClickMode = 'chat' | 'search' | 'qna' | 'recommendations' | 'query_refinement';
|
|
329
|
+
/** Page surface an agent CTA was clicked on. */
|
|
330
|
+
export type AgentButtonClickPageType = 'home' | 'plp' | 'pdp' | 'search' | 'collection' | 'email_campaign' | 'cart';
|
|
331
|
+
/** Where an agent CTA sits on the page. All fields are optional. */
|
|
332
|
+
export interface AgentButtonClickPlacement {
|
|
333
|
+
/** Stable label describing where the CTA is placed, e.g. `'header'` or `'search_bar'`. */
|
|
334
|
+
positionOnPage?: string;
|
|
335
|
+
/** Page surface where the CTA was clicked. */
|
|
336
|
+
pageType?: AgentButtonClickPageType;
|
|
337
|
+
/** 1-based index distinguishing CTA instances with the same mode and position during one page view. */
|
|
338
|
+
instanceId?: number;
|
|
339
|
+
}
|
|
340
|
+
/** Fields sent with `ai_agent_button_click` and passed to `onAgentButtonClick`. */
|
|
341
|
+
export interface AgentButtonClickPayload extends AgentButtonClickPlacement {
|
|
342
|
+
mode: AgentButtonClickMode;
|
|
343
|
+
/** Agent experience the CTA opens, sent as `agent_domain`. */
|
|
344
|
+
agentDomain: string;
|
|
345
|
+
}
|
|
300
346
|
/**
|
|
301
347
|
* Optional consumer callbacks fired alongside the built-in behavioral tracking.
|
|
302
348
|
* Each fires immediately after its corresponding `trackAssistant*` beacon is sent,
|
|
303
349
|
* so consumers can mirror ASA analytics into their own systems. All are optional.
|
|
304
350
|
*/
|
|
305
351
|
export interface AsaCallbacks {
|
|
352
|
+
/** A CTA that opens the assistant (the built-in `Button`) was clicked. */
|
|
353
|
+
onAgentButtonClick?: (payload: AgentButtonClickPayload) => void;
|
|
306
354
|
/** User submitted an intent (typed) or clicked a suggestion / refinement chip. */
|
|
307
355
|
onAssistantSubmit?: (payload: {
|
|
308
356
|
intent: string;
|
|
@@ -383,12 +431,13 @@ export interface ChatInputRenderProps {
|
|
|
383
431
|
onSubmit: () => void;
|
|
384
432
|
placeholder: string;
|
|
385
433
|
isDisabled: boolean;
|
|
434
|
+
/** Whether a reply is currently streaming, here or in another tab; for status and disabled state. */
|
|
435
|
+
isStreaming: boolean;
|
|
386
436
|
/**
|
|
387
|
-
* Whether
|
|
388
|
-
*
|
|
389
|
-
* is often the only way a user can cancel.
|
|
437
|
+
* Whether `onAbort` can stop the reply streaming now; show a cancel control only then. The
|
|
438
|
+
* built-in stop button is off by default, so an override is often the only way a user can cancel.
|
|
390
439
|
*/
|
|
391
|
-
|
|
440
|
+
canAbort: boolean;
|
|
392
441
|
/** Cancel the in-flight reply. Keeps the conversation and the thread. */
|
|
393
442
|
onAbort: () => void;
|
|
394
443
|
}
|
|
@@ -8,6 +8,8 @@ export declare const DEFAULT_PERSISTENCE_KEY = "cio-asa:chat";
|
|
|
8
8
|
export declare const DEFAULT_PERSISTENCE_TTL_MS: number;
|
|
9
9
|
/** How long a stored answer written by another tab is still shown as "typing" before it is settled. */
|
|
10
10
|
export declare const IN_FLIGHT_GRACE_MS: number;
|
|
11
|
+
/** How long to wait for the tab streaming an answer to store it stopped, before settling it here. */
|
|
12
|
+
export declare const FOREIGN_ABORT_TIMEOUT_MS: number;
|
|
11
13
|
/** Random token for the ids that must not collide between tabs: threads, tabs and messages. */
|
|
12
14
|
export declare function randomId(): string;
|
|
13
15
|
/** Client-side thread id for a conversation the server has not named yet. */
|
|
@@ -28,6 +30,8 @@ export declare function nextMessageCounter(messages: ChatMessage[]): number;
|
|
|
28
30
|
export declare function isInFlight(messages: ChatMessage[]): boolean;
|
|
29
31
|
/** Settles answers stored mid-stream: `done` when they have content, an interrupted `error` otherwise. */
|
|
30
32
|
export declare function normalizeHydratedMessages(messages: ChatMessage[]): ChatMessage[];
|
|
33
|
+
/** `messages` with the cancelled reply settled: `done` when it has content, dropped otherwise. */
|
|
34
|
+
export declare function settleCancelledReply(messages: ChatMessage[], assistantId: string): ChatMessage[];
|
|
31
35
|
/** Makes the product card for a raw search-result item. */
|
|
32
36
|
export type ItemNormalizer = (item: Record<string, unknown>) => Product;
|
|
33
37
|
/** Messages as stored: raw items replaced by the cards `normalize` makes; a restored group keeps its cards. */
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns the agent's markdown into sanitized HTML: paragraphs, bold, links, lists and tables.
|
|
3
|
+
* Links to other sites become plain text. Browser only: without a DOM to sanitize with (server
|
|
4
|
+
* rendering) it returns `''`, so render the plain text instead.
|
|
5
|
+
*/
|
|
6
|
+
export declare function renderMarkdown(markdown: string): string;
|
|
7
|
+
/** The agent's markdown as plain text, one space between blocks and table cells, for screen readers. */
|
|
8
|
+
export declare function markdownToText(markdown: string): string;
|
package/lib/types/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "1.
|
|
1
|
+
declare const _default: "1.10.0";
|
|
2
2
|
export default _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructor-io/constructorio-ui-asa",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Constructor.io AI Shopping Agent UI library for web applications",
|
|
5
5
|
"author": "constructor.io",
|
|
6
6
|
"license": "MIT",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"@babel/preset-env": "^7.28.3",
|
|
83
83
|
"@babel/preset-react": "^7.27.1",
|
|
84
84
|
"@babel/preset-typescript": "^7.27.1",
|
|
85
|
-
"@constructor-io/constructorio-client-javascript": "2.
|
|
85
|
+
"@constructor-io/constructorio-client-javascript": "2.94.0",
|
|
86
86
|
"@constructor-io/constructorio-ui-components": "^1.6.0",
|
|
87
87
|
"@cspell/eslint-plugin": "^6.18.1",
|
|
88
88
|
"@storybook/addon-a11y": "^8.6.14",
|
|
@@ -148,5 +148,9 @@
|
|
|
148
148
|
"volta": {
|
|
149
149
|
"node": "22.18.0",
|
|
150
150
|
"npm": "10.9.3"
|
|
151
|
+
},
|
|
152
|
+
"dependencies": {
|
|
153
|
+
"dompurify": "3.4.17",
|
|
154
|
+
"marked": "15.0.12"
|
|
151
155
|
}
|
|
152
156
|
}
|