@accurix/centrinfo-widget 4.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/runtime.cjs CHANGED
@@ -1 +1,2 @@
1
- const e=require(`./config-DsNMbdKp.cjs`),t=t=>t.demo?new e.S:t.preview?new e.x(new e.C(t.apiBaseUrl,t.token,t.gifApiKey,t.analyticsContextToken,{agentName:t.agentName,agentAvatarUrl:t.agentAvatarUrl},t.identityToken,t.getIdentityToken,t.chatSurface),t.strings):new e.C(t.apiBaseUrl,t.token,t.gifApiKey,t.analyticsContextToken,{agentName:t.agentName,agentAvatarUrl:t.agentAvatarUrl},t.identityToken,t.getIdentityToken,t.chatSurface);exports.ResultTable=e.m,exports.WidgetAnalyticsChart=e._,exports.buildWidgetAnalyticsChartModel=e.v,exports.createChatTransport=t,exports.createPreferredAudioRecorder=e.u,exports.createVoiceAudioConstraints=e.d,exports.formatResultCell=e.h,exports.renderRich=e.a,exports.resolveConfig=e.t,exports.serializeResultCsv=e.g,exports.stopRecorderWithFlush=e.f,exports.useChat=e.n;
1
+ const e=require(`./styles-BH7P8Q_3.cjs`),t=(e,n)=>{let r=e.replace(/\/\*[\s\S]*?\*\//g,``),i=e=>n.some(t=>e.includes(t)),a=[],o=0;for(;o<r.length;){let e=r.indexOf(`{`,o);if(e<0)break;let s=r.slice(o,e).trim(),c=1,l=e+1;for(;l<r.length&&c>0;)r[l]===`{`?c++:r[l]===`}`&&c--,l++;let u=r.slice(e+1,l-1);if(s.startsWith(`@`))if(/^@(media|supports|container)\b/.test(s)){let e=t(u,n);e&&a.push(`${s} {\n${e}\n}`)}else /^@keyframes\b/.test(s)&&i(s)&&a.push(`${s} {${u}}`);else i(s)&&a.push(`${s} {${u}}`);o=l}return a.join(`
2
+ `)},n=(t,n,r)=>e.W(t,n,r),r=t(e.t,[`.cf-action`,`.cf-form`,`.cf-booking`]);exports.ActionsArea=e._,exports.ResultTable=e.G,exports.StringsProvider=e.z,exports.WIDGET_ACTION_STYLES=r,exports.WidgetAnalyticsChart=e.J,exports.analyticsResultDetails=n,exports.buildWidgetAnalyticsChartModel=e.Y,exports.createAdaptiveVoiceActivityDetector=e.o,exports.createChatTransport=e.X,exports.createPreferredAudioRecorder=e.s,exports.createVoiceAudioConstraints=e.c,exports.findLiveSupportAction=e.r,exports.formatResultCell=e.K,exports.looksLikeEcho=e.f,exports.reconnectableHandbackId=e.i,exports.renderRich=e.D,exports.resolveConfig=e.n,exports.selectStyleRules=t,exports.serializeResultCsv=e.q,exports.stopRecorderWithFlush=e.l,exports.usableTranscript=e.g,exports.useChat=e.a;
@@ -1,42 +1,38 @@
1
- import { _ as PublicChatActionField, a as Source, c as WidgetConfig, d as WidgetUser, f as ActionResult, g as PublicChatAction, h as GifResult, i as FeaturedLink, m as DemoSlotsResult, n as ChatArtifact, o as Visitor, p as AnalyticsVisualization, r as ChatMessage, s as WidgetActionTranslation, t as BootstrapInfo, u as WidgetThemeTokens, v as Transport, y as WidgetStrings } from "./types-B0r4SXaT.cjs";
2
- import * as preact0 from "preact";
1
+ import { C as StringsProvider, D as AnalyticsExplanationInput, E as AnalyticsAIExplanationTransport, O as AnalyticsGroupComparisonPoint, S as Transport, T as ResultLabels, _ as DemoSlotsResult, a as MessageAttachment, b as PublicChatAction, c as Visitor, f as WidgetThemeTokens, g as DemoBooking, h as AnalyticsVisualization, i as FeaturedLink, k as AnalyticsPeriodComparison, l as WidgetActionTranslation, m as ActionResult, n as ChatArtifact, o as SchedulerInfo, p as WidgetUser, r as ChatMessage, s as Source, t as BootstrapInfo, u as WidgetConfig, v as ExplanationFeedbackInput, w as WidgetStrings, x as PublicChatActionField, y as GifResult } from "./types-CYFMH8yg.cjs";
2
+ import * as preact1 from "preact";
3
3
  import { JSX } from "preact";
4
4
 
5
- //#region src/config.d.ts
6
- interface ResolvedConfig extends Required<Omit<WidgetConfig, 'accentColor' | 'agentName' | 'agentAvatarUrl' | 'launcherIcon' | 'themeTokens' | 'gifApiKey' | 'labels' | 'locale' | 'translations' | 'user' | 'analyticsContextToken' | 'identityToken' | 'getIdentityToken' | 'customLauncherSelector' | 'proactiveMessage' | 'proactiveOnPaths' | 'onOpen' | 'onClose' | 'onShow' | 'onHide' | 'onUnreadChange' | 'onMessage' | 'onAction' | 'onHandoff'>> {
7
- accentColor?: string;
8
- agentName?: string;
9
- agentAvatarUrl?: string;
10
- launcherIcon?: string;
11
- themeTokens?: WidgetConfig['themeTokens'];
12
- gifApiKey?: string;
13
- /** Resolved string table (English defaults + host `labels` overrides). */
14
- strings: WidgetStrings;
15
- locale: string;
16
- actionTranslations: Record<string, WidgetActionTranslation>;
17
- /** Host-app SSO passthrough (see WidgetConfig.user). Optional. */
18
- user?: WidgetConfig['user'];
19
- /** Short-lived signed context for governed customer analytics. */
20
- analyticsContextToken?: WidgetConfig['analyticsContextToken'];
21
- identityToken?: WidgetConfig['identityToken'];
22
- getIdentityToken?: WidgetConfig['getIdentityToken'];
23
- customLauncherSelector?: string;
24
- proactiveMessage?: string;
25
- proactiveOnPaths?: string[];
26
- onOpen?: WidgetConfig['onOpen'];
27
- onClose?: WidgetConfig['onClose'];
28
- onShow?: WidgetConfig['onShow'];
29
- onHide?: WidgetConfig['onHide'];
30
- onUnreadChange?: WidgetConfig['onUnreadChange'];
31
- onMessage?: WidgetConfig['onMessage'];
32
- onAction?: WidgetConfig['onAction'];
33
- onHandoff?: WidgetConfig['onHandoff'];
34
- }
35
- declare const resolveConfig: (cfg: WidgetConfig) => ResolvedConfig;
36
- //#endregion
37
5
  //#region ../centrinfo-results/src/analytics-chart-catalog.d.ts
38
6
  type AnalyticsChartCatalogType = 'kpi' | 'table' | 'line' | 'bar' | 'pie' | 'scatter' | 'effectScatter' | 'map' | 'candlestick' | 'boxplot' | 'graph' | 'lines' | 'tree' | 'treemap' | 'sunburst' | 'parallel' | 'sankey' | 'funnel' | 'heatmap' | 'radar' | 'gauge' | 'pictorialBar' | 'themeRiver' | 'matrix' | 'chord' | 'custom' | 'dataset' | 'dataZoom' | 'graphic' | 'richText' | 'globe' | 'bar3D' | 'scatter3D' | 'surface' | 'map3D' | 'lines3D' | 'line3D' | 'scatterGL' | 'linesGL' | 'flowGL' | 'graphGL' | 'polygons3D';
39
7
  //#endregion
8
+ //#region ../centrinfo-results/src/format.d.ts
9
+ /**
10
+ * The one place numbers, currency, percentages and dates are formatted, so the
11
+ * chart axis, tooltip, table and KPI show the same value the same way.
12
+ *
13
+ * Rules:
14
+ * - Currency comes from column metadata (`currencyCode`) or the result's fixed
15
+ * currency. With no known code the amount is shown as a plain number.
16
+ * - A `percent` column is read as percentage points (0.5 is "0.5%") unless its
17
+ * `formatPattern` contains `%` (Excel style), which marks a fraction (0.5 is
18
+ * "50%"). Magnitude is never used to guess.
19
+ * - Date-only values (`2024-03-05`) are calendar dates: they are formatted in
20
+ * UTC so they never shift a day. Instants are formatted in the result
21
+ * timezone. Granularity follows column metadata, the result's comparison
22
+ * grain, or the shape of the values — a daily series is never "Mar 2024".
23
+ */
24
+ type ResultGrain = 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';
25
+ interface ResultFormatContext {
26
+ locale?: string;
27
+ /** IANA zone of the result; used for instants, never for date-only values. */
28
+ timezone?: string;
29
+ grain?: ResultGrain;
30
+ /** Result-level fixed currency, used when the column has none. */
31
+ currencyCode?: string;
32
+ yes?: string;
33
+ no?: string;
34
+ }
35
+ //#endregion
40
36
  //#region ../centrinfo-results/src/types.d.ts
41
37
  interface AnalyticsVisualizationColumn {
42
38
  key: string;
@@ -44,8 +40,11 @@ interface AnalyticsVisualizationColumn {
44
40
  dataType: 'text' | 'number' | 'currency' | 'percent' | 'boolean' | 'date' | 'datetime';
45
41
  semanticRole: 'identifier' | 'dimension' | 'measure' | 'date' | 'geography' | 'boolean';
46
42
  aggregation?: 'none' | 'sum' | 'avg' | 'count' | 'count_distinct' | 'min' | 'max';
43
+ allowedAggregations?: Array<'none' | 'sum' | 'avg' | 'count' | 'count_distinct' | 'min' | 'max'>;
47
44
  formatPattern?: string;
48
45
  currencyCode?: string;
46
+ /** Time granularity of a date column; drives how its values are labelled. */
47
+ grain?: ResultGrain;
49
48
  description?: string;
50
49
  priority?: 'primary' | 'secondary' | 'detail';
51
50
  sortable?: boolean;
@@ -65,6 +64,10 @@ interface AnalyticsVisualizationRecommendation {
65
64
  confidence?: number;
66
65
  }
67
66
  interface AnalyticsVisualization$1 {
67
+ /** The latest time bucket is still in progress (drawn dashed). */
68
+ lastPeriodInProgress?: boolean;
69
+ /** Like-for-like comparison basis (reader-safe). */
70
+ periodComparison?: AnalyticsPeriodComparison;
68
71
  version?: number;
69
72
  presentation?: 'kpi' | 'chart' | 'table';
70
73
  type: AnalyticsChartCatalogType | 'area' | 'stacked_bar';
@@ -81,6 +84,31 @@ interface AnalyticsVisualization$1 {
81
84
  rows?: Array<Record<string, unknown>>;
82
85
  rowCount?: number;
83
86
  timezone?: string;
87
+ freshness?: {
88
+ status?: string;
89
+ answeredAt?: string;
90
+ };
91
+ reportingPeriod?: {
92
+ label?: string;
93
+ start?: string;
94
+ end?: string;
95
+ timezone?: string;
96
+ };
97
+ appliedFilters?: Array<{
98
+ field: string;
99
+ operator: string;
100
+ value: unknown;
101
+ }>;
102
+ explanation?: {
103
+ checkedAt?: string;
104
+ timezone?: string;
105
+ dataFreshness?: {
106
+ status?: string;
107
+ };
108
+ };
109
+ expandable?: boolean;
110
+ tableAvailable?: boolean;
111
+ downloadAvailable?: boolean;
84
112
  columnMetadata?: AnalyticsVisualizationColumn[];
85
113
  currency?: {
86
114
  code?: string;
@@ -95,6 +123,8 @@ interface ResultColumn {
95
123
  label?: string;
96
124
  dataType?: AnalyticsVisualizationColumn['dataType'];
97
125
  currencyCode?: string;
126
+ formatPattern?: string;
127
+ grain?: ResultGrain;
98
128
  }
99
129
  interface ResultTableClassNames {
100
130
  wrap?: string;
@@ -108,6 +138,8 @@ type WidgetAnalyticsSeries = {
108
138
  name: string;
109
139
  values: Array<number | null>;
110
140
  valueColumn?: AnalyticsVisualizationColumn;
141
+ /** Like-for-like breakdown: per-point comparison (tooltip detail). */
142
+ points?: Array<AnalyticsGroupComparisonPoint | undefined>;
111
143
  };
112
144
  type WidgetAnalyticsChartType = 'line' | 'bar' | 'stacked_bar';
113
145
  type WidgetAnalyticsChartModel = {
@@ -119,18 +151,34 @@ type WidgetAnalyticsChartModel = {
119
151
  series: WidgetAnalyticsSeries[];
120
152
  summary: string;
121
153
  omittedSeriesCount: number;
154
+ /** Index of the in-progress (latest) time bucket, drawn dashed / faded. */
155
+ inProgressIndex?: number;
156
+ /** Like-for-like breakdown: the comparison drawn (previous-to-date bars). */
157
+ comparison?: AnalyticsPeriodComparison;
158
+ /** "Today so far, compared with yesterday at this time". */
159
+ comparisonNote?: string;
160
+ locale?: string;
161
+ /** Resolved copy used by the chart's tooltips, summary and zoom controls. */
162
+ labels: ResultLabels;
122
163
  };
123
- declare const buildWidgetAnalyticsChartModel: (visualization: AnalyticsVisualization$1, overrideType?: WidgetAnalyticsChartType) => WidgetAnalyticsChartModel | null;
164
+ type WidgetAnalyticsChartOptions = {
165
+ locale?: string;
166
+ labels?: Partial<ResultLabels>;
167
+ };
168
+ declare const buildWidgetAnalyticsChartModel: (visualization: AnalyticsVisualization$1, overrideType?: WidgetAnalyticsChartType, options?: WidgetAnalyticsChartOptions) => WidgetAnalyticsChartModel | null;
124
169
  declare const WidgetAnalyticsChart: ({
125
170
  model,
126
- expanded
171
+ expanded,
172
+ classPrefix: p
127
173
  }: {
128
174
  model: WidgetAnalyticsChartModel;
129
175
  expanded?: boolean;
130
- }) => preact0.JSX.Element;
176
+ /** Class prefix of the surface (`cf` widget, `ca` chat app). */
177
+ classPrefix?: string;
178
+ }) => preact1.JSX.Element;
131
179
  //#endregion
132
180
  //#region ../centrinfo-results/src/result.d.ts
133
- declare const formatResultCell: (value: unknown, locale?: string, column?: ResultColumn) => string;
181
+ declare const formatResultCell: (value: unknown, locale?: string, column?: ResultColumn, context?: ResultFormatContext) => string;
134
182
  declare const serializeResultCsv: (rows: Array<Record<string, unknown>>, columns?: Array<string | ResultColumn>) => string;
135
183
  //#endregion
136
184
  //#region ../centrinfo-results/src/table.d.ts
@@ -139,6 +187,8 @@ interface ResultTableProps {
139
187
  columns?: Array<string | ResultColumn>;
140
188
  maxRows?: number;
141
189
  locale?: string;
190
+ /** Timezone / grain / currency context so cells format like the chart. */
191
+ format?: ResultFormatContext;
142
192
  expanded?: boolean;
143
193
  classNames?: ResultTableClassNames;
144
194
  emptyLabel?: string;
@@ -148,30 +198,66 @@ declare const ResultTable: ({
148
198
  columns,
149
199
  maxRows,
150
200
  locale,
201
+ format,
151
202
  expanded,
152
203
  classNames,
153
204
  emptyLabel
154
- }: ResultTableProps) => preact0.JSX.Element;
205
+ }: ResultTableProps) => preact1.JSX.Element;
155
206
  //#endregion
156
- //#region src/rich.d.ts
157
- declare const renderRich: (text: string) => JSX.Element[];
207
+ //#region ../centrinfo-results/src/result-details.d.ts
208
+ interface AnalyticsResultDetail {
209
+ label: string;
210
+ value: string;
211
+ }
158
212
  //#endregion
159
- //#region src/audio.d.ts
160
- interface VoiceAudioCapabilities {
161
- echoCancellation?: boolean;
162
- noiseSuppression?: boolean;
163
- autoGainControl?: boolean;
164
- channelCount?: boolean;
165
- voiceIsolation?: boolean;
213
+ //#region src/config.d.ts
214
+ interface ResolvedConfig extends Required<Omit<WidgetConfig, 'accentColor' | 'agentName' | 'agentAvatarUrl' | 'launcherIcon' | 'themeTokens' | 'gifApiKey' | 'labels' | 'locale' | 'dir' | 'translations' | 'user' | 'analyticsContextToken' | 'identityToken' | 'getIdentityToken' | 'customLauncherSelector' | 'proactiveMessage' | 'proactiveOnPaths' | 'onOpen' | 'onClose' | 'onShow' | 'onHide' | 'onUnreadChange' | 'onMessage' | 'onOpenAnalyticsSource' | 'onAction' | 'onHandoff'>> {
215
+ accentColor?: string;
216
+ agentName?: string;
217
+ agentAvatarUrl?: string;
218
+ launcherIcon?: string;
219
+ themeTokens?: WidgetConfig['themeTokens'];
220
+ gifApiKey?: string;
221
+ /** Resolved string table (English defaults + host `labels` overrides). */
222
+ strings: WidgetStrings;
223
+ locale: string;
224
+ /** Resolved text direction (from `dir`, else the locale). */
225
+ dir: 'ltr' | 'rtl';
226
+ actionTranslations: Record<string, WidgetActionTranslation>;
227
+ /** Host-app SSO passthrough (see WidgetConfig.user). Optional. */
228
+ user?: WidgetConfig['user'];
229
+ /** Short-lived signed context for governed customer analytics. */
230
+ analyticsContextToken?: WidgetConfig['analyticsContextToken'];
231
+ identityToken?: WidgetConfig['identityToken'];
232
+ getIdentityToken?: WidgetConfig['getIdentityToken'];
233
+ customLauncherSelector?: string;
234
+ proactiveMessage?: string;
235
+ proactiveOnPaths?: string[];
236
+ onOpen?: WidgetConfig['onOpen'];
237
+ onClose?: WidgetConfig['onClose'];
238
+ onShow?: WidgetConfig['onShow'];
239
+ onHide?: WidgetConfig['onHide'];
240
+ onUnreadChange?: WidgetConfig['onUnreadChange'];
241
+ onMessage?: WidgetConfig['onMessage'];
242
+ onOpenAnalyticsSource?: WidgetConfig['onOpenAnalyticsSource'];
243
+ onAction?: WidgetConfig['onAction'];
244
+ onHandoff?: WidgetConfig['onHandoff'];
166
245
  }
246
+ declare const resolveConfig: (cfg: WidgetConfig) => ResolvedConfig;
247
+ //#endregion
248
+ //#region src/api/factory.d.ts
167
249
  /**
168
- * Build a best-effort microphone profile for conversational speech. Every
169
- * enhancement is capability-driven and optional, so unsupported processing
170
- * cannot make microphone permission fail.
250
+ * The real client is bundled; the demo and preview transports are fetched the
251
+ * first time they are used, so production widgets never download them.
171
252
  */
172
- declare const createVoiceAudioConstraints: (deviceId?: string, supported?: VoiceAudioCapabilities) => MediaTrackConstraints;
173
- declare const createPreferredAudioRecorder: (stream: MediaStream) => MediaRecorder;
174
- declare const stopRecorderWithFlush: (recorder: MediaRecorder | null | undefined) => void;
253
+ declare const createChatTransport: (config: ResolvedConfig) => Transport;
254
+ //#endregion
255
+ //#region src/rich.d.ts
256
+ declare const renderRich: (text: string) => JSX.Element[];
257
+ //#endregion
258
+ //#region src/result-details.d.ts
259
+ /** Reader-safe result context shared by the floating widget and chat app. */
260
+ declare const analyticsResultDetails: (result: AnalyticsVisualization, labels?: Partial<ResultLabels>, locale?: string) => AnalyticsResultDetail[];
175
261
  //#endregion
176
262
  //#region src/useChat.d.ts
177
263
  /** One past conversation, for the in-widget history list. */
@@ -183,7 +269,18 @@ interface HistoryEntry {
183
269
  title: string;
184
270
  ended: boolean;
185
271
  }
272
+ /** The catalogue action that brings a teammate into the chat, when usable.
273
+ * A backend older than the liveHandoff flag is recognised by its fixed id. */
274
+ declare const findLiveSupportAction: (actions: PublicChatAction[] | undefined) => PublicChatAction | undefined;
275
+ /** The ai_handback notice that may still offer to reconnect: the latest one,
276
+ * while the AI has the chat and the visitor has not already asked again. */
277
+ declare const reconnectableHandbackId: (messages: ChatMessage[], liveMode: "ai" | "queued" | "human") => string | undefined;
186
278
  /** Optional extras when sending — an inline image (GIF) or an extracted file. */
279
+ interface VoiceReply {
280
+ status: 'idle' | 'answering' | 'speaking' | 'done' | 'failed';
281
+ /** The assistant message answering the voice turn. */
282
+ agentId?: string;
283
+ }
187
284
  interface SendOpts {
188
285
  imageUrl?: string;
189
286
  /** Voice-call turns should speak the assistant reply using provider TTS when configured. */
@@ -194,6 +291,19 @@ interface SendOpts {
194
291
  attachmentName?: string;
195
292
  /** Text extracted from the attachment, folded into the backend question. */
196
293
  attachmentText?: string;
294
+ attachmentId?: string;
295
+ /** The attached file itself, kept in memory so it can be previewed. */
296
+ attachmentFile?: Blob;
297
+ /** Several files sent with the message (replaces the single fields). */
298
+ attachments?: OutgoingAttachment[];
299
+ }
300
+ interface OutgoingAttachment {
301
+ id?: string;
302
+ name: string;
303
+ /** Text extracted from the file, folded into the backend question. */
304
+ text?: string;
305
+ /** Kept in memory so it can be previewed. */
306
+ file?: Blob;
197
307
  }
198
308
  interface ChatApi {
199
309
  persona: BootstrapInfo | null;
@@ -201,6 +311,12 @@ interface ChatApi {
201
311
  sending: boolean;
202
312
  /** True while a TTS reply audio element is actively playing. */
203
313
  assistantSpeaking: boolean;
314
+ /** Progress of the answer to the latest voice turn (a send or retry with
315
+ * forceVoicePlayback): answering until its audio starts, speaking while it
316
+ * plays, then done — or failed when the request failed. Done is only set
317
+ * once playback has ended or there was nothing to play, so a caller can
318
+ * safely reopen the microphone. */
319
+ voiceReply: VoiceReply;
204
320
  visitor: Visitor;
205
321
  /** Effective starter prompts: host `starters` if set, else token `starterQuestions`. */
206
322
  starters: string[];
@@ -215,17 +331,42 @@ interface ChatApi {
215
331
  /** Human currently typing in the live chat, if any. */
216
332
  agentTypingName?: string;
217
333
  send: (text: string, opts?: SendOpts) => void;
334
+ /** Add to the question being answered (the visitor kept talking while the
335
+ * reply was prepared): cancels that reply and asks again with all of it.
336
+ * Also completes a held question (see `hold`). An ordinary send otherwise. */
337
+ amend: (text: string, opts?: SendOpts) => void;
338
+ /** The visitor started talking while the reply was prepared: cancel it now
339
+ * (so its audio never plays over them) but keep the question, to be asked
340
+ * again by `amend` with their words, or by `resumeHeld` if it was noise.
341
+ * Returns false when nothing was in flight. */
342
+ hold: () => boolean;
343
+ /** Ask a held question again, unchanged (what was heard was not speech). */
344
+ resumeHeld: () => void;
345
+ /** Lower (true) or restore (false) the reply being read aloud, while the
346
+ * visitor may be talking over it: it keeps playing until we know whether
347
+ * that was the visitor or the reply's own echo. */
348
+ duckSpeaking: (ducked: boolean) => void;
218
349
  sendGif: (url: string) => void;
219
350
  /** Soft visitor typing hint for the staff console. */
220
351
  notifyTyping: (isTyping: boolean) => void;
221
352
  /** Cancel the in-flight streaming reply (Stop button). */
222
353
  stop: () => void;
223
354
  /** Re-run a failed turn in place. */
224
- retry: (agentId: string, question: string) => void;
355
+ retry: (agentId: string, question: string, opts?: Pick<SendOpts, 'forceVoicePlayback'>) => void;
225
356
  /** Record a 👍/👎 on an assistant reply (optional comment on 👎). Optimistic. */
226
357
  rateMessage: (messageId: string, rating: 'up' | 'down', comment?: string) => void;
358
+ /** Record a vote on an analytics explanation. Rejects when it could not be
359
+ * saved (or the transport has no explanation feedback) so the UI can retry. */
360
+ rateExplanation: (input: Omit<ExplanationFeedbackInput, 'sessionId' | 'surface'>, surface?: ExplanationFeedbackInput['surface']) => Promise<void>;
361
+ /** Poll / retry the detailed AI explanation of an analytics answer for this
362
+ * session; undefined when the transport cannot. */
363
+ explanationTransport: (surface?: ExplanationFeedbackInput['surface']) => AnalyticsAIExplanationTransport<AnalyticsExplanationInput> | undefined;
227
364
  /** Append a proactive assistant message (auto-engagement). No-op duplicate-guarded. */
228
365
  injectAssistant: (content: string) => void;
366
+ /** After a teammate handed the chat back to the AI: offer the live-support
367
+ * action again (its form opens in the conversation). False when this
368
+ * widget has no live-support action. */
369
+ reconnectSupport: () => boolean;
229
370
  /** Add/update/remove local-only bubbles used by the live voice capture UI. */
230
371
  appendUserDraft: (content: string) => string;
231
372
  patchMessage: (id: string, fields: Partial<ChatMessage>) => void;
@@ -235,9 +376,15 @@ interface ChatApi {
235
376
  /** Submit an inline action form; persists identity so Case-1 auto-handoff can fire later. */
236
377
  submitForm: (type: string, payload: Record<string, unknown>, identity?: Visitor, /** Backend-declared endpoint; authoritative when present. */
237
378
  endpointOverride?: string) => Promise<ActionResult>;
379
+ confirmHostedBooking: (inquiryId: string, eventUri: string, inviteeUri: string) => Promise<DemoBooking | undefined>;
238
380
  transcribe: (audio: Blob | string, mimeType: string, languageHint?: string, durationSeconds?: number) => Promise<string>;
239
- /** Extract text from an attached image/PDF (folded into the next message). */
240
- extract: (fileBase64: string, mimeType: string, filename?: string) => Promise<string>;
381
+ uploadAttachment: (fileBase64: string, mimeType: string, filename: string, analyze: boolean) => Promise<{
382
+ id: string;
383
+ text: string;
384
+ analysisFailed: boolean;
385
+ }>;
386
+ /** The file attached to a visitor message, for preview. */
387
+ loadAttachment: (message: Pick<ChatMessage, 'id'>, attachment: MessageAttachment, index?: number) => Promise<Blob>;
241
388
  searchGifs: (query: string) => Promise<GifResult[]>;
242
389
  /** Booking availability in a window (booked slots + connected-calendar busy ranges). */
243
390
  demoSlots: (fromISO: string, toISO: string) => Promise<DemoSlotsResult>;
@@ -272,7 +419,116 @@ interface ChatApi {
272
419
  }
273
420
  declare const useChat: (transport: Transport, config: ResolvedConfig, active?: boolean) => ChatApi;
274
421
  //#endregion
422
+ //#region src/components.d.ts
423
+ /** Submit handler shared by the forms + handoff card. */
424
+ type SubmitForm = (type: string, payload: Record<string, unknown>, identity?: Visitor, /** Backend-declared endpoint; authoritative when present. */
425
+ endpointOverride?: string) => Promise<ActionResult>;
426
+ type ConfirmHostedBooking = (inquiryId: string, eventUri: string, inviteeUri: string) => Promise<DemoBooking | undefined>;
427
+ declare const ActionsArea: ({
428
+ actions,
429
+ descriptors,
430
+ visitor,
431
+ onSubmitForm,
432
+ onDemoSlots,
433
+ onConfirmHostedBooking,
434
+ scheduler,
435
+ exclude,
436
+ openAction,
437
+ translations,
438
+ onClose
439
+ }: {
440
+ /** Legacy tool ids. Used only when `descriptors` is absent (older backend). */
441
+ actions?: string[];
442
+ /** Structured descriptors — preferred. */
443
+ descriptors?: PublicChatAction[];
444
+ visitor: Visitor;
445
+ onSubmitForm: SubmitForm;
446
+ onDemoSlots?: (fromISO: string, toISO: string) => Promise<DemoSlotsResult>;
447
+ onConfirmHostedBooking?: ConfirmHostedBooking;
448
+ scheduler?: SchedulerInfo;
449
+ exclude?: string[];
450
+ /** Action id the backend resolved for this turn — opens its form directly. */
451
+ openAction?: string;
452
+ /** Locale-specific copy keyed by stable action ID. */
453
+ translations?: Record<string, WidgetActionTranslation>;
454
+ /** A host that shows the actions in its own panel: closing or cancelling
455
+ * the action closes that panel instead of returning to the action menu. */
456
+ onClose?: () => void;
457
+ }) => JSX.Element | null;
458
+ //#endregion
459
+ //#region src/style-rules.d.ts
460
+ /**
461
+ * Picks the rules for some components out of a stylesheet, so another
462
+ * surface can render those components without the whole widget stylesheet.
463
+ *
464
+ * A rule is kept when its selector names one of the class prefixes; at-rules
465
+ * such as @media keep only their matching inner rules and are dropped when
466
+ * none match. Comments are removed. This is a small parser for our own,
467
+ * well-formed stylesheet — not a general CSS parser.
468
+ */
469
+ declare const selectStyleRules: (css: string, classPrefixes: string[]) => string;
470
+ //#endregion
471
+ //#region src/transcript.d.ts
472
+ /** A transcript worth sending as the visitor's turn: annotations stripped,
473
+ * and neither noise, silence nor a leaked transcription prompt. Returns ''
474
+ * when there is nothing to send. */
475
+ declare const usableTranscript: (text: string) => string;
476
+ /** The microphone picked up the AI's own reply from the speakers, not the
477
+ * visitor (shared with every voice surface). */
478
+ declare const looksLikeEcho: (transcript: string, spoken: string) => boolean;
479
+ //#endregion
480
+ //#region src/audio.d.ts
481
+ interface VoiceAudioCapabilities {
482
+ echoCancellation?: boolean;
483
+ noiseSuppression?: boolean;
484
+ autoGainControl?: boolean;
485
+ channelCount?: boolean;
486
+ voiceIsolation?: boolean;
487
+ }
488
+ /**
489
+ * Build a best-effort microphone profile for conversational speech. Every
490
+ * enhancement is capability-driven and optional, so unsupported processing
491
+ * cannot make microphone permission fail.
492
+ */
493
+ declare const createVoiceAudioConstraints: (deviceId?: string, supported?: VoiceAudioCapabilities) => MediaTrackConstraints;
494
+ interface AdaptiveVoiceActivityOptions {
495
+ calibrationSamples?: number;
496
+ ambientWindowSamples?: number;
497
+ ambientPercentile?: number;
498
+ smoothing?: number;
499
+ minimumNoiseFloor?: number;
500
+ speechToNoiseRatio?: number;
501
+ quietToNoiseRatio?: number;
502
+ minimumEndSilenceMs?: number;
503
+ maximumEndSilenceMs?: number;
504
+ }
505
+ interface VoiceActivitySample {
506
+ speech: boolean;
507
+ quiet: boolean;
508
+ calibrated: boolean;
509
+ noiseFloor: number;
510
+ speechThreshold: number;
511
+ quietThreshold: number;
512
+ endOfSpeechDelayMs: number;
513
+ }
514
+ /**
515
+ * Learn the room's ambient level continuously and classify relative changes.
516
+ * The detector is synchronous and runs on samples already collected for the
517
+ * level meter, so it adds no network request or post-recording delay.
518
+ */
519
+ declare const createAdaptiveVoiceActivityDetector: (options?: AdaptiveVoiceActivityOptions) => {
520
+ observe: (rms: number) => VoiceActivitySample;
521
+ reset: () => void;
522
+ };
523
+ declare const createPreferredAudioRecorder: (stream: MediaStream) => MediaRecorder;
524
+ declare const stopRecorderWithFlush: (recorder: MediaRecorder | null | undefined) => void;
525
+ //#endregion
275
526
  //#region src/runtime.d.ts
276
- declare const createChatTransport: (config: ResolvedConfig) => Transport;
527
+ /**
528
+ * The widget's action buttons, forms and booking picker, for surfaces that
529
+ * render ActionsArea. They read the --cf-* theme variables, which the host
530
+ * surface maps onto its own theme.
531
+ */
532
+ declare const WIDGET_ACTION_STYLES: string;
277
533
  //#endregion
278
- export { type ActionResult, type AnalyticsVisualization, type BootstrapInfo, type ChatApi, type ChatArtifact, type ChatMessage, type DemoSlotsResult, type HistoryEntry, type PublicChatAction, type PublicChatActionField, type ResolvedConfig, ResultTable, type Source, type Transport, WidgetAnalyticsChart, type WidgetConfig, type WidgetThemeTokens, type WidgetUser, buildWidgetAnalyticsChartModel, createChatTransport, createPreferredAudioRecorder, createVoiceAudioConstraints, formatResultCell, renderRich, resolveConfig, serializeResultCsv, stopRecorderWithFlush, useChat };
534
+ export { type ActionResult, ActionsArea, type AnalyticsVisualization, type BootstrapInfo, type ChatApi, type ChatArtifact, type ChatMessage, type DemoSlotsResult, type HistoryEntry, type MessageAttachment, type PublicChatAction, type PublicChatActionField, type ResolvedConfig, ResultTable, type Source, StringsProvider, type Transport, type VoiceReply, WIDGET_ACTION_STYLES, WidgetAnalyticsChart, type WidgetConfig, type WidgetThemeTokens, type WidgetUser, analyticsResultDetails, buildWidgetAnalyticsChartModel, createAdaptiveVoiceActivityDetector, createChatTransport, createPreferredAudioRecorder, createVoiceAudioConstraints, findLiveSupportAction, formatResultCell, looksLikeEcho, reconnectableHandbackId, renderRich, resolveConfig, selectStyleRules, serializeResultCsv, stopRecorderWithFlush, usableTranscript, useChat };