@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
package/README.md CHANGED
@@ -1,365 +1,172 @@
1
- # Bridge AI Chat Widget
1
+ # Lola AI Assistant
2
2
 
3
- Embeddable React + TypeScript chat widget for Bridge AI agents, with:
3
+ Embeddable browser library for the Lola assistant. The package owns its DOM host,
4
+ Shadow DOM, chat UI, avatar, realtime transports, voice flow, and backend command
5
+ runtime. A product frontend supplies only an authenticated interaction session and
6
+ the few integrations that must cross into the host application.
4
7
 
5
- - text chat
6
- - optional realtime voice mode backed by the Lola Socket.IO proxy and xAI
7
- - optional animated 3D avatar (three.js)
8
- - WebSocket live message updates (AnyCable)
9
- - Shadow DOM isolation for host-page style safety
8
+ ## Install and build
10
9
 
11
- ## What This Project Is
10
+ The package requires React 19 or newer as a peer dependency.
12
11
 
13
- `bridgeapp-ai-chat-widget` is an ESM library bundle that host applications instantiate via:
14
-
15
- - `new ChatWidgetInstance(config)`
16
-
17
- The instance mounts a React app into a host element's Shadow DOM, fetches static asset mappings from a remote manifest, initializes chat/voice/avatar modules, and exposes a small integration API (`setOpen`, `destroy`, `setCustomerInteractionSession`, events).
18
-
19
- ## Tech Stack
20
-
21
- - React 19
22
- - TypeScript
23
- - Vite (dev app + library build)
24
- - Tailwind CSS 4
25
- - Zustand (state stores)
26
- - three.js + FBX assets (avatar rendering/animation)
27
- - AnyCable Web client (live chat transport)
28
- - Socket.IO + AudioWorklet (realtime voice mode through Lola Backend)
29
-
30
- ## Repository Layout
31
-
32
- High-level structure:
33
-
34
- - `src/index.ts` - public library entry (`ChatWidgetInstance`)
35
- - `src/index.types.ts` - public config/types surface
36
- - `src/App.tsx` - provider composition root
37
- - `src/react/mount.tsx` - React root mount helper
38
- - `src/ui/components` - UI components (chat widget, routes, controls)
39
- - `src/domain/message` - message store + websocket channel integration
40
- - `src/domain/voice` - Lola voice session, PCM media, and xAI realtime events
41
- - `src/avatar` - three.js avatar scene, animation manager, blend shapes
42
- - `src/api` - HTTP clients for messages/voice/session-related calls
43
- - `src/context/ChatWidgetContext.tsx` - widget-level UI state/context
44
- - `src/dev` - local/dev/demo stand bootstrap (non-library integration path)
45
- - `src/assets` - local assets used by the widget and avatar (not used directly, rather this whole folder is getting pushed to assets repo)
46
- - `scripts` - utility scripts (for example asset sync to remote static repo)
47
-
48
- ## Runtime Architecture
49
-
50
- ### 1) Host Integration Layer
51
-
52
- `ChatWidgetInstance` (`src/index.ts`) is the host-facing API:
53
-
54
- - validates `mountElementId`
55
- - creates `shadowRoot` on mount element
56
- - injects bundled CSS into shadow root
57
- - fetches `${ASSETS_URL}/manifest.json`
58
- - resolves hashed asset paths via `resolveAssetPath(path)`
59
- - optionally merges remote config (`remoteConfig`)
60
- - mounts React app and wires `AppApi` callbacks/events
61
-
62
- ### 2) React App + Providers
63
-
64
- `App` composes:
65
-
66
- - `ChatWidgetContextProvider` (widget open state, sizing, config, loading progress)
67
- - `CableProvider` (AnyCable websocket service + network status)
68
- - `HashRouter` (voice/text/list routes)
69
-
70
- ### 3) Messaging Domain
71
-
72
- `useMessageStore` handles:
73
-
74
- - initial thread bootstrap (`ListMessages`, `ListMessagesForThreads`)
75
- - optimistic and server-driven message updates
76
- - thread map and per-thread message derivation
77
- - message send (`CreateMessage`)
78
- - agentic steps merge/update and rendering support
79
-
80
- Live updates arrive via AnyCable channel events and are pushed into the store.
81
- Versioned `messageDelta` updates are applied by `messageId` and increasing
82
- `sequence`; each frame contains the current accumulated text, so duplicate or
83
- stale frames cannot append content twice. The UI renders every accepted frame
84
- immediately and animates only the newly arrived suffix. See
85
- [`docs/chat-streaming.ru.md`](docs/chat-streaming.ru.md) for the wire contract,
86
- lifecycle, rendering, and scroll behavior.
87
-
88
- ### 4) Voice Domain
89
-
90
- `useVoiceStore` manages the Lola voice turn lifecycle:
91
-
92
- - creates a canonical `POST /voice/sessions` session
93
- - captures mono microphone input and converts it to PCM16 24 kHz in an AudioWorklet
94
- - connects to the authenticated `/assistant` Socket.IO namespace, activates the
95
- provider session with `voice.connect`, and sends sequenced Lola protocol v4
96
- `voice.audio.append` events with acknowledgements
97
- - plays `response.output_audio.delta` through a continuous AudioWorklet queue
98
- - unwraps canonical `voice.event` envelopes, renders Grok realtime transcripts,
99
- and keeps avatar talking state in sync
100
- - creates a fresh VoiceSession after an unexpected voice socket disconnect
101
- - closes the session through `voice.disconnect` with the REST endpoint as a fallback
102
-
103
- ### 5) Avatar Domain
104
-
105
- `Avatar` + `AnimationManager`:
106
-
107
- - initializes three.js renderer/camera/lights/materials
108
- - loads model + texture + animation assets from resolved remote paths
109
- - emits `loading_progress`
110
- - starts animation mixer loops
111
- - maps viseme timeline to morph target animation during speech
112
- - exposes external animation actions (`excited`, `fix_hair`, `spin`, `kiss`)
113
-
114
- When all assets load, widget emits `avatar_ready` through `ChatWidgetInstance`.
115
-
116
- ## Public API
117
-
118
- Import:
119
-
120
- ```ts
121
- import {
122
- ChatWidgetInstance,
123
- type WidgetConfig,
124
- } from "bridgeapp-ai-chat-widget";
12
+ ```bash
13
+ npm install
14
+ npm run build-lib
125
15
  ```
126
16
 
127
- ### `ExternalWidgetConfig`
128
-
129
- - `mountElementId: string`
130
- - - `configName: string` - remote config, lives at the same place as other static assets
131
- - `customerInteractionSession?: { accessToken; chatId; expiresAt }` - if there's no session (separate case for dev/demo mode) - we look for customerId in remote config and create session ourselves.
132
-
133
- ### `RemoteWidgetConfig`
17
+ Library transport and asset origins are embedded at build time:
134
18
 
135
- Actual widget config
136
-
137
- - `agentId: string`
138
- - `customerId?: string`
139
- - `wsUrl: string`
140
- - `apiUrl: string`
141
- - `AIAvatar?: boolean` - is 3D avatar be used
142
- - `voiceEnabled?: boolean` - is voice mode enebled
143
- - `voiceConfig?: { voice: "ara" | "eve" | "leo" | "rex" | "sal" }` - optional xAI voice
144
- - `background?: boolean` - clear or visible background
145
- - `footer?: boolean` - is footer rendered
146
- - `debug?: boolean` (avatar debug GUI)
147
- - `manualOpen?: boolean` - is widget trigger rendered or should it be open only programatically
148
-
149
- ### Instance Methods
150
-
151
- - `setOpen(open: boolean): void` - open/close widget
152
- - `setCustomerInteractionSession(session): void` - update session after initialization (on session expire)
153
- - `playAnimation(name): void`
154
- - `destroy(): void`
19
+ ```dotenv
20
+ VITE_LOLA_API_URL=https://api.example.test/api/v1
21
+ VITE_LOLA_WS_URL=wss://ws.example.test/cable
22
+ VITE_AI_ASSISTANT_ASSETS_URL=https://assets.example.test
23
+ ```
155
24
 
156
- ### Events
25
+ All three values are required absolute URLs. The library build fails when a value
26
+ is missing, malformed, or uses an incompatible protocol. `VITE_*` values are
27
+ public client configuration: never place service-account keys, access tokens, or
28
+ other credentials in them. CI values override the placeholders in `.env`.
157
29
 
158
- - `avatar_ready` - emitted once avatar assets are fully loaded
159
- - `renew_session` - emitted when session is expired or near expiry
30
+ ## Minimal integration
160
31
 
161
- ## Host Usage Example
32
+ The product backend creates a Lola customer interaction session. The product
33
+ frontend passes the short-lived result to the library:
162
34
 
163
35
  ```ts
164
- import { ChatWidgetInstance } from "bridgeapp-ai-chat-widget";
36
+ import { ChatWidgetInstance } from "@alxxsck/ai-assistant";
165
37
 
166
38
  const widget = new ChatWidgetInstance({
167
- mountElementId: "chat-widget-root",
168
- customerInteractionSession: CustomerInteractionSession,
169
- AIAvatar: true,
170
- background: false,
171
- voiceEnabled: true,
172
- footer: false,
173
- manualOpen: true,
174
- });
175
-
176
- widget.addEventListener("avatar_ready", () => {
177
- widget.setOpen(true);
178
- });
179
-
180
- widget.addEventListener("renew_session", async () => {
181
- const newSession = await fetchNewSessionSomehow();
182
- widget.setCustomerInteractionSession(newSession);
39
+ customerInteractionSession: {
40
+ accessToken: session.accessToken,
41
+ interactionSessionId: session.interactionSessionId,
42
+ expiresAt: session.expiresAt,
43
+ },
183
44
  });
184
45
  ```
185
46
 
186
- Teardown:
47
+ `CustomerInteractionSession` contains exactly:
187
48
 
188
49
  ```ts
189
- widget.destroy();
50
+ type CustomerInteractionSession = {
51
+ readonly accessToken: string;
52
+ readonly interactionSessionId: string;
53
+ readonly expiresAt: string;
54
+ };
190
55
  ```
191
56
 
192
- ## Local Development
57
+ Realtime settings, voice availability, provider voice selection, and project
58
+ settings belong to Lola Backend. They are not widget constructor properties and
59
+ must not be copied into the interaction session.
193
60
 
194
- Install:
61
+ The instance creates a dedicated host below `document.body` and attaches an open
62
+ Shadow DOM to it. Multiple instances remain isolated. Call `destroy()` to unmount
63
+ the widget, disconnect its runtime, clear pending work, and remove the owned host.
195
64
 
196
- ```bash
197
- npm install
198
- ```
65
+ ## Lifecycle
199
66
 
200
- Start dev server:
67
+ The supported instance methods are:
201
68
 
202
- ```bash
203
- npm run dev
69
+ ```ts
70
+ widget.setOpen(true);
71
+ widget.setCustomerInteractionSession(nextSession);
72
+ widget.destroy();
204
73
  ```
205
74
 
206
- Notes:
207
-
208
- - Vite dev server runs on `5179` by default.
209
- - `src/dev/main.tsx` is the local bootstrap path (creates session and mounts widget directly).
210
- - `vite.config.ts` is for app/dev runtime.
211
- - `vite.config.lib.ts` is for distributable library build.
212
-
213
- ## Build, Publish, and Deployment
214
-
215
- ### Build local dev app
216
-
217
- ```bash
218
- npm run build-dev
219
- ```
75
+ `setOpen` may be called before asynchronous widget initialization completes; the
76
+ latest requested state is applied when the UI is ready. Session replacement updates
77
+ authenticated HTTP, realtime, message, voice, and command dependencies without
78
+ recreating the public widget instance.
220
79
 
221
- ### Build library artifacts
80
+ The widget emits `renew_session` before expiry and after supported authentication
81
+ failures. Refresh through the product backend and replace the session:
222
82
 
223
- ```bash
224
- npm run build-lib
83
+ ```ts
84
+ widget.addEventListener("renew_session", async () => {
85
+ const nextSession = await productApi.createLolaInteractionSession();
86
+ widget.setCustomerInteractionSession(nextSession);
87
+ });
225
88
  ```
226
89
 
227
- Outputs include:
228
-
229
- - `dist/bridge-ai-chat-widget.es.js`
230
- - `dist/index.types.d.ts`
90
+ The constructor and replacement method reject empty tokens, empty interaction
91
+ session identifiers, and invalid expiry timestamps.
231
92
 
232
- ### Publish flow
93
+ ## Launcher control
233
94
 
234
- - `prepublishOnly` runs `build-lib`
235
- - package exports are defined in `package.json` under `"exports"`
95
+ The built-in launcher is visible by default. Products that render their own button
96
+ can hide it while keeping the same programmatic open path:
236
97
 
237
- ### Other project scripts
98
+ ```ts
99
+ const widget = new ChatWidgetInstance({
100
+ customerInteractionSession: session,
101
+ hideOpenButton: true,
102
+ });
238
103
 
239
- The demo app reads its service credential from
240
- `VITE_SERVICE_ACCOUNT_API_KEY`; credentials must not be committed to source or
241
- static config files.
104
+ productButton.addEventListener("click", () => widget.setOpen(true));
105
+ ```
242
106
 
243
- - `npm run lint`
244
- - `npm run lint-fix`
245
- - `npm run format`
246
- - `npm run format:check`
247
- - deployment scripts for S3 buckets (project-specific, to be reworked)
248
- - `npm run push-assets-metamediastatic` (sync `src/assets` into remote static assets repo)
107
+ Closing a hidden-launcher widget leaves it non-interactive until the product calls
108
+ `setOpen(true)` again. The runtime and active interaction session remain mounted.
249
109
 
250
- ## Session Handling
110
+ ## Host handlers
251
111
 
252
- Widget relies on `customerInteractionSession`:
112
+ `handlers` is optional and is the only command integration surface. Use it when a
113
+ backend command must navigate the product, open a product modal, or customize an
114
+ element highlight:
253
115
 
254
- - used as Bearer token for HTTP APIs
255
- - used in websocket query for AnyCable auth
256
- - periodically checked by `useSessionExpiryChecks`
116
+ ```ts
117
+ const widget = new ChatWidgetInstance({
118
+ customerInteractionSession: session,
119
+ handlers: {
120
+ openPage: ({ route }) => productRouter.push(route),
121
+ openModal: ({ modalName }) => productModals.open(modalName),
122
+ highlight: ({ element, active }) => {
123
+ element?.classList.toggle("lola-highlight", active);
124
+ },
125
+ },
126
+ });
127
+ ```
257
128
 
258
- When session is near expiry or invalid, `renew_session` event is emitted; host app must provide a fresh session via `setCustomerInteractionSession`.
129
+ Page and modal targets arrive in canonical Lola command envelopes. The built-in
130
+ element fallback resolves stable `[data-lola="..."]` attributes. CTA display,
131
+ chat open/close, speech, voice conversations, and avatar animation stay internal.
259
132
 
260
- ## Lola Backend conversations
133
+ Command lifecycle events are available as `command_received`,
134
+ `command_succeeded`, `command_failed`, `command_expired`, and
135
+ `command_unsupported`.
261
136
 
262
- The widget uses Lola's canonical conversation API. Interaction `chatId` remains
263
- the authenticated session identifier; chat history is keyed independently by
264
- `conversationId` (`threadId` in realtime compatibility messages).
137
+ ## Diagnostics
265
138
 
266
- - `GET /chat/conversations` loads the open chat list.
267
- - `GET /chat/conversations/:conversationId/messages` loads one history.
268
- - `POST /chat/conversations` creates and selects a new chat.
269
- - `POST /chat/conversations/:conversationId/select` selects an existing chat
270
- for the current interaction session.
271
- - `POST /chat/messages` sends `conversationId` and adopts the canonical
272
- `conversationId` returned by the backend when a chat is resolved or created.
139
+ Set `debug: true` to enable verbose lifecycle, realtime, speech, and voice logs
140
+ prefixed with `[Lola-Widget]`. Initialization and runtime errors remain visible
141
+ without this flag. The option does not restore the removed debug GUI or avatar
142
+ debug controls.
273
143
 
274
- A `409` response means that the selected conversation was closed. It is shown
275
- as a chat error and the open conversation list is refreshed; only `401`
276
- requests trigger interaction-session renewal.
144
+ ## Breaking migration
277
145
 
278
- ## Lola Backend command runtime
146
+ This release intentionally removes the former dev/demo and host-configuration
147
+ surface. Remove these constructor properties from integrations:
279
148
 
280
- The widget consumes Lola Backend `command.created` envelopes from the AnyCable
281
- `commandCreated`/`uiCommand` frame, acknowledges `received` and a final result, and
282
- deduplicates `commandId` during reconnect replay. Updating the interaction session
283
- now reconnects REST and AnyCable without remounting the widget.
149
+ - `mountElementId`, `agentId`, `customerId`, `configName`
150
+ - `apiUrl`, `wsUrl`
151
+ - `AIAvatar`, `background`, `footer`, `voiceEnabled`, `voiceConfig`, `locale`
152
+ - `manualOpen`, `avatarDebug`, `uiTargets`, `commandHandlers`
284
153
 
285
- The complete frontend integration and rollout guide is available in
286
- [`docs/ui-actions-sdk.ru.md`](docs/ui-actions-sdk.ru.md).
154
+ Replace `manualOpen` with `hideOpenButton: true` only when the standard launcher
155
+ must be hidden. Remove calls to `playAnimation`, `executeReaction`,
156
+ `sendServiceMessage`, `setLocale`, `registerUiTarget`, and
157
+ `registerCommandHandler`. Backend commands retain the supported assistant
158
+ behaviour internally.
287
159
 
288
- The previous callback fields (`url`, `target`, `commandType`,
289
- `targetDefinition`, and `modalId`) remain as deprecated aliases for a
290
- zero-downtime host migration.
160
+ The repository ships only the library build. It no longer contains an app-mode
161
+ HTML entry, local session creation, remote JSON widget configs, a debug GUI,
162
+ preview/deploy demo scripts, or a Vite dev-server configuration.
291
163
 
292
- Canonical page routes and modal names arrive in `data.target`; the host only
293
- provides typed callbacks:
164
+ ## Verification
294
165
 
295
- ```ts
296
- const widget = new ChatWidgetInstance({
297
- // Existing widget options...
298
- customerInteractionSession: {
299
- accessToken,
300
- chatId: sessionId,
301
- sessionId,
302
- expiresAt,
303
- },
304
- handlers: {
305
- openModal: ({ modalName }) => modalRegistry.open(modalName),
306
- openPage: ({ route }) => router.push(route),
307
- },
308
- // Temporary fallback for legacy commands without data.target.
309
- uiTargets: {
310
- deposit_button: {
311
- kind: "button",
312
- selector: '[data-lola-action="deposit"]',
313
- },
314
- deposit_modal: {
315
- kind: "modal",
316
- modalName: "deposit",
317
- },
318
- account_page: {
319
- kind: "page",
320
- route: "/account",
321
- query: { source: "lola" },
322
- },
323
- },
324
- });
166
+ ```bash
167
+ npm run typecheck
168
+ npm test
169
+ npm run lint
170
+ npm run format:check
171
+ npm run build-lib
325
172
  ```
326
-
327
- Targets and handlers can also be registered after construction with
328
- `registerUiTarget(code, target)` and `registerCommandHandler(name, handler)`.
329
- Both return an unregister callback.
330
-
331
- Built-in handlers cover assistant/chat visibility, supported avatar animations,
332
- CTA rendering inside the text chat, and element highlighting. Highlight targets
333
- fall back to `[data-lola="code"]` or `[data-lola-action="code"]`. The default
334
- highlight is a fixed overlay attached to `document.body`, so it is not clipped
335
- by an element's `overflow` or container bounds and follows resize and scroll. A registered page
336
- URL fallback uses `history.pushState` and emits `popstate`, so an explicitly
337
- configured query such as `?lola_modal=deposit` can be handled without reloading the
338
- host SPA. A registered modal selector can also open a native `HTMLDialogElement`.
339
- `data.target` is authoritative. Legacy commands without it are resolved through
340
- `payload.modalId`/`pageId` and `uiTargets`. If no safe handler/fallback exists, the widget sends
341
- `unsupported` and emits `command_unsupported`; other lifecycle events are
342
- `command_received`, `command_succeeded`, `command_failed`, and `command_expired`.
343
-
344
- ## Asset Pipeline
345
-
346
- Runtime asset resolution:
347
-
348
- 1. fetch remote manifest from `https://metamediastatic.com/manifest.json`
349
- 2. map logical path (for example `animations/idle_1.fbx`) to hashed URL
350
- 3. load via `resolveAssetPath`
351
-
352
- This allows cache-friendly hashed asset delivery without changing code references.
353
-
354
- ## Troubleshooting
355
-
356
- - Widget does not mount:
357
- - verify mount element exists and `mountElementId` is correct
358
- - No messages or send failures:
359
- - verify `apiUrl`, `accessToken`, and `chatId`
360
- - No live updates:
361
- - verify `wsUrl`, websocket reachability, and token validity
362
- - Voice fails to start:
363
- - verify mic permission, Lola `apiUrl`, Socket.IO reachability, and backend `Project.settings.voiceEnabled`
364
- - Avatar never becomes ready:
365
- - verify manifest URL + asset availability under static host
package/dist/App.d.ts CHANGED
@@ -13,14 +13,7 @@ export type AppApi = {
13
13
  playAvatarAnimation: (name: ExternallyAvailableActions, expiresAt?: string | null) => Promise<void>;
14
14
  onSessionExpired: () => void;
15
15
  registerSetOpen: (fn: ((open: boolean) => void) | null) => void;
16
- registerExecuteReaction: (fn: ((params: {
17
- animation: string;
18
- voice: string;
19
- text: string;
20
- }) => void) | null) => void;
21
16
  resolveAssetPath: (path: string) => string;
22
- registerSendServiceMessage: (fn: ((message: string, animationName: ExternallyAvailableActions) => void) | null) => void;
23
- registerSetLocale: (fn: ((locale: string) => void) | null) => void;
24
17
  registerSetSession: (fn: ((session: CustomerInteractionSession) => void) | null) => void;
25
18
  commandRuntime: CommandRuntime;
26
19
  };