@ringg/core 0.0.1-alpha.10
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/LICENSE +21 -0
- package/README.md +93 -0
- package/dist/index.cjs +757 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +762 -0
- package/dist/index.d.ts +762 -0
- package/dist/index.js +718 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,762 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme types for the widget.
|
|
3
|
+
* Covers both widget-level theming and per-component theming.
|
|
4
|
+
*/
|
|
5
|
+
type ButtonStyle = "rounded" | "pill" | "square";
|
|
6
|
+
type ButtonSize = "sm" | "md" | "lg";
|
|
7
|
+
/**
|
|
8
|
+
* Widget-level theme — applies to the entire widget chrome
|
|
9
|
+
* (header, messages, buttons, trigger FAB, etc.)
|
|
10
|
+
*/
|
|
11
|
+
interface WidgetTheme {
|
|
12
|
+
/** Main accent color (buttons, selected states). Supports CSS gradients. */
|
|
13
|
+
primaryColor?: string;
|
|
14
|
+
/** Text color on primary-colored elements */
|
|
15
|
+
primaryTextColor?: string;
|
|
16
|
+
/** Widget background */
|
|
17
|
+
backgroundColor?: string;
|
|
18
|
+
/** Cards, inputs background */
|
|
19
|
+
surfaceColor?: string;
|
|
20
|
+
/** Main text color */
|
|
21
|
+
textColor?: string;
|
|
22
|
+
/** Secondary/muted text color */
|
|
23
|
+
mutedTextColor?: string;
|
|
24
|
+
/** Border color */
|
|
25
|
+
borderColor?: string;
|
|
26
|
+
/** Error state color */
|
|
27
|
+
errorColor?: string;
|
|
28
|
+
/** Success state color */
|
|
29
|
+
successColor?: string;
|
|
30
|
+
/** Button corner style */
|
|
31
|
+
buttonStyle?: ButtonStyle;
|
|
32
|
+
/** Global border radius (e.g., "12px", "20px") */
|
|
33
|
+
borderRadius?: string;
|
|
34
|
+
/** Font family */
|
|
35
|
+
fontFamily?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Component-level theme — applies to interactive components
|
|
39
|
+
* (calendar, form, buttons, confirmation).
|
|
40
|
+
* Extends widget theme with additional component-specific properties.
|
|
41
|
+
*/
|
|
42
|
+
interface ComponentTheme {
|
|
43
|
+
primaryColor?: string;
|
|
44
|
+
primaryTextColor?: string;
|
|
45
|
+
backgroundColor?: string;
|
|
46
|
+
surfaceColor?: string;
|
|
47
|
+
textColor?: string;
|
|
48
|
+
mutedTextColor?: string;
|
|
49
|
+
borderColor?: string;
|
|
50
|
+
errorColor?: string;
|
|
51
|
+
successColor?: string;
|
|
52
|
+
fontFamily?: string;
|
|
53
|
+
fontSize?: string;
|
|
54
|
+
borderRadius?: string;
|
|
55
|
+
padding?: string;
|
|
56
|
+
buttonStyle?: ButtonStyle;
|
|
57
|
+
buttonSize?: ButtonSize;
|
|
58
|
+
}
|
|
59
|
+
/** Fully resolved widget theme — all fields guaranteed present */
|
|
60
|
+
type ResolvedWidgetTheme = Required<WidgetTheme>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Slash command types — commands available during text chat.
|
|
64
|
+
*/
|
|
65
|
+
type SlashCommandToolType = "CALLBACK_SCHEDULE_TOOL" | "WIDGET_TOOL" | "DISEASE_ACCEPTANCE_TOOL";
|
|
66
|
+
interface SlashCommand {
|
|
67
|
+
tool_type: SlashCommandToolType;
|
|
68
|
+
command: string;
|
|
69
|
+
display_name: string;
|
|
70
|
+
description: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Widget configuration types.
|
|
75
|
+
* These define the public API surface for consumers initializing the widget.
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
type MediaType = "audio" | "text";
|
|
79
|
+
type EnvironmentMode = "dev" | "stage" | "prod";
|
|
80
|
+
type TriggerPlacement = "fixed" | "absolute";
|
|
81
|
+
type TriggerAlignment = "center" | "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
82
|
+
type WidgetAlignment = "bottom-right" | "bottom-center" | "bottom-left";
|
|
83
|
+
interface WidgetPositionConfig {
|
|
84
|
+
triggerPlacement?: TriggerPlacement;
|
|
85
|
+
triggerAlignment?: TriggerAlignment;
|
|
86
|
+
hideTriggerOnExpand?: boolean;
|
|
87
|
+
widgetAlignment?: WidgetAlignment;
|
|
88
|
+
}
|
|
89
|
+
interface LegalDisclaimerConfig {
|
|
90
|
+
text: string;
|
|
91
|
+
links?: Record<string, string>;
|
|
92
|
+
}
|
|
93
|
+
/** Styles that are safe to pass cross-platform (subset of CSS properties that map to RN) */
|
|
94
|
+
interface PortableStyles {
|
|
95
|
+
height?: string | number;
|
|
96
|
+
width?: string | number;
|
|
97
|
+
backgroundColor?: string;
|
|
98
|
+
padding?: string | number;
|
|
99
|
+
borderRadius?: string | number;
|
|
100
|
+
}
|
|
101
|
+
interface ButtonIconConfig {
|
|
102
|
+
size?: string | number;
|
|
103
|
+
url?: string;
|
|
104
|
+
}
|
|
105
|
+
interface ButtonsConfig {
|
|
106
|
+
mic?: {
|
|
107
|
+
styles?: PortableStyles;
|
|
108
|
+
};
|
|
109
|
+
modalTrigger?: {
|
|
110
|
+
styles?: PortableStyles;
|
|
111
|
+
icon?: ButtonIconConfig;
|
|
112
|
+
};
|
|
113
|
+
text?: {
|
|
114
|
+
textBeforeCall?: string;
|
|
115
|
+
textDuringCall?: string;
|
|
116
|
+
styles?: PortableStyles;
|
|
117
|
+
};
|
|
118
|
+
call?: {
|
|
119
|
+
textBeforeCall?: string;
|
|
120
|
+
textDuringCall?: string;
|
|
121
|
+
styles?: PortableStyles;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
interface FeedbackScreenConfig {
|
|
125
|
+
title?: string;
|
|
126
|
+
description?: string;
|
|
127
|
+
starsCount?: number;
|
|
128
|
+
starsStyles?: {
|
|
129
|
+
filledColor?: string;
|
|
130
|
+
emptyColor?: string;
|
|
131
|
+
};
|
|
132
|
+
placeholder?: string;
|
|
133
|
+
submitBtnCTA?: string;
|
|
134
|
+
submitBtnStyles?: PortableStyles;
|
|
135
|
+
}
|
|
136
|
+
interface InnerWindowConfig {
|
|
137
|
+
width?: string | number;
|
|
138
|
+
height?: string | number;
|
|
139
|
+
borderRadius?: string | number;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The main configuration object consumers pass to initialize the widget.
|
|
143
|
+
* Used by both web (loadAgent) and React Native (<RinggWidget />) entry points.
|
|
144
|
+
*/
|
|
145
|
+
interface RinggWidgetConfig {
|
|
146
|
+
/** Agent identifier — required */
|
|
147
|
+
agentId: string;
|
|
148
|
+
/** API key for authentication — required */
|
|
149
|
+
xApiKey: string;
|
|
150
|
+
/** Custom variables passed to the agent (e.g., user name, role) */
|
|
151
|
+
variables: Record<string, string>;
|
|
152
|
+
/** Environment mode — determines backend/LiveKit URLs */
|
|
153
|
+
mode?: EnvironmentMode;
|
|
154
|
+
/** Widget title displayed in the header */
|
|
155
|
+
title?: string;
|
|
156
|
+
/** Widget description displayed in the header */
|
|
157
|
+
description?: string;
|
|
158
|
+
/** Default communication tab */
|
|
159
|
+
defaultTab?: MediaType;
|
|
160
|
+
/** Whether to hide the audio/text tab selector */
|
|
161
|
+
hideTabSelector?: boolean;
|
|
162
|
+
/** Custom logo URL for the widget header */
|
|
163
|
+
logoUrl?: string;
|
|
164
|
+
/** Styles for the logo element */
|
|
165
|
+
logoStyles?: PortableStyles;
|
|
166
|
+
/** Slash commands available from config (merged with runtime ones) */
|
|
167
|
+
enabledSlashCommands?: SlashCommand[];
|
|
168
|
+
/** App-wide theming */
|
|
169
|
+
theme?: WidgetTheme;
|
|
170
|
+
/** Widget positioning (web-only, ignored on RN) */
|
|
171
|
+
widgetPosition?: WidgetPositionConfig;
|
|
172
|
+
/** Legal disclaimer shown before call start */
|
|
173
|
+
legalDisclaimer?: LegalDisclaimerConfig;
|
|
174
|
+
/** Button customizations */
|
|
175
|
+
buttons?: ButtonsConfig;
|
|
176
|
+
/** Post-call feedback screen customizations */
|
|
177
|
+
feedbackScreen?: FeedbackScreenConfig;
|
|
178
|
+
/** Widget window dimensions (web-only) */
|
|
179
|
+
innerWindowProps?: InnerWindowConfig;
|
|
180
|
+
/** URL for the notification sound */
|
|
181
|
+
notificationTuneUrl?: string;
|
|
182
|
+
}
|
|
183
|
+
/** Default values for optional config fields */
|
|
184
|
+
declare const DEFAULT_CONFIG: {
|
|
185
|
+
readonly mode: "prod";
|
|
186
|
+
readonly title: "Ringg AI Support";
|
|
187
|
+
readonly description: "Ringg AI offers 24/7 voice support to handle your business calls efficiently and professionally";
|
|
188
|
+
readonly defaultTab: MediaType;
|
|
189
|
+
readonly hideTabSelector: false;
|
|
190
|
+
readonly notificationTuneUrl: "https://assets.ringg.ai/audios/misc/widget_notification.mp3";
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Interactive component types pushed from the backend during a call.
|
|
195
|
+
* These define the data contracts for calendar, form, buttons, confirmation, and flows.
|
|
196
|
+
*/
|
|
197
|
+
|
|
198
|
+
interface BaseComponent {
|
|
199
|
+
component_type: string;
|
|
200
|
+
component_id: string;
|
|
201
|
+
data: unknown;
|
|
202
|
+
theme?: ComponentTheme;
|
|
203
|
+
}
|
|
204
|
+
interface CalendarSlot {
|
|
205
|
+
id: string;
|
|
206
|
+
datetime: string;
|
|
207
|
+
}
|
|
208
|
+
interface CalendarBookingData {
|
|
209
|
+
available_slots: CalendarSlot[];
|
|
210
|
+
timezone: string;
|
|
211
|
+
title: string;
|
|
212
|
+
}
|
|
213
|
+
interface CalendarBookingPayload extends BaseComponent {
|
|
214
|
+
component_type: "calendar_booking";
|
|
215
|
+
data: CalendarBookingData;
|
|
216
|
+
}
|
|
217
|
+
type FormFieldType = "text" | "email" | "tel" | "number" | "select" | "multiselect" | "textarea" | "date" | "boolean";
|
|
218
|
+
interface FormFieldOption {
|
|
219
|
+
value: string;
|
|
220
|
+
label: string;
|
|
221
|
+
}
|
|
222
|
+
interface FormField {
|
|
223
|
+
name: string;
|
|
224
|
+
type: FormFieldType;
|
|
225
|
+
label: string;
|
|
226
|
+
placeholder?: string;
|
|
227
|
+
required?: boolean;
|
|
228
|
+
options?: string[] | FormFieldOption[];
|
|
229
|
+
validation?: {
|
|
230
|
+
pattern?: string;
|
|
231
|
+
minLength?: number;
|
|
232
|
+
maxLength?: number;
|
|
233
|
+
message?: string;
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
interface FormData {
|
|
237
|
+
title: string;
|
|
238
|
+
description?: string;
|
|
239
|
+
fields: FormField[];
|
|
240
|
+
submit_label?: string;
|
|
241
|
+
}
|
|
242
|
+
interface FormPayload extends BaseComponent {
|
|
243
|
+
component_type: "form";
|
|
244
|
+
data: FormData;
|
|
245
|
+
}
|
|
246
|
+
interface ButtonAction {
|
|
247
|
+
type: "navigate" | "trigger_component" | "api_call";
|
|
248
|
+
url?: string;
|
|
249
|
+
component_type?: string;
|
|
250
|
+
method?: "POST" | "GET";
|
|
251
|
+
endpoint?: string;
|
|
252
|
+
payload?: Record<string, string>;
|
|
253
|
+
}
|
|
254
|
+
interface ButtonItem {
|
|
255
|
+
id: string;
|
|
256
|
+
label: string;
|
|
257
|
+
style?: "primary" | "secondary" | "outline" | "destructive";
|
|
258
|
+
action: ButtonAction;
|
|
259
|
+
}
|
|
260
|
+
interface ButtonsData {
|
|
261
|
+
title?: string;
|
|
262
|
+
buttons: ButtonItem[];
|
|
263
|
+
}
|
|
264
|
+
interface ButtonsPayload extends BaseComponent {
|
|
265
|
+
component_type: "buttons";
|
|
266
|
+
data: ButtonsData;
|
|
267
|
+
}
|
|
268
|
+
interface ConfirmationData {
|
|
269
|
+
title: string;
|
|
270
|
+
message: string;
|
|
271
|
+
icon?: "success" | "info" | "warning" | "error";
|
|
272
|
+
details?: Array<{
|
|
273
|
+
label: string;
|
|
274
|
+
value: string;
|
|
275
|
+
}>;
|
|
276
|
+
}
|
|
277
|
+
interface ConfirmationPayload extends BaseComponent {
|
|
278
|
+
component_type: "confirmation";
|
|
279
|
+
data: ConfirmationData;
|
|
280
|
+
}
|
|
281
|
+
interface FlowStep {
|
|
282
|
+
id: string;
|
|
283
|
+
title: string;
|
|
284
|
+
component: SimpleComponentPayload;
|
|
285
|
+
}
|
|
286
|
+
interface InteractiveFlowData {
|
|
287
|
+
title?: string;
|
|
288
|
+
steps: FlowStep[];
|
|
289
|
+
on_complete: {
|
|
290
|
+
method: "POST" | "GET";
|
|
291
|
+
endpoint: string;
|
|
292
|
+
payload: Record<string, string>;
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
interface InteractiveFlowPayload extends BaseComponent {
|
|
296
|
+
component_type: "interactive_flow";
|
|
297
|
+
data: InteractiveFlowData;
|
|
298
|
+
}
|
|
299
|
+
type ComponentPayload = CalendarBookingPayload | FormPayload | ButtonsPayload | ConfirmationPayload | InteractiveFlowPayload;
|
|
300
|
+
type SimpleComponentPayload = CalendarBookingPayload | FormPayload | ButtonsPayload | ConfirmationPayload;
|
|
301
|
+
interface ComponentActionResponse {
|
|
302
|
+
success: boolean;
|
|
303
|
+
message: string;
|
|
304
|
+
next_step?: SimpleComponentPayload;
|
|
305
|
+
confirmation?: ConfirmationData;
|
|
306
|
+
}
|
|
307
|
+
interface GroupedSlots {
|
|
308
|
+
date: string;
|
|
309
|
+
dateLabel: string;
|
|
310
|
+
slots: CalendarSlot[];
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Widget event types — dispatched to the host application.
|
|
315
|
+
* These provide lifecycle hooks for the embedding app to react to widget state changes.
|
|
316
|
+
*/
|
|
317
|
+
|
|
318
|
+
type WidgetEventName = "ringg:widget_status" | "ringg:conversation_status" | "ringg:feedback_status" | "ringg:calendar_booking" | "ringg:component_acknowledgement";
|
|
319
|
+
interface WidgetStatusPayload {
|
|
320
|
+
status: "maximised" | "minimised";
|
|
321
|
+
mode: MediaType;
|
|
322
|
+
}
|
|
323
|
+
interface ConversationStatusPayload {
|
|
324
|
+
status: "started" | "ended";
|
|
325
|
+
mode: MediaType;
|
|
326
|
+
callId: string;
|
|
327
|
+
}
|
|
328
|
+
interface FeedbackStatusPayload {
|
|
329
|
+
status: "submitted" | "skipped";
|
|
330
|
+
callId: string;
|
|
331
|
+
rating?: number;
|
|
332
|
+
}
|
|
333
|
+
interface CalendarBookingEventPayload {
|
|
334
|
+
status: "shown" | "confirmed" | "failed";
|
|
335
|
+
componentId: string;
|
|
336
|
+
slotId?: string;
|
|
337
|
+
message?: string;
|
|
338
|
+
}
|
|
339
|
+
interface ComponentAcknowledgementPayload {
|
|
340
|
+
componentName: string;
|
|
341
|
+
componentId: string;
|
|
342
|
+
status: string;
|
|
343
|
+
}
|
|
344
|
+
/** Union of all possible event payloads */
|
|
345
|
+
type WidgetEventPayload = WidgetStatusPayload | ConversationStatusPayload | FeedbackStatusPayload | CalendarBookingEventPayload | ComponentAcknowledgementPayload;
|
|
346
|
+
/**
|
|
347
|
+
* Event map — maps event names to their payload types.
|
|
348
|
+
* Enables type-safe event dispatch/subscription.
|
|
349
|
+
*/
|
|
350
|
+
interface WidgetEventMap {
|
|
351
|
+
"ringg:widget_status": WidgetStatusPayload;
|
|
352
|
+
"ringg:conversation_status": ConversationStatusPayload;
|
|
353
|
+
"ringg:feedback_status": FeedbackStatusPayload;
|
|
354
|
+
"ringg:calendar_booking": CalendarBookingEventPayload;
|
|
355
|
+
"ringg:component_acknowledgement": ComponentAcknowledgementPayload;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Domain-specific widget types (e.g., disease/policy finder).
|
|
360
|
+
*/
|
|
361
|
+
type SubQuestionType = "SINGLE_SELECT" | "MULTI_SELECT" | "INPUT";
|
|
362
|
+
interface SubQuestion {
|
|
363
|
+
question_id: string;
|
|
364
|
+
question_type: SubQuestionType;
|
|
365
|
+
label: string;
|
|
366
|
+
options?: string[];
|
|
367
|
+
placeholder?: string;
|
|
368
|
+
}
|
|
369
|
+
interface DiseaseOption {
|
|
370
|
+
disease_name: string;
|
|
371
|
+
sub_questions: SubQuestion[];
|
|
372
|
+
}
|
|
373
|
+
interface SubQuestionResponse {
|
|
374
|
+
question_id: string;
|
|
375
|
+
answer: string;
|
|
376
|
+
}
|
|
377
|
+
interface DiseaseResponse {
|
|
378
|
+
disease_name: string;
|
|
379
|
+
sub_questions: SubQuestionResponse[];
|
|
380
|
+
}
|
|
381
|
+
interface WidgetSubmitPayload {
|
|
382
|
+
selections: DiseaseResponse[];
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Chat message types — the normalized message format used across platforms.
|
|
387
|
+
*/
|
|
388
|
+
|
|
389
|
+
interface ChatMessage {
|
|
390
|
+
name: string;
|
|
391
|
+
message: string;
|
|
392
|
+
isSelf: boolean;
|
|
393
|
+
timestamp: number;
|
|
394
|
+
sourceUrl?: string;
|
|
395
|
+
/** When present, this message renders a component instead of text */
|
|
396
|
+
componentType?: string;
|
|
397
|
+
componentData?: ComponentPayload;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* LiveKit adapter interface — platform implementations inject the actual SDK.
|
|
402
|
+
*
|
|
403
|
+
* Web: uses `livekit-client` + `@livekit/components-react`
|
|
404
|
+
* React Native: uses `@livekit/react-native`
|
|
405
|
+
*
|
|
406
|
+
* The core never imports any LiveKit SDK directly.
|
|
407
|
+
*/
|
|
408
|
+
interface RpcInvocation {
|
|
409
|
+
/** The RPC method name */
|
|
410
|
+
method: string;
|
|
411
|
+
/** The JSON-encoded payload */
|
|
412
|
+
payload: string;
|
|
413
|
+
/** Identity of the caller */
|
|
414
|
+
callerIdentity: string;
|
|
415
|
+
}
|
|
416
|
+
interface TextStreamInfo {
|
|
417
|
+
/** Full text content of the stream */
|
|
418
|
+
message: string;
|
|
419
|
+
/** Identity of the participant who sent the stream */
|
|
420
|
+
participantIdentity: string;
|
|
421
|
+
}
|
|
422
|
+
interface TranscriptionSegment {
|
|
423
|
+
id: string;
|
|
424
|
+
text: string;
|
|
425
|
+
isFinal: boolean;
|
|
426
|
+
participantIdentity: string;
|
|
427
|
+
isAgent: boolean;
|
|
428
|
+
}
|
|
429
|
+
type ConnectionState = "disconnected" | "connecting" | "connected" | "reconnecting";
|
|
430
|
+
/**
|
|
431
|
+
* Abstract LiveKit operations for cross-platform use.
|
|
432
|
+
* Each platform provides its own implementation.
|
|
433
|
+
*/
|
|
434
|
+
interface LiveKitAdapter {
|
|
435
|
+
/** Current connection state */
|
|
436
|
+
getConnectionState(): ConnectionState;
|
|
437
|
+
/** Connect to a LiveKit room */
|
|
438
|
+
connect(url: string, token: string): Promise<void>;
|
|
439
|
+
/** Disconnect from the current room */
|
|
440
|
+
disconnect(): void;
|
|
441
|
+
/** Enable or disable the local microphone */
|
|
442
|
+
setMicrophoneEnabled(enabled: boolean): Promise<void>;
|
|
443
|
+
/** Check if microphone is currently enabled */
|
|
444
|
+
isMicrophoneEnabled(): boolean;
|
|
445
|
+
/** Register an RPC method handler */
|
|
446
|
+
registerRpcMethod(method: string, handler: (data: RpcInvocation) => Promise<string>): void;
|
|
447
|
+
/** Unregister an RPC method handler */
|
|
448
|
+
unregisterRpcMethod(method: string): void;
|
|
449
|
+
/** Perform an RPC call to a remote participant */
|
|
450
|
+
performRpc(destinationIdentity: string, method: string, payload: string): Promise<string>;
|
|
451
|
+
/** Register a text stream handler */
|
|
452
|
+
registerTextStreamHandler(topic: string, handler: (info: TextStreamInfo) => void): void;
|
|
453
|
+
/** Unregister a text stream handler */
|
|
454
|
+
unregisterTextStreamHandler(topic: string): void;
|
|
455
|
+
/** Subscribe to connection state changes */
|
|
456
|
+
onConnectionStateChange(handler: (state: ConnectionState) => void): () => void;
|
|
457
|
+
/** Subscribe to participant disconnect events */
|
|
458
|
+
onParticipantDisconnected(handler: (identity: string) => void): () => void;
|
|
459
|
+
/** Subscribe to room disconnect events */
|
|
460
|
+
onDisconnected(handler: () => void): () => void;
|
|
461
|
+
/** Subscribe to transcription segments (audio mode) */
|
|
462
|
+
onTranscription(handler: (segment: TranscriptionSegment) => void): () => void;
|
|
463
|
+
/** Get the identity of the agent participant (if connected) */
|
|
464
|
+
getAgentIdentity(): string | null;
|
|
465
|
+
/** Get the local participant identity */
|
|
466
|
+
getLocalIdentity(): string;
|
|
467
|
+
/** Dispose all listeners and clean up */
|
|
468
|
+
dispose(): void;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Event bus interface — abstraction over platform-specific event dispatch.
|
|
473
|
+
*
|
|
474
|
+
* Web: uses `window.dispatchEvent(new CustomEvent(...))` / `window.addEventListener`
|
|
475
|
+
* React Native: uses callback props or an EventEmitter
|
|
476
|
+
*
|
|
477
|
+
* This enables the host application to listen to widget lifecycle events
|
|
478
|
+
* without coupling to a specific event mechanism.
|
|
479
|
+
*/
|
|
480
|
+
|
|
481
|
+
interface EventBus {
|
|
482
|
+
/**
|
|
483
|
+
* Emit a typed event to the host application.
|
|
484
|
+
*/
|
|
485
|
+
emit<K extends WidgetEventName>(event: K, payload: WidgetEventMap[K]): void;
|
|
486
|
+
/**
|
|
487
|
+
* Subscribe to a typed event. Returns an unsubscribe function.
|
|
488
|
+
*/
|
|
489
|
+
on<K extends WidgetEventName>(event: K, handler: (payload: WidgetEventMap[K]) => void): () => void;
|
|
490
|
+
/**
|
|
491
|
+
* Remove all listeners for a specific event, or all events if no name is provided.
|
|
492
|
+
*/
|
|
493
|
+
off(event?: WidgetEventName): void;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Web implementation — dispatches/listens via DOM CustomEvents on `window`.
|
|
497
|
+
* This is the default for web-based widget usage.
|
|
498
|
+
*/
|
|
499
|
+
declare class DomEventBus implements EventBus {
|
|
500
|
+
private listeners;
|
|
501
|
+
emit<K extends WidgetEventName>(event: K, payload: WidgetEventMap[K]): void;
|
|
502
|
+
on<K extends WidgetEventName>(event: K, handler: (payload: WidgetEventMap[K]) => void): () => void;
|
|
503
|
+
off(event?: WidgetEventName): void;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* In-memory event bus — for React Native or testing.
|
|
507
|
+
* Events are dispatched to registered JS callbacks, not DOM events.
|
|
508
|
+
*/
|
|
509
|
+
declare class CallbackEventBus implements EventBus {
|
|
510
|
+
private listeners;
|
|
511
|
+
emit<K extends WidgetEventName>(event: K, payload: WidgetEventMap[K]): void;
|
|
512
|
+
on<K extends WidgetEventName>(event: K, handler: (payload: WidgetEventMap[K]) => void): () => void;
|
|
513
|
+
off(event?: WidgetEventName): void;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* API client for the Ringg backend.
|
|
518
|
+
* Pure fetch-based — works in any JS runtime (browser, Node, React Native).
|
|
519
|
+
*/
|
|
520
|
+
|
|
521
|
+
interface EnvironmentUrls {
|
|
522
|
+
backendUrl: string;
|
|
523
|
+
livekitUrl: string;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Resolve backend and LiveKit URLs for a given environment mode.
|
|
527
|
+
* Consumers must provide these URLs — the core doesn't embed them.
|
|
528
|
+
*/
|
|
529
|
+
interface UrlResolver {
|
|
530
|
+
resolve(mode: EnvironmentMode): EnvironmentUrls;
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Static URL resolver — URLs are provided directly.
|
|
534
|
+
*/
|
|
535
|
+
declare class StaticUrlResolver implements UrlResolver {
|
|
536
|
+
private urls;
|
|
537
|
+
constructor(urls: Record<EnvironmentMode, EnvironmentUrls>);
|
|
538
|
+
resolve(mode: EnvironmentMode): EnvironmentUrls;
|
|
539
|
+
}
|
|
540
|
+
interface WebcallResponse {
|
|
541
|
+
call_id: string;
|
|
542
|
+
user_token: string;
|
|
543
|
+
enabled_slash_commands?: SlashCommand[];
|
|
544
|
+
}
|
|
545
|
+
interface FeedbackPayload {
|
|
546
|
+
rating: number;
|
|
547
|
+
comment: string;
|
|
548
|
+
}
|
|
549
|
+
interface ApiClientConfig {
|
|
550
|
+
urlResolver: UrlResolver;
|
|
551
|
+
mode: EnvironmentMode;
|
|
552
|
+
xApiKey: string;
|
|
553
|
+
}
|
|
554
|
+
declare class RinggApiClient {
|
|
555
|
+
private backendUrl;
|
|
556
|
+
private xApiKey;
|
|
557
|
+
constructor(config: ApiClientConfig);
|
|
558
|
+
/** Common headers for all API requests. Includes Origin for CORS. */
|
|
559
|
+
private get headers();
|
|
560
|
+
/**
|
|
561
|
+
* Initiate a webcall — returns the LiveKit token and call ID.
|
|
562
|
+
*/
|
|
563
|
+
startWebcall(params: {
|
|
564
|
+
agentId: string;
|
|
565
|
+
variables: Record<string, string>;
|
|
566
|
+
mediaType: "audio" | "text";
|
|
567
|
+
}): Promise<WebcallResponse>;
|
|
568
|
+
/**
|
|
569
|
+
* Submit post-call feedback.
|
|
570
|
+
*/
|
|
571
|
+
submitFeedback(callId: string, feedback: FeedbackPayload): Promise<void>;
|
|
572
|
+
/**
|
|
573
|
+
* Call a component API endpoint (for interactive flows).
|
|
574
|
+
*/
|
|
575
|
+
callComponentApi(method: "POST" | "GET", endpoint: string, payload: Record<string, string>): Promise<ComponentActionResponse>;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Widget state machine — framework-agnostic state management.
|
|
580
|
+
*
|
|
581
|
+
* This is the pure logic layer for widget open/close/feedback lifecycle.
|
|
582
|
+
* Framework-specific wrappers (React hooks, RN state) wrap this controller.
|
|
583
|
+
*
|
|
584
|
+
* The controller emits events via the EventBus so the host app can react.
|
|
585
|
+
*/
|
|
586
|
+
|
|
587
|
+
type WidgetViewState = "closed" | "open" | "feedback";
|
|
588
|
+
interface WidgetStateSnapshot {
|
|
589
|
+
viewState: WidgetViewState;
|
|
590
|
+
currentCallId: string | null;
|
|
591
|
+
callMode: MediaType;
|
|
592
|
+
}
|
|
593
|
+
type WidgetStateListener = (snapshot: WidgetStateSnapshot) => void;
|
|
594
|
+
declare class WidgetStateController {
|
|
595
|
+
private eventBus;
|
|
596
|
+
private viewState;
|
|
597
|
+
private currentCallId;
|
|
598
|
+
private callMode;
|
|
599
|
+
private listeners;
|
|
600
|
+
private conversationEndDispatched;
|
|
601
|
+
constructor(eventBus: EventBus, initialCallMode?: MediaType);
|
|
602
|
+
getSnapshot(): WidgetStateSnapshot;
|
|
603
|
+
get isOpen(): boolean;
|
|
604
|
+
get isShowingFeedback(): boolean;
|
|
605
|
+
open(): void;
|
|
606
|
+
minimize(): void;
|
|
607
|
+
close(): void;
|
|
608
|
+
toggle(): void;
|
|
609
|
+
showFeedback(): void;
|
|
610
|
+
setCallMode(mode: MediaType): void;
|
|
611
|
+
setCurrentCallId(callId: string): void;
|
|
612
|
+
dispatchConversationStart(mode: MediaType, callId: string): void;
|
|
613
|
+
dispatchConversationEnd(mode: MediaType, callId: string): void;
|
|
614
|
+
subscribe(listener: WidgetStateListener): () => void;
|
|
615
|
+
private notify;
|
|
616
|
+
dispose(): void;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Theme engine — resolves, merges, and provides theme values.
|
|
621
|
+
* Pure functions with no framework dependency.
|
|
622
|
+
*/
|
|
623
|
+
|
|
624
|
+
declare const DEFAULT_WIDGET_THEME: ResolvedWidgetTheme;
|
|
625
|
+
/** Merge a partial user theme with the defaults. Returns a fully resolved theme. */
|
|
626
|
+
declare function mergeWidgetTheme(theme?: WidgetTheme): ResolvedWidgetTheme;
|
|
627
|
+
/** Merge a component-level theme with the widget theme as fallback. */
|
|
628
|
+
declare function mergeComponentTheme(componentTheme?: ComponentTheme, widgetTheme?: ResolvedWidgetTheme): ComponentTheme;
|
|
629
|
+
/** Get button border radius based on style */
|
|
630
|
+
declare function getButtonRadius(style?: ButtonStyle): string;
|
|
631
|
+
/** Check if a color is considered "light" (for auto-contrast) */
|
|
632
|
+
declare function isLightColor(hexColor: string): boolean;
|
|
633
|
+
/** Get a contrasting text color (black or white) for a given background */
|
|
634
|
+
declare function getContrastingTextColor(bgColor: string): string;
|
|
635
|
+
declare const WIDGET_PRESET_THEMES: Record<string, WidgetTheme>;
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* Gradient-aware style utilities for the widget theme system.
|
|
639
|
+
*
|
|
640
|
+
* CSS `backgroundColor` does not support gradient values — only the `background`
|
|
641
|
+
* shorthand does. These helpers detect whether a color value is a solid hex/rgb
|
|
642
|
+
* or a CSS gradient string, then return the correct CSS property.
|
|
643
|
+
*
|
|
644
|
+
* These utilities are platform-agnostic (no DOM dependency).
|
|
645
|
+
* Platform renderers consume the output to apply styles appropriately.
|
|
646
|
+
*/
|
|
647
|
+
/** Detect whether a CSS color value is a gradient string. */
|
|
648
|
+
declare function isGradient(color: string): boolean;
|
|
649
|
+
/** Extract all hex and rgb/rgba color values from a gradient string. */
|
|
650
|
+
declare function extractColorsFromGradient(gradient: string): string[];
|
|
651
|
+
/**
|
|
652
|
+
* Return the dominant (first) color from a gradient, or the color as-is for solid values.
|
|
653
|
+
* Falls back to the original string if no colors can be extracted.
|
|
654
|
+
*/
|
|
655
|
+
declare function getDominantColor(color: string): string;
|
|
656
|
+
/**
|
|
657
|
+
* Determine the correct CSS properties for a background color.
|
|
658
|
+
*
|
|
659
|
+
* Returns `{ backgroundColor }` for solid colors, `{ background }` for gradients.
|
|
660
|
+
*
|
|
661
|
+
* On web, spread this directly into a style object.
|
|
662
|
+
* On React Native, gradients aren't natively supported — use `getDominantColor()`
|
|
663
|
+
* to fall back to a solid color.
|
|
664
|
+
*/
|
|
665
|
+
declare function colorToBackground(color: string): {
|
|
666
|
+
backgroundColor?: string;
|
|
667
|
+
background?: string;
|
|
668
|
+
};
|
|
669
|
+
/**
|
|
670
|
+
* Always return a solid hex/rgb color string.
|
|
671
|
+
* Extracts the dominant color from gradients, or returns the color as-is.
|
|
672
|
+
* Use for properties that don't support gradients: border, box-shadow, accent-color.
|
|
673
|
+
*/
|
|
674
|
+
declare function colorToSolid(color: string): string;
|
|
675
|
+
/**
|
|
676
|
+
* Return the correct CSS properties for a border color.
|
|
677
|
+
* Solid colors -> `{ borderColor }`, Gradients -> `{ borderImage, borderStyle: "solid" }`.
|
|
678
|
+
*/
|
|
679
|
+
declare function colorToBorder(color: string): Record<string, string>;
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Component data helpers — pure functions for working with interactive component data.
|
|
683
|
+
* Shared across web and React Native.
|
|
684
|
+
*/
|
|
685
|
+
|
|
686
|
+
/** Group calendar slots by date for display */
|
|
687
|
+
declare function groupSlotsByDate(slots: CalendarSlot[]): GroupedSlots[];
|
|
688
|
+
/** Format a slot time for display */
|
|
689
|
+
declare function formatSlotTime(datetime: string, timezone?: string): string;
|
|
690
|
+
/** Format a slot date for display */
|
|
691
|
+
declare function formatSlotDate(datetime: string, timezone?: string): string;
|
|
692
|
+
/** Replace placeholders in a payload template with actual values */
|
|
693
|
+
declare function buildPayload(template: Record<string, string>, values: Record<string, string>): Record<string, string>;
|
|
694
|
+
declare function isCalendarBooking(payload: ComponentPayload): payload is CalendarBookingPayload;
|
|
695
|
+
declare function isForm(payload: ComponentPayload): payload is FormPayload;
|
|
696
|
+
declare function isButtons(payload: ComponentPayload): payload is ButtonsPayload;
|
|
697
|
+
declare function isConfirmation(payload: ComponentPayload): payload is ConfirmationPayload;
|
|
698
|
+
declare function isInteractiveFlow(payload: ComponentPayload): payload is InteractiveFlowPayload;
|
|
699
|
+
|
|
700
|
+
/** Filter slash commands by query (must start with "/") */
|
|
701
|
+
declare function filterSlashCommands(commands: SlashCommand[], query: string): SlashCommand[];
|
|
702
|
+
|
|
703
|
+
declare function hasSubQuestions(disease: DiseaseOption): boolean;
|
|
704
|
+
declare function getDiseasesWithSubQuestions(selected: DiseaseOption[]): DiseaseOption[];
|
|
705
|
+
declare function formatTimestamp(dateString: string | number, mode?: "fromnow" | "formatted"): string;
|
|
706
|
+
/** Detect if a participant identity is an agent */
|
|
707
|
+
declare function isAgentIdentity(identity: string): boolean;
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* RPC message formatting — transforms between backend RPC format and internal component format.
|
|
711
|
+
*
|
|
712
|
+
* The backend sends `send_dynamic_data` RPCs with a format like:
|
|
713
|
+
* { component_type: "render_component_calendar", component_config: { ... } }
|
|
714
|
+
*
|
|
715
|
+
* The widget needs them in an internal format like:
|
|
716
|
+
* { component_type: "calendar_booking", component_id: "calendar_1234", data: { ... } }
|
|
717
|
+
*
|
|
718
|
+
* This module handles both directions of transformation.
|
|
719
|
+
*/
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Transform a backend RPC payload into the internal component format.
|
|
723
|
+
* Returns null if the component type is unknown.
|
|
724
|
+
*/
|
|
725
|
+
declare function transformRpcToComponent(componentName: string, rpcPayload: Record<string, unknown>): SimpleComponentPayload | InteractiveFlowPayload | null;
|
|
726
|
+
/**
|
|
727
|
+
* Format a component response payload for sending back to the backend via RPC.
|
|
728
|
+
* Used when the user interacts with a component (e.g., selects a calendar slot, submits a form).
|
|
729
|
+
*/
|
|
730
|
+
declare function formatComponentResponse(componentName: string, componentId: string, responseData: Record<string, unknown>, originalConfig: unknown): {
|
|
731
|
+
method: string;
|
|
732
|
+
payload: string;
|
|
733
|
+
};
|
|
734
|
+
/**
|
|
735
|
+
* Format a disease widget submission for sending via RPC.
|
|
736
|
+
*/
|
|
737
|
+
declare function formatDiseaseSubmission(componentId: string, selections: Array<{
|
|
738
|
+
disease_name: string;
|
|
739
|
+
sub_questions: Array<{
|
|
740
|
+
question_id: string;
|
|
741
|
+
answer: string;
|
|
742
|
+
}>;
|
|
743
|
+
}>): {
|
|
744
|
+
method: string;
|
|
745
|
+
payload: string;
|
|
746
|
+
};
|
|
747
|
+
/**
|
|
748
|
+
* Format a disease search query for sending via RPC.
|
|
749
|
+
*/
|
|
750
|
+
declare function formatDiseaseSearch(query: string): {
|
|
751
|
+
method: string;
|
|
752
|
+
payload: string;
|
|
753
|
+
};
|
|
754
|
+
/**
|
|
755
|
+
* Format a slash command for sending via RPC.
|
|
756
|
+
*/
|
|
757
|
+
declare function formatSlashCommand(command: string): {
|
|
758
|
+
method: string;
|
|
759
|
+
payload: string;
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
export { type ApiClientConfig, type BaseComponent, type ButtonAction, type ButtonIconConfig, type ButtonItem, type ButtonSize, type ButtonStyle, type ButtonsConfig, type ButtonsData, type ButtonsPayload, type CalendarBookingData, type CalendarBookingEventPayload, type CalendarBookingPayload, type CalendarSlot, CallbackEventBus, type ChatMessage, type ComponentAcknowledgementPayload, type ComponentActionResponse, type ComponentPayload, type ComponentTheme, type ConfirmationData, type ConfirmationPayload, type ConnectionState, type ConversationStatusPayload, DEFAULT_CONFIG, DEFAULT_WIDGET_THEME, type DiseaseOption, type DiseaseResponse, DomEventBus, type EnvironmentMode, type EnvironmentUrls, type EventBus, type FeedbackPayload, type FeedbackScreenConfig, type FeedbackStatusPayload, type FlowStep, type FormData, type FormField, type FormFieldOption, type FormFieldType, type FormPayload, type GroupedSlots, type InnerWindowConfig, type InteractiveFlowData, type InteractiveFlowPayload, type LegalDisclaimerConfig, type LiveKitAdapter, type MediaType, type PortableStyles, type ResolvedWidgetTheme, RinggApiClient, type RinggWidgetConfig, type RpcInvocation, type SimpleComponentPayload, type SlashCommand, type SlashCommandToolType, StaticUrlResolver, type SubQuestion, type SubQuestionResponse, type SubQuestionType, type TextStreamInfo, type TranscriptionSegment, type TriggerAlignment, type TriggerPlacement, type UrlResolver, WIDGET_PRESET_THEMES, type WebcallResponse, type WidgetAlignment, type WidgetEventMap, type WidgetEventName, type WidgetEventPayload, type WidgetPositionConfig, WidgetStateController, type WidgetStateListener, type WidgetStateSnapshot, type WidgetStatusPayload, type WidgetSubmitPayload, type WidgetTheme, type WidgetViewState, buildPayload, colorToBackground, colorToBorder, colorToSolid, extractColorsFromGradient, filterSlashCommands, formatComponentResponse, formatDiseaseSearch, formatDiseaseSubmission, formatSlashCommand, formatSlotDate, formatSlotTime, formatTimestamp, getButtonRadius, getContrastingTextColor, getDiseasesWithSubQuestions, getDominantColor, groupSlotsByDate, hasSubQuestions, isAgentIdentity, isButtons, isCalendarBooking, isConfirmation, isForm, isGradient, isInteractiveFlow, isLightColor, mergeComponentTheme, mergeWidgetTheme, transformRpcToComponent };
|