@oxvo/ai-live-assist 7.3.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 (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -0
  3. package/cjs/AiLiveAssist.d.ts +108 -0
  4. package/cjs/AiLiveAssist.js +1774 -0
  5. package/cjs/client.d.ts +53 -0
  6. package/cjs/client.js +193 -0
  7. package/cjs/context.d.ts +58 -0
  8. package/cjs/context.js +979 -0
  9. package/cjs/control.d.ts +31 -0
  10. package/cjs/control.js +190 -0
  11. package/cjs/experienceState.d.ts +18 -0
  12. package/cjs/experienceState.js +82 -0
  13. package/cjs/index.d.ts +13 -0
  14. package/cjs/index.js +32 -0
  15. package/cjs/media.d.ts +34 -0
  16. package/cjs/media.js +207 -0
  17. package/cjs/messages.d.ts +2 -0
  18. package/cjs/messages.js +95 -0
  19. package/cjs/package.json +1 -0
  20. package/cjs/placement.d.ts +52 -0
  21. package/cjs/placement.js +293 -0
  22. package/cjs/presentation.d.ts +41 -0
  23. package/cjs/presentation.js +483 -0
  24. package/cjs/recordingPolicy.d.ts +2 -0
  25. package/cjs/recordingPolicy.js +12 -0
  26. package/cjs/safeSvg.d.ts +1 -0
  27. package/cjs/safeSvg.js +157 -0
  28. package/cjs/tabLock.d.ts +31 -0
  29. package/cjs/tabLock.js +260 -0
  30. package/cjs/types.d.ts +299 -0
  31. package/cjs/types.js +2 -0
  32. package/cjs/ui.d.ts +184 -0
  33. package/cjs/ui.js +2353 -0
  34. package/cjs/version.d.ts +1 -0
  35. package/cjs/version.js +4 -0
  36. package/cjs/visualContext.d.ts +21 -0
  37. package/cjs/visualContext.js +72 -0
  38. package/cjs/voicePresenceUi.d.ts +148 -0
  39. package/cjs/voicePresenceUi.js +2182 -0
  40. package/lib/AiLiveAssist.d.ts +108 -0
  41. package/lib/AiLiveAssist.js +1769 -0
  42. package/lib/client.d.ts +53 -0
  43. package/lib/client.js +187 -0
  44. package/lib/context.d.ts +58 -0
  45. package/lib/context.js +975 -0
  46. package/lib/control.d.ts +31 -0
  47. package/lib/control.js +186 -0
  48. package/lib/experienceState.d.ts +18 -0
  49. package/lib/experienceState.js +78 -0
  50. package/lib/index.d.ts +13 -0
  51. package/lib/index.js +26 -0
  52. package/lib/media.d.ts +34 -0
  53. package/lib/media.js +203 -0
  54. package/lib/messages.d.ts +2 -0
  55. package/lib/messages.js +92 -0
  56. package/lib/placement.d.ts +52 -0
  57. package/lib/placement.js +286 -0
  58. package/lib/presentation.d.ts +41 -0
  59. package/lib/presentation.js +478 -0
  60. package/lib/recordingPolicy.d.ts +2 -0
  61. package/lib/recordingPolicy.js +8 -0
  62. package/lib/safeSvg.d.ts +1 -0
  63. package/lib/safeSvg.js +153 -0
  64. package/lib/tabLock.d.ts +31 -0
  65. package/lib/tabLock.js +256 -0
  66. package/lib/types.d.ts +299 -0
  67. package/lib/types.js +1 -0
  68. package/lib/ui.d.ts +184 -0
  69. package/lib/ui.js +2349 -0
  70. package/lib/version.d.ts +1 -0
  71. package/lib/version.js +1 -0
  72. package/lib/visualContext.d.ts +21 -0
  73. package/lib/visualContext.js +68 -0
  74. package/lib/voicePresenceUi.d.ts +148 -0
  75. package/lib/voicePresenceUi.js +2178 -0
  76. package/package.json +58 -0
package/lib/tabLock.js ADDED
@@ -0,0 +1,256 @@
1
+ const validId = (value) => typeof value === 'string' && /^[A-Za-z0-9_.:-]{8,128}$/.test(value);
2
+ const parse = (value) => {
3
+ if (!value)
4
+ return null;
5
+ try {
6
+ const record = JSON.parse(value);
7
+ const ownerId = validId(record.ownerId)
8
+ ? record.ownerId
9
+ : validId(record.tabId)
10
+ ? record.tabId
11
+ : null;
12
+ return ownerId &&
13
+ typeof record.expiresAt === 'number' &&
14
+ Number.isFinite(record.expiresAt)
15
+ ? { ownerId, expiresAt: record.expiresAt }
16
+ : null;
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ };
22
+ export class TabActivityLock {
23
+ constructor(siteKey, ownerId, onOtherTabChange, onTakeoverRequest = () => undefined, onHandoff = () => undefined) {
24
+ this.ownerId = ownerId;
25
+ this.onOtherTabChange = onOtherTabChange;
26
+ this.onTakeoverRequest = onTakeoverRequest;
27
+ this.onHandoff = onHandoff;
28
+ this.refreshTimer = null;
29
+ this.takeoverRetryTimer = null;
30
+ this.owned = false;
31
+ this.takeoverRequestId = null;
32
+ this.takeoverOwnerId = null;
33
+ this.takeoverAttempts = 0;
34
+ this.onStorage = (event) => {
35
+ if (event.key !== this.key)
36
+ return;
37
+ if (this.takeoverRequestId &&
38
+ !this.owned &&
39
+ this.read()?.ownerId === this.ownerId) {
40
+ return;
41
+ }
42
+ this.reportOtherTab();
43
+ };
44
+ this.onMessage = (event) => {
45
+ const value = event.data;
46
+ if (value.type === 'active' && value.ownerId !== this.ownerId) {
47
+ this.onOtherTabChange(true);
48
+ return;
49
+ }
50
+ if (value.type === 'ended') {
51
+ this.reportOtherTab();
52
+ return;
53
+ }
54
+ if (value.type === 'takeover-request' &&
55
+ value.ownerId === this.ownerId &&
56
+ validId(value.requesterId) &&
57
+ validId(value.requestId) &&
58
+ this.owned) {
59
+ this.onTakeoverRequest(value.requesterId, value.requestId);
60
+ return;
61
+ }
62
+ if (value.type === 'handoff' &&
63
+ value.ownerId === this.ownerId &&
64
+ value.requesterId === this.ownerId &&
65
+ validId(value.requestId) &&
66
+ value.requestId === this.takeoverRequestId &&
67
+ this.read()?.ownerId === this.ownerId) {
68
+ this.clearTakeoverRequest();
69
+ this.owned = true;
70
+ this.startRefresh();
71
+ this.onOtherTabChange(false);
72
+ this.onHandoff(value.payload);
73
+ }
74
+ };
75
+ this.key = `__oxvo_ai_live_assist_active_${siteKey}`;
76
+ this.channel = typeof BroadcastChannel === 'undefined'
77
+ ? null
78
+ : new BroadcastChannel(`oxvo-ai-live-assist:${siteKey}`);
79
+ this.channel?.addEventListener('message', this.onMessage);
80
+ window.addEventListener('storage', this.onStorage);
81
+ this.reportOtherTab();
82
+ }
83
+ acquire() {
84
+ const current = this.read();
85
+ if (current &&
86
+ current.expiresAt > Date.now() &&
87
+ current.ownerId !== this.ownerId) {
88
+ this.onOtherTabChange(true);
89
+ return false;
90
+ }
91
+ this.writeOwner(this.ownerId);
92
+ const confirmed = this.read();
93
+ if (confirmed?.ownerId !== this.ownerId) {
94
+ this.onOtherTabChange(true);
95
+ return false;
96
+ }
97
+ this.owned = true;
98
+ this.startRefresh();
99
+ this.channel?.postMessage({ type: 'active', ownerId: this.ownerId });
100
+ this.onOtherTabChange(false);
101
+ return true;
102
+ }
103
+ requestTakeover() {
104
+ const current = this.read();
105
+ if (!this.channel ||
106
+ !current ||
107
+ current.expiresAt <= Date.now() ||
108
+ current.ownerId === this.ownerId) {
109
+ return false;
110
+ }
111
+ const requestId = `takeover_${crypto.randomUUID()}`;
112
+ this.clearTakeoverRequest();
113
+ this.takeoverRequestId = requestId;
114
+ this.takeoverOwnerId = current.ownerId;
115
+ this.sendTakeoverRequest();
116
+ return true;
117
+ }
118
+ handoff(requesterId, requestId, payload) {
119
+ if (!this.channel ||
120
+ !this.owned ||
121
+ !validId(requesterId) ||
122
+ !validId(requestId) ||
123
+ this.read()?.ownerId !== this.ownerId) {
124
+ return false;
125
+ }
126
+ this.stopRefresh();
127
+ this.writeOwner(requesterId);
128
+ if (this.read()?.ownerId !== requesterId) {
129
+ this.startRefresh();
130
+ return false;
131
+ }
132
+ this.owned = false;
133
+ this.channel.postMessage({
134
+ type: 'handoff',
135
+ ownerId: requesterId,
136
+ requesterId,
137
+ requestId,
138
+ payload,
139
+ });
140
+ this.onOtherTabChange(true);
141
+ return true;
142
+ }
143
+ isOwnedByOther() {
144
+ const current = this.read();
145
+ return Boolean(current &&
146
+ current.expiresAt > Date.now() &&
147
+ current.ownerId !== this.ownerId);
148
+ }
149
+ release() {
150
+ this.stopRefresh();
151
+ const released = this.owned && this.read()?.ownerId === this.ownerId;
152
+ if (released) {
153
+ try {
154
+ localStorage.removeItem(this.key);
155
+ }
156
+ catch {
157
+ // Storage may be unavailable in strict privacy modes.
158
+ }
159
+ }
160
+ this.owned = false;
161
+ this.clearTakeoverRequest();
162
+ if (released) {
163
+ this.channel?.postMessage({ type: 'ended', ownerId: this.ownerId });
164
+ }
165
+ this.reportOtherTab();
166
+ }
167
+ destroy() {
168
+ this.release();
169
+ this.channel?.removeEventListener('message', this.onMessage);
170
+ this.channel?.close();
171
+ window.removeEventListener('storage', this.onStorage);
172
+ }
173
+ read() {
174
+ try {
175
+ return parse(localStorage.getItem(this.key));
176
+ }
177
+ catch {
178
+ return null;
179
+ }
180
+ }
181
+ writeOwner(ownerId) {
182
+ try {
183
+ localStorage.setItem(this.key, JSON.stringify({ ownerId, expiresAt: Date.now() + 15000 }));
184
+ }
185
+ catch {
186
+ // The server's distributed lease remains authoritative.
187
+ }
188
+ }
189
+ startRefresh() {
190
+ this.stopRefresh();
191
+ this.refreshTimer = setInterval(() => this.writeOwner(this.ownerId), 5000);
192
+ }
193
+ stopRefresh() {
194
+ if (this.refreshTimer)
195
+ clearInterval(this.refreshTimer);
196
+ this.refreshTimer = null;
197
+ }
198
+ reportOtherTab() {
199
+ this.onOtherTabChange(this.isOwnedByOther());
200
+ }
201
+ sendTakeoverRequest() {
202
+ const requestId = this.takeoverRequestId;
203
+ const ownerId = this.takeoverOwnerId;
204
+ if (!this.channel || !requestId || !ownerId || this.takeoverAttempts >= 6) {
205
+ this.clearTakeoverRequest();
206
+ return;
207
+ }
208
+ const current = this.read();
209
+ if (!current || current.expiresAt <= Date.now()) {
210
+ this.clearTakeoverRequest();
211
+ this.reportOtherTab();
212
+ return;
213
+ }
214
+ if (current.ownerId !== ownerId) {
215
+ if (current.ownerId === this.ownerId && !this.owned) {
216
+ if (this.takeoverRetryTimer)
217
+ clearTimeout(this.takeoverRetryTimer);
218
+ this.takeoverRetryTimer = setTimeout(() => this.expireIncompleteHandoff(), 5000);
219
+ return;
220
+ }
221
+ this.clearTakeoverRequest();
222
+ this.reportOtherTab();
223
+ return;
224
+ }
225
+ this.takeoverAttempts += 1;
226
+ this.channel.postMessage({
227
+ type: 'takeover-request',
228
+ ownerId,
229
+ requesterId: this.ownerId,
230
+ requestId,
231
+ });
232
+ if (this.takeoverRequestId === requestId) {
233
+ this.takeoverRetryTimer = setTimeout(() => this.sendTakeoverRequest(), 250);
234
+ }
235
+ }
236
+ clearTakeoverRequest() {
237
+ if (this.takeoverRetryTimer)
238
+ clearTimeout(this.takeoverRetryTimer);
239
+ this.takeoverRetryTimer = null;
240
+ this.takeoverRequestId = null;
241
+ this.takeoverOwnerId = null;
242
+ this.takeoverAttempts = 0;
243
+ }
244
+ expireIncompleteHandoff() {
245
+ if (!this.owned && this.read()?.ownerId === this.ownerId) {
246
+ try {
247
+ localStorage.removeItem(this.key);
248
+ }
249
+ catch {
250
+ // The distributed lease expires independently when storage is unavailable.
251
+ }
252
+ }
253
+ this.clearTakeoverRequest();
254
+ this.reportOtherTab();
255
+ }
256
+ }
package/lib/types.d.ts ADDED
@@ -0,0 +1,299 @@
1
+ export type ConsentScope = "ai_disclosure" | "text" | "microphone" | "page_context" | "browser_control" | "visual_context" | "handoff_context" | "retained_transcript" | "presentation_guidance";
2
+ export type ExperienceMode = "standard" | "voice_presence";
3
+ export type CapabilityTier = "standard" | "reduced_motion" | "low_power" | "static";
4
+ export type VoicePresenceConfig = {
5
+ enabled: boolean;
6
+ strictVoiceOnly: boolean;
7
+ fallback: "none" | "offer_standard_assist" | "offer_human_handoff";
8
+ launcher: {
9
+ position: "bottom_right" | "bottom_left";
10
+ size: "compact" | "comfortable";
11
+ theme?: "light" | "dark";
12
+ offsetInlinePx: number;
13
+ offsetBlockPx: number;
14
+ showLabelOnFirstVisit: boolean;
15
+ customIconSvg?: string | null;
16
+ };
17
+ activation: {
18
+ title: string;
19
+ description: string;
20
+ primaryLabel: string;
21
+ secondaryLabel: string;
22
+ detailsLabel: string | null;
23
+ };
24
+ captions: {
25
+ enabled: true;
26
+ showVisitorFinal: boolean;
27
+ showAssistantFinal: boolean;
28
+ showInterimVisitor: boolean;
29
+ maxLines: number;
30
+ maxCharacters: number;
31
+ visibleMs: number;
32
+ placement: "adaptive" | "launcher_only" | "target_when_relevant";
33
+ };
34
+ visual: {
35
+ themeVersion: 1;
36
+ intensity: "subtle" | "balanced" | "immersive";
37
+ introWake: boolean;
38
+ spatialTrail: boolean;
39
+ lowPowerMode: "auto" | "always" | "never";
40
+ };
41
+ presentation: {
42
+ aiCursor: boolean;
43
+ spotlight: boolean;
44
+ annotations: boolean;
45
+ spatialCallouts: boolean;
46
+ sequenceMarkers: boolean;
47
+ maxActiveCues: number;
48
+ maxCuesPerMinute: number;
49
+ };
50
+ };
51
+ export type AssistMode = "text" | "voice";
52
+ export type BrowserAction = "scroll" | "highlight" | "focus" | "click" | "type" | "select" | "submit";
53
+ export type Sensitivity = "none" | "private" | "password" | "otp" | "payment" | "banking" | "recovery" | "authentication_secret" | "api_secret";
54
+ export type BootstrapConfig = {
55
+ schemaVersion: 1;
56
+ protocol: {
57
+ min: number;
58
+ max: number;
59
+ };
60
+ available: boolean;
61
+ replayRecordingEnabled?: boolean;
62
+ experienceMode?: ExperienceMode;
63
+ minimumProtocolVersion?: 1 | 2;
64
+ minimumClientVersion?: string;
65
+ configRevision?: number;
66
+ configChecksum?: string;
67
+ widgetVersion?: string;
68
+ capabilities?: {
69
+ text: boolean;
70
+ voice: boolean;
71
+ captions: boolean;
72
+ pageContext: boolean;
73
+ browserControl: boolean;
74
+ visualContext: boolean;
75
+ voicePresence: boolean;
76
+ presentation: boolean;
77
+ aiCursor: boolean;
78
+ annotations: boolean;
79
+ spatialCallouts: boolean;
80
+ handoff: boolean;
81
+ };
82
+ agentAccess?: {
83
+ discoveryUrl: string;
84
+ };
85
+ voice?: {
86
+ turnMode: "semantic_vad" | "server_vad" | "manual";
87
+ };
88
+ appearance?: {
89
+ brandName: string;
90
+ launcherLabel: string;
91
+ accent: string;
92
+ position: "left" | "right";
93
+ panelWidth: number;
94
+ glassEffect: boolean;
95
+ hideLauncherWhenVisitorLimited: boolean;
96
+ attribution?: {
97
+ enabled: boolean;
98
+ };
99
+ welcomeMessage: string | null;
100
+ voicePresence?: VoicePresenceConfig;
101
+ };
102
+ visitorEligibility?: {
103
+ status: "eligible" | "visitor_active" | "visitor_limited" | "cooldown_limited";
104
+ };
105
+ consent?: {
106
+ disclosure: string;
107
+ disclosureChecksum: string;
108
+ policyUrl: string | null;
109
+ termsUrl: string | null;
110
+ requiredScopes: ConsentScope[];
111
+ optionalScopes: ConsentScope[];
112
+ };
113
+ locale?: {
114
+ default: string;
115
+ allowed: string[];
116
+ };
117
+ safety?: {
118
+ policyVersion: number;
119
+ selectorRegions: Array<{
120
+ digest: string;
121
+ selector: string;
122
+ }>;
123
+ };
124
+ cache: {
125
+ maxAgeSeconds: number;
126
+ };
127
+ };
128
+ export type LaunchResult = {
129
+ schemaVersion: 1 | 2;
130
+ protocolVersion: 1 | 2;
131
+ experienceMode: ExperienceMode;
132
+ capabilityTier: CapabilityTier;
133
+ sessionId: string;
134
+ launchCredential: string;
135
+ controlCredential: string;
136
+ resumeCredential: string;
137
+ feedbackCredential: string;
138
+ expiresAt: string;
139
+ feedbackExpiresAt: string;
140
+ controlUrl: string;
141
+ realtimeOfferUrl: string;
142
+ capabilities?: NonNullable<BootstrapConfig["capabilities"]>;
143
+ assistant?: {
144
+ name: string;
145
+ voice: string | null;
146
+ welcomeMessage: string | null;
147
+ };
148
+ state?: "reconnecting";
149
+ correlationId?: string;
150
+ };
151
+ export type ControlServerEnvelope = {
152
+ v: 1 | 2;
153
+ id: string;
154
+ type: string;
155
+ sessionId: string;
156
+ sequence: number;
157
+ sentAt: string;
158
+ payload: Record<string, unknown>;
159
+ };
160
+ export type SanitizedOption = {
161
+ id: string;
162
+ label: string;
163
+ disabled: boolean;
164
+ };
165
+ export type SanitizedTarget = {
166
+ targetId: string;
167
+ revision: number;
168
+ role: string;
169
+ name: string;
170
+ inputType?: string;
171
+ autocomplete?: string;
172
+ semanticRegion?: string;
173
+ sensitivity: Sensitivity;
174
+ protectedRegion?: boolean;
175
+ frameOrigin?: "same_origin" | "cross_origin";
176
+ consequence?: "none" | "navigation" | "state_change" | "submission" | "financial" | "account" | "destructive";
177
+ regionAssessment?: {
178
+ policyVersion: number;
179
+ evaluatedRuleDigests: string[];
180
+ matchedRuleDigests: string[];
181
+ };
182
+ state: {
183
+ visible: boolean;
184
+ enabled: boolean;
185
+ covered?: boolean;
186
+ checked?: boolean;
187
+ };
188
+ options?: SanitizedOption[];
189
+ };
190
+ export type PageContextSnapshot = {
191
+ schemaVersion: 1;
192
+ pageId: string;
193
+ revision: number;
194
+ url: string;
195
+ title: string;
196
+ locale: string;
197
+ viewport: {
198
+ width: number;
199
+ height: number;
200
+ scrollY: number;
201
+ };
202
+ landmarks: Array<{
203
+ role: string;
204
+ label: string;
205
+ }>;
206
+ visibleText: Array<{
207
+ id: string;
208
+ text: string;
209
+ provenance: "page";
210
+ }>;
211
+ selection?: {
212
+ text: string;
213
+ source: "document";
214
+ capturedAt: string;
215
+ };
216
+ targets: SanitizedTarget[];
217
+ alerts: string[];
218
+ truncated: boolean;
219
+ };
220
+ export type VisualContextCapture = {
221
+ source: "sanitized_layout";
222
+ mimeType: "image/jpeg";
223
+ dataUrl: string;
224
+ width: number;
225
+ height: number;
226
+ pageId: string;
227
+ revision: number;
228
+ };
229
+ export type VisualContextRequest = {
230
+ requestId: string;
231
+ functionCallId: string;
232
+ reason: string;
233
+ expiresAt: string;
234
+ approvalMode: "manual" | "automatic";
235
+ };
236
+ export type ActionGrant = {
237
+ grant: string;
238
+ actionId: string;
239
+ action: BrowserAction;
240
+ targetId: string;
241
+ domRevision: number;
242
+ fencingToken: number;
243
+ expiresAt: string;
244
+ value?: string;
245
+ optionValueId?: string;
246
+ desiredChecked?: boolean;
247
+ };
248
+ export type ActionExecutionResult = {
249
+ grant: string;
250
+ actionId: string;
251
+ status: "executed" | "blocked" | "stale" | "failed";
252
+ observed: {
253
+ url?: string;
254
+ revision: number;
255
+ targetState: "unchanged" | "changed" | "detached" | "unknown";
256
+ safeSummary: string;
257
+ checked?: boolean;
258
+ };
259
+ };
260
+ export type PresentationKind = "pointer" | "spotlight" | "underline" | "circle" | "arrow" | "connector" | "sequence_marker" | "callout" | "clear";
261
+ export type PresentationIntent = {
262
+ presentationId: string;
263
+ groupId: string | null;
264
+ kind: PresentationKind;
265
+ targetId: string | null;
266
+ secondaryTargetId: string | null;
267
+ domRevision: number;
268
+ message: string | null;
269
+ emphasis: "subtle" | "normal" | "strong";
270
+ ttlMs: number;
271
+ replaceGroup: boolean;
272
+ };
273
+ export type PresentationResult = {
274
+ presentationId: string;
275
+ status: "shown" | "blocked" | "stale" | "unsupported" | "cleared";
276
+ reasonCode: "OK" | "PRESENTATION_DISABLED" | "PRESENTATION_TARGET_STALE" | "PRESENTATION_TARGET_BLOCKED" | "PRESENTATION_RATE_LIMITED" | "VISITOR_ACTIVITY" | "REDUCED_MOTION_FALLBACK" | "CAPABILITY_UNAVAILABLE" | "NAVIGATION";
277
+ pageId: string;
278
+ domRevision: number;
279
+ shownAt: string | null;
280
+ };
281
+ export type PresentationTarget = {
282
+ targetId: string;
283
+ pageId: string;
284
+ revision: number;
285
+ rect: DOMRectReadOnly;
286
+ safe: boolean;
287
+ };
288
+ export type WidgetMessageKey = "launcher" | "introTitle" | "disclosure" | "requiredConsent" | "consentAgreement" | "legalDetails" | "legalTitle" | "legalClose" | "termsOfService" | "microphoneConsent" | "pageConsent" | "controlConsent" | "visualConsent" | "visualRequest" | "shareVisual" | "declineVisual" | "visualShared" | "visualUnavailable" | "pauseVisual" | "resumeVisual" | "handoffConsent" | "retentionConsent" | "startText" | "startVoice" | "connecting" | "listening" | "thinking" | "speaking" | "ready" | "paused" | "reconnecting" | "end" | "restart" | "close" | "minimize" | "maximize" | "activeCall" | "movePanel" | "mute" | "unmute" | "interrupt" | "usePushToTalk" | "useAutomaticTurns" | "automaticTurnsUnavailable" | "startSpeaking" | "sendVoiceTurn" | "microphoneUnavailable" | "pauseActions" | "resumeActions" | "captionsOn" | "captionsOff" | "textOnly" | "send" | "messagePlaceholder" | "requestHuman" | "continueWithFullAssist" | "requestHumanFallback" | "approve" | "decline" | "actionRequest" | "actionRunning" | "actionVerified" | "actionFailed" | "limitReached" | "ended" | "idleEnded" | "feedbackQuestion" | "resolved" | "partiallyResolved" | "notResolved" | "submitFeedback" | "error" | "retry" | "activeElsewhere" | "visitorLimitReached" | "visitorCooldown" | "visitorAlreadyActive" | "safetyBoundary" | "privacyPolicy" | "moreControls" | "emptyConversation" | "audioPaused" | "humanConnected" | "humanConnecting" | "humanUnavailable" | "textMode" | "reconnectFailed" | "connectedTool" | "approvedService" | "approvedToolEffect";
289
+ export type PluginOptions = {
290
+ enabled?: boolean;
291
+ recordReplay?: boolean;
292
+ runtimeUrl?: string;
293
+ siteKey?: string;
294
+ locale?: string;
295
+ messages?: Partial<Record<WidgetMessageKey, string>>;
296
+ bootstrapTimeoutMs?: number;
297
+ visualTestMode?: boolean;
298
+ onStateChange?: (state: string) => void;
299
+ };
package/lib/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};