@alxxsck/ai-assistant 1.0.0 → 1.2.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 +12 -12
- package/dist/{Avatar-XISRbl7X.js → Avatar-B6ktAPlH.js} +23 -5
- package/dist/{OrbitControls-XelJ40xM.js → OrbitControls-BE3BANZi.js} +1 -1
- package/dist/api/audio.api.d.ts +20 -0
- package/dist/api/voice.api.d.ts +8 -63
- package/dist/api/voice.api.types.d.ts +15 -31
- package/dist/avatar/AnimationManager.d.ts +3 -1
- package/dist/avatar/Avatar.d.ts +4 -0
- package/dist/bridge-ai-chat-widget.es.js +3948 -3996
- package/dist/domain/command/CommandRuntime.d.ts +3 -1
- package/dist/domain/command/command.types.d.ts +24 -1
- package/dist/domain/message/cable/widget-frame.d.ts +13 -0
- package/dist/domain/message/cable/widget-message.d.ts +2 -1
- package/dist/domain/message/message.store.d.ts +3 -3
- package/dist/domain/speech/SpeechPlayer.d.ts +15 -0
- package/dist/domain/speech/speech.constants.d.ts +5 -0
- package/dist/domain/voice/voice.store.d.ts +14 -45
- package/dist/hooks/useSessionExpiryChecks.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.types.d.ts +2 -2
- package/dist/lib/isSessionExpired.d.ts +2 -1
- package/dist/ui/chat-routes.d.ts +2 -0
- package/package.json +3 -3
- package/dist/api/messages.api.utils.d.ts +0 -2
- package/dist/hooks/useDeviceManager.d.ts +0 -25
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { CustomerInteractionSession } from "@/types";
|
|
2
|
-
import { type CommandAck, type CommandEnvelope, type CommandEventDetail, type CtaCommandContext, type HostCommandHandlerName, type HostCommandHandlers, type UiTarget } from "./command.types";
|
|
2
|
+
import { type CommandAck, type CommandEnvelope, type CommandEventDetail, type CtaCommandContext, type HostCommandHandlerName, type HostCommandHandlers, type SpeakTextCommandContext, type StartVoiceConversationCommandContext, type UiTarget } from "./command.types";
|
|
3
3
|
type AckSender = (ack: CommandAck) => Promise<unknown>;
|
|
4
4
|
type InternalHandlers = {
|
|
5
5
|
setAssistantVisible?: (visible: boolean) => void;
|
|
6
6
|
setChatOpen?: (open: boolean) => void;
|
|
7
7
|
playAnimation?: (animation: string) => void;
|
|
8
8
|
showCta?: (context: CtaCommandContext) => void;
|
|
9
|
+
speakText?: (context: SpeakTextCommandContext) => void | Promise<void>;
|
|
10
|
+
startVoiceConversation?: (context: StartVoiceConversationCommandContext) => void | Promise<void>;
|
|
9
11
|
};
|
|
10
12
|
export declare class CommandRuntime {
|
|
11
13
|
private readonly onStatus?;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import type { StreamingSpeechMimeType } from "@/domain/speech/speech.constants";
|
|
2
|
+
export declare const COMMAND_TYPES: readonly ["show_assistant", "hide_assistant", "open_chat", "close_chat", "play_animation", "highlight_element", "remove_highlight", "show_cta", "speak_text", "start_voice_conversation", "open_page", "open_modal"];
|
|
2
3
|
export type CommandType = (typeof COMMAND_TYPES)[number];
|
|
3
4
|
export type CommandAckStatus = "received" | "succeeded" | "failed" | "expired" | "unsupported";
|
|
4
5
|
export type CommandAck = {
|
|
@@ -57,6 +58,28 @@ export type CtaCommandContext = Omit<HostCommandContext, "target"> & {
|
|
|
57
58
|
action: "none" | "open_modal" | "open_page";
|
|
58
59
|
target?: string;
|
|
59
60
|
};
|
|
61
|
+
export type StartVoiceConversationCommandContext = {
|
|
62
|
+
commandId: string;
|
|
63
|
+
commandType: "start_voice_conversation";
|
|
64
|
+
voiceSessionId: string;
|
|
65
|
+
conversationId: string;
|
|
66
|
+
messageId: string;
|
|
67
|
+
text: string;
|
|
68
|
+
voice: string;
|
|
69
|
+
requiresUserGesture: true;
|
|
70
|
+
webrtcPath: string;
|
|
71
|
+
introAudioPath: string;
|
|
72
|
+
};
|
|
73
|
+
export type SpeakTextCommandContext = {
|
|
74
|
+
commandId: string;
|
|
75
|
+
commandType: "speak_text";
|
|
76
|
+
audioPath: string;
|
|
77
|
+
method: "POST";
|
|
78
|
+
mimeType: StreamingSpeechMimeType;
|
|
79
|
+
format: "pcm16";
|
|
80
|
+
sampleRate: 24_000;
|
|
81
|
+
channels: 1;
|
|
82
|
+
};
|
|
60
83
|
export type HostCommandHandlers = {
|
|
61
84
|
openPage?: (context: HostCommandContext) => void | Promise<void>;
|
|
62
85
|
openModal?: (context: HostCommandContext) => void | Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CustomerInteractionSession } from "@/types";
|
|
2
|
+
import type { CommandAck } from "@/domain/command/command.types";
|
|
3
|
+
import type { CommandRuntime } from "@/domain/command/CommandRuntime";
|
|
4
|
+
import type { MessageStoreActions } from "@/domain/message/message.store";
|
|
5
|
+
type WidgetFrameDependencies = {
|
|
6
|
+
messageActions: Pick<MessageStoreActions, "handleConversationCreated" | "handleMessagesAgenticSteps" | "handleMessage">;
|
|
7
|
+
commandRuntime: CommandRuntime;
|
|
8
|
+
session: CustomerInteractionSession;
|
|
9
|
+
sendAck: (ack: CommandAck) => Promise<unknown>;
|
|
10
|
+
onPresenceOnline: () => void;
|
|
11
|
+
};
|
|
12
|
+
export declare const dispatchWidgetFrame: (message: unknown, dependencies: WidgetFrameDependencies) => Promise<void> | null;
|
|
13
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import type { AgenticStepsAppendedData, MessageData } from "@/api/messages.api.types";
|
|
1
|
+
import type { AgenticStepsAppendedData, ConversationData, MessageData } from "@/api/messages.api.types";
|
|
2
|
+
export declare const getConversationCreatedFromFrame: (frame: unknown) => ConversationData | null;
|
|
2
3
|
export declare const getMessageFromFrame: (frame: unknown) => MessageData | null;
|
|
3
4
|
export declare const getAgenticStepsFromFrame: (frame: unknown) => AgenticStepsAppendedData | null;
|
|
@@ -20,12 +20,13 @@ export type MessageStore = {
|
|
|
20
20
|
latestMessageDate: string | null;
|
|
21
21
|
actions: MessageStoreActions;
|
|
22
22
|
};
|
|
23
|
-
type MessageStoreActions = {
|
|
23
|
+
export type MessageStoreActions = {
|
|
24
24
|
initMessageStore: (config: WidgetConfig, api: AppApi) => Promise<void>;
|
|
25
25
|
setCurrentThread: (conversationId: string) => Promise<void>;
|
|
26
26
|
createNewConversation: () => Promise<string>;
|
|
27
|
+
handleConversationCreated: (conversation: ConversationData) => void;
|
|
27
28
|
handleMessage: (message: MessageData) => void;
|
|
28
|
-
sendMessage: (message: string) => Promise<
|
|
29
|
+
sendMessage: (message: string) => Promise<MessageData | undefined>;
|
|
29
30
|
clearSendError: () => void;
|
|
30
31
|
getThreadsSummaryData: () => ThreadSummary[];
|
|
31
32
|
setLatestReadMessageDate: (readMessageDate: string) => void;
|
|
@@ -48,4 +49,3 @@ export declare const useLatestReadMessageDate: () => string | null;
|
|
|
48
49
|
export declare const useLatestMessageDate: () => string | null;
|
|
49
50
|
export declare const useSendError: () => string | null;
|
|
50
51
|
export declare const useMessageStoreActions: () => MessageStoreActions;
|
|
51
|
-
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type SpeechPlaybackOptions = {
|
|
2
|
+
onStarted?: () => void;
|
|
3
|
+
};
|
|
4
|
+
export type PcmStreamLoader = (signal: AbortSignal) => Promise<ReadableStream<Uint8Array>>;
|
|
5
|
+
export type PcmPlaybackOptions = SpeechPlaybackOptions & {
|
|
6
|
+
sampleRate: number;
|
|
7
|
+
jitterBufferMs?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare class SpeechPlayer {
|
|
10
|
+
private active;
|
|
11
|
+
get isPlaying(): boolean;
|
|
12
|
+
play(audioBlob: Blob, options?: SpeechPlaybackOptions): Promise<boolean>;
|
|
13
|
+
playPcm16(loadStream: PcmStreamLoader, options: PcmPlaybackOptions): Promise<boolean>;
|
|
14
|
+
stop(): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const PROTECTED_SPEECH_MIME_TYPE: "audio/wav";
|
|
2
|
+
export declare const STREAMING_SPEECH_MIME_TYPE: "audio/pcm";
|
|
3
|
+
export type ProtectedSpeechMimeType = typeof PROTECTED_SPEECH_MIME_TYPE;
|
|
4
|
+
export type StreamingSpeechMimeType = typeof STREAMING_SPEECH_MIME_TYPE;
|
|
5
|
+
export type ProtectedAudioMimeType = ProtectedSpeechMimeType | StreamingSpeechMimeType;
|
|
@@ -1,69 +1,38 @@
|
|
|
1
1
|
import type { AppApi } from "@/App";
|
|
2
2
|
import type { VoiceSessionData } from "@/api/voice.api.types";
|
|
3
|
+
import type { SpeakTextCommandContext, StartVoiceConversationCommandContext } from "@/domain/command/command.types";
|
|
3
4
|
import type { WidgetConfig } from "@/index.types";
|
|
4
|
-
|
|
5
|
-
export interface GetLocalStreamArgs {
|
|
6
|
-
/** Optional audio input device ID */
|
|
7
|
-
inputAudioDeviceId?: string;
|
|
8
|
-
}
|
|
9
|
-
type VoiceStatus = "idle" | "connecting" | "live" | "ending" | "error";
|
|
5
|
+
type VoiceStatus = "idle" | "connecting" | "listening" | "speaking" | "error";
|
|
10
6
|
type VoiceStore = {
|
|
11
|
-
activeVoiceSessionData: VoiceSessionData | null;
|
|
12
7
|
config: WidgetConfig | null;
|
|
13
8
|
api: AppApi | null;
|
|
9
|
+
session: VoiceSessionData | null;
|
|
14
10
|
status: VoiceStatus;
|
|
15
11
|
errorMessage: string | null;
|
|
16
|
-
isVoiceBootstrapped: boolean;
|
|
17
12
|
connection: RTCPeerConnection | null;
|
|
18
|
-
|
|
19
|
-
connectionGeneration: number | null;
|
|
20
|
-
iceCandidates: RTCIceCandidateInit[];
|
|
21
|
-
voiceEventsChannel: RTCDataChannel | null;
|
|
22
|
-
voiceInputChannel: RTCDataChannel | null;
|
|
23
|
-
downstream: MediaStream | null;
|
|
13
|
+
eventsChannel: RTCDataChannel | null;
|
|
24
14
|
localStream: MediaStream | null;
|
|
15
|
+
remoteStream: MediaStream | null;
|
|
25
16
|
remoteAudioElement: HTMLAudioElement | null;
|
|
17
|
+
pendingInvitation: StartVoiceConversationCommandContext | null;
|
|
26
18
|
customerMessageTranscript: string;
|
|
27
19
|
customerMessageTranscriptVisible: boolean;
|
|
28
20
|
assistantMessageTranscript: string;
|
|
29
21
|
assistantMessageTranscriptVisible: boolean;
|
|
30
22
|
assistantResponseInProgress: boolean;
|
|
31
23
|
microphoneEnabled: boolean;
|
|
32
|
-
|
|
33
|
-
audioInputDevices: MediaDeviceInfo[];
|
|
24
|
+
generation: number;
|
|
34
25
|
actions: VoiceStoreActions;
|
|
35
26
|
};
|
|
36
27
|
type VoiceStoreActions = {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
setMicrophoneEnabled: (enabled: boolean) => void;
|
|
45
|
-
sendOffer: (offer: RTCSessionDescriptionInit) => Promise<void>;
|
|
46
|
-
getLocalStream: (deviceId?: string) => Promise<MediaStream | null>;
|
|
47
|
-
setNewLocalStream: () => Promise<void>;
|
|
48
|
-
createAudioTrack: () => Promise<MediaStreamTrack | null>;
|
|
49
|
-
attachAudioTrack: (newTrack: MediaStreamTrack, { replaceExisting }: {
|
|
50
|
-
replaceExisting: boolean;
|
|
51
|
-
}) => Promise<MediaStreamTrack>;
|
|
52
|
-
ensureAudioTrack: () => Promise<boolean>;
|
|
53
|
-
recreateAudioTrack: () => Promise<boolean>;
|
|
54
|
-
enableMicrophone: () => Promise<void>;
|
|
55
|
-
disableMicrophone: () => void;
|
|
56
|
-
switchAudio: () => Promise<void>;
|
|
57
|
-
refreshAudioProcessing: () => Promise<void>;
|
|
58
|
-
switchInputAudioDevice: (newDevice: MediaDeviceInfo) => Promise<void>;
|
|
28
|
+
startListening: (config: WidgetConfig, api: AppApi) => Promise<void>;
|
|
29
|
+
offerConversation: (invitation: StartVoiceConversationCommandContext) => Promise<void>;
|
|
30
|
+
acceptConversation: (config: WidgetConfig, api: AppApi) => Promise<void>;
|
|
31
|
+
declineConversation: (config: WidgetConfig, api: AppApi) => Promise<void>;
|
|
32
|
+
speakText: (config: WidgetConfig, api: AppApi, speech: SpeakTextCommandContext) => Promise<void>;
|
|
33
|
+
stopListening: () => void;
|
|
34
|
+
endVoiceChat: (reason?: string) => Promise<void>;
|
|
59
35
|
};
|
|
60
36
|
export declare const useVoiceStore: import("zustand").UseBoundStore<import("zustand").StoreApi<VoiceStore>>;
|
|
61
37
|
export declare const useVoiceStoreActions: () => VoiceStoreActions;
|
|
62
|
-
export declare const useMicrophoneEnabled: () => boolean;
|
|
63
|
-
export declare const useInputAudioDevice: () => MediaDeviceInfo | null;
|
|
64
|
-
export declare const useLocalStream: () => MediaStream | null;
|
|
65
|
-
export declare const useConnection: () => RTCPeerConnection | null;
|
|
66
|
-
export declare const useConnectionId: () => string | null;
|
|
67
|
-
export declare const useDownstream: () => MediaStream | null;
|
|
68
|
-
export declare const useCustomerMessageTranscript: () => string;
|
|
69
38
|
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { AppApi } from "@/App";
|
|
2
2
|
import type { WidgetConfig } from "@/index.types";
|
|
3
|
-
export declare function useSessionExpiryChecks(config: WidgetConfig, api: AppApi
|
|
3
|
+
export declare function useSessionExpiryChecks(config: WidgetConfig, api: AppApi): void;
|
package/dist/index.d.ts
CHANGED
package/dist/index.types.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type WidgetConfig = {
|
|
|
9
9
|
customerId?: string;
|
|
10
10
|
wsUrl: string;
|
|
11
11
|
apiUrl: string;
|
|
12
|
-
|
|
12
|
+
/** Optional Lola Realtime voice passed when creating a voice session. */
|
|
13
13
|
voiceConfig?: {
|
|
14
14
|
voice: string;
|
|
15
15
|
};
|
|
@@ -47,4 +47,4 @@ export declare class ChatWidgetInstance extends EventTarget {
|
|
|
47
47
|
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
48
48
|
}
|
|
49
49
|
export type { CustomerInteractionSession };
|
|
50
|
-
export type { CommandAck, CommandAckStatus, CommandEnvelope, CommandEventDetail, CommandType, CtaCommandContext, HighlightCommandContext, HostCommandContext, HostCommandHandler, HostCommandHandlerName, HostCommandHandlers, UiTarget, UiTargetKind, } from "./domain/command/command.types";
|
|
50
|
+
export type { CommandAck, CommandAckStatus, CommandEnvelope, CommandEventDetail, CommandType, CtaCommandContext, HighlightCommandContext, HostCommandContext, HostCommandHandler, HostCommandHandlerName, HostCommandHandlers, SpeakTextCommandContext, StartVoiceConversationCommandContext, UiTarget, UiTargetKind, } from "./domain/command/command.types";
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { CustomerInteractionSession } from "@/types";
|
|
2
|
-
export declare
|
|
2
|
+
export declare const SESSION_RENEWAL_BUFFER_MS: number;
|
|
3
|
+
export declare function isSessionExpiringSoon(session: CustomerInteractionSession, now?: number): boolean;
|
package/dist/ui/chat-routes.d.ts
CHANGED
|
@@ -9,3 +9,5 @@ export declare const CHAT_PATHS: {
|
|
|
9
9
|
};
|
|
10
10
|
export declare function getChatModeFromPathname(pathname: string): ChatMode;
|
|
11
11
|
export declare function isChatListPath(pathname: string): boolean;
|
|
12
|
+
export declare function isVoiceChatPath(pathname: string): boolean;
|
|
13
|
+
export declare function shouldOpenIncomingMessageInTextMode(pathname: string): boolean;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alxxsck/ai-assistant",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.2.0",
|
|
5
5
|
"description": "Embeddable chat widget for communication with Bridge AI agent",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/bridge-ai-chat-widget.es.js",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"preview": "vite preview",
|
|
42
42
|
"prepublishOnly": "npm run build-lib",
|
|
43
43
|
"clean-g-spot-prod-bucket": "aws s3 rm s3://bridgeapp-ai-chat-widget-dev.com --recursive",
|
|
44
|
-
"upload-g-spot-prod-bucket": "aws s3 cp dist s3://bridgeapp-ai-chat-widget-dev.com/g-spot-prod --recursive",
|
|
44
|
+
"upload-g-spot-prod-bucket": "aws s3 cp dist-demo s3://bridgeapp-ai-chat-widget-dev.com/g-spot-prod --recursive",
|
|
45
45
|
"clean-bridge-demo-bucket": "aws s3 rm s3://bridge-ai-assistant --recursive",
|
|
46
|
-
"upload-bridge-demo-bucket": "aws s3 cp dist s3://bridge-ai-assistant/bridge-demo --recursive",
|
|
46
|
+
"upload-bridge-demo-bucket": "aws s3 cp dist-demo s3://bridge-ai-assistant/bridge-demo --recursive",
|
|
47
47
|
"push-assets-metamediastatic": "bash scripts/push-assets-to-metamediastatic.sh"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hook for managing media devices (audio input, audio output, video input) in
|
|
3
|
-
* video calls.
|
|
4
|
-
*
|
|
5
|
-
* This hook provides:
|
|
6
|
-
*
|
|
7
|
-
* - Automatic device enumeration and updates
|
|
8
|
-
* - Device change event listening
|
|
9
|
-
* - Automatic fallback to available devices when current device is disconnected
|
|
10
|
-
* - Permission handling for device access
|
|
11
|
-
*
|
|
12
|
-
* The hook automatically:
|
|
13
|
-
*
|
|
14
|
-
* - Enumerates available devices on mount
|
|
15
|
-
* - Listens for device changes (connect/disconnect)
|
|
16
|
-
* - Switches to the first available device if the current device becomes
|
|
17
|
-
* unavailable
|
|
18
|
-
* - Requests microphone permission if needed to get device labels
|
|
19
|
-
*
|
|
20
|
-
* @returns Void - This hook doesn't return any values, it manages device state
|
|
21
|
-
* internally
|
|
22
|
-
*/
|
|
23
|
-
export declare const useDeviceManager: () => {
|
|
24
|
-
updateDevices: (e?: Event) => Promise<void>;
|
|
25
|
-
};
|