@alxxsck/ai-assistant 2.25.4 → 3.0.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 (55) hide show
  1. package/dist/{Avatar-1SXtYcpL.js → Avatar-Bsv7Y3ZQ.js} +19082 -18842
  2. package/dist/{ChatWidgetContent-Cfqo7BfS.js → ChatWidgetContent-Cq2Y5IHt.js} +2837 -2578
  3. package/dist/api/audio.api.d.ts +1 -1
  4. package/dist/avatar/AnimationManager.d.ts +7 -3
  5. package/dist/avatar/Avatar.d.ts +20 -3
  6. package/dist/avatar/avatarMeshes.d.ts +8 -0
  7. package/dist/avatar/loaders.d.ts +16 -0
  8. package/dist/bridge-ai-chat-widget.es.js +1 -1
  9. package/dist/constants.d.ts +1 -0
  10. package/dist/context/ChatWidgetContext.d.ts +0 -2
  11. package/dist/domain/client-environment/ClientEnvironmentRuntime.d.ts +61 -0
  12. package/dist/domain/client-environment/collectClientEnvironment.d.ts +6 -0
  13. package/dist/domain/client-environment/types.d.ts +93 -0
  14. package/dist/domain/command/CommandRuntime.d.ts +1 -0
  15. package/dist/domain/message/message.store.d.ts +3 -0
  16. package/dist/domain/speech/SpeechPlayer.d.ts +2 -0
  17. package/dist/domain/tracking/LolaEventTracker.d.ts +5 -1
  18. package/dist/domain/ui/widget-geometry.d.ts +7 -5
  19. package/dist/domain/voice/media/ReliableVoiceUplink.d.ts +4 -0
  20. package/dist/domain/voice/voice-audio-meter.d.ts +12 -0
  21. package/dist/domain/voice/voice.store.d.ts +5 -1
  22. package/dist/i18n/messages.d.ts +5 -2
  23. package/dist/index-DY_Y_QHI.js +2825 -0
  24. package/dist/index.d.ts +2 -0
  25. package/dist/inter-cyrillic-wght-italic.woff2 +0 -0
  26. package/dist/inter-cyrillic-wght-normal.woff2 +0 -0
  27. package/dist/inter-latin-ext-wght-italic.woff2 +0 -0
  28. package/dist/inter-latin-ext-wght-normal.woff2 +0 -0
  29. package/dist/inter-latin-wght-italic.woff2 +0 -0
  30. package/dist/inter-latin-wght-normal.woff2 +0 -0
  31. package/dist/lib/uuid.d.ts +2 -0
  32. package/dist/{mount-CtHQDVwj.js → mount-RA3wsImP.js} +6415 -5939
  33. package/dist/roboto-cyrillic-400-normal.woff2 +0 -0
  34. package/dist/roboto-cyrillic-700-normal.woff2 +0 -0
  35. package/dist/roboto-latin-400-normal.woff2 +0 -0
  36. package/dist/roboto-latin-700-normal.woff2 +0 -0
  37. package/dist/roboto-latin-ext-400-normal.woff2 +0 -0
  38. package/dist/roboto-latin-ext-700-normal.woff2 +0 -0
  39. package/dist/sdk-version.d.ts +1 -0
  40. package/dist/ui/components/ChatListItem.d.ts +4 -1
  41. package/dist/ui/components/ChatSurfaceFrameContext.d.ts +6 -0
  42. package/dist/ui/components/ChatTopControls.d.ts +5 -5
  43. package/dist/ui/components/ChatVoiceMode.d.ts +5 -1
  44. package/dist/ui/components/ChatWidgetFrame.d.ts +3 -3
  45. package/dist/ui/components/VoiceComposer.d.ts +18 -0
  46. package/dist/ui/components/voice-waveform.d.ts +15 -0
  47. package/dist/ui/responder-visual-state.d.ts +7 -0
  48. package/dist/widget-fonts-CFulYNmT.js +16 -0
  49. package/dist/widget-fonts.d.ts +1 -0
  50. package/package.json +6 -2
  51. package/dist/avatar/consolidateMaterialGroups.d.ts +0 -2
  52. package/dist/index-1DOqo2bD.js +0 -2208
  53. package/dist/ui/chat-composer-layout.d.ts +0 -1
  54. package/dist/ui/components/overlays/ChatBlurOverlayTop.d.ts +0 -1
  55. package/dist/ui/components/overlays/ChatDarkOverlay.d.ts +0 -1
@@ -16,5 +16,5 @@ export declare class AudioApiError extends Error {
16
16
  readonly status: number;
17
17
  constructor(status: number, message: string);
18
18
  }
19
- export declare const fetchProtectedAudio: (config: WidgetConfig, api: AppApi, request: ProtectedAudioRequest) => Promise<Blob>;
19
+ export declare const fetchProtectedAudio: (config: WidgetConfig, api: AppApi, request: ProtectedAudioRequest, signal?: AbortSignal) => Promise<Blob>;
20
20
  export declare const fetchProtectedAudioStream: (config: WidgetConfig, api: AppApi, request: StreamingAudioRequest, signal: AbortSignal) => Promise<ReadableStream<Uint8Array>>;
@@ -1,5 +1,6 @@
1
- import { Object3D, Group } from "three";
1
+ import { Object3D } from "three";
2
2
  import type { Viseme } from "@/domain/speech/LipSyncRuntime";
3
+ import { type AnimatedAsset } from "./loaders";
3
4
  import type { Avatar } from "./Avatar";
4
5
  export declare const BLEND_SHAPE_KEYS: readonly ["blendShape1.AE", "blendShape1.ChJ", "blendShape1.FV", "blendShape1.Oh", "blendShape1.Ah", "blendShape1.Ih", "blendShape1.L", "blendShape1.SZ", "blendShape1.Woo", "blendShape1.MBP", "blendShape1.Smile_Closed", "blendShape1.Smile_Open", "blendShape1.Kiss"];
5
6
  export type BlendShapeKey = (typeof BLEND_SHAPE_KEYS)[number];
@@ -16,7 +17,7 @@ type InitialAnimationAssets = {
16
17
  animationData: AnimationAssetsData;
17
18
  mandatoryAnimations: Array<{
18
19
  data: AnimationAsset;
19
- animation: Group;
20
+ animation: AnimatedAsset;
20
21
  }>;
21
22
  };
22
23
  export default class AnimationManager {
@@ -29,9 +30,11 @@ export default class AnimationManager {
29
30
  private lazyAnimations;
30
31
  private animationLoads;
31
32
  private loadingManager;
32
- private fbxLoader;
33
+ private animationLoader;
33
34
  private initialAssets;
34
35
  private backgroundPreloadCancelled;
36
+ private backgroundPreloadGeneration;
37
+ private backgroundPreloadComplete;
35
38
  private latestActionRequest;
36
39
  private pendingActionLoads;
37
40
  private idleFallbackPending;
@@ -47,6 +50,7 @@ export default class AnimationManager {
47
50
  private loadAnimationLazy;
48
51
  loadAction(name: string): Promise<void>;
49
52
  cancelBackgroundPreload(): void;
53
+ setBackgroundPreloadEnabled(enabled: boolean): void;
50
54
  private scheduleBackgroundPreload;
51
55
  private waitForBackgroundOpportunity;
52
56
  private preloadRemainingAnimations;
@@ -1,5 +1,5 @@
1
1
  import { Mesh, Vector3 } from "three";
2
- import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
2
+ import type { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
3
3
  import type { AppApi } from "@/App";
4
4
  import type { LipSyncSnapshot } from "@/domain/speech/LipSyncRuntime";
5
5
  import type { ExternallyAvailableActions } from "./publicAnimations";
@@ -9,12 +9,18 @@ type CameraParams = {
9
9
  lookAt: Vector3;
10
10
  fov: number;
11
11
  };
12
+ export type AvatarFramingMode = "default" | "chat-surface";
12
13
  export declare class Avatar extends EventTarget {
13
14
  private canvas;
14
15
  private videoContainer;
15
16
  api: AppApi;
16
- initialAssetsfbxLoader: FBXLoader;
17
+ initialAssetsLoader: GLTFLoader;
17
18
  head: Mesh;
19
+ /**
20
+ * The brows are a separate primitive in glTF but share the head's blend
21
+ * shapes, so they have to follow the same influences array. See syncFaceMorphs.
22
+ */
23
+ private brows?;
18
24
  private renderer;
19
25
  private sound?;
20
26
  private cubeTexture;
@@ -26,6 +32,7 @@ export declare class Avatar extends EventTarget {
26
32
  private body;
27
33
  private animationManager;
28
34
  private cameraParams;
35
+ private framingMode;
29
36
  private locale?;
30
37
  private animationFrame;
31
38
  private renderingEnabled;
@@ -33,6 +40,7 @@ export declare class Avatar extends EventTarget {
33
40
  constructor(canvas: HTMLCanvasElement, videoContainer: HTMLDivElement, api: AppApi);
34
41
  private lightAmbient;
35
42
  private lightDirectional;
43
+ private lightRim;
36
44
  private loadingManager;
37
45
  private criticalAssetsReady;
38
46
  private sounds;
@@ -40,13 +48,22 @@ export declare class Avatar extends EventTarget {
40
48
  init(): Promise<void>;
41
49
  initSounds(locale: string): void;
42
50
  private tempLookAt;
43
- setCamera(params: CameraParams, cb?: () => void): void;
51
+ setCamera(params: CameraParams, cb?: () => void, duration?: number): void;
52
+ setFramingMode(mode: AvatarFramingMode): void;
44
53
  private width;
45
54
  private height;
46
55
  onResize: (width?: number, height?: number) => void;
47
56
  animate: () => void;
57
+ /**
58
+ * The head and the brows are two meshes sharing one set of blend shapes.
59
+ * Everything that drives the face (lip sync, blend shape scenarios, gsap
60
+ * tweens) writes into `head.morphTargetInfluences`, and some of it swaps the
61
+ * array outright, so the brows follow the head's current array every frame.
62
+ */
63
+ private syncFaceMorphs;
48
64
  setRenderingEnabled(enabled: boolean): void;
49
65
  cancelBackgroundPreload(): void;
66
+ setBackgroundPreloadEnabled(enabled: boolean): void;
50
67
  waitForCriticalAssets(): Promise<void>;
51
68
  private SPEAKING_ANIMATION_NAME_1;
52
69
  private SPEAKING_ANIMATION_NAME_2;
@@ -0,0 +1,8 @@
1
+ import type { Object3D, SkinnedMesh } from "three";
2
+ export type AvatarMeshSlot = "eyes" | "hair" | "head" | "brows" | "shell" | "body";
3
+ export type AvatarMeshes = Partial<Record<AvatarMeshSlot, SkinnedMesh>>;
4
+ /** Maps the meshes of a loaded avatar rig onto the slots the renderer knows about. */
5
+ export declare function collectAvatarMeshes(root: Object3D): AvatarMeshes;
6
+ /** Slots the avatar cannot render without. */
7
+ export declare const REQUIRED_AVATAR_MESH_SLOTS: AvatarMeshSlot[];
8
+ export declare function findMissingAvatarMeshes(meshes: AvatarMeshes): AvatarMeshSlot[];
@@ -0,0 +1,16 @@
1
+ import type { AnimationClip, LoadingManager } from "three";
2
+ import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
3
+ /**
4
+ * Anything the avatar loads carries animation clips: the rig itself has none,
5
+ * an animation asset has exactly one. Narrowing to this shape keeps the call
6
+ * sites independent of whether a GLTF or a plain Object3D came back.
7
+ */
8
+ export type AnimatedAsset = {
9
+ animations: AnimationClip[];
10
+ };
11
+ /**
12
+ * Avatar assets are glTF binaries compressed with EXT_meshopt_compression
13
+ * (see scripts/asset-pipeline/optimize-assets.mjs). The decoder ships its
14
+ * WebAssembly inline, so no extra file has to be served.
15
+ */
16
+ export declare function createAvatarLoader(manager?: LoadingManager): GLTFLoader;
@@ -1,4 +1,4 @@
1
- import { C as A, E as e, S as s, d as E, c } from "./index-1DOqo2bD.js";
1
+ import { C as A, E as e, S as s, d as E, c } from "./index-DY_Y_QHI.js";
2
2
  export {
3
3
  A as ChatWidgetInstance,
4
4
  e as EXTERNALLY_AVAILABLE_ACTIONS,
@@ -1,2 +1,3 @@
1
1
  export declare const SM_BREAKPOINT = 640;
2
+ export declare function isPhoneViewport(): boolean;
2
3
  export declare const SHOW_REACTION_MESSAGE_DURATION = 5000;
@@ -10,8 +10,6 @@ type ChatWidgetContextValue = {
10
10
  transitionSurface: (open: boolean, context: SurfaceTransitionContext) => void;
11
11
  openCompactPreview: (context: SurfaceTransitionContext) => Promise<boolean> | null;
12
12
  surfaceEpisodeId: string | null;
13
- isFullscreen: boolean;
14
- setFullscreen: (fullscreen: boolean) => void;
15
13
  contentActivated: boolean;
16
14
  isAvatarCoveredByChatList: boolean;
17
15
  setAvatarCoveredByChatList: (covered: boolean) => void;
@@ -0,0 +1,61 @@
1
+ import type { CustomerInteractionSession } from "@/types";
2
+ import { changeProjectionV1, collectClientEnvironmentV1 } from "./collectClientEnvironment";
3
+ type ClientEnvironmentRuntimeOptions = Readonly<{
4
+ baseUrl?: string;
5
+ fetch?: typeof fetch;
6
+ collect?: typeof collectClientEnvironmentV1;
7
+ project?: typeof changeProjectionV1;
8
+ createId?: () => string;
9
+ now?: () => number;
10
+ random?: () => number;
11
+ sdkVersion?: string;
12
+ }>;
13
+ export declare class ClientEnvironmentRuntime {
14
+ private readonly getSession;
15
+ private readonly onSessionExpired;
16
+ private readonly baseUrl;
17
+ private readonly fetchImpl;
18
+ private readonly collect;
19
+ private readonly project;
20
+ private readonly createId;
21
+ private readonly now;
22
+ private readonly random;
23
+ private readonly sdkVersion;
24
+ private sessionId;
25
+ private accessToken;
26
+ private generation;
27
+ private runtimeId;
28
+ private nextSequence;
29
+ private latestFenceRevision;
30
+ private lastStartedAt;
31
+ private cooldownUntil;
32
+ private lastCollectedProjection;
33
+ private acknowledged;
34
+ private active;
35
+ private pending;
36
+ private recovery;
37
+ private awaitingRenewalToken;
38
+ private currentProjectionUncertain;
39
+ private suppressedProjectionKey;
40
+ private pumpTimer;
41
+ private readonly eventWaiters;
42
+ private started;
43
+ private destroyed;
44
+ constructor(getSession: () => CustomerInteractionSession, onSessionExpired: () => void, options?: ClientEnvironmentRuntimeOptions);
45
+ start(): void;
46
+ ensureForEvent(expectedSessionId: string): Promise<string | null>;
47
+ updateSession(session: CustomerInteractionSession): void;
48
+ destroy(): void;
49
+ private requestCurrentObservation;
50
+ private startRecovery;
51
+ private pump;
52
+ private upload;
53
+ private runAttempts;
54
+ private sendOnce;
55
+ private withEventDeadline;
56
+ private delay;
57
+ private resetGeneration;
58
+ private safeCreateId;
59
+ private cancelGeneration;
60
+ }
61
+ export {};
@@ -0,0 +1,6 @@
1
+ import { type ClientEnvironmentBrowserSources, type ClientEnvironmentChangeProjectionV1, type ClientEnvironmentCollectionInput, type ClientEnvironmentObservationV1 } from "./types";
2
+ export declare const CLIENT_ENVIRONMENT_BROWSER_INSTANCE_STORAGE_KEY = "lola-ai-assistant:client-environment:browser-instance:v1";
3
+ export declare const browserClientEnvironmentSources: ClientEnvironmentBrowserSources;
4
+ export declare const resolveClientEnvironmentBrowserInstanceId: (sources?: ClientEnvironmentBrowserSources) => string | null;
5
+ export declare const collectClientEnvironmentV1: (input: ClientEnvironmentCollectionInput, sources?: ClientEnvironmentBrowserSources) => ClientEnvironmentObservationV1;
6
+ export declare const changeProjectionV1: (observation: ClientEnvironmentObservationV1, previous?: ClientEnvironmentChangeProjectionV1 | null) => ClientEnvironmentChangeProjectionV1;
@@ -0,0 +1,93 @@
1
+ export declare const CLIENT_ENVIRONMENT_SCHEMA_VERSION: 1;
2
+ export declare const CLIENT_ENVIRONMENT_CHANGE_PROJECTION_VERSION: 1;
3
+ export type ClientEnvironmentOrientation = "portrait" | "landscape" | "unknown";
4
+ export interface ClientEnvironmentObservationV1 {
5
+ readonly schemaVersion: typeof CLIENT_ENVIRONMENT_SCHEMA_VERSION;
6
+ readonly clientObservationId: string;
7
+ readonly clientRuntimeId: string;
8
+ readonly clientSequence: number;
9
+ readonly browserInstanceId: string | null;
10
+ readonly collectedAt: string;
11
+ readonly sdk: Readonly<{
12
+ name: "lola-ai-assistant";
13
+ version: string;
14
+ }>;
15
+ readonly locale: Readonly<{
16
+ language: string | null;
17
+ languages: readonly string[];
18
+ timeZone: string | null;
19
+ localUtcOffsetMinutes: number | null;
20
+ }>;
21
+ readonly screen: Readonly<{
22
+ widthCssPx: number | null;
23
+ heightCssPx: number | null;
24
+ availableWidthCssPx: number | null;
25
+ availableHeightCssPx: number | null;
26
+ devicePixelRatio: number | null;
27
+ orientation: ClientEnvironmentOrientation;
28
+ }>;
29
+ readonly viewport: Readonly<{
30
+ widthCssPx: number | null;
31
+ heightCssPx: number | null;
32
+ visualWidthCssPx: number | null;
33
+ visualHeightCssPx: number | null;
34
+ visualScale: number | null;
35
+ }>;
36
+ readonly interaction: Readonly<{
37
+ maxTouchPoints: number | null;
38
+ coarsePointer: boolean | null;
39
+ hoverSupported: boolean | null;
40
+ }>;
41
+ }
42
+ export interface ClientEnvironmentCollectionInput {
43
+ readonly clientObservationId: string;
44
+ readonly clientRuntimeId: string;
45
+ readonly clientSequence: number;
46
+ readonly sdkVersion: string;
47
+ }
48
+ export interface BrowserInstanceStorage {
49
+ getItem(key: string): string | null;
50
+ setItem(key: string, value: string): void;
51
+ }
52
+ export interface ClientEnvironmentBrowserSources {
53
+ readonly now: () => unknown;
54
+ readonly language: () => unknown;
55
+ readonly languages: () => unknown;
56
+ readonly timeZone: () => unknown;
57
+ readonly timeZoneOffsetMinutes: () => unknown;
58
+ readonly screenWidth: () => unknown;
59
+ readonly screenHeight: () => unknown;
60
+ readonly screenAvailableWidth: () => unknown;
61
+ readonly screenAvailableHeight: () => unknown;
62
+ readonly devicePixelRatio: () => unknown;
63
+ readonly screenOrientationType: () => unknown;
64
+ readonly viewportWidth: () => unknown;
65
+ readonly viewportHeight: () => unknown;
66
+ readonly visualViewportWidth: () => unknown;
67
+ readonly visualViewportHeight: () => unknown;
68
+ readonly visualViewportScale: () => unknown;
69
+ readonly maxTouchPoints: () => unknown;
70
+ readonly coarsePointer: () => unknown;
71
+ readonly hoverSupported: () => unknown;
72
+ readonly storage: () => BrowserInstanceStorage | null | undefined;
73
+ readonly randomUuid: () => unknown;
74
+ }
75
+ export interface ClientEnvironmentChangeProjectionV1 {
76
+ readonly projectionVersion: typeof CLIENT_ENVIRONMENT_CHANGE_PROJECTION_VERSION;
77
+ readonly browserInstanceId: string | null;
78
+ readonly language: string | null;
79
+ readonly languages: readonly string[];
80
+ readonly timeZone: string | null;
81
+ readonly localUtcOffsetMinutes: number | null;
82
+ readonly screenWidthCssPx: number | null;
83
+ readonly screenHeightCssPx: number | null;
84
+ readonly screenAvailableWidthCssPx: number | null;
85
+ readonly screenAvailableHeightCssPx: number | null;
86
+ readonly devicePixelRatio: number | null;
87
+ readonly orientation: ClientEnvironmentOrientation;
88
+ readonly viewportWidthBucketCssPx: number | null;
89
+ readonly visualScale: number | null;
90
+ readonly maxTouchPoints: number | null;
91
+ readonly coarsePointer: boolean | null;
92
+ readonly hoverSupported: boolean | null;
93
+ }
@@ -53,6 +53,7 @@ export declare class CommandRuntime {
53
53
  private requireEnvelopeTarget;
54
54
  private findTargetElement;
55
55
  private applyDefaultHighlight;
56
+ private applyHighlightEffect;
56
57
  private removeDefaultHighlight;
57
58
  private observeTarget;
58
59
  private createTargetActivationReporter;
@@ -3,11 +3,14 @@ import type { AppApi } from "@/App";
3
3
  import type { WidgetConfig } from "@/index.types";
4
4
  import { type MessageStreamState } from "./message-stream";
5
5
  import type { ChatAttachment, ChatTypingState } from "./chat-experience";
6
+ import { type SafeResponderPresentation } from "@/domain/support-presentation/support-presentation.types";
6
7
  import type { ResponderPresentationChanged, ScenarioConversationCreated } from "./cable/widget-message";
7
8
  import { type ScenarioChoiceLifecycleChanged, type ScenarioChoiceSubmissionResult } from "@/domain/scenario/scenario-choice";
8
9
  export interface ThreadSummary {
9
10
  threadId: string;
11
+ title: string | null;
10
12
  lastMessage: MessageData;
13
+ responderPresentation: SafeResponderPresentation;
11
14
  }
12
15
  export type AgentResponsePhase = "idle" | "awaiting-first-token" | "streaming";
13
16
  export type ConversationNavigationRequest = {
@@ -1,6 +1,8 @@
1
1
  export type SpeechPlaybackOptions = {
2
2
  onStarted?: () => void;
3
3
  onStopped?: (completed: boolean) => void;
4
+ onLevel?: (level: number) => void;
5
+ levelContext?: AudioContext;
4
6
  };
5
7
  export type PcmStreamLoader = (signal: AbortSignal) => Promise<ReadableStream<Uint8Array>>;
6
8
  export type PcmPlaybackOptions = SpeechPlaybackOptions & {
@@ -1,4 +1,5 @@
1
1
  import type { CustomerInteractionSession } from "@/types";
2
+ import type { ClientEnvironmentRuntime } from "@/domain/client-environment/ClientEnvironmentRuntime";
2
3
  export type TrackEvent = {
3
4
  event: string;
4
5
  params?: Record<string, unknown>;
@@ -6,6 +7,9 @@ export type TrackEvent = {
6
7
  export declare class LolaEventTracker {
7
8
  private readonly getSession;
8
9
  private readonly onSessionExpired;
9
- constructor(getSession: () => CustomerInteractionSession, onSessionExpired: () => void);
10
+ private readonly clientEnvironment;
11
+ private destroyed;
12
+ constructor(getSession: () => CustomerInteractionSession, onSessionExpired: () => void, clientEnvironment: Pick<ClientEnvironmentRuntime, "ensureForEvent">);
10
13
  track(trackingEvent: TrackEvent): Promise<void>;
14
+ destroy(): void;
11
15
  }
@@ -31,10 +31,11 @@ export type CompactPreviewLayout = {
31
31
  export declare const LAUNCHER_SIZE = 52;
32
32
  export declare const LAUNCHER_EDGE_INSET = 24;
33
33
  export declare const VIEWPORT_MARGIN = 16;
34
- export declare const MIN_WIDGET_WIDTH = 240;
35
- export declare const DEFAULT_WIDGET_WIDTH = 360;
36
- export declare const MIN_WIDGET_HEIGHT = 320;
34
+ export declare const CHAT_SURFACE_ASPECT_RATIO: number;
35
+ export declare const MIN_WIDGET_HEIGHT = 519;
36
+ export declare const MIN_WIDGET_WIDTH: number;
37
37
  export declare const DEFAULT_WIDGET_HEIGHT = 680;
38
+ export declare const DEFAULT_WIDGET_WIDTH: number;
38
39
  export declare const COMPACT_PREVIEW_MAX_WIDTH = 320;
39
40
  export declare const COMPACT_PREVIEW_MARGIN = 12;
40
41
  export declare const COMPACT_PREVIEW_GAP = 12;
@@ -45,7 +46,8 @@ export declare function dockLauncherPosition(point: Point, viewport: Viewport):
45
46
  export declare function launcherPointFromDock(launcher: DockedLauncher, viewport: Viewport): Point;
46
47
  export declare function clampLauncherPosition(point: Point, viewport: Viewport): Point;
47
48
  export declare function clampPanelRect(rect: Rect, viewport: Viewport): Rect;
49
+ export declare function dockPanelRect(rect: Rect, viewport: Viewport): Rect;
50
+ export declare function dockPanelRectToSide(rect: Rect, viewport: Viewport, side: LauncherSide): Rect;
48
51
  export declare function placePanelFromLauncher(launcher: Point, size: Size, viewport: Viewport): Rect;
49
52
  export declare function placeCompactPreview(launcher: Point, measuredSize: Size, viewport: Viewport, side: LauncherSide, avoidRect?: Rect | null): CompactPreviewLayout;
50
- export declare function resizePanelFromNorthWest(start: Rect, delta: Point, axes: "top" | "left" | "corner", viewport: Viewport): Rect;
51
- export declare function resizePanelFromSouthEast(start: Rect, delta: Point, viewport: Viewport): Rect;
53
+ export declare function resizePanelFromTopCorner(start: Rect, delta: Point, corner: "northWest" | "northEast", viewport: Viewport): Rect;
@@ -6,10 +6,14 @@ export declare class ReliableVoiceUplink {
6
6
  private readonly queue;
7
7
  private sending;
8
8
  private closed;
9
+ private enabled;
10
+ private epoch;
9
11
  private firstCaptureSample;
10
12
  private firstDispatchAtMs;
11
13
  constructor(send: (chunk: CapturedAudioChunk) => Promise<VoiceAudioAcknowledgement>, onFailure: (error: Error) => void);
14
+ get isAcceptingInput(): boolean;
12
15
  enqueue(chunk: CapturedAudioChunk): void;
16
+ setEnabled(enabled: boolean): void;
13
17
  close(): void;
14
18
  private drain;
15
19
  private waitForPacing;
@@ -0,0 +1,12 @@
1
+ export type VoiceAudioMeterChannel = "input" | "output";
2
+ type VoiceAudioMeterListener = (level: number) => void;
3
+ export declare class VoiceAudioMeter {
4
+ private readonly levels;
5
+ private readonly listeners;
6
+ write(channel: VoiceAudioMeterChannel, value: unknown): void;
7
+ read(channel: VoiceAudioMeterChannel): number;
8
+ subscribe(channel: VoiceAudioMeterChannel, listener: VoiceAudioMeterListener): () => void;
9
+ reset(channel?: VoiceAudioMeterChannel): void;
10
+ }
11
+ export declare const voiceAudioMeter: VoiceAudioMeter;
12
+ export {};
@@ -1,6 +1,7 @@
1
1
  import { type Socket } from "socket.io-client";
2
2
  import type { AppApi } from "@/App";
3
3
  import type { VoiceSessionData } from "@/api/voice.api.types";
4
+ import { ReliableVoiceUplink } from "./media/ReliableVoiceUplink";
4
5
  import type { SpeakTextCommandContext, StartVoiceConversationCommandContext } from "@/domain/command/command.types";
5
6
  import type { WidgetConfig } from "@/index.types";
6
7
  type VoiceStatus = "idle" | "connecting" | "listening" | "speaking" | "error";
@@ -16,20 +17,23 @@ type VoiceStore = {
16
17
  localStream: MediaStream | null;
17
18
  inputAudioContext: AudioContext | null;
18
19
  inputAudioNode: AudioWorkletNode | null;
20
+ inputAudioUplink: ReliableVoiceUplink | null;
19
21
  pendingInvitation: StartVoiceConversationCommandContext | null;
20
22
  customerMessageTranscript: string;
21
23
  customerMessageTranscriptVisible: boolean;
22
24
  assistantMessageTranscript: string;
23
25
  assistantMessageTranscriptVisible: boolean;
24
26
  assistantResponseInProgress: boolean;
27
+ assistantAudioPlaying: boolean;
25
28
  microphoneEnabled: boolean;
29
+ microphoneMutedByUser: boolean;
26
30
  generation: number;
27
31
  actions: VoiceStoreActions;
28
32
  };
29
33
  type VoiceStoreActions = {
30
34
  updateSession: (config: WidgetConfig, api: AppApi) => Promise<void>;
31
35
  startListening: (config: WidgetConfig, api: AppApi) => Promise<void>;
32
- offerConversation: (invitation: StartVoiceConversationCommandContext) => Promise<void>;
36
+ offerConversation: (invitation: StartVoiceConversationCommandContext, config: WidgetConfig, api: AppApi) => Promise<void>;
33
37
  acceptConversation: (config: WidgetConfig, api: AppApi) => Promise<void>;
34
38
  declineConversation: (config: WidgetConfig, api: AppApi) => Promise<void>;
35
39
  speakText: (config: WidgetConfig, api: AppApi, speech: SpeakTextCommandContext) => Promise<void>;
@@ -14,6 +14,7 @@ declare const en: {
14
14
  };
15
15
  readonly controls: {
16
16
  readonly close: "Close chat";
17
+ readonly collapse: "Collapse chat";
17
18
  readonly move: "Move Lola";
18
19
  readonly exitFullscreen: "Exit fullscreen";
19
20
  readonly enterFullscreen: "Enter fullscreen";
@@ -25,6 +26,7 @@ declare const en: {
25
26
  readonly identity: {
26
27
  readonly support: "Support";
27
28
  readonly system: "System";
29
+ readonly online: "online";
28
30
  readonly aiAssistant: "AI assistant";
29
31
  readonly waiting: "Waiting for a specialist";
30
32
  readonly operator: "Support operator";
@@ -33,8 +35,9 @@ declare const en: {
33
35
  };
34
36
  readonly chat: {
35
37
  readonly back: "Back to chat";
36
- readonly listTitle: "Chats";
38
+ readonly listTitle: "Chat history";
37
39
  readonly new: "New chat";
40
+ readonly createNew: "Create new chat";
38
41
  readonly loadOlder: "Load older chats";
39
42
  readonly retryOlder: "Retry older chats";
40
43
  readonly olderLoadFailed: "Couldn't load older chats.";
@@ -47,7 +50,7 @@ declare const en: {
47
50
  readonly switchToVoice: "Switch to voice chat";
48
51
  readonly talk: "Talk";
49
52
  readonly messageLabel: "Message";
50
- readonly messagePlaceholder: "Message…";
53
+ readonly messagePlaceholder: "Write to Lola";
51
54
  readonly send: "Send message";
52
55
  readonly thinking: "AI is thinking";
53
56
  readonly unread: "Unread messages";