@accurix/centrinfo-widget 5.2.1 → 5.4.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 (49) hide show
  1. package/README.md +231 -38
  2. package/dist/bundle-ar-D_Sk4igF.mjs +1 -0
  3. package/dist/bundle-ar-fKjs-fvS.cjs +1 -0
  4. package/dist/bundle-de-BST4qEm1.cjs +1 -0
  5. package/dist/bundle-de-BWnVOyv0.mjs +1 -0
  6. package/dist/bundle-es-Bes8ddxv.mjs +1 -0
  7. package/dist/bundle-es-Bfphsx9c.cjs +1 -0
  8. package/dist/bundle-fr-D1QlfFID.mjs +1 -0
  9. package/dist/bundle-fr-X5Ian15d.cjs +1 -0
  10. package/dist/bundle-it-9j6g91Cu.mjs +1 -0
  11. package/dist/bundle-it-C2HPnGql.cjs +1 -0
  12. package/dist/bundle-pt-BK9LBxix.mjs +1 -0
  13. package/dist/bundle-pt-BMcCSSgB.cjs +1 -0
  14. package/dist/bundle-sw-BKWnwk-0.cjs +1 -0
  15. package/dist/bundle-sw-DA2XuFS_.mjs +1 -0
  16. package/dist/cdn/centrinfo-widget-dev.js +35 -23
  17. package/dist/cdn/centrinfo-widget-locale-ar.js +4 -0
  18. package/dist/cdn/centrinfo-widget-locale-de.js +4 -0
  19. package/dist/cdn/centrinfo-widget-locale-es.js +4 -0
  20. package/dist/cdn/centrinfo-widget-locale-fr.js +4 -0
  21. package/dist/cdn/centrinfo-widget-locale-it.js +4 -0
  22. package/dist/cdn/centrinfo-widget-locale-pt.js +4 -0
  23. package/dist/cdn/centrinfo-widget-locale-sw.js +4 -0
  24. package/dist/cdn/centrinfo-widget-voice.js +272 -0
  25. package/dist/cdn/centrinfo-widget.js +154 -128
  26. package/dist/cdn/manifest.json +57 -9
  27. package/dist/dev-transports-DP4ilDW1.mjs +13 -0
  28. package/dist/dev-transports-uGHAao9W.cjs +13 -0
  29. package/dist/index.cjs +2 -1
  30. package/dist/index.d.cts +2 -2
  31. package/dist/index.d.mts +2 -2
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.mjs +2 -1
  34. package/dist/runtime.cjs +2 -2
  35. package/dist/runtime.d.cts +128 -11
  36. package/dist/runtime.d.mts +122 -8
  37. package/dist/runtime.d.ts +479 -0
  38. package/dist/runtime.mjs +2 -2
  39. package/dist/speech-detector-runtime-D5GpV8VJ.cjs +68 -0
  40. package/dist/speech-detector-runtime-D7gguFpP.mjs +68 -0
  41. package/dist/styles-BWPJrttg.cjs +3563 -0
  42. package/dist/styles-C8MXPiR-.mjs +3563 -0
  43. package/dist/{types-95uGbSpk.d.mts → types-M-juCXr7.d.mts} +558 -93
  44. package/dist/{types-DAYxNBhI.d.cts → types-sRV3p0Gu.d.cts} +549 -87
  45. package/package.json +4 -3
  46. package/dist/dev-transports-DqSPyIEz.mjs +0 -1
  47. package/dist/dev-transports-KlSdSZpj.cjs +0 -1
  48. package/dist/styles-CCw1cP6m.cjs +0 -3543
  49. package/dist/styles-CiqV_OsG.mjs +0 -3543
@@ -0,0 +1,479 @@
1
+ import { A as WidgetStrings, B as ResultLabels, C as PublicChatActionField, D as VoiceAnswer, E as LiveVoiceTransport, F as ResultTable, H as AnalyticsExplanationInput, I as formatResultCell, L as serializeResultCsv, N as SdkLanguage, O as DEFAULT_STRINGS, P as AnalyticsResultDetail, R as WidgetAnalyticsChart, S as PublicChatAction, T as VoiceFormField, V as AnalyticsAIExplanationTransport, _ as AnalyticsVisualization, a as MessageAttachment, b as ExplanationFeedbackInput, c as Visitor, f as WidgetLocaleUpdate, g as AnalyticsModelOption, h as ActionResult, i as FeaturedLink, j as mergeStrings, k as StringsProvider, l as WidgetActionTranslation, m as WidgetUser, n as ChatArtifact, o as SchedulerInfo, p as WidgetThemeTokens, r as ChatMessage, s as Source, t as BootstrapInfo, u as WidgetConfig, v as DemoBooking, w as Transport, x as GifResult, y as DemoSlotsResult, z as buildWidgetAnalyticsChartModel } from "./types-M-juCXr7.mjs";
2
+ import * as preact2 from "preact";
3
+ import { JSX } from "preact";
4
+
5
+ //#region src/localization.d.ts
6
+ /** Everything the widget shows for one language: its own chrome + analytics results. */
7
+ interface WidgetLocaleBundle {
8
+ widget: Partial<WidgetStrings>;
9
+ results: Partial<ResultLabels>;
10
+ }
11
+ type WidgetLocaleModule = {
12
+ default: WidgetLocaleBundle;
13
+ };
14
+ type WidgetLocaleLoader = (language: SdkLanguage) => Promise<WidgetLocaleModule>;
15
+ /**
16
+ * Replace how bundled catalogs are fetched. The CDN build points this at the
17
+ * sibling `centrinfo-widget-locale-<lang>.js` chunks.
18
+ */
19
+ declare const setWidgetLocaleLoader: (next: WidgetLocaleLoader) => void;
20
+ /**
21
+ * The bundled catalogs for a locale (`fr-CA` → `fr`). English, unbundled
22
+ * languages, the empty Yoruba/Hausa/Igbo slots and failed loads resolve to
23
+ * an empty bundle, so every key falls back to English. Never rejects.
24
+ */
25
+ declare const loadWidgetLocale: (locale: string | undefined) => Promise<WidgetLocaleBundle>;
26
+ //#endregion
27
+ //#region src/config.d.ts
28
+ interface ResolvedConfig extends Required<Omit<WidgetConfig, 'accentColor' | 'workspaceUrl' | 'analyticsRenderer' | 'branding' | 'composer' | 'agentName' | 'agentAvatarUrl' | 'launcherIcon' | 'themeTokens' | 'gifApiKey' | 'labels' | 'strings' | 'locale' | 'dir' | 'translations' | 'user' | 'analyticsContextToken' | 'analyticsModelId' | 'identityToken' | 'getIdentityToken' | 'customLauncherSelector' | 'proactiveMessage' | 'proactiveOnPaths' | 'onOpen' | 'onClose' | 'onShow' | 'onHide' | 'onUnreadChange' | 'onMessage' | 'onOpenAnalyticsSource' | 'onAction' | 'onHandoff'>> {
29
+ accentColor?: string;
30
+ workspaceUrl?: string;
31
+ analyticsRenderer?: 'hosted' | 'local';
32
+ composer?: WidgetConfig['composer'];
33
+ agentName?: string;
34
+ agentAvatarUrl?: string;
35
+ launcherIcon?: string;
36
+ themeTokens?: WidgetConfig['themeTokens'];
37
+ gifApiKey?: string;
38
+ /** Resolved string table (English defaults + host `labels` overrides). */
39
+ strings: WidgetStrings;
40
+ locale: string;
41
+ /** Resolved text direction (from `dir`, else the locale). */
42
+ dir: 'ltr' | 'rtl';
43
+ actionTranslations: Record<string, WidgetActionTranslation>;
44
+ /** Host-app SSO passthrough (see WidgetConfig.user). Optional. */
45
+ user?: WidgetConfig['user'];
46
+ /** Short-lived signed context for governed customer analytics. */
47
+ analyticsContextToken?: WidgetConfig['analyticsContextToken'];
48
+ analyticsModelId?: string;
49
+ identityToken?: WidgetConfig['identityToken'];
50
+ getIdentityToken?: WidgetConfig['getIdentityToken'];
51
+ customLauncherSelector?: string;
52
+ proactiveMessage?: string;
53
+ proactiveOnPaths?: string[];
54
+ onOpen?: WidgetConfig['onOpen'];
55
+ onClose?: WidgetConfig['onClose'];
56
+ onShow?: WidgetConfig['onShow'];
57
+ onHide?: WidgetConfig['onHide'];
58
+ onUnreadChange?: WidgetConfig['onUnreadChange'];
59
+ onMessage?: WidgetConfig['onMessage'];
60
+ onOpenAnalyticsSource?: WidgetConfig['onOpenAnalyticsSource'];
61
+ onAction?: WidgetConfig['onAction'];
62
+ onHandoff?: WidgetConfig['onHandoff'];
63
+ }
64
+ /** The language-dependent part of a resolved config. */
65
+ type LocalizedConfig = Pick<ResolvedConfig, 'strings' | 'locale' | 'dir' | 'actionTranslations'>;
66
+ /**
67
+ * Text for a config in its locale. Layers, lowest first: English, the bundled
68
+ * catalog (`bundle`), `translations[locale]`, `labels`, `strings`. Analytics
69
+ * result labels layer the same way over the results catalog.
70
+ */
71
+ declare const localizeConfig: (cfg: Pick<WidgetConfig, "locale" | "dir" | "labels" | "strings" | "translations">, bundle?: WidgetLocaleBundle) => LocalizedConfig;
72
+ declare const resolveConfig: (input: WidgetConfig) => ResolvedConfig;
73
+ //#endregion
74
+ //#region src/api/factory.d.ts
75
+ /**
76
+ * The real client is bundled; the demo and preview transports are fetched the
77
+ * first time they are used, so production widgets never download them.
78
+ */
79
+ declare const createChatTransport: (config: ResolvedConfig) => Transport;
80
+ //#endregion
81
+ //#region src/rich.d.ts
82
+ declare const renderRich: (text: string) => JSX.Element[];
83
+ //#endregion
84
+ //#region src/response-content.d.ts
85
+ type CopyStrings = Pick<WidgetStrings, 'copyResultData' | 'copyRowsReturned' | 'copyRowsReturnedOf' | 'copyTruncated' | 'copyTotals'>;
86
+ /**
87
+ * The text and structured values actually displayed with a chat reply.
88
+ * `strings` localizes the table summary lines (English by default).
89
+ */
90
+ declare const copyableChatResponse: (message: ChatMessage, strings?: CopyStrings) => string;
91
+ //#endregion
92
+ //#region src/message-action.d.ts
93
+ /** An AI proposal never authorizes opening a support form. Manual contact
94
+ * controls still open it; other requested action forms retain their behaviour. */
95
+ declare const automaticMessageAction: (selected: string | undefined, descriptors?: PublicChatAction[], visitorRequested?: boolean) => string | undefined;
96
+ //#endregion
97
+ //#region src/result-details.d.ts
98
+ /** Reader-safe result context shared by the floating widget and chat app. */
99
+ declare const analyticsResultDetails: (result: AnalyticsVisualization, labels?: Partial<ResultLabels>, locale?: string) => AnalyticsResultDetail[];
100
+ //#endregion
101
+ //#region src/voice-forms.d.ts
102
+ interface VoiceFormSnapshot {
103
+ actionId: string;
104
+ submitLabel: string;
105
+ fields: VoiceFormField[];
106
+ values: Record<string, string>;
107
+ ready: boolean;
108
+ notice?: string;
109
+ reviewNote?: string;
110
+ autoStart?: boolean;
111
+ }
112
+ interface VoiceFormTarget {
113
+ key: string;
114
+ scopeId?: string;
115
+ read: () => VoiceFormSnapshot;
116
+ apply: (values: Record<string, string>) => void;
117
+ submit: () => Promise<ActionResult | null>;
118
+ cancel: () => void;
119
+ }
120
+ interface VoiceFormController {
121
+ readonly enabled: boolean;
122
+ readonly busy: boolean;
123
+ readonly activeScope: string | undefined;
124
+ setEnabled: (enabled: boolean, delegated?: boolean) => void;
125
+ register: (target: VoiceFormTarget) => () => void;
126
+ refresh: (key: string) => void;
127
+ handleTranscript: (text: string, messageId?: string) => boolean;
128
+ delegateTranscript: (text: string, signal: AbortSignal) => Promise<VoiceFormDelegation | undefined>;
129
+ stop: () => void;
130
+ onIdle: () => void;
131
+ }
132
+ interface VoiceFormDelegation {
133
+ answer?: string | null;
134
+ userMessageId?: string;
135
+ }
136
+ declare const VoiceFormsProvider: preact2.Provider<VoiceFormController | null>;
137
+ //#endregion
138
+ //#region src/useChat.d.ts
139
+ /** One past conversation, for the in-widget history list. */
140
+ interface HistoryEntry {
141
+ sessionId: string;
142
+ /** Last-activity timestamp (epoch ms) — newest first. */
143
+ ts: number;
144
+ /** Short label: the visitor's first message, else a snippet of the reply. */
145
+ title: string;
146
+ ended: boolean;
147
+ }
148
+ /** The catalogue action that brings a teammate into the chat, when usable.
149
+ * A backend older than the liveHandoff flag is recognised by its fixed id. */
150
+ declare const findLiveSupportAction: (actions: PublicChatAction[] | undefined) => PublicChatAction | undefined;
151
+ /** The ai_handback notice that may still offer to reconnect: the latest one,
152
+ * while the AI has the chat and the visitor has not already asked again. */
153
+ declare const reconnectableHandbackId: (messages: ChatMessage[], liveMode: "ai" | "queued" | "human") => string | undefined;
154
+ /** Optional extras when sending — an inline image (GIF) or an extracted file. */
155
+ interface VoiceReply {
156
+ status: 'idle' | 'answering' | 'speaking' | 'done' | 'failed';
157
+ /** The assistant message answering the voice turn. */
158
+ agentId?: string;
159
+ }
160
+ interface SendOpts {
161
+ signal?: AbortSignal;
162
+ imageUrl?: string;
163
+ /** Voice-call turns should speak the assistant reply using provider TTS when configured. */
164
+ forceVoicePlayback?: boolean;
165
+ /** The host collects and confirms action fields through its active voice call. */
166
+ voiceFormEntry?: boolean;
167
+ /** Spoken in a voice call whose audio plays elsewhere (realtime voice):
168
+ * the answer may still carry a call control. Implied by forceVoicePlayback. */
169
+ voiceCall?: boolean;
170
+ /** Voice turns only: receives the call control the answer asked for. */
171
+ onVoiceControl?: (value: string) => void;
172
+ /** The call is waiting (the visitor asked the assistant to hold): the
173
+ * answer is quiet — neither shown nor spoken, and the turn is removed —
174
+ * unless it reports that the visitor resumed. */
175
+ voiceWaiting?: boolean;
176
+ /** Existing local user bubble to turn into the sent visitor message. */
177
+ userMessageId?: string;
178
+ /** Display name of an attached file (shown as a chip on the user bubble). */
179
+ attachmentName?: string;
180
+ /** Text extracted from the attachment, folded into the backend question. */
181
+ attachmentText?: string;
182
+ attachmentId?: string;
183
+ /** The attached file itself, kept in memory so it can be previewed. */
184
+ attachmentFile?: Blob;
185
+ /** Several files sent with the message (replaces the single fields). */
186
+ attachments?: OutgoingAttachment[];
187
+ }
188
+ interface OutgoingAttachment {
189
+ id?: string;
190
+ name: string;
191
+ /** Text extracted from the file, folded into the backend question. */
192
+ text?: string;
193
+ /** Kept in memory so it can be previewed. */
194
+ file?: Blob;
195
+ }
196
+ interface ChatApi {
197
+ voiceForms: VoiceFormController;
198
+ liveVoice?: LiveVoiceTransport;
199
+ delegateVoice: (question: string, signal: AbortSignal, info?: {
200
+ waiting: boolean;
201
+ }) => Promise<VoiceAnswer | null>;
202
+ setLiveSpeaking: (active: boolean) => void;
203
+ analyticsModels: AnalyticsModelOption[];
204
+ analyticsModelId: string;
205
+ selectAnalyticsModel: (id: string) => void;
206
+ persona: BootstrapInfo | null;
207
+ messages: ChatMessage[];
208
+ sending: boolean;
209
+ /** True while a TTS reply audio element is actively playing. */
210
+ assistantSpeaking: boolean;
211
+ /** Progress of the answer to the latest voice turn (a send or retry with
212
+ * forceVoicePlayback): answering until its audio starts, speaking while it
213
+ * plays, then done — or failed when the request failed. Done is only set
214
+ * once playback has ended or there was nothing to play, so a caller can
215
+ * safely reopen the microphone. */
216
+ voiceReply: VoiceReply;
217
+ visitor: Visitor;
218
+ /** Effective starter prompts: host `starters` if set, else token `starterQuestions`. */
219
+ starters: string[];
220
+ /** Manual featured links configured on the token, shown before first visitor message. */
221
+ featuredLinks: FeaturedLink[];
222
+ /** True once we know the visitor's email — drives the handoff UI (Case 1 vs 2). */
223
+ hasEmail: boolean;
224
+ /** Current handoff state for this live session. */
225
+ liveMode: 'ai' | 'queued' | 'human';
226
+ /** Human currently assigned to the live chat, if any. */
227
+ assignedAgentName?: string;
228
+ /** Human currently typing in the live chat, if any. */
229
+ agentTypingName?: string;
230
+ send: (text: string, opts?: SendOpts) => void;
231
+ /** Add to the question being answered (the visitor kept talking while the
232
+ * reply was prepared): cancels that reply and asks again with all of it.
233
+ * Also completes a held question (see `hold`). An ordinary send otherwise. */
234
+ amend: (text: string, opts?: SendOpts) => void;
235
+ /** The visitor started talking while the reply was prepared: cancel it now
236
+ * (so its audio never plays over them) but keep the question, to be asked
237
+ * again by `amend` with their words, or by `resumeHeld` if it was noise.
238
+ * Returns false when nothing was in flight. */
239
+ hold: () => boolean;
240
+ /** Ask a held question again, unchanged (what was heard was not speech). */
241
+ resumeHeld: () => void;
242
+ /** Lower (true) or restore (false) the reply being read aloud, while the
243
+ * visitor may be talking over it: it keeps playing until we know whether
244
+ * that was the visitor or the reply's own echo. */
245
+ duckSpeaking: (ducked: boolean) => void;
246
+ sendGif: (url: string) => void;
247
+ /** Soft visitor typing hint for the staff console. */
248
+ notifyTyping: (isTyping: boolean) => void;
249
+ /** Cancel the in-flight streaming reply (Stop button). */
250
+ stop: () => void;
251
+ /** Re-run a failed turn in place. */
252
+ retry: (agentId: string, question: string, opts?: Pick<SendOpts, 'forceVoicePlayback'>) => void;
253
+ /** Record a 👍/👎 on an assistant reply (optional comment on 👎). Optimistic. */
254
+ rateMessage: (messageId: string, rating: 'up' | 'down', comment?: string) => void;
255
+ /** Verify a specific reply against the sources or data available to the agent. */
256
+ doubleCheckResponse: (messageId: string) => void;
257
+ retryResponse: (messageId: string) => void;
258
+ /** Record a vote on an analytics explanation. Rejects when it could not be
259
+ * saved (or the transport has no explanation feedback) so the UI can retry. */
260
+ rateExplanation: (input: Omit<ExplanationFeedbackInput, 'sessionId' | 'surface'>, surface?: ExplanationFeedbackInput['surface']) => Promise<void>;
261
+ /** Poll / retry the detailed AI explanation of an analytics answer for this
262
+ * session; undefined when the transport cannot. */
263
+ explanationTransport: (surface?: ExplanationFeedbackInput['surface']) => AnalyticsAIExplanationTransport<AnalyticsExplanationInput> | undefined;
264
+ /** Append a proactive assistant message (auto-engagement). No-op duplicate-guarded. */
265
+ injectAssistant: (content: string) => void;
266
+ /** After a teammate handed the chat back to the AI: offer the live-support
267
+ * action again (its form opens in the conversation). False when this
268
+ * widget has no live-support action. */
269
+ reconnectSupport: () => boolean;
270
+ /** Add/update/remove local-only bubbles used by the live voice capture UI. */
271
+ appendUserDraft: (content: string) => string;
272
+ patchMessage: (id: string, fields: Partial<ChatMessage>) => void;
273
+ removeMessage: (id: string) => void;
274
+ /** Conversation-level CSAT at end-of-chat. Best-effort. */
275
+ submitCsat: (rating: 'up' | 'down', comment?: string) => void;
276
+ /** Submit an inline action form; persists identity so Case-1 auto-handoff can fire later. */
277
+ submitForm: (type: string, payload: Record<string, unknown>, identity?: Visitor, /** Backend-declared endpoint; authoritative when present. */
278
+ endpointOverride?: string) => Promise<ActionResult>;
279
+ confirmHostedBooking: (inquiryId: string, eventUri: string, inviteeUri: string) => Promise<DemoBooking | undefined>;
280
+ transcribe: (audio: Blob | string, mimeType: string, languageHint?: string, durationSeconds?: number) => Promise<string>;
281
+ uploadAttachment: (fileBase64: string, mimeType: string, filename: string, analyze: boolean) => Promise<{
282
+ id: string;
283
+ text: string;
284
+ analysisFailed: boolean;
285
+ }>;
286
+ /** The file attached to a visitor message, for preview. */
287
+ loadAttachment: (message: Pick<ChatMessage, 'id'>, attachment: MessageAttachment, index?: number) => Promise<Blob>;
288
+ searchGifs: (query: string) => Promise<GifResult[]>;
289
+ /** Booking availability in a window (booked slots + connected-calendar busy ranges). */
290
+ demoSlots: (fromISO: string, toISO: string) => Promise<DemoSlotsResult>;
291
+ gifEnabled: boolean;
292
+ /** Host-app SSO passthrough. */
293
+ identify: (user: WidgetUser) => void;
294
+ /** True once the conversation is closed (visitor ended it, 24h idle, or the
295
+ * backend reported it ended). The composer is disabled; only `startNew` works. */
296
+ ended: boolean;
297
+ /** Close the current conversation — tells the backend, disables the composer. */
298
+ endConversation: () => void;
299
+ /** Start a fresh conversation: new backend session, transcript reset to greeting. */
300
+ startNew: () => void;
301
+ /** Past conversations (newest first), for the in-widget history list. */
302
+ history: HistoryEntry[];
303
+ /** sessionId of the archived conversation being viewed read-only (null = live). */
304
+ viewingSessionId: string | null;
305
+ /** The read-only transcript of the conversation being viewed. */
306
+ viewMessages: ChatMessage[];
307
+ /** Resume an open signed-in conversation; otherwise show its read-only transcript. */
308
+ openConversation: (sessionId: string) => void;
309
+ renameConversation: (sessionId: string, title: string) => Promise<void>;
310
+ deleteConversation: (sessionId: string) => Promise<void>;
311
+ /** Leave the read-only history view, back to the live conversation. */
312
+ closeHistoryView: () => void;
313
+ /** Logout: erase ALL of this visitor's locally-stored data (identity,
314
+ * transcripts, history) and reset to a fresh anonymous session. For
315
+ * shared devices / host-app logout — à la Intercom `shutdown`. */
316
+ shutdown: () => void;
317
+ /** Stop any currently-playing TTS reply audio (voice call "Talk now" interrupt). */
318
+ stopSpeaking: () => void;
319
+ /** Speak a local assistant message, used for call-mode welcome/status prompts. */
320
+ speakAssistantText: (text: string) => Promise<boolean>;
321
+ }
322
+ declare const useChat: (transport: Transport, config: ResolvedConfig, active?: boolean) => ChatApi;
323
+ //#endregion
324
+ //#region src/components.d.ts
325
+ /** Submit handler shared by the forms + handoff card. */
326
+ type SubmitForm = (type: string, payload: Record<string, unknown>, identity?: Visitor, /** Backend-declared endpoint; authoritative when present. */
327
+ endpointOverride?: string) => Promise<ActionResult>;
328
+ type ConfirmHostedBooking = (inquiryId: string, eventUri: string, inviteeUri: string) => Promise<DemoBooking | undefined>;
329
+ declare const AssistantAvatarFace: ({
330
+ persona
331
+ }: {
332
+ persona: BootstrapInfo;
333
+ }) => JSX.Element;
334
+ declare const PendingReply: ({
335
+ className,
336
+ label
337
+ }: {
338
+ className?: string;
339
+ label?: string;
340
+ }) => JSX.Element;
341
+ declare const ActionsArea: ({
342
+ actions,
343
+ descriptors,
344
+ visitor,
345
+ onSubmitForm,
346
+ onDemoSlots,
347
+ onConfirmHostedBooking,
348
+ scheduler,
349
+ exclude,
350
+ openAction,
351
+ showTrigger,
352
+ translations,
353
+ onClose,
354
+ voiceAutoStart,
355
+ voiceScopeId
356
+ }: {
357
+ /** Legacy tool ids. Used only when `descriptors` is absent (older backend). */
358
+ actions?: string[];
359
+ /** Structured descriptors — preferred. */
360
+ descriptors?: PublicChatAction[];
361
+ visitor: Visitor;
362
+ onSubmitForm: SubmitForm;
363
+ onDemoSlots?: (fromISO: string, toISO: string) => Promise<DemoSlotsResult>;
364
+ onConfirmHostedBooking?: ConfirmHostedBooking;
365
+ scheduler?: SchedulerInfo;
366
+ exclude?: string[];
367
+ /** Action id the backend resolved for this turn — opens its form directly. */
368
+ openAction?: string;
369
+ /** Inline chat forms use the shared footer menu instead of a second trigger. */
370
+ showTrigger?: boolean;
371
+ /** Locale-specific copy keyed by stable action ID. */
372
+ translations?: Record<string, WidgetActionTranslation>;
373
+ /** A host that shows the actions in its own panel: closing or cancelling
374
+ * the action closes that panel instead of returning to the action menu. */
375
+ onClose?: () => void;
376
+ voiceAutoStart?: boolean;
377
+ voiceScopeId?: string;
378
+ }) => JSX.Element | null;
379
+ //#endregion
380
+ //#region src/analytics-model-selector.d.ts
381
+ declare const ANALYTICS_MODEL_SELECTOR_STYLES = "\n.ci-analytics-model{display:block;flex:0 1 auto;min-width:0;width:fit-content;max-width:180px;margin:0 4px;--rv-bg:var(--ca-bg,var(--cf-bg,#fff));--rv-text:var(--ca-ink,var(--cf-text,#0f1e2a));--rv-border:var(--ca-line,var(--cf-border,#d3e0e8));--rv-accent:var(--ca-accent,var(--cf-accent,#167d55));--rv-surface:var(--ca-hover-bg,var(--cf-surface,#f4f6f8))}\n.ci-analytics-model summary{min-width:0;max-width:100%;min-height:30px;box-sizing:border-box;padding:5px 9px;font-size:12px;border-radius:8px}\n.ci-analytics-model summary>span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ci-analytics-model summary[aria-disabled=\"true\"]{opacity:.6;cursor:default}\n";
382
+ declare const AnalyticsModelSelector: ({
383
+ models,
384
+ value,
385
+ onChange,
386
+ disabled,
387
+ copy,
388
+ classPrefix
389
+ }: {
390
+ models: AnalyticsModelOption[];
391
+ value: string;
392
+ onChange: (id: string) => void;
393
+ disabled?: boolean;
394
+ copy?: Partial<WidgetStrings>;
395
+ classPrefix?: string;
396
+ }) => preact2.JSX.Element | null;
397
+ //#endregion
398
+ //#region src/customization.d.ts
399
+ /** Translate the simple options once; explicit advanced options take precedence. */
400
+ declare const normalizeChatCustomization: <T extends WidgetConfig>(config: T) => T & WidgetConfig;
401
+ //#endregion
402
+ //#region src/style-rules.d.ts
403
+ /**
404
+ * Picks the rules for some components out of a stylesheet, so another
405
+ * surface can render those components without the whole widget stylesheet.
406
+ *
407
+ * A rule is kept when its selector names one of the class prefixes; at-rules
408
+ * such as @media keep only their matching inner rules and are dropped when
409
+ * none match. Comments are removed. This is a small parser for our own,
410
+ * well-formed stylesheet — not a general CSS parser.
411
+ */
412
+ declare const selectStyleRules: (css: string, classPrefixes: string[]) => string;
413
+ //#endregion
414
+ //#region src/transcript.d.ts
415
+ /** A transcript worth sending as the visitor's turn: annotations stripped,
416
+ * and neither noise, silence nor a leaked transcription prompt. Returns ''
417
+ * when there is nothing to send. */
418
+ declare const usableTranscript: (text: string) => string;
419
+ /** The microphone picked up the AI's own reply from the speakers, not the
420
+ * visitor (shared with every voice surface). */
421
+ declare const looksLikeEcho: (transcript: string, spoken: string) => boolean;
422
+ //#endregion
423
+ //#region src/audio.d.ts
424
+ interface VoiceAudioCapabilities {
425
+ echoCancellation?: boolean;
426
+ noiseSuppression?: boolean;
427
+ autoGainControl?: boolean;
428
+ channelCount?: boolean;
429
+ voiceIsolation?: boolean;
430
+ }
431
+ /**
432
+ * Build a best-effort microphone profile for conversational speech. Every
433
+ * enhancement is capability-driven and optional, so unsupported processing
434
+ * cannot make microphone permission fail.
435
+ */
436
+ declare const createVoiceAudioConstraints: (deviceId?: string, supported?: VoiceAudioCapabilities) => MediaTrackConstraints;
437
+ interface AdaptiveVoiceActivityOptions {
438
+ calibrationSamples?: number;
439
+ ambientWindowSamples?: number;
440
+ ambientPercentile?: number;
441
+ smoothing?: number;
442
+ minimumNoiseFloor?: number;
443
+ speechToNoiseRatio?: number;
444
+ quietToNoiseRatio?: number;
445
+ minimumEndSilenceMs?: number;
446
+ maximumEndSilenceMs?: number;
447
+ }
448
+ interface VoiceActivitySample {
449
+ speech: boolean;
450
+ quiet: boolean;
451
+ calibrated: boolean;
452
+ noiseFloor: number;
453
+ speechThreshold: number;
454
+ quietThreshold: number;
455
+ endOfSpeechDelayMs: number;
456
+ }
457
+ /**
458
+ * Learn the room's ambient level continuously and classify relative changes.
459
+ * The detector is synchronous and runs on samples already collected for the
460
+ * level meter, so it adds no network request or post-recording delay.
461
+ */
462
+ declare const createAdaptiveVoiceActivityDetector: (options?: AdaptiveVoiceActivityOptions) => {
463
+ observe: (rms: number) => VoiceActivitySample;
464
+ reset: () => void;
465
+ };
466
+ declare const createPreferredAudioRecorder: (stream: MediaStream) => MediaRecorder;
467
+ declare const stopRecorderWithFlush: (recorder: MediaRecorder | null | undefined) => void;
468
+ //#endregion
469
+ //#region src/runtime.d.ts
470
+ /**
471
+ * The widget's action buttons, forms and booking picker, for surfaces that
472
+ * render ActionsArea. They read the --cf-* theme variables, which the host
473
+ * surface maps onto its own theme.
474
+ */
475
+ declare const WIDGET_ACTION_STYLES: string;
476
+ declare const WIDGET_PENDING_STYLES: string;
477
+ declare const WIDGET_ASSISTANT_AVATAR_STYLES: string;
478
+ //#endregion
479
+ export { ANALYTICS_MODEL_SELECTOR_STYLES, type ActionResult, ActionsArea, AnalyticsModelSelector, type AnalyticsVisualization, AssistantAvatarFace, type BootstrapInfo, type ChatApi, type ChatArtifact, type ChatMessage, DEFAULT_STRINGS, type DemoSlotsResult, type HistoryEntry, type LocalizedConfig, type MessageAttachment, PendingReply, type PublicChatAction, type PublicChatActionField, type ResolvedConfig, ResultTable, type Source, StringsProvider, type Transport, VoiceFormsProvider, type VoiceReply, WIDGET_ACTION_STYLES, WIDGET_ASSISTANT_AVATAR_STYLES, WIDGET_PENDING_STYLES, WidgetAnalyticsChart, type WidgetConfig, type WidgetLocaleBundle, type WidgetLocaleLoader, type WidgetLocaleUpdate, type WidgetThemeTokens, type WidgetUser, analyticsResultDetails, automaticMessageAction, buildWidgetAnalyticsChartModel, copyableChatResponse, createAdaptiveVoiceActivityDetector, createChatTransport, createPreferredAudioRecorder, createVoiceAudioConstraints, findLiveSupportAction, formatResultCell, loadWidgetLocale, localizeConfig, looksLikeEcho, mergeStrings, normalizeChatCustomization, reconnectableHandbackId, renderRich, resolveConfig, selectStyleRules, serializeResultCsv, setWidgetLocaleLoader, stopRecorderWithFlush, usableTranscript, useChat };
package/dist/runtime.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{$ as e,G as t,H as n,J as r,O as i,Q as a,U as o,X as s,Y as c,Z as l,_ as u,a as d,c as f,et as p,i as m,l as h,n as g,o as _,p as v,r as y,s as b,t as x,u as S,v as C,z as w}from"./styles-CiqV_OsG.mjs";const T=(e,t)=>{let n=e.replace(/\/\*[\s\S]*?\*\//g,``),r=e=>t.some(t=>e.includes(t)),i=[],a=0;for(;a<n.length;){let e=n.indexOf(`{`,a);if(e<0)break;let o=n.slice(a,e).trim(),s=1,c=e+1;for(;c<n.length&&s>0;)n[c]===`{`?s++:n[c]===`}`&&s--,c++;let l=n.slice(e+1,c-1);if(o.startsWith(`@`))if(/^@(media|supports|container)\b/.test(o)){let e=T(l,t);e&&i.push(`${o} {\n${e}\n}`)}else /^@keyframes\b/.test(o)&&r(o)&&i.push(`${o} {${l}}`);else r(o)&&i.push(`${o} {${l}}`);a=c}return i.join(`
2
- `)},E=(e,t,n)=>r(e,t,n),D=T(x,[`.cf-action`,`.cf-form`,`.cf-booking`]);export{n as ANALYTICS_MODEL_SELECTOR_STYLES,C as ActionsArea,o as AnalyticsModelSelector,c as ResultTable,t as StringsProvider,D as WIDGET_ACTION_STYLES,a as WidgetAnalyticsChart,E as analyticsResultDetails,e as buildWidgetAnalyticsChartModel,w as copyableChatResponse,b as createAdaptiveVoiceActivityDetector,p as createChatTransport,f as createPreferredAudioRecorder,h as createVoiceAudioConstraints,m as findLiveSupportAction,s as formatResultCell,v as looksLikeEcho,y as normalizeChatCustomization,d as reconnectableHandbackId,i as renderRich,g as resolveConfig,T as selectStyleRules,l as serializeResultCsv,S as stopRecorderWithFlush,u as usableTranscript,_ as useChat};
1
+ import{D as e,H as t,Q as n,U as r,W as i,X as a,Z as o,a as s,c,d as l,dt as u,et as d,f,ft as p,g as m,i as h,it as g,j as _,l as v,lt as y,mt as b,n as x,o as S,p as C,pt as w,r as T,s as E,t as D,tt as O,u as k,ut as A,v as j,x as M,y as N}from"./styles-C8MXPiR-.mjs";const P=(e,t)=>{let n=e.replace(/\/\*[\s\S]*?\*\//g,``),r=e=>t.some(t=>e.includes(t)),i=[],a=0;for(;a<n.length;){let e=n.indexOf(`{`,a);if(e<0)break;let o=n.slice(a,e).trim(),s=1,c=e+1;for(;c<n.length&&s>0;)n[c]===`{`?s++:n[c]===`}`&&s--,c++;let l=n.slice(e+1,c-1);if(o.startsWith(`@`))if(/^@(media|supports|container)\b/.test(o)){let e=P(l,t);e&&i.push(`${o} {\n${e}\n}`)}else /^@keyframes\b/.test(o)&&r(o)&&i.push(`${o} {${l}}`);else r(o)&&i.push(`${o} {${l}}`);a=c}return i.join(`
2
+ `)},F=(e,t,n)=>y(e,t,n),I=P(D,[`.cf-action`,`.cf-form`,`.cf-booking`]),L=P(D,[`cf-typing`]),R=P(D,[`cf-assistant-card__stage--local`,`cf-assistant-card__media`,`cf-assistant-card__avatar-stage`,`cf-assistant-card__face`,`cf-assistant-card__initials`,`cf-assistant-card__eye`,`cf-assistant-card__mouth`,`cf-avatar-preset--`,`cf-mouth-talk`,`cf-avatar-nod`]);export{a as ANALYTICS_MODEL_SELECTOR_STYLES,N as ActionsArea,o as AnalyticsModelSelector,M as AssistantAvatarFace,n as DEFAULT_STRINGS,e as PendingReply,A as ResultTable,d as StringsProvider,t as VoiceFormsProvider,I as WIDGET_ACTION_STYLES,R as WIDGET_ASSISTANT_AVATAR_STYLES,L as WIDGET_PENDING_STYLES,w as WidgetAnalyticsChart,F as analyticsResultDetails,r as automaticMessageAction,b as buildWidgetAnalyticsChartModel,i as copyableChatResponse,k as createAdaptiveVoiceActivityDetector,g as createChatTransport,l as createPreferredAudioRecorder,f as createVoiceAudioConstraints,E as findLiveSupportAction,u as formatResultCell,x as loadWidgetLocale,h as localizeConfig,m as looksLikeEcho,O as mergeStrings,S as normalizeChatCustomization,c as reconnectableHandbackId,_ as renderRich,s as resolveConfig,P as selectStyleRules,p as serializeResultCsv,T as setWidgetLocaleLoader,C as stopRecorderWithFlush,j as usableTranscript,v as useChat};