@alxxsck/ai-assistant 1.8.0 → 2.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.
Files changed (41) hide show
  1. package/README.md +121 -314
  2. package/dist/App.d.ts +0 -7
  3. package/dist/{Avatar-BAlmduYw.js → Avatar-DKGkEfXe.js} +2608 -2716
  4. package/dist/ChatWidgetContent-Coj_NDep.js +8570 -0
  5. package/dist/avatar/AnimationManager.d.ts +45 -15
  6. package/dist/avatar/Avatar.d.ts +15 -19
  7. package/dist/avatar/publicAnimations.d.ts +3 -0
  8. package/dist/bridge-ai-chat-widget.es.js +4 -14123
  9. package/dist/config/runtime-config.d.ts +4 -0
  10. package/dist/context/ChatWidgetContext.d.ts +6 -5
  11. package/dist/domain/command/CommandRuntime.d.ts +1 -0
  12. package/dist/domain/command/command.types.d.ts +15 -24
  13. package/dist/domain/message/cable/AnyCable.service.d.ts +2 -1
  14. package/dist/domain/message/cable/CableContext.d.ts +2 -1
  15. package/dist/domain/message/cable/CableContext.types.d.ts +2 -4
  16. package/dist/domain/speech/LipSyncCueSource.d.ts +25 -0
  17. package/dist/domain/speech/LipSyncRuntime.d.ts +54 -0
  18. package/dist/domain/speech/RealtimeLipSyncCueSource.d.ts +13 -0
  19. package/dist/domain/speech/SpeechPlayer.d.ts +10 -0
  20. package/dist/domain/ui/ui.service.d.ts +7 -1
  21. package/dist/domain/ui/widget-geometry.d.ts +23 -0
  22. package/dist/domain/voice/voice.store.d.ts +1 -0
  23. package/dist/index-Dt2DYOP-.js +9632 -0
  24. package/dist/index.d.ts +18 -21
  25. package/dist/index.types.d.ts +6 -43
  26. package/dist/lib/isAuthenticationError.d.ts +1 -0
  27. package/dist/lib/logger.d.ts +5 -2
  28. package/dist/lib/markdownRenderer.d.ts +4 -0
  29. package/dist/types/index.d.ts +4 -6
  30. package/dist/ui/chat-routes.d.ts +2 -0
  31. package/dist/ui/components/ChatAvatarStage.d.ts +1 -0
  32. package/dist/ui/components/ChatWidget.d.ts +0 -2
  33. package/dist/ui/components/ChatWidgetContent.d.ts +1 -0
  34. package/dist/ui/components/ChatWidgetFrame.d.ts +13 -0
  35. package/dist/ui/components/StreamingMessageText.d.ts +2 -1
  36. package/dist/ui/hooks/useSmoothStreamingText.d.ts +2 -1
  37. package/dist/ui/streaming/smooth-text.d.ts +5 -0
  38. package/package.json +7 -20
  39. package/dist/OrbitControls-BhEr8WlG.js +0 -458
  40. package/dist/lil-gui.esm-BicvE3D7.js +0 -1263
  41. package/dist/ui/components/ChatFooter.d.ts +0 -2
@@ -0,0 +1,4 @@
1
+ export declare const LOLA_API_URL: string;
2
+ export declare const LOLA_WS_URL: any;
3
+ export declare const AI_ASSISTANT_ASSETS_URL: string;
4
+ export declare const getAuthenticatedLolaWsUrl: (accessToken: string) => string;
@@ -5,12 +5,13 @@ import type { CtaCommandContext } from "@/domain/command/command.types";
5
5
  type ChatWidgetContextValue = {
6
6
  open: boolean;
7
7
  setOpen: (v: boolean) => void;
8
- /** False when `manualOpen` is false and the widget was dismissed; chrome stays mounted but is hidden and non-interactive until `setOpen(true)`. */
8
+ isFullscreen: boolean;
9
+ setFullscreen: (fullscreen: boolean) => void;
10
+ contentActivated: boolean;
11
+ isAvatarCoveredByChatList: boolean;
12
+ setAvatarCoveredByChatList: (covered: boolean) => void;
13
+ /** False after a hidden-launcher widget is closed until `setOpen(true)`. */
9
14
  isChromeVisible: boolean;
10
- widgetHeight: number;
11
- setWidgetHeight: (h: number) => void;
12
- widgetWidth: number;
13
- setWidgetWidth: (w: number) => void;
14
15
  reactionMessage: string | null;
15
16
  setReactionMessage: (message: string | null) => void;
16
17
  isMobile: boolean;
@@ -30,6 +30,7 @@ export declare class CommandRuntime {
30
30
  private executeHighlight;
31
31
  private executeShowCta;
32
32
  private requireTarget;
33
+ private readLipSyncDescriptor;
33
34
  private requireEnvelopeTarget;
34
35
  private findTargetElement;
35
36
  private applyDefaultHighlight;
@@ -61,42 +61,19 @@ export type HostCommandContext = {
61
61
  commandId: string;
62
62
  commandType: CommandType;
63
63
  target: string;
64
- targetDefinition?: UiTarget;
65
64
  payload: Readonly<Record<string, unknown>>;
66
- url?: string;
67
- route?: string;
68
- modalId?: string;
69
- modalCode?: string;
70
65
  };
71
66
  export type OpenPageContext = {
72
67
  commandId: string;
73
68
  pageCode: string;
74
69
  route: string;
75
70
  payload: Readonly<Record<string, unknown>>;
76
- /** @deprecated Use pageCode. */
77
- target: string;
78
- /** @deprecated The command type is fixed for this callback. */
79
- commandType: "open_page";
80
- /** @deprecated Use route. */
81
- url: string;
82
- /** @deprecated Used only by legacy local target integrations. */
83
- targetDefinition?: UiTarget;
84
71
  };
85
72
  export type OpenModalContext = {
86
73
  commandId: string;
87
74
  modalCode: string;
88
75
  modalName: string;
89
76
  payload: Readonly<Record<string, unknown>>;
90
- /** @deprecated Use modalCode. */
91
- target: string;
92
- /** @deprecated The command type is fixed for this callback. */
93
- commandType: "open_modal";
94
- /** @deprecated Use modalCode. */
95
- modalId: string;
96
- /** @deprecated Used only by legacy URL-based modal integrations. */
97
- url?: string;
98
- /** @deprecated Used only by legacy local target integrations. */
99
- targetDefinition?: UiTarget;
100
77
  };
101
78
  export type UiCommandActionSnapshot = {
102
79
  kind: "page";
@@ -142,12 +119,26 @@ export type SpeakTextCommandContext = {
142
119
  format: "pcm16";
143
120
  sampleRate: 24_000;
144
121
  channels: 1;
122
+ lipSync?: LipSyncPlaybackDescriptor;
123
+ };
124
+ export type LipSyncPlaybackDescriptor = {
125
+ contractVersion: 1;
126
+ playbackId: string;
127
+ audio: {
128
+ encoding: "pcm_s16le";
129
+ sampleRate: 24_000;
130
+ channels: 1;
131
+ };
132
+ cueTimebase: "milliseconds";
133
+ transport: {
134
+ socketIoEvent: "lip_sync.cues";
135
+ cableField: "lipSyncCues";
136
+ };
145
137
  };
146
138
  export type HostCommandHandlers = {
147
139
  openPage?: (context: OpenPageContext) => void | Promise<void>;
148
140
  openModal?: (context: OpenModalContext) => void | Promise<void>;
149
141
  highlight?: (context: HighlightCommandContext) => void | Promise<void>;
150
- showCta?: (context: CtaCommandContext) => void | Promise<void>;
151
142
  };
152
143
  export type HostCommandHandlerName = keyof HostCommandHandlers;
153
144
  export type HostCommandHandler = NonNullable<HostCommandHandlers[HostCommandHandlerName]>;
@@ -7,12 +7,13 @@ import type { ScenarioChoiceInput } from "@/domain/scenario/scenario-choice";
7
7
  * subscribing to channels.
8
8
  */
9
9
  export declare class AnyCableService {
10
+ private readonly onAuthenticationError?;
10
11
  private url;
11
12
  private cable?;
12
13
  channels: {
13
14
  chat: WidgetChatChannel;
14
15
  };
15
- constructor(url: string, onMessage?: (message: unknown) => void);
16
+ constructor(url: string, onMessage?: (message: unknown) => void, onAuthenticationError?: (() => void) | undefined);
16
17
  /**
17
18
  * Subscribes to a channel
18
19
  *
@@ -11,7 +11,8 @@ interface CableProviderProps {
11
11
  children: ReactNode;
12
12
  config: WidgetConfig;
13
13
  commandRuntime: CommandRuntime;
14
+ onSessionExpired?: () => void;
14
15
  }
15
- export declare const CableProvider: ({ children, config, commandRuntime, }: CableProviderProps) => import("react/jsx-runtime").JSX.Element;
16
+ export declare const CableProvider: ({ children, config, commandRuntime, onSessionExpired, }: CableProviderProps) => import("react/jsx-runtime").JSX.Element;
16
17
  export declare const useCable: () => CableContextType;
17
18
  export {};
@@ -7,13 +7,11 @@ export declare enum NetworkStatus {
7
7
  */
8
8
  Available = "available",
9
9
  /**
10
- * When the user is offline (no internet access) but WS connection is
11
- * established
10
+ * When the browser reports that the user has no network access
12
11
  */
13
12
  Offline = "offline",
14
13
  /**
15
- * When the user is offline (no internet access) and WS connection is not
16
- * established
14
+ * When the browser is online but the WS connection is not established
17
15
  */
18
16
  Unavailable = "unavailable"
19
17
  }
@@ -0,0 +1,25 @@
1
+ import type { Viseme } from "./LipSyncRuntime";
2
+ import { LipSyncRuntime } from "./LipSyncRuntime";
3
+ export type TimedLipSyncCue = Readonly<{
4
+ viseme: Viseme;
5
+ startMs: number;
6
+ endMs: number;
7
+ }>;
8
+ export type TimedLipSyncCueBatch = Readonly<{
9
+ playbackId: string;
10
+ sequence: number;
11
+ cues: readonly TimedLipSyncCue[];
12
+ }>;
13
+ export interface LipSyncCueSource {
14
+ read(request: {
15
+ playbackId: string;
16
+ signal: AbortSignal;
17
+ }): AsyncIterable<TimedLipSyncCueBatch>;
18
+ }
19
+ export declare function consumeLipSyncCueSource({ source, runtime, playbackId, sampleRate, signal, }: {
20
+ source: LipSyncCueSource;
21
+ runtime: LipSyncRuntime;
22
+ playbackId: string;
23
+ sampleRate: number;
24
+ signal: AbortSignal;
25
+ }): Promise<void>;
@@ -0,0 +1,54 @@
1
+ export type LipSyncPhase = "idle" | "playing" | "underrun";
2
+ export type Viseme = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "X";
3
+ export type LipSyncCue = Readonly<{
4
+ viseme: Viseme;
5
+ startSample: number;
6
+ endSample: number;
7
+ }>;
8
+ export type LipSyncSnapshot = Readonly<{
9
+ playbackId: string | null;
10
+ phase: LipSyncPhase;
11
+ sampleRate: number;
12
+ sourceSample: number;
13
+ mouthOpen: number;
14
+ activeViseme: Viseme | null;
15
+ }>;
16
+ export type LipSyncEvent = Readonly<{
17
+ type: "playback-started";
18
+ playbackId: string;
19
+ sampleRate: number;
20
+ }> | Readonly<{
21
+ type: "playback-progress";
22
+ playbackId: string;
23
+ sourceSample: number;
24
+ mouthOpen: number;
25
+ }> | Readonly<{
26
+ type: "playback-stopped";
27
+ playbackId: string;
28
+ }> | Readonly<{
29
+ type: "playback-underrun" | "playback-resumed";
30
+ playbackId: string;
31
+ }> | Readonly<{
32
+ type: "cue-batch";
33
+ playbackId: string;
34
+ sequence: number;
35
+ cues: readonly LipSyncCue[];
36
+ }>;
37
+ type LipSyncListener = (snapshot: LipSyncSnapshot) => void;
38
+ export declare class LipSyncRuntime {
39
+ private snapshot;
40
+ private readonly listeners;
41
+ private cues;
42
+ private cueIndex;
43
+ private nextCueSequence;
44
+ private cuesEnabled;
45
+ private rmsMouthOpen;
46
+ dispatch(event: LipSyncEvent): void;
47
+ subscribe(listener: LipSyncListener): () => void;
48
+ private publish;
49
+ private notify;
50
+ private deriveSnapshot;
51
+ private acceptCueBatch;
52
+ }
53
+ export declare const lipSyncRuntime: LipSyncRuntime;
54
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { LipSyncCueSource, TimedLipSyncCueBatch } from "./LipSyncCueSource";
2
+ export declare class RealtimeLipSyncCueSource implements LipSyncCueSource {
3
+ private readonly playbacks;
4
+ private readonly terminalPlaybackIds;
5
+ publish(value: unknown): void;
6
+ read({ playbackId, signal, }: {
7
+ playbackId: string;
8
+ signal: AbortSignal;
9
+ }): AsyncIterable<TimedLipSyncCueBatch>;
10
+ private bufferFor;
11
+ private markTerminal;
12
+ }
13
+ export declare const realtimeLipSyncCueSource: RealtimeLipSyncCueSource;
@@ -1,11 +1,21 @@
1
1
  export type SpeechPlaybackOptions = {
2
2
  onStarted?: () => void;
3
+ onStopped?: (completed: boolean) => void;
3
4
  };
4
5
  export type PcmStreamLoader = (signal: AbortSignal) => Promise<ReadableStream<Uint8Array>>;
5
6
  export type PcmPlaybackOptions = SpeechPlaybackOptions & {
6
7
  sampleRate: number;
7
8
  jitterBufferMs?: number;
9
+ onProgress?: (progress: PcmPlaybackProgress) => void;
10
+ onUnderrun?: () => void;
11
+ onResumed?: () => void;
8
12
  };
13
+ export type PcmPlaybackProgress = Readonly<{
14
+ sourceSample: number;
15
+ renderContextFrame: number;
16
+ mouthOpen: number;
17
+ peak: number;
18
+ }>;
9
19
  export declare class SpeechPlayer {
10
20
  private active;
11
21
  get isPlaying(): boolean;
@@ -1,7 +1,13 @@
1
- type WidgetUIData = {
1
+ import type { Point } from "./widget-geometry";
2
+ type PanelGeometry = Partial<Point> & {
2
3
  width: number;
3
4
  height: number;
4
5
  };
6
+ export type WidgetUIData = {
7
+ version: 2;
8
+ launcher?: Point;
9
+ panel: PanelGeometry;
10
+ };
5
11
  export declare function loadWidgetUIData(): WidgetUIData | null;
6
12
  export declare function saveWidgetUIData(data: WidgetUIData): void;
7
13
  export {};
@@ -0,0 +1,23 @@
1
+ export type Point = {
2
+ x: number;
3
+ y: number;
4
+ };
5
+ export type Size = {
6
+ width: number;
7
+ height: number;
8
+ };
9
+ export type Rect = Point & Size;
10
+ export type Viewport = Size;
11
+ export declare const LAUNCHER_SIZE = 52;
12
+ export declare const VIEWPORT_MARGIN = 16;
13
+ export declare const MIN_WIDGET_WIDTH = 240;
14
+ export declare const DEFAULT_WIDGET_WIDTH = 360;
15
+ export declare const MIN_WIDGET_HEIGHT = 320;
16
+ export declare const DEFAULT_WIDGET_HEIGHT = 680;
17
+ export declare function getViewport(): Viewport;
18
+ export declare function getDefaultLauncherPosition(viewport: Viewport): Point;
19
+ export declare function clampLauncherPosition(point: Point, viewport: Viewport): Point;
20
+ export declare function clampPanelRect(rect: Rect, viewport: Viewport): Rect;
21
+ export declare function placePanelFromLauncher(launcher: Point, size: Size, viewport: Viewport): Rect;
22
+ export declare function resizePanelFromNorthWest(start: Rect, delta: Point, axes: "top" | "left" | "corner", viewport: Viewport): Rect;
23
+ export declare function resizePanelFromSouthEast(start: Rect, delta: Point, viewport: Viewport): Rect;
@@ -25,6 +25,7 @@ type VoiceStore = {
25
25
  actions: VoiceStoreActions;
26
26
  };
27
27
  type VoiceStoreActions = {
28
+ updateSession: (config: WidgetConfig, api: AppApi) => Promise<void>;
28
29
  startListening: (config: WidgetConfig, api: AppApi) => Promise<void>;
29
30
  offerConversation: (invitation: StartVoiceConversationCommandContext) => Promise<void>;
30
31
  acceptConversation: (config: WidgetConfig, api: AppApi) => Promise<void>;