@smooai/chat-widget 0.13.0 → 0.14.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/chat-widget.global.js +472 -39
- package/dist/chat-widget.global.js.map +1 -1
- package/dist/index.d.ts +197 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +499 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +18 -1
- package/src/conversation.ts +23 -1
- package/src/element.ts +114 -1
- package/src/index.ts +19 -1
- package/src/styles.ts +41 -0
- package/src/voice-session.ts +420 -0
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,17 @@ import { Citation } from "@smooai/smooth-operator";
|
|
|
2
2
|
import { StoreApi } from "zustand/vanilla";
|
|
3
3
|
|
|
4
4
|
//#region src/config.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Browser voice input/output (SMOODEV-2534). OFF by default — when disabled the
|
|
7
|
+
* widget renders zero voice UI. When enabled, a mic toggle appears in the
|
|
8
|
+
* composer and speech flows over the browser-voice WebSocket.
|
|
9
|
+
*/
|
|
10
|
+
interface ChatWidgetVoiceConfig {
|
|
11
|
+
/** Turn the voice feature on. Default `false`. */
|
|
12
|
+
enabled?: boolean;
|
|
13
|
+
/** Browser-voice WS endpoint. Defaults to the hosted SmooAI voice service. */
|
|
14
|
+
url?: string;
|
|
15
|
+
}
|
|
5
16
|
interface ChatWidgetTheme {
|
|
6
17
|
/** Foreground text color for the widget chrome. */
|
|
7
18
|
text?: string;
|
|
@@ -144,6 +155,8 @@ interface ChatWidgetConfig {
|
|
|
144
155
|
* surfaces where seeing what the agent did mid-turn is valuable.
|
|
145
156
|
*/
|
|
146
157
|
showToolActivity?: boolean;
|
|
158
|
+
/** Browser voice input/output. OFF by default (zero UI when off). */
|
|
159
|
+
voice?: ChatWidgetVoiceConfig;
|
|
147
160
|
/** Theme overrides. */
|
|
148
161
|
theme?: ChatWidgetTheme;
|
|
149
162
|
}
|
|
@@ -395,6 +408,8 @@ declare class ConversationController {
|
|
|
395
408
|
private readonly store;
|
|
396
409
|
private client;
|
|
397
410
|
private sessionId;
|
|
411
|
+
/** Conversation id of the live session (create or resume) — lets voice join the same thread. */
|
|
412
|
+
private conversationId;
|
|
398
413
|
private readonly messages;
|
|
399
414
|
private status;
|
|
400
415
|
private seq;
|
|
@@ -423,6 +438,14 @@ declare class ConversationController {
|
|
|
423
438
|
private readonly httpBase;
|
|
424
439
|
constructor(config: ChatWidgetConfig, events: ConversationEvents, store?: StoreApi<WidgetStore>);
|
|
425
440
|
get connectionStatus(): ConnectionStatus;
|
|
441
|
+
/** Conversation id of the live session, or null before connect (voice passes this as `conversation_id`). */
|
|
442
|
+
get currentConversationId(): string | null;
|
|
443
|
+
/**
|
|
444
|
+
* Append an already-finalized message to the transcript and emit — the voice
|
|
445
|
+
* path reuses this so `transcript_final` (user) and `reply_text` (assistant)
|
|
446
|
+
* turns land in the same message list / render pipeline as typed chat.
|
|
447
|
+
*/
|
|
448
|
+
appendLocalMessage(role: Role, text: string): void;
|
|
426
449
|
/** The persisted store, exposed so the view can read identity for the pre-chat gate. */
|
|
427
450
|
getStore(): StoreApi<WidgetStore>;
|
|
428
451
|
/** True when a persisted session pointer exists (drives the resume path). */
|
|
@@ -571,6 +594,10 @@ declare class SmoothAgentChatElement extends HTMLElement {
|
|
|
571
594
|
private allowChatRestore;
|
|
572
595
|
/** True while the pre-chat identity gate is showing (blocks premature connect). */
|
|
573
596
|
private gating;
|
|
597
|
+
/** Voice config (SMOODEV-2534) — enabled=false renders zero voice UI. */
|
|
598
|
+
private voiceCfg;
|
|
599
|
+
/** Live voice session, or null when voice is off. */
|
|
600
|
+
private voiceSession;
|
|
574
601
|
private panelEl;
|
|
575
602
|
private launcherEl;
|
|
576
603
|
private messagesEl;
|
|
@@ -578,6 +605,7 @@ declare class SmoothAgentChatElement extends HTMLElement {
|
|
|
578
605
|
private dotEl;
|
|
579
606
|
private inputEl;
|
|
580
607
|
private sendBtn;
|
|
608
|
+
private micBtn;
|
|
581
609
|
private suggestionsEl;
|
|
582
610
|
/** The live streaming assistant bubble whose textContent the rAF loop drives. */
|
|
583
611
|
private streamBubbleEl;
|
|
@@ -738,6 +766,17 @@ declare class SmoothAgentChatElement extends HTMLElement {
|
|
|
738
766
|
private renderSources;
|
|
739
767
|
private renderStatus;
|
|
740
768
|
private renderComposerState;
|
|
769
|
+
/**
|
|
770
|
+
* Mic button: start a voice session, or — when one is live — end it. Hitting
|
|
771
|
+
* the button while the agent's TTS is playing barges in first (interrupt +
|
|
772
|
+
* playback flush) so the audio dies instantly, then the session ends.
|
|
773
|
+
*/
|
|
774
|
+
private toggleVoice;
|
|
775
|
+
private startVoice;
|
|
776
|
+
/** End any live voice session and reset the composer UI. Idempotent. */
|
|
777
|
+
private stopVoice;
|
|
778
|
+
/** Toggle the mic button's listening state + clear the partial transcript. */
|
|
779
|
+
private syncVoiceUi;
|
|
741
780
|
private submit;
|
|
742
781
|
}
|
|
743
782
|
/** Register the custom element once. Safe to call multiple times. */
|
|
@@ -763,6 +802,163 @@ declare function mountChatWidget(config: ChatWidgetConfig, target?: HTMLElement)
|
|
|
763
802
|
*/
|
|
764
803
|
declare function mountFullPageChat(config: Omit<ChatWidgetConfig, 'mode'>, target?: HTMLElement): SmoothAgentChatElement;
|
|
765
804
|
//#endregion
|
|
805
|
+
//#region src/voice-session.d.ts
|
|
806
|
+
/**
|
|
807
|
+
* VoiceSession — framework-free browser voice for the chat widget.
|
|
808
|
+
*
|
|
809
|
+
* Speaks the FROZEN browser-voice WebSocket protocol (SMOODEV-2534 / ADR-084):
|
|
810
|
+
*
|
|
811
|
+
* client → server:
|
|
812
|
+
* - first frame, JSON: `{"type":"start","agent_id":"…","conversation_id":"…?","token":"…?"}`
|
|
813
|
+
* (public-agent auth is the `Origin` header the browser sends automatically;
|
|
814
|
+
* `token` only for authenticated contexts)
|
|
815
|
+
* - binary frames: raw PCM linear16 mono @ 16 kHz mic chunks
|
|
816
|
+
* - JSON `{"type":"interrupt"}` (user barged in), `{"type":"stop"}`
|
|
817
|
+
* server → client:
|
|
818
|
+
* - JSON `transcript_partial` / `transcript_final` / `reply_text` /
|
|
819
|
+
* `speaking_started` / `speaking_done` / `handoff` / `error {code}`
|
|
820
|
+
* - binary frames: PCM linear16 mono @ 16 kHz TTS audio chunks
|
|
821
|
+
*
|
|
822
|
+
* The class owns: the WS lifecycle, mic capture (getUserMedia → AudioWorklet or
|
|
823
|
+
* ScriptProcessor fallback → downsample to 16 kHz mono Int16 → binary frames),
|
|
824
|
+
* gapless playback of incoming PCM through a 16 kHz AudioContext, and barge-in
|
|
825
|
+
* (RMS speech detection while the agent is speaking → `interrupt` + playback
|
|
826
|
+
* flush). Browser audio + WebSocket are thin injectable seams so unit tests run
|
|
827
|
+
* under jsdom/happy-dom with no real audio.
|
|
828
|
+
*/
|
|
829
|
+
declare const DEFAULT_VOICE_URL = "wss://twilio-voice.smoo.ai/browser-voice/ws";
|
|
830
|
+
/** Target wire format: PCM linear16 mono @ 16 kHz. */
|
|
831
|
+
declare const VOICE_SAMPLE_RATE = 16000;
|
|
832
|
+
/**
|
|
833
|
+
* Downsample Float32 mic samples at `inputRate` to 16 kHz mono Int16 (linear16).
|
|
834
|
+
* Bucket-averaging decimation: each output sample averages its source bucket,
|
|
835
|
+
* which is a cheap low-pass that's plenty for speech (and handles non-integer
|
|
836
|
+
* ratios like 44.1k → 16k). Values are clamped to the Int16 range.
|
|
837
|
+
*/
|
|
838
|
+
declare function downsampleTo16k(samples: Float32Array, inputRate: number): Int16Array;
|
|
839
|
+
/** Root-mean-square level of a Float32 frame (0..1) — the barge-in speech gate. */
|
|
840
|
+
declare function rmsLevel(samples: Float32Array): number;
|
|
841
|
+
/** The subset of WebSocket the session needs (mockable in tests). */
|
|
842
|
+
interface VoiceWebSocket {
|
|
843
|
+
binaryType: string;
|
|
844
|
+
readyState: number;
|
|
845
|
+
send(data: string | ArrayBuffer): void;
|
|
846
|
+
close(code?: number, reason?: string): void;
|
|
847
|
+
addEventListener(type: 'open' | 'message' | 'close' | 'error', fn: (ev: never) => void): void;
|
|
848
|
+
}
|
|
849
|
+
/** Playback sink for incoming 16 kHz PCM chunks (mockable in tests). */
|
|
850
|
+
interface VoicePlayer {
|
|
851
|
+
/** Queue a linear16 chunk for gapless playback. */
|
|
852
|
+
enqueue(chunk: ArrayBuffer): void;
|
|
853
|
+
/** Stop everything queued/playing immediately (barge-in). */
|
|
854
|
+
flush(): void;
|
|
855
|
+
/** Flush + release the audio device. */
|
|
856
|
+
close(): void;
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Start mic capture, invoking `onFrame(samples, sampleRate)` with raw Float32
|
|
860
|
+
* frames until the returned stop function is called.
|
|
861
|
+
*/
|
|
862
|
+
type StartCapture = (onFrame: (samples: Float32Array, sampleRate: number) => void) => Promise<() => void>;
|
|
863
|
+
interface VoiceSessionSeams {
|
|
864
|
+
createWebSocket?: (url: string) => VoiceWebSocket;
|
|
865
|
+
startCapture?: StartCapture;
|
|
866
|
+
createPlayer?: () => VoicePlayer;
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* The minimal AudioContext surface {@link PcmPlayer} uses — injectable so the
|
|
870
|
+
* scheduling/flush logic is unit-testable without real audio hardware.
|
|
871
|
+
*/
|
|
872
|
+
interface PlayerAudioContext {
|
|
873
|
+
readonly currentTime: number;
|
|
874
|
+
readonly destination: unknown;
|
|
875
|
+
createBuffer(channels: number, length: number, sampleRate: number): {
|
|
876
|
+
getChannelData(channel: number): Float32Array;
|
|
877
|
+
};
|
|
878
|
+
createBufferSource(): {
|
|
879
|
+
buffer: unknown;
|
|
880
|
+
connect(dest: unknown): void;
|
|
881
|
+
start(when?: number): void;
|
|
882
|
+
stop(): void;
|
|
883
|
+
onended: (() => void) | null;
|
|
884
|
+
};
|
|
885
|
+
close?(): Promise<void>;
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Gapless PCM playback: each incoming linear16 chunk becomes an AudioBuffer
|
|
889
|
+
* scheduled back-to-back (`nextTime`) so consecutive chunks butt together with
|
|
890
|
+
* no gaps. `flush()` stops every scheduled source (barge-in / mic-button stop).
|
|
891
|
+
*/
|
|
892
|
+
declare class PcmPlayer implements VoicePlayer {
|
|
893
|
+
private readonly ctx;
|
|
894
|
+
private nextTime;
|
|
895
|
+
private readonly live;
|
|
896
|
+
constructor(ctx: PlayerAudioContext);
|
|
897
|
+
enqueue(chunk: ArrayBuffer): void;
|
|
898
|
+
flush(): void;
|
|
899
|
+
close(): void;
|
|
900
|
+
}
|
|
901
|
+
interface VoiceSessionOptions {
|
|
902
|
+
/** Full browser-voice WS endpoint (default {@link DEFAULT_VOICE_URL}). */
|
|
903
|
+
url?: string;
|
|
904
|
+
/** UUID of the agent to talk to. */
|
|
905
|
+
agentId: string;
|
|
906
|
+
/** Existing conversation id so voice resumes the same thread. */
|
|
907
|
+
conversationId?: string;
|
|
908
|
+
/** Optional JWT for authenticated contexts (public agents auth by Origin). */
|
|
909
|
+
token?: string;
|
|
910
|
+
/**
|
|
911
|
+
* RMS level (0..1) above which a mic frame counts as speech for barge-in
|
|
912
|
+
* while the agent is speaking. Default 0.02 — comfortably above room noise
|
|
913
|
+
* post-AGC, well below speech.
|
|
914
|
+
*/
|
|
915
|
+
bargeInThreshold?: number;
|
|
916
|
+
/** Injectable browser seams (tests). */
|
|
917
|
+
seams?: VoiceSessionSeams;
|
|
918
|
+
}
|
|
919
|
+
interface VoiceSessionEvents {
|
|
920
|
+
onTranscriptPartial?: (text: string) => void;
|
|
921
|
+
onTranscriptFinal?: (text: string) => void;
|
|
922
|
+
onReplyText?: (text: string) => void;
|
|
923
|
+
/** Agent TTS started/stopped playing. */
|
|
924
|
+
onSpeaking?: (speaking: boolean) => void;
|
|
925
|
+
onError?: (code: string) => void;
|
|
926
|
+
/** The session is over (stop, server close, handoff, or error). Fires once. */
|
|
927
|
+
onEnded?: () => void;
|
|
928
|
+
}
|
|
929
|
+
type VoiceSessionState = 'idle' | 'connecting' | 'active' | 'ended';
|
|
930
|
+
declare class VoiceSession {
|
|
931
|
+
private readonly opts;
|
|
932
|
+
private readonly events;
|
|
933
|
+
private ws;
|
|
934
|
+
private player;
|
|
935
|
+
private stopCapture;
|
|
936
|
+
private speaking;
|
|
937
|
+
private ended;
|
|
938
|
+
state: VoiceSessionState;
|
|
939
|
+
constructor(opts: VoiceSessionOptions, events?: VoiceSessionEvents);
|
|
940
|
+
/** Open the WS, send the start frame, and begin streaming mic audio. */
|
|
941
|
+
start(): Promise<void>;
|
|
942
|
+
/** One raw mic frame: barge-in check, then downsample → binary frame. */
|
|
943
|
+
private handleMicFrame;
|
|
944
|
+
/** Route a server frame: binary = TTS audio, string = JSON control event. */
|
|
945
|
+
private handleServerFrame;
|
|
946
|
+
private setSpeaking;
|
|
947
|
+
/** True while agent TTS is playing (between speaking_started/done). */
|
|
948
|
+
get isSpeaking(): boolean;
|
|
949
|
+
/**
|
|
950
|
+
* Barge in: tell the server the user interrupted and flush queued TTS so the
|
|
951
|
+
* agent goes silent immediately. Called automatically on mic speech during
|
|
952
|
+
* playback; the widget also calls it when the visitor hits the mic button
|
|
953
|
+
* mid-playback.
|
|
954
|
+
*/
|
|
955
|
+
interrupt(): void;
|
|
956
|
+
/** Graceful end: send `stop`, then tear everything down. */
|
|
957
|
+
stop(): void;
|
|
958
|
+
/** Idempotent teardown: capture, playback, socket, `ended` event. */
|
|
959
|
+
private teardown;
|
|
960
|
+
}
|
|
961
|
+
//#endregion
|
|
766
962
|
//#region src/loader-core.d.ts
|
|
767
963
|
/**
|
|
768
964
|
* Tiny, dependency-free deferred loader for `@smooai/chat-widget`.
|
|
@@ -849,5 +1045,5 @@ declare function computeFingerprint(): string;
|
|
|
849
1045
|
*/
|
|
850
1046
|
declare function getOrCreateFingerprint(get: () => string | null, set: (fp: string) => void): string;
|
|
851
1047
|
//#endregion
|
|
852
|
-
export { type ChatMessage, type ChatWidgetConfig, type ChatWidgetMode, type ChatWidgetTheme, type Citation, type ConnectionStatus, type ConsentState, ConversationController, type ConversationEvents, ELEMENT_TAG, type IdentityRestore, type IdentityState, type MessageBlock, PERSIST_VERSION, type PersistedWidgetState, type RestorableConversation, type Role, SmoothAgentChatElement, type ToolCall, type UserInfo, type WidgetStore, computeFingerprint, createWidgetStore, defineChatWidget, getOrCreateFingerprint, httpBaseFromWsEndpoint, initChatWidgetLoader, mountChatWidget, mountFullPageChat, storageKey };
|
|
1048
|
+
export { type ChatMessage, type ChatWidgetConfig, type ChatWidgetMode, type ChatWidgetTheme, type ChatWidgetVoiceConfig, type Citation, type ConnectionStatus, type ConsentState, ConversationController, type ConversationEvents, DEFAULT_VOICE_URL, ELEMENT_TAG, type IdentityRestore, type IdentityState, type MessageBlock, PERSIST_VERSION, PcmPlayer, type PersistedWidgetState, type PlayerAudioContext, type RestorableConversation, type Role, SmoothAgentChatElement, type StartCapture, type ToolCall, type UserInfo, VOICE_SAMPLE_RATE, type VoicePlayer, VoiceSession, type VoiceSessionEvents, type VoiceSessionOptions, type VoiceSessionSeams, type VoiceSessionState, type VoiceWebSocket, type WidgetStore, computeFingerprint, createWidgetStore, defineChatWidget, downsampleTo16k, getOrCreateFingerprint, httpBaseFromWsEndpoint, initChatWidgetLoader, mountChatWidget, mountFullPageChat, rmsLevel, storageKey };
|
|
853
1049
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/config.ts","../src/persistence.ts","../src/conversation.ts","../src/element.ts","../src/loader-core.ts","../src/fingerprint.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/config.ts","../src/persistence.ts","../src/conversation.ts","../src/element.ts","../src/voice-session.ts","../src/loader-core.ts","../src/fingerprint.ts"],"mappings":"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"}
|