@alxxsck/ai-assistant 2.18.0 → 2.21.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 +34 -7
- package/dist/App.d.ts +2 -0
- package/dist/{Avatar-DNRiUnuW.js → Avatar-CI9_caGl.js} +1 -1
- package/dist/{ChatWidgetContent-CWarBHsS.js → ChatWidgetContent-CBWyqiVF.js} +1873 -1700
- package/dist/api/messages.api.d.ts +11 -5
- package/dist/api/messages.api.types.d.ts +4 -0
- package/dist/bridge-ai-chat-widget.es.js +1 -1
- package/dist/context/ChatWidgetContext.d.ts +3 -0
- package/dist/domain/command/CommandRuntime.d.ts +26 -3
- package/dist/domain/command/command.types.d.ts +6 -0
- package/dist/domain/message/cable/CableContext.d.ts +2 -0
- package/dist/domain/message/cable/widget-frame.d.ts +1 -1
- package/dist/domain/message/chat-experience.d.ts +0 -9
- package/dist/domain/message/message.store.d.ts +18 -9
- package/dist/domain/message/typing/end-user-typing.client.d.ts +38 -0
- package/dist/domain/scenario-interaction/ScenarioInteractionCollector.d.ts +91 -0
- package/dist/domain/scenario-interaction/ScenarioInteractionRuntime.d.ts +28 -0
- package/dist/domain/scenario-interaction/SurfaceController.d.ts +13 -0
- package/dist/domain/scenario-interaction/presentation-observer.d.ts +12 -0
- package/dist/domain/scenario-interaction/scenario-interaction.context.d.ts +7 -0
- package/dist/domain/scenario-interaction/scenario-interaction.types.d.ts +84 -0
- package/dist/domain/scenario-interaction/useScenarioPresentation.d.ts +4 -0
- package/dist/domain/support-presentation/PresentationAvatarResolver.d.ts +2 -0
- package/dist/domain/support-presentation/support-presentation.reconciliation.d.ts +13 -0
- package/dist/domain/support-presentation/support-presentation.types.d.ts +15 -6
- package/dist/i18n/messages.d.ts +0 -1
- package/dist/{index-raaheNwM.js → index-o7DbTuwa.js} +7734 -5026
- package/dist/index.d.ts +1 -0
- package/dist/ui/components/ChatResponderIdentity.d.ts +2 -2
- package/dist/ui/components/PresentationAvatar.d.ts +4 -5
- package/dist/ui/hooks/usePresentedResponderPresentation.d.ts +10 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AppApi } from "@/App";
|
|
2
2
|
import type { WidgetConfig } from "@/index.types";
|
|
3
|
-
import { type ConversationData, type MessageData, type RawMessageData, type SendMessageResult } from "./messages.api.types";
|
|
3
|
+
import { type ConversationData, type MessageData, type RawConversationData, type RawMessageData, type SendMessageResult } from "./messages.api.types";
|
|
4
4
|
import type { ChatAttachment } from "@/domain/message/chat-experience";
|
|
5
5
|
export declare const MAX_FETCH_MESSAGES = 100;
|
|
6
6
|
export type CursorPage<T> = {
|
|
@@ -10,7 +10,6 @@ export type CursorPage<T> = {
|
|
|
10
10
|
type VersionedCursorPage<T> = CursorPage<T> & {
|
|
11
11
|
contractVersion?: unknown;
|
|
12
12
|
};
|
|
13
|
-
type ConversationsResponse = VersionedCursorPage<ConversationData>;
|
|
14
13
|
export declare class ChatApiError extends Error {
|
|
15
14
|
readonly status: number;
|
|
16
15
|
constructor(status: number, message: string);
|
|
@@ -20,12 +19,19 @@ export declare class ChatContractError extends Error {
|
|
|
20
19
|
}
|
|
21
20
|
export declare const isConversationClosedError: (error: unknown) => boolean;
|
|
22
21
|
export declare const requestChatJson: <T>(config: WidgetConfig, api: AppApi, path: string, init?: RequestInit) => Promise<T>;
|
|
23
|
-
export declare const normalizeConversation: (conversation:
|
|
22
|
+
export declare const normalizeConversation: (conversation: RawConversationData) => ConversationData;
|
|
24
23
|
export declare const normalizeMessage: (message: RawMessageData, config: WidgetConfig) => MessageData;
|
|
24
|
+
export declare const normalizeMessageAuthorPresentation: (role: RawMessageData["role"], author: unknown) => Readonly<{
|
|
25
|
+
contractState: "VERSIONED" | "LEGACY";
|
|
26
|
+
displayName: string;
|
|
27
|
+
avatarAsset: import("@/domain/support-presentation/support-presentation.types").PresentationAvatarAsset | null;
|
|
28
|
+
presentationVersion: number | null;
|
|
29
|
+
legacyAvatarUrl: string | null;
|
|
30
|
+
}> | null;
|
|
25
31
|
export declare const normalizeMessageForSession: (message: RawMessageData, interactionSessionId: string) => MessageData;
|
|
26
|
-
export declare const listConversations: (config: WidgetConfig, api: AppApi, cursor?: string, signal?: AbortSignal) => Promise<
|
|
32
|
+
export declare const listConversations: (config: WidgetConfig, api: AppApi, cursor?: string, signal?: AbortSignal) => Promise<VersionedCursorPage<ConversationData>>;
|
|
27
33
|
export declare const listConversationMessages: (config: WidgetConfig, api: AppApi, conversationId: string, cursor?: string, signal?: AbortSignal) => Promise<CursorPage<MessageData>>;
|
|
28
|
-
export declare const createConversation: (config: WidgetConfig, api: AppApi) => Promise<ConversationData>;
|
|
34
|
+
export declare const createConversation: (config: WidgetConfig, api: AppApi, signal?: AbortSignal) => Promise<ConversationData>;
|
|
29
35
|
export declare const selectConversation: (config: WidgetConfig, api: AppApi, conversationId: string, signal?: AbortSignal) => Promise<ConversationData>;
|
|
30
36
|
export declare const getConversation: (config: WidgetConfig, api: AppApi, conversationId: string, signal?: AbortSignal) => Promise<ConversationData>;
|
|
31
37
|
export declare function sendMessage(config: WidgetConfig, api: AppApi, messageText: string, conversationId?: string, clientMessageId?: `${string}-${string}-${string}-${string}-${string}`, attachments?: readonly ChatAttachment[]): Promise<SendMessageResult>;
|
|
@@ -103,6 +103,10 @@ export type ConversationData = {
|
|
|
103
103
|
aiSuspension?: ConversationAISuspension;
|
|
104
104
|
responderPresentation?: import("@/domain/support-presentation/support-presentation.types").SafeResponderPresentation;
|
|
105
105
|
};
|
|
106
|
+
/** Untrusted transport shape before responder contract normalization. */
|
|
107
|
+
export type RawConversationData = Omit<ConversationData, "responderPresentation"> & {
|
|
108
|
+
responderPresentation?: unknown;
|
|
109
|
+
};
|
|
106
110
|
export type MessageRole = "USER" | "ASSISTANT" | "ADMIN" | "SCENARIO" | "SYSTEM";
|
|
107
111
|
export type RawMessageData = {
|
|
108
112
|
id: string;
|
|
@@ -2,9 +2,12 @@ import type { AppApi } from "@/App";
|
|
|
2
2
|
import type { Avatar } from "@/avatar/Avatar";
|
|
3
3
|
import type { WidgetConfig } from "@/index.types";
|
|
4
4
|
import type { CtaCommandContext } from "@/domain/command/command.types";
|
|
5
|
+
import type { SurfaceTransitionContext } from "@/domain/scenario-interaction/scenario-interaction.types";
|
|
5
6
|
type ChatWidgetContextValue = {
|
|
6
7
|
open: boolean;
|
|
7
8
|
setOpen: (v: boolean) => void;
|
|
9
|
+
transitionSurface: (open: boolean, context: SurfaceTransitionContext) => void;
|
|
10
|
+
surfaceEpisodeId: string | null;
|
|
8
11
|
isFullscreen: boolean;
|
|
9
12
|
setFullscreen: (fullscreen: boolean) => void;
|
|
10
13
|
contentActivated: boolean;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { CustomerInteractionSession } from "@/types";
|
|
2
2
|
import { type CommandAck, type CommandEnvelope, type CommandEventDetail, type CtaCommandContext, type HostCommandHandlerName, type HostCommandHandlers, type SpeakTextCommandContext, type StartVoiceConversationCommandContext, type UiTarget } from "./command.types";
|
|
3
|
+
import type { ScenarioInteractionRuntime } from "@/domain/scenario-interaction/ScenarioInteractionRuntime";
|
|
3
4
|
type AckSender = (ack: CommandAck) => Promise<unknown>;
|
|
4
5
|
type InternalHandlers = {
|
|
5
|
-
setAssistantVisible?: (visible: boolean) => void;
|
|
6
|
-
setChatOpen?: (open: boolean) => void;
|
|
6
|
+
setAssistantVisible?: (visible: boolean, commandId: string) => void;
|
|
7
|
+
setChatOpen?: (open: boolean, commandId: string) => void;
|
|
7
8
|
playAnimation?: (animation: string, expiresAt?: string | null) => void | Promise<void>;
|
|
8
9
|
showCta?: (context: CtaCommandContext) => void;
|
|
9
10
|
connectTelegram?: (context: CtaCommandContext) => void | Promise<void>;
|
|
@@ -12,6 +13,7 @@ type InternalHandlers = {
|
|
|
12
13
|
};
|
|
13
14
|
export declare class CommandRuntime {
|
|
14
15
|
private readonly onStatus?;
|
|
16
|
+
private readonly scenarioInteractions?;
|
|
15
17
|
private readonly uiCommands;
|
|
16
18
|
private readonly internalHandlers;
|
|
17
19
|
private readonly internalHandlersReady;
|
|
@@ -19,16 +21,25 @@ export declare class CommandRuntime {
|
|
|
19
21
|
private readonly completed;
|
|
20
22
|
private readonly inFlight;
|
|
21
23
|
private readonly highlights;
|
|
22
|
-
|
|
24
|
+
private readonly targetObservationCleanups;
|
|
25
|
+
private readonly targetActivationOwners;
|
|
26
|
+
private readonly activeCustomHighlights;
|
|
27
|
+
private readonly targetHighlightOperations;
|
|
28
|
+
private principalSessionId;
|
|
29
|
+
private principalGeneration;
|
|
30
|
+
private destroyed;
|
|
31
|
+
constructor(targets?: Record<string, UiTarget>, handlers?: HostCommandHandlers, onStatus?: ((detail: CommandEventDetail) => void) | undefined, scenarioInteractions?: ScenarioInteractionRuntime | undefined);
|
|
23
32
|
registerTarget(code: string, target: UiTarget): () => void;
|
|
24
33
|
registerHostHandler<K extends HostCommandHandlerName>(name: K, handler: NonNullable<HostCommandHandlers[K]>): () => void;
|
|
25
34
|
setInternalHandlers(handlers: InternalHandlers): () => void;
|
|
26
35
|
execute(envelope: CommandEnvelope, session: CustomerInteractionSession, sendAck: AckSender): Promise<void>;
|
|
36
|
+
updateSession(session: CustomerInteractionSession): void;
|
|
27
37
|
executeCtaAction(context: CtaCommandContext): Promise<void>;
|
|
28
38
|
destroy(): void;
|
|
29
39
|
private executeOnce;
|
|
30
40
|
private dispatch;
|
|
31
41
|
private executeHighlight;
|
|
42
|
+
private executeHighlightSerial;
|
|
32
43
|
private executeShowCta;
|
|
33
44
|
private executeConnectTelegram;
|
|
34
45
|
private requireTarget;
|
|
@@ -37,10 +48,22 @@ export declare class CommandRuntime {
|
|
|
37
48
|
private findTargetElement;
|
|
38
49
|
private applyDefaultHighlight;
|
|
39
50
|
private removeDefaultHighlight;
|
|
51
|
+
private observeTarget;
|
|
52
|
+
private createTargetActivationReporter;
|
|
53
|
+
private removeTargetObservation;
|
|
54
|
+
private removeTargetTracking;
|
|
55
|
+
private deactivateCustomHighlight;
|
|
56
|
+
private removeCustomHighlightForCommand;
|
|
57
|
+
private invokeCustomHighlight;
|
|
58
|
+
private queueCustomHighlightCleanup;
|
|
59
|
+
private clearCustomHighlights;
|
|
40
60
|
private requireInternal;
|
|
41
61
|
private requireString;
|
|
42
62
|
private firstDefined;
|
|
43
63
|
private finish;
|
|
64
|
+
private ensurePrincipal;
|
|
65
|
+
private resetPrincipalState;
|
|
66
|
+
private isCurrentPrincipal;
|
|
44
67
|
private storageKey;
|
|
45
68
|
private loadCompleted;
|
|
46
69
|
private saveCompleted;
|
|
@@ -91,6 +91,12 @@ export type UiCommandActionSnapshot = {
|
|
|
91
91
|
export type HighlightCommandContext = HostCommandContext & {
|
|
92
92
|
active: boolean;
|
|
93
93
|
element?: Element;
|
|
94
|
+
/**
|
|
95
|
+
* Reports the product action caused by this active highlight. Call it
|
|
96
|
+
* synchronously from the host-owned action handler, before navigation. The
|
|
97
|
+
* SDK records only that activation happened; it does not infer its outcome.
|
|
98
|
+
*/
|
|
99
|
+
reportActivation: () => void;
|
|
94
100
|
};
|
|
95
101
|
export type CtaCommandContext = Omit<HostCommandContext, "target"> & {
|
|
96
102
|
label: string;
|
|
@@ -3,8 +3,10 @@ import { AnyCableService } from "./AnyCable.service";
|
|
|
3
3
|
import { NetworkStatus } from "./CableContext.types";
|
|
4
4
|
import type { WidgetConfig } from "@/index.types";
|
|
5
5
|
import type { CommandRuntime } from "@/domain/command/CommandRuntime";
|
|
6
|
+
import { EndUserTypingClient } from "@/domain/message/typing/end-user-typing.client";
|
|
6
7
|
interface CableContextType {
|
|
7
8
|
anycableService: AnyCableService | null;
|
|
9
|
+
endUserTypingClient: EndUserTypingClient;
|
|
8
10
|
networkStatus: NetworkStatus;
|
|
9
11
|
}
|
|
10
12
|
interface CableProviderProps {
|
|
@@ -3,7 +3,7 @@ import type { CommandAck } from "@/domain/command/command.types";
|
|
|
3
3
|
import type { CommandRuntime } from "@/domain/command/CommandRuntime";
|
|
4
4
|
import type { MessageStoreActions } from "@/domain/message/message.store";
|
|
5
5
|
type WidgetFrameDependencies = {
|
|
6
|
-
messageActions: Pick<MessageStoreActions, "handleConversationCreated" | "handleScenarioChoiceLifecycleChanged" | "handleScenarioChoiceSubmissionResult" | "handleMessageDelta" | "handleMessagesAgenticSteps" | "handleMessage" | "handleChatTyping" | "
|
|
6
|
+
messageActions: Pick<MessageStoreActions, "handleConversationCreated" | "handleScenarioChoiceLifecycleChanged" | "handleScenarioChoiceSubmissionResult" | "handleMessageDelta" | "handleMessagesAgenticSteps" | "handleMessage" | "handleChatTyping" | "handleResponderPresentationChanged">;
|
|
7
7
|
commandRuntime: CommandRuntime;
|
|
8
8
|
session: CustomerInteractionSession;
|
|
9
9
|
sendAck: (ack: CommandAck) => Promise<unknown>;
|
|
@@ -20,14 +20,6 @@ export type ChatTypingState = {
|
|
|
20
20
|
conversationId: string;
|
|
21
21
|
actor: "ASSISTANT" | "ADMIN";
|
|
22
22
|
active: boolean;
|
|
23
|
-
displayName?: string;
|
|
24
|
-
avatarUrl?: string | null;
|
|
25
|
-
};
|
|
26
|
-
export type SupportPresenceState = {
|
|
27
|
-
conversationId: string;
|
|
28
|
-
live: boolean;
|
|
29
|
-
displayName?: string;
|
|
30
|
-
avatarUrl?: string | null;
|
|
31
23
|
};
|
|
32
24
|
/**
|
|
33
25
|
* Opt-in future frame fields. Unknown frames are ignored so the SDK remains
|
|
@@ -35,7 +27,6 @@ export type SupportPresenceState = {
|
|
|
35
27
|
*/
|
|
36
28
|
export declare const normalizeChatExperienceFrame: (frame: unknown) => {
|
|
37
29
|
typing: ChatTypingState | null;
|
|
38
|
-
presence: SupportPresenceState | null;
|
|
39
30
|
};
|
|
40
31
|
/**
|
|
41
32
|
* A deterministic transport for visual QA and integration tests. Production
|
|
@@ -2,7 +2,7 @@ import { type AgenticStepsAppendedData, type ChatMessageDeltaData, type Conversa
|
|
|
2
2
|
import type { AppApi } from "@/App";
|
|
3
3
|
import type { WidgetConfig } from "@/index.types";
|
|
4
4
|
import { type MessageStreamState } from "./message-stream";
|
|
5
|
-
import type { ChatAttachment, ChatTypingState
|
|
5
|
+
import type { ChatAttachment, ChatTypingState } from "./chat-experience";
|
|
6
6
|
import type { ResponderPresentationChanged, ScenarioConversationCreated } from "./cable/widget-message";
|
|
7
7
|
import { type ScenarioChoiceLifecycleChanged, type ScenarioChoiceSubmissionResult } from "@/domain/scenario/scenario-choice";
|
|
8
8
|
export interface ThreadSummary {
|
|
@@ -21,6 +21,7 @@ export type PendingCustomerMessage = {
|
|
|
21
21
|
conversationId: string | undefined;
|
|
22
22
|
afterMessageId: string | null;
|
|
23
23
|
acknowledged: boolean;
|
|
24
|
+
acceptanceConfirmed?: boolean;
|
|
24
25
|
canonicalMessageId: string | null;
|
|
25
26
|
attachments: ChatAttachment[];
|
|
26
27
|
readByAssistant: boolean;
|
|
@@ -54,7 +55,14 @@ export type MessageStore = {
|
|
|
54
55
|
responsePhase: AgentResponsePhase;
|
|
55
56
|
sendInFlight: boolean;
|
|
56
57
|
typingByConversation: Map<string, ChatTypingState>;
|
|
57
|
-
|
|
58
|
+
concealedConversationIds: Set<string>;
|
|
59
|
+
concealedMessageIds: Set<string>;
|
|
60
|
+
inactiveConversationIds: Set<string>;
|
|
61
|
+
inactiveConversationUpdatedAt: Map<string, string | null>;
|
|
62
|
+
inactiveConversationRevalidation: Map<string, "ANY_OPEN" | "NEWER_OPEN" | "EXACT_ONLY">;
|
|
63
|
+
conversationScanCandidateIds: Set<string>;
|
|
64
|
+
conversationScanAuthorityVersion: number | null;
|
|
65
|
+
conversationScanSnapshots: Map<string, ConversationData>;
|
|
58
66
|
assistantSuspendedConversationIds: Set<string>;
|
|
59
67
|
actions: MessageStoreActions;
|
|
60
68
|
};
|
|
@@ -68,6 +76,7 @@ export type MessageStoreActions = {
|
|
|
68
76
|
handleScenarioChoiceSubmissionResult: (result: ScenarioChoiceSubmissionResult) => void;
|
|
69
77
|
handleMessage: (message: MessageData) => void;
|
|
70
78
|
handleResponderPresentationChanged: (hint: ResponderPresentationChanged) => void;
|
|
79
|
+
refreshResponderPresentation: (conversationId: string, minimumRevision?: string, retryAfterTransportFailure?: boolean) => void;
|
|
71
80
|
handleMessageDelta: (delta: ChatMessageDeltaData) => void;
|
|
72
81
|
settleMessageStream: (messageId: string) => void;
|
|
73
82
|
sendMessage: (message: string, attachments?: ChatAttachment[]) => Promise<SendMessageResult | undefined>;
|
|
@@ -83,11 +92,10 @@ export type MessageStoreActions = {
|
|
|
83
92
|
cancelThreadMessagesRequest: (conversationId: string) => void;
|
|
84
93
|
cancelConversationPagination: () => void;
|
|
85
94
|
setCurrentThreadMessages: (conversationId: string) => void;
|
|
86
|
-
sendServiceMessage: (message: string) => Promise<void>;
|
|
87
95
|
handleChatTyping: (typing: ChatTypingState) => void;
|
|
88
|
-
|
|
96
|
+
clearTransientRealtimeState: () => void;
|
|
89
97
|
updateConfig: (config: WidgetConfig, api: AppApi) => void;
|
|
90
|
-
recoverMessages: (preserveLoadedConversations?: boolean) => Promise<void>;
|
|
98
|
+
recoverMessages: (preserveLoadedConversations?: boolean, preserveCurrentThread?: boolean) => Promise<void>;
|
|
91
99
|
fetchMoreConversations: () => Promise<void>;
|
|
92
100
|
};
|
|
93
101
|
export declare const useMessageStore: import("zustand").UseBoundStore<import("zustand").StoreApi<MessageStore>>;
|
|
@@ -99,8 +107,9 @@ export declare const useIsLoadingMoreConversations: () => boolean;
|
|
|
99
107
|
export declare const useCurrentThreadId: () => string | undefined;
|
|
100
108
|
export declare const useCurrentResponderPresentation: () => Readonly<{
|
|
101
109
|
contractState: "CURRENT" | "LEGACY" | "INCOMPATIBLE";
|
|
102
|
-
schemaVersion: 0 |
|
|
103
|
-
|
|
110
|
+
schemaVersion: 0 | 2;
|
|
111
|
+
humanSupport: import("@/domain/support-presentation/support-presentation.types").ResponderHumanSupportState | "UNKNOWN";
|
|
112
|
+
ai: import("@/domain/support-presentation/support-presentation.types").ResponderAIState | "UNKNOWN";
|
|
104
113
|
identity: import("@/domain/support-presentation/support-presentation.types").ResponderIdentity;
|
|
105
114
|
displayName: string | null;
|
|
106
115
|
avatarAsset: import("@/domain/support-presentation/support-presentation.types").PresentationAvatarAsset | null;
|
|
@@ -124,8 +133,8 @@ export declare const useIsResponseActive: () => boolean;
|
|
|
124
133
|
export declare const selectCurrentThreadPendingCustomerMessage: (state: MessageStore) => PendingCustomerMessage | null;
|
|
125
134
|
export declare const usePendingCustomerMessage: () => PendingCustomerMessage | null;
|
|
126
135
|
export declare const useMessageStream: (messageId: string) => MessageStreamState | undefined;
|
|
127
|
-
export declare const
|
|
128
|
-
export declare const
|
|
136
|
+
export declare const selectCurrentChatTypingByActor: (state: MessageStore, actor: ChatTypingState["actor"]) => ChatTypingState | null;
|
|
137
|
+
export declare const useCurrentChatTypingByActor: (actor: ChatTypingState["actor"]) => ChatTypingState | null;
|
|
129
138
|
export declare const selectIsCurrentConversationAISuspended: (state: MessageStore) => boolean;
|
|
130
139
|
export declare const useCurrentConversationAISuspended: () => boolean;
|
|
131
140
|
export declare const useMessageStoreActions: () => MessageStoreActions;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const END_USER_TYPING_IDLE_MS = 2000;
|
|
2
|
+
export declare const END_USER_TYPING_RENEW_MS = 3000;
|
|
3
|
+
export type EndUserTypingCommand = Readonly<{
|
|
4
|
+
conversationId: string;
|
|
5
|
+
isTyping: boolean;
|
|
6
|
+
}>;
|
|
7
|
+
export interface EndUserTypingSocket {
|
|
8
|
+
isConnected(): boolean;
|
|
9
|
+
onConnect(listener: () => void): void;
|
|
10
|
+
offConnect(listener: () => void): void;
|
|
11
|
+
connect(): void;
|
|
12
|
+
disconnect(): void;
|
|
13
|
+
send(command: EndUserTypingCommand): void;
|
|
14
|
+
}
|
|
15
|
+
type EndUserTypingSocketFactory = (accessToken: string) => EndUserTypingSocket;
|
|
16
|
+
/**
|
|
17
|
+
* Sends content-free, volatile typing hints for the one conversation being edited.
|
|
18
|
+
* The socket is created lazily and no command is queued while the transport is offline.
|
|
19
|
+
*/
|
|
20
|
+
export declare class EndUserTypingClient {
|
|
21
|
+
private readonly accessToken;
|
|
22
|
+
private readonly socketFactory;
|
|
23
|
+
private readonly now;
|
|
24
|
+
private socket;
|
|
25
|
+
private conversationId;
|
|
26
|
+
private lastPublicationAt;
|
|
27
|
+
private idleTimer;
|
|
28
|
+
constructor(accessToken: string, socketFactory?: EndUserTypingSocketFactory, now?: () => number);
|
|
29
|
+
markActivity(conversationId: string): void;
|
|
30
|
+
stop(): void;
|
|
31
|
+
dispose(): void;
|
|
32
|
+
private readonly handleConnect;
|
|
33
|
+
private publish;
|
|
34
|
+
private ensureSocket;
|
|
35
|
+
private scheduleIdleStop;
|
|
36
|
+
private clearIdleTimer;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { CustomerInteractionSession } from "@/types";
|
|
2
|
+
import { type ScenarioInteractionDraft, type ScenarioInteractionObservation } from "./scenario-interaction.types";
|
|
3
|
+
type CollectorOptions = {
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
queueLimit?: number;
|
|
6
|
+
batchLimit?: number;
|
|
7
|
+
flushIntervalMs?: number;
|
|
8
|
+
requestTimeoutMs?: number;
|
|
9
|
+
fetch?: typeof fetch;
|
|
10
|
+
createId?: () => string;
|
|
11
|
+
now?: () => number;
|
|
12
|
+
random?: () => number;
|
|
13
|
+
};
|
|
14
|
+
export declare class ScenarioInteractionCollector {
|
|
15
|
+
private readonly getSession;
|
|
16
|
+
private readonly onSessionExpired;
|
|
17
|
+
private readonly queue;
|
|
18
|
+
private readonly baseUrl;
|
|
19
|
+
private readonly queueLimit;
|
|
20
|
+
private readonly batchLimit;
|
|
21
|
+
private readonly flushIntervalMs;
|
|
22
|
+
private readonly requestTimeoutMs;
|
|
23
|
+
private readonly fetchImpl;
|
|
24
|
+
private readonly createId;
|
|
25
|
+
private readonly now;
|
|
26
|
+
private readonly random;
|
|
27
|
+
private sequence;
|
|
28
|
+
private capabilities;
|
|
29
|
+
private capabilityRequest;
|
|
30
|
+
private flushRequest;
|
|
31
|
+
private capabilityRequestControl;
|
|
32
|
+
private batchRequestControl;
|
|
33
|
+
private batchRequestUsesKeepalive;
|
|
34
|
+
private flushTimer;
|
|
35
|
+
private retryTimer;
|
|
36
|
+
private capabilityRetryTimer;
|
|
37
|
+
private retryAttempt;
|
|
38
|
+
private capabilityRetryAttempt;
|
|
39
|
+
private batchRetriesSuspended;
|
|
40
|
+
private capabilityRetriesSuspended;
|
|
41
|
+
private awaitingRenewalToken;
|
|
42
|
+
private sessionGeneration;
|
|
43
|
+
private quotaBlockedUntil;
|
|
44
|
+
private admissionWindowStartedAt;
|
|
45
|
+
private admissionCount;
|
|
46
|
+
private started;
|
|
47
|
+
private destroyed;
|
|
48
|
+
private principalSessionId;
|
|
49
|
+
private principalAccessToken;
|
|
50
|
+
constructor(getSession: () => CustomerInteractionSession, onSessionExpired: () => void, options?: CollectorOptions);
|
|
51
|
+
start(): void;
|
|
52
|
+
destroy(): void;
|
|
53
|
+
updateSession(session: CustomerInteractionSession): boolean;
|
|
54
|
+
enqueue(draft: ScenarioInteractionDraft): string | null;
|
|
55
|
+
getQueueSnapshot(): readonly ScenarioInteractionObservation[];
|
|
56
|
+
isSendingEnabled(): boolean;
|
|
57
|
+
getPrincipalSessionId(): string;
|
|
58
|
+
flush(options?: {
|
|
59
|
+
keepalive?: boolean;
|
|
60
|
+
}): Promise<void>;
|
|
61
|
+
private readonly onOnlineOrFocus;
|
|
62
|
+
private readonly onVisibilityChange;
|
|
63
|
+
private readonly onPageHide;
|
|
64
|
+
private buildObservation;
|
|
65
|
+
private buildDetails;
|
|
66
|
+
private ensureCapabilities;
|
|
67
|
+
private loadCapabilities;
|
|
68
|
+
private flushOnce;
|
|
69
|
+
private selectBatch;
|
|
70
|
+
private dropUnsupportedObservations;
|
|
71
|
+
private isSupported;
|
|
72
|
+
private sessionNeedsRenewal;
|
|
73
|
+
private isCurrentGeneration;
|
|
74
|
+
private nextSequence;
|
|
75
|
+
private abortPendingRequests;
|
|
76
|
+
private createRequestControl;
|
|
77
|
+
private finishRequestControl;
|
|
78
|
+
private handleUnauthorized;
|
|
79
|
+
private scheduleFlush;
|
|
80
|
+
private scheduleRetry;
|
|
81
|
+
private scheduleCapabilityRetry;
|
|
82
|
+
private clearFlushTimer;
|
|
83
|
+
private clearTimers;
|
|
84
|
+
private clearRetryTimer;
|
|
85
|
+
private clearCapabilityRetryTimer;
|
|
86
|
+
private retryDelay;
|
|
87
|
+
private disableSending;
|
|
88
|
+
private admitWithinSessionQuota;
|
|
89
|
+
private isQuotaBlocked;
|
|
90
|
+
}
|
|
91
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CustomerInteractionSession } from "@/types";
|
|
2
|
+
import { ScenarioInteractionCollector } from "./ScenarioInteractionCollector";
|
|
3
|
+
import type { EngagementSubject, PresentationSubject, SurfaceState, SurfaceTransition, SurfaceTransitionContext } from "./scenario-interaction.types";
|
|
4
|
+
type RuntimeOptions = ConstructorParameters<typeof ScenarioInteractionCollector>[2];
|
|
5
|
+
export declare class ScenarioInteractionRuntime {
|
|
6
|
+
readonly collector: ScenarioInteractionCollector;
|
|
7
|
+
private readonly surfaceController;
|
|
8
|
+
private readonly presented;
|
|
9
|
+
private readonly engaged;
|
|
10
|
+
constructor(getSession: () => CustomerInteractionSession, onSessionExpired: () => void, options?: RuntimeOptions);
|
|
11
|
+
start(): void;
|
|
12
|
+
destroy(): void;
|
|
13
|
+
updateSession(session: CustomerInteractionSession): void;
|
|
14
|
+
transitionSurface(nextState: SurfaceState, context: SurfaceTransitionContext): SurfaceTransition;
|
|
15
|
+
getSurfaceState(): SurfaceState;
|
|
16
|
+
getSurfaceEpisodeId(): string | null;
|
|
17
|
+
getPrincipalSessionId(): string;
|
|
18
|
+
recordPresented(subject: PresentationSubject, expectedEpisodeId?: string | null): boolean;
|
|
19
|
+
recordEngagement(subject: EngagementSubject): boolean;
|
|
20
|
+
recordTargetPresented(commandId: string, surfaceEpisodeId?: string | null): boolean;
|
|
21
|
+
recordTargetActivation(commandId: string, surfaceEpisodeId?: string | null): boolean;
|
|
22
|
+
observeHighlightedTarget(input: {
|
|
23
|
+
element: Element;
|
|
24
|
+
commandId: string;
|
|
25
|
+
}): () => void;
|
|
26
|
+
private markCurrentTargetContext;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ScenarioInteractionDraft, SurfaceState, SurfaceTransition, SurfaceTransitionContext } from "./scenario-interaction.types";
|
|
2
|
+
export declare class SurfaceController {
|
|
3
|
+
private readonly observe;
|
|
4
|
+
private readonly createId;
|
|
5
|
+
private state;
|
|
6
|
+
private episode;
|
|
7
|
+
constructor(observe: (draft: ScenarioInteractionDraft) => void, createId?: () => string);
|
|
8
|
+
transition(nextState: SurfaceState, context: SurfaceTransitionContext): SurfaceTransition;
|
|
9
|
+
getState(): SurfaceState;
|
|
10
|
+
getEpisodeId(): string | null;
|
|
11
|
+
markScenarioContext(attributionHandle: string): void;
|
|
12
|
+
replacePrincipal(): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const PRESENTATION_INTERSECTION_RATIO = 0.5;
|
|
2
|
+
export declare const PRESENTATION_DWELL_MS = 500;
|
|
3
|
+
type PresentationObserverInput = {
|
|
4
|
+
element: Element;
|
|
5
|
+
isActive: () => boolean;
|
|
6
|
+
isPresentable?: () => boolean;
|
|
7
|
+
onPresented: () => void;
|
|
8
|
+
intersectionRatio?: number;
|
|
9
|
+
dwellMs?: number;
|
|
10
|
+
};
|
|
11
|
+
export declare const observePresentedElement: ({ element, isActive, isPresentable, onPresented, intersectionRatio, dwellMs, }: PresentationObserverInput) => (() => void);
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ScenarioInteractionRuntime } from "./ScenarioInteractionRuntime";
|
|
2
|
+
export type ScenarioInteractionContextValue = {
|
|
3
|
+
open: boolean;
|
|
4
|
+
surfaceEpisodeId: string | null;
|
|
5
|
+
runtime: ScenarioInteractionRuntime;
|
|
6
|
+
};
|
|
7
|
+
export declare const ScenarioInteractionContext: import("react").Context<ScenarioInteractionContextValue | null>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export declare const SCENARIO_INTERACTION_VERSION: 1;
|
|
2
|
+
export declare const SCENARIO_INTERACTION_KINDS: readonly ["SURFACE_STATE_CHANGED", "EXPERIENCE_PRESENTED", "EXPERIENCE_ENGAGED"];
|
|
3
|
+
export declare const SCENARIO_INTERACTION_TYPES: readonly ["CHAT_OPENED", "CHAT_CLOSED", "MESSAGE_PRESENTED", "CHOICE_PRESENTED", "CTA_PRESENTED", "CTA_CLICKED", "CTA_DISMISSED", "TARGET_PRESENTED", "TARGET_ACTIVATED"];
|
|
4
|
+
export declare const SCENARIO_INTERACTION_ACTORS: readonly ["USER", "SCENARIO", "HOST"];
|
|
5
|
+
export declare const SCENARIO_INTERACTION_SUBJECT_KINDS: readonly ["SURFACE", "MESSAGE", "CHOICE", "CTA", "TARGET"];
|
|
6
|
+
export declare const SCENARIO_INTERACTION_RESULTS: readonly ["SUCCEEDED", "FAILED"];
|
|
7
|
+
export declare const SCENARIO_INTERACTION_REASONS: readonly ["USER_LAUNCHER", "USER_CLOSE_BUTTON", "HOST_SET_OPEN", "SCENARIO_COMMAND", "UNKNOWN"];
|
|
8
|
+
export type ScenarioInteractionKind = (typeof SCENARIO_INTERACTION_KINDS)[number];
|
|
9
|
+
export type ScenarioInteractionType = (typeof SCENARIO_INTERACTION_TYPES)[number];
|
|
10
|
+
export type ScenarioInteractionActor = (typeof SCENARIO_INTERACTION_ACTORS)[number];
|
|
11
|
+
export type ScenarioInteractionSubjectKind = (typeof SCENARIO_INTERACTION_SUBJECT_KINDS)[number];
|
|
12
|
+
export type ScenarioInteractionResult = (typeof SCENARIO_INTERACTION_RESULTS)[number];
|
|
13
|
+
export type ScenarioInteractionReason = (typeof SCENARIO_INTERACTION_REASONS)[number];
|
|
14
|
+
export type ScenarioInteractionDetails = {
|
|
15
|
+
presentationOrdinal?: number;
|
|
16
|
+
};
|
|
17
|
+
export type ScenarioInteractionObservation = {
|
|
18
|
+
clientObservationId: string;
|
|
19
|
+
version: typeof SCENARIO_INTERACTION_VERSION;
|
|
20
|
+
kind: ScenarioInteractionKind;
|
|
21
|
+
type: ScenarioInteractionType;
|
|
22
|
+
actor: ScenarioInteractionActor;
|
|
23
|
+
occurredAt: string;
|
|
24
|
+
sequence: number;
|
|
25
|
+
surfaceEpisodeId?: string;
|
|
26
|
+
subjectKind?: ScenarioInteractionSubjectKind;
|
|
27
|
+
subjectId?: string;
|
|
28
|
+
result?: ScenarioInteractionResult;
|
|
29
|
+
reason?: ScenarioInteractionReason;
|
|
30
|
+
attributionHandle?: string;
|
|
31
|
+
details?: ScenarioInteractionDetails;
|
|
32
|
+
};
|
|
33
|
+
export type ScenarioInteractionDraft = Omit<ScenarioInteractionObservation, "clientObservationId" | "version" | "occurredAt" | "sequence">;
|
|
34
|
+
export type ScenarioInteractionCapabilities = {
|
|
35
|
+
version: number;
|
|
36
|
+
maxBatchItems: number;
|
|
37
|
+
maxRequestBytes: number;
|
|
38
|
+
sessionHourlyLimit: number;
|
|
39
|
+
retentionDays: number;
|
|
40
|
+
kinds: readonly ScenarioInteractionKind[];
|
|
41
|
+
types: readonly ScenarioInteractionType[];
|
|
42
|
+
actors: readonly ScenarioInteractionActor[];
|
|
43
|
+
attributionHandleSupported: boolean;
|
|
44
|
+
};
|
|
45
|
+
export type ScenarioInteractionReceipt = {
|
|
46
|
+
clientObservationId: string;
|
|
47
|
+
status: "ACCEPTED" | "DUPLICATE" | "IGNORED_NO_INTEREST" | "REJECTED";
|
|
48
|
+
code?: string | null;
|
|
49
|
+
observationId?: string | null;
|
|
50
|
+
runId?: string | null;
|
|
51
|
+
};
|
|
52
|
+
export type ScenarioInteractionBatchResponse = {
|
|
53
|
+
receipts: ScenarioInteractionReceipt[];
|
|
54
|
+
};
|
|
55
|
+
export type SurfaceState = "OPEN" | "CLOSED";
|
|
56
|
+
export type SurfaceTransitionActor = ScenarioInteractionActor | "SYSTEM";
|
|
57
|
+
/** Exact SDK-local reasons; state-changing reasons are preserved on the wire. */
|
|
58
|
+
export type SurfaceTransitionReason = "USER_LAUNCHER" | "USER_CLOSE_BUTTON" | "VOICE_SWITCH_TO_TEXT" | "HOST_SET_OPEN" | "SCENARIO_COMMAND" | "SYSTEM_RESTORE";
|
|
59
|
+
export type SurfaceTransitionContext = {
|
|
60
|
+
actor: SurfaceTransitionActor;
|
|
61
|
+
reason: SurfaceTransitionReason;
|
|
62
|
+
sourceCommandId?: string;
|
|
63
|
+
};
|
|
64
|
+
export type SurfaceTransition = {
|
|
65
|
+
changed: boolean;
|
|
66
|
+
from: SurfaceState;
|
|
67
|
+
to: SurfaceState;
|
|
68
|
+
episodeId: string | null;
|
|
69
|
+
context: SurfaceTransitionContext;
|
|
70
|
+
};
|
|
71
|
+
export type PresentationSubject = {
|
|
72
|
+
subjectKind: Extract<ScenarioInteractionSubjectKind, "MESSAGE" | "CHOICE" | "CTA" | "TARGET">;
|
|
73
|
+
subjectId: string;
|
|
74
|
+
actor?: ScenarioInteractionActor;
|
|
75
|
+
attributionHandle?: string;
|
|
76
|
+
presentationOrdinal?: number;
|
|
77
|
+
};
|
|
78
|
+
export type EngagementSubject = {
|
|
79
|
+
type: Extract<ScenarioInteractionType, "CTA_CLICKED" | "CTA_DISMISSED" | "TARGET_ACTIVATED">;
|
|
80
|
+
subjectKind: Extract<ScenarioInteractionSubjectKind, "CTA" | "TARGET">;
|
|
81
|
+
subjectId: string;
|
|
82
|
+
attributionHandle?: string;
|
|
83
|
+
result?: ScenarioInteractionResult;
|
|
84
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
import type { PresentationSubject } from "./scenario-interaction.types";
|
|
3
|
+
import type { ScenarioInteractionRuntime } from "./ScenarioInteractionRuntime";
|
|
4
|
+
export declare const useScenarioPresentation: (runtime: ScenarioInteractionRuntime | undefined, ref: RefObject<Element | null>, active: boolean, episodeId: string | null, subject: PresentationSubject | null, isPresentable?: () => boolean) => void;
|
|
@@ -34,11 +34,13 @@ export declare class PresentationAvatarResolver {
|
|
|
34
34
|
private readonly queue;
|
|
35
35
|
private readonly authorityListeners;
|
|
36
36
|
private readonly conversationEpochs;
|
|
37
|
+
private readonly activeKeys;
|
|
37
38
|
private activeCount;
|
|
38
39
|
private generation;
|
|
39
40
|
constructor(config: WidgetConfig, api: AppApi, options?: ResolverOptions);
|
|
40
41
|
resolve(request: PresentationAvatarRequest): Promise<ResolvedPresentationAvatar | null>;
|
|
41
42
|
private drainQueue;
|
|
43
|
+
private releaseActiveSlot;
|
|
42
44
|
private trimCache;
|
|
43
45
|
private loadGrant;
|
|
44
46
|
replaceSession(config: WidgetConfig, api: AppApi): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type SafeResponderPresentation } from "./support-presentation.types";
|
|
2
|
+
export type ResponderReconciliationOutcome = "APPLIED" | "REPLAY" | "STALE" | "HINT_AHEAD" | "INCOMPATIBLE";
|
|
3
|
+
export type ResponderReconciliation = Readonly<{
|
|
4
|
+
presentation: SafeResponderPresentation;
|
|
5
|
+
outcome: ResponderReconciliationOutcome;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const compareResponderRevisions: (left: string, right: string) => number;
|
|
8
|
+
/**
|
|
9
|
+
* The one merge rule for REST snapshots and revision-only realtime hints.
|
|
10
|
+
* The backend owns the compound revision; consumers never compare or advance
|
|
11
|
+
* individual source revisions themselves.
|
|
12
|
+
*/
|
|
13
|
+
export declare function reconcileResponderPresentation(current: SafeResponderPresentation | undefined, incoming: SafeResponderPresentation, minimumRevision?: string): ResponderReconciliation;
|