@oxvo/ai-live-assist 7.4.37 → 7.4.49

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/lib/context.d.ts CHANGED
@@ -24,6 +24,7 @@ export declare class PageContextCollector {
24
24
  private captureTimer;
25
25
  private mutationCaptureTimer;
26
26
  private targetIds;
27
+ private navigationTargetBindings;
27
28
  private textIds;
28
29
  private optionIds;
29
30
  private targets;
@@ -69,6 +70,7 @@ export declare class PageContextCollector {
69
70
  private beginNavigationSettlement;
70
71
  private observeCausalNavigationAfterMutation;
71
72
  private reportCausalNavigationObservation;
73
+ private resetBoundTargetIds;
72
74
  private installNavigationHooks;
73
75
  private restoreNavigationHooks;
74
76
  private reducedMotion;
package/lib/context.js CHANGED
@@ -7,6 +7,9 @@ const MAX_SELECTED_TEXT = 2000;
7
7
  const SELECTION_RETENTION_MS = 120000;
8
8
  const CAPTURE_SETTLE_MS = 250;
9
9
  const MUTATION_CAPTURE_DEBOUNCE_MS = 350;
10
+ const FRAMER_TOGGLE_ROOT_SELECTOR = '[data-framer-name="Toggle"]';
11
+ const FRAMER_TOGGLE_CONTROL_SELECTOR = 'div[name="Toggle Switch"][data-highlight="true"][tabindex]';
12
+ const MAX_FRAMER_TOGGLE_LABEL = 120;
10
13
  const PRIVATE_SELECTOR = [
11
14
  '[data-oxvo-ai-live-assist-root]',
12
15
  '[data-oxvo-private]',
@@ -37,6 +40,8 @@ const EXPLICIT_SENSITIVITIES = new Set([
37
40
  'api_secret',
38
41
  ]);
39
42
  const id = (prefix) => `${prefix}_${crypto.randomUUID()}`;
43
+ // The runtime may rebind only IDs whose navigation identity this collector rotates.
44
+ const BOUND_NAVIGATION_TARGET_PREFIX = 'target_bound';
40
45
  const normalize = (value, maximum) => value
41
46
  .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, '')
42
47
  .replace(/\s+/g, ' ')
@@ -55,6 +60,31 @@ const canonicalJson = (value) => {
55
60
  };
56
61
  return JSON.stringify(sort(value));
57
62
  };
63
+ const navigationTargetGeometry = (element) => {
64
+ const rect = element.getBoundingClientRect();
65
+ return {
66
+ x: Math.round(rect.left + window.scrollX),
67
+ y: Math.round(rect.top + window.scrollY),
68
+ width: Math.round(rect.width),
69
+ height: Math.round(rect.height),
70
+ };
71
+ };
72
+ const navigationTargetBinding = (element, target) => canonicalJson({
73
+ role: target.role,
74
+ name: target.name,
75
+ inputType: target.inputType ?? null,
76
+ autocomplete: target.autocomplete ?? null,
77
+ semanticRegion: target.semanticRegion ?? null,
78
+ destinationPath: target.destinationPath ?? null,
79
+ sensitivity: target.sensitivity,
80
+ protectedRegion: target.protectedRegion ?? null,
81
+ frameOrigin: target.frameOrigin ?? null,
82
+ consequence: target.consequence ?? null,
83
+ regionAssessment: target.regionAssessment ?? null,
84
+ state: target.state,
85
+ options: target.options ?? null,
86
+ geometry: navigationTargetGeometry(element),
87
+ });
58
88
  export const actionTargetFingerprint = async (target, subtle = globalThis.crypto?.subtle) => {
59
89
  if (!subtle)
60
90
  return null;
@@ -177,6 +207,8 @@ const sensitivityFor = (element, name) => {
177
207
  return 'none';
178
208
  };
179
209
  const roleFor = (element) => {
210
+ if (framerToggleDescriptor(element))
211
+ return 'checkbox';
180
212
  const explicit = normalize(element.getAttribute('role') ?? '', 64);
181
213
  if (explicit)
182
214
  return explicit;
@@ -205,6 +237,9 @@ const roleFor = (element) => {
205
237
  return tag.slice(0, 64);
206
238
  };
207
239
  const nameFor = (element) => {
240
+ const framerToggle = framerToggleDescriptor(element);
241
+ if (framerToggle)
242
+ return framerToggle.name;
208
243
  const input = element instanceof HTMLInputElement ? element : null;
209
244
  const formControl = element instanceof HTMLInputElement ||
210
245
  element instanceof HTMLSelectElement ||
@@ -316,6 +351,131 @@ const safeAccessibleNameText = (element, maximum) => {
316
351
  const text = safeDescendantText(element, maximum, true);
317
352
  return text && sensitivityFor(element, text) === 'none' ? text : '';
318
353
  };
354
+ const safeFramerToggleLabel = (element) => {
355
+ if (!isVisible(element) ||
356
+ element.closest(PRIVATE_SELECTOR) ||
357
+ element.querySelector(PRIVATE_SELECTOR) ||
358
+ element.matches('a[href],button,input,select,textarea,summary,form,[contenteditable="true"],[role],[tabindex]') ||
359
+ element.querySelector('a[href],button,input,select,textarea,summary,form,[contenteditable="true"],[role],[tabindex]')) {
360
+ return '';
361
+ }
362
+ const label = safeDescendantText(element, MAX_FRAMER_TOGGLE_LABEL + 1);
363
+ if (!label ||
364
+ label.length > MAX_FRAMER_TOGGLE_LABEL ||
365
+ sensitivityFor(element, label) !== 'none') {
366
+ return '';
367
+ }
368
+ return label;
369
+ };
370
+ function framerToggleDescriptor(element) {
371
+ if (element.tagName !== 'DIV' ||
372
+ element.getAttribute('name') !== 'Toggle Switch' ||
373
+ element.getAttribute('data-highlight') !== 'true' ||
374
+ !element.hasAttribute('tabindex') ||
375
+ !(element instanceof HTMLElement) ||
376
+ element.tabIndex < 0) {
377
+ return null;
378
+ }
379
+ const state = element.getAttribute('data-framer-name');
380
+ if (state !== 'Off' && state !== 'On')
381
+ return null;
382
+ const root = element.closest(FRAMER_TOGGLE_ROOT_SELECTOR);
383
+ if (!root || root === element || root.closest(PRIVATE_SELECTOR))
384
+ return null;
385
+ const controls = Array.from(root.querySelectorAll(FRAMER_TOGGLE_CONTROL_SELECTOR));
386
+ if (controls.length !== 1 || controls[0] !== element)
387
+ return null;
388
+ let controlBranch = element;
389
+ while (controlBranch.parentElement && controlBranch.parentElement !== root) {
390
+ controlBranch = controlBranch.parentElement;
391
+ }
392
+ if (controlBranch.parentElement !== root)
393
+ return null;
394
+ const labels = [controlBranch.previousElementSibling, controlBranch.nextElementSibling]
395
+ .flatMap((candidate) => (candidate ? [safeFramerToggleLabel(candidate)] : []))
396
+ .filter(Boolean);
397
+ if (labels.length !== 1)
398
+ return null;
399
+ return { checked: state === 'On', name: labels[0] };
400
+ }
401
+ const checkedStateFor = (element) => {
402
+ if (element instanceof HTMLInputElement && ['checkbox', 'radio'].includes(element.type)) {
403
+ return element.checked;
404
+ }
405
+ return framerToggleDescriptor(element)?.checked;
406
+ };
407
+ const dispatchFramerTogglePrimaryPointer = (element) => {
408
+ if (!framerToggleDescriptor(element) || typeof window.PointerEvent !== 'function') {
409
+ throw new Error('Framer toggle pointer interaction is unavailable.');
410
+ }
411
+ const rect = element.getBoundingClientRect();
412
+ const clientX = rect.left + rect.width / 2;
413
+ const clientY = rect.top + rect.height / 2;
414
+ const shared = {
415
+ view: window,
416
+ bubbles: true,
417
+ cancelable: true,
418
+ composed: true,
419
+ clientX,
420
+ clientY,
421
+ };
422
+ const pointer = (type, init) => {
423
+ element.dispatchEvent(new window.PointerEvent(type, {
424
+ ...shared,
425
+ pointerId: 1,
426
+ pointerType: 'mouse',
427
+ width: 1,
428
+ height: 1,
429
+ isPrimary: true,
430
+ ...init,
431
+ }));
432
+ };
433
+ const mouse = (type, init) => {
434
+ element.dispatchEvent(new MouseEvent(type, { ...shared, ...init }));
435
+ };
436
+ pointer('pointerover', { button: -1, buttons: 0 });
437
+ element.dispatchEvent(new window.PointerEvent('pointerenter', {
438
+ ...shared,
439
+ bubbles: false,
440
+ cancelable: false,
441
+ pointerId: 1,
442
+ pointerType: 'mouse',
443
+ width: 1,
444
+ height: 1,
445
+ isPrimary: true,
446
+ button: -1,
447
+ buttons: 0,
448
+ }));
449
+ mouse('mouseover', { button: 0, buttons: 0, detail: 0 });
450
+ element.dispatchEvent(new MouseEvent('mouseenter', {
451
+ ...shared,
452
+ bubbles: false,
453
+ cancelable: false,
454
+ button: 0,
455
+ buttons: 0,
456
+ detail: 0,
457
+ }));
458
+ pointer('pointermove', { button: -1, buttons: 0 });
459
+ mouse('mousemove', { button: 0, buttons: 0, detail: 0 });
460
+ pointer('pointerdown', { button: 0, buttons: 1 });
461
+ mouse('mousedown', { button: 0, buttons: 1, detail: 1 });
462
+ element.focus({ preventScroll: true });
463
+ pointer('pointerup', { button: 0, buttons: 0 });
464
+ mouse('mouseup', { button: 0, buttons: 0, detail: 1 });
465
+ // Chromium's trusted mouse sequence keeps pointerId 1 on click but reports
466
+ // isPrimary false; these fields are trace-bound rather than normalized.
467
+ element.dispatchEvent(new window.PointerEvent('click', {
468
+ ...shared,
469
+ pointerId: 1,
470
+ pointerType: 'mouse',
471
+ width: 1,
472
+ height: 1,
473
+ isPrimary: false,
474
+ button: 0,
475
+ buttons: 0,
476
+ detail: 1,
477
+ }));
478
+ };
319
479
  const semanticSourceSensitivity = (source) => {
320
480
  if (source.closest(PRIVATE_SELECTOR) || source.querySelector(PRIVATE_SELECTOR)) {
321
481
  return 'private';
@@ -478,6 +638,7 @@ export class PageContextCollector {
478
638
  this.captureTimer = null;
479
639
  this.mutationCaptureTimer = null;
480
640
  this.targetIds = new WeakMap();
641
+ this.navigationTargetBindings = new WeakMap();
481
642
  this.textIds = new WeakMap();
482
643
  this.optionIds = new WeakMap();
483
644
  this.targets = new Map();
@@ -561,6 +722,7 @@ export class PageContextCollector {
561
722
  this.pageId = id('page');
562
723
  this.revision += 1;
563
724
  this.targets.clear();
725
+ this.resetBoundTargetIds();
564
726
  this.recentSelection = null;
565
727
  if (this.executingActionId) {
566
728
  this.pendingNavigation = {
@@ -636,6 +798,7 @@ export class PageContextCollector {
636
798
  'aria-pressed',
637
799
  'aria-live',
638
800
  'class',
801
+ 'data-framer-name',
639
802
  'disabled',
640
803
  'href',
641
804
  'hidden',
@@ -731,8 +894,6 @@ export class PageContextCollector {
731
894
  const name = nameFor(element);
732
895
  if (!name && !['form', 'textbox'].includes(role))
733
896
  continue;
734
- const targetId = this.targetIds.get(element) ?? id('target');
735
- this.targetIds.set(element, targetId);
736
897
  const optionMap = new Map();
737
898
  let options;
738
899
  if (element instanceof HTMLSelectElement) {
@@ -777,9 +938,8 @@ export class PageContextCollector {
777
938
  const destinationPath = safeDestinationPath(element);
778
939
  const expanded = literalBooleanAttribute(element, 'aria-expanded');
779
940
  const pressed = literalBooleanAttribute(element, 'aria-pressed');
780
- const target = {
781
- targetId,
782
- revision,
941
+ const checked = checkedStateFor(element);
942
+ const targetIdentity = {
783
943
  role,
784
944
  name,
785
945
  ...(element instanceof HTMLInputElement || element instanceof HTMLButtonElement
@@ -803,14 +963,38 @@ export class PageContextCollector {
803
963
  visible,
804
964
  enabled: enabled(element),
805
965
  covered: visible ? isCovered(element, this.trustedGuideRoot) : false,
806
- ...(element instanceof HTMLInputElement && ['checkbox', 'radio'].includes(element.type)
807
- ? { checked: element.checked }
808
- : {}),
966
+ ...(checked !== undefined ? { checked } : {}),
809
967
  ...(this.statefulButtonActionProof && expanded !== undefined ? { expanded } : {}),
810
968
  ...(this.statefulButtonActionProof && pressed !== undefined ? { pressed } : {}),
811
969
  },
812
970
  ...(options ? { options } : {}),
813
971
  };
972
+ const priorTargetId = this.targetIds.get(element);
973
+ const boundNavigation = targetIdentity.consequence === 'navigation' &&
974
+ typeof targetIdentity.destinationPath === 'string';
975
+ const binding = boundNavigation
976
+ ? navigationTargetBinding(element, targetIdentity)
977
+ : null;
978
+ const priorBinding = this.navigationTargetBindings.get(element);
979
+ const targetId = binding
980
+ ? priorTargetId?.startsWith(`${BOUND_NAVIGATION_TARGET_PREFIX}_`) &&
981
+ priorBinding === binding
982
+ ? priorTargetId
983
+ : id(BOUND_NAVIGATION_TARGET_PREFIX)
984
+ : priorTargetId &&
985
+ !priorTargetId.startsWith(`${BOUND_NAVIGATION_TARGET_PREFIX}_`)
986
+ ? priorTargetId
987
+ : id('target');
988
+ this.targetIds.set(element, targetId);
989
+ if (binding)
990
+ this.navigationTargetBindings.set(element, binding);
991
+ else
992
+ this.navigationTargetBindings.delete(element);
993
+ const target = {
994
+ targetId,
995
+ revision,
996
+ ...targetIdentity,
997
+ };
814
998
  targetValues.push(target);
815
999
  nextTargets.set(targetId, { element, revision, options: optionMap, target });
816
1000
  }
@@ -1015,8 +1199,7 @@ export class PageContextCollector {
1015
1199
  const sensitivity = sensitivityFor(element, nameFor(element));
1016
1200
  const canRevealDesiredStateTarget = grant.action === 'click' &&
1017
1201
  grant.desiredChecked !== undefined &&
1018
- element instanceof HTMLInputElement &&
1019
- ['checkbox', 'radio'].includes(element.type);
1202
+ checkedStateFor(element) !== undefined;
1020
1203
  if (sensitivity !== 'none' ||
1021
1204
  handle.target.protectedRegion !== false ||
1022
1205
  !isRendered(element) ||
@@ -1123,6 +1306,7 @@ export class PageContextCollector {
1123
1306
  const pressed = attached
1124
1307
  ? literalBooleanAttribute(element, 'aria-pressed')
1125
1308
  : undefined;
1309
+ const checked = attached ? checkedStateFor(element) : undefined;
1126
1310
  this.callbacks.onHighlight(attached ? element : null, 'success');
1127
1311
  return {
1128
1312
  ...base,
@@ -1144,9 +1328,7 @@ export class PageContextCollector {
1144
1328
  : grant.desiredExpanded !== undefined || grant.desiredPressed !== undefined
1145
1329
  ? 'The requested button state was applied.'
1146
1330
  : `${grant.action} executed on the approved ${roleFor(element)} target.`,
1147
- ...(element instanceof HTMLInputElement && ['checkbox', 'radio'].includes(element.type)
1148
- ? { checked: element.checked }
1149
- : {}),
1331
+ ...(checked !== undefined ? { checked } : {}),
1150
1332
  ...(this.statefulButtonActionProof && expanded !== undefined ? { expanded } : {}),
1151
1333
  ...(this.statefulButtonActionProof && pressed !== undefined ? { pressed } : {}),
1152
1334
  },
@@ -1210,11 +1392,15 @@ export class PageContextCollector {
1210
1392
  }
1211
1393
  const desiredStates = [];
1212
1394
  if (desiredChecked !== undefined) {
1213
- if (!(element instanceof HTMLInputElement) || !['checkbox', 'radio'].includes(element.type)) {
1395
+ const checked = checkedStateFor(element);
1396
+ if (checked === undefined) {
1214
1397
  throw new Error('Desired checked state requires a checkbox or radio target.');
1215
1398
  }
1216
- desiredStates.push(element.checked === desiredChecked);
1217
- if (element.type === 'radio' && !desiredChecked && element.checked !== desiredChecked) {
1399
+ desiredStates.push(checked === desiredChecked);
1400
+ if (element instanceof HTMLInputElement &&
1401
+ element.type === 'radio' &&
1402
+ !desiredChecked &&
1403
+ element.checked !== desiredChecked) {
1218
1404
  throw new Error('A radio target cannot be cleared by clicking it.');
1219
1405
  }
1220
1406
  }
@@ -1234,6 +1420,10 @@ export class PageContextCollector {
1234
1420
  }
1235
1421
  if (desiredStates.length > 0 && desiredStates.every(Boolean))
1236
1422
  return;
1423
+ if (desiredChecked !== undefined && framerToggleDescriptor(element)) {
1424
+ dispatchFramerTogglePrimaryPointer(element);
1425
+ return;
1426
+ }
1237
1427
  if (element instanceof HTMLAnchorElement) {
1238
1428
  const target = new URL(element.href, window.location.href);
1239
1429
  if (expectedDestinationPath !== undefined &&
@@ -1352,18 +1542,14 @@ export class PageContextCollector {
1352
1542
  disabled: !enabled(element),
1353
1543
  expanded: element.getAttribute('aria-expanded'),
1354
1544
  pressed: element.getAttribute('aria-pressed'),
1355
- checked: element instanceof HTMLInputElement && ['checkbox', 'radio'].includes(element.type)
1356
- ? element.checked
1357
- : undefined,
1545
+ checked: checkedStateFor(element),
1358
1546
  selectedIndex: element instanceof HTMLSelectElement ? element.selectedIndex : undefined,
1359
1547
  path: window.location.pathname,
1360
1548
  });
1361
1549
  }
1362
1550
  actionApplied(grant, element, handle) {
1363
1551
  if (grant.desiredChecked !== undefined) {
1364
- return (element instanceof HTMLInputElement &&
1365
- ['checkbox', 'radio'].includes(element.type) &&
1366
- element.checked === grant.desiredChecked);
1552
+ return checkedStateFor(element) === grant.desiredChecked;
1367
1553
  }
1368
1554
  if (grant.desiredExpanded !== undefined &&
1369
1555
  literalBooleanAttribute(element, 'aria-expanded') !== grant.desiredExpanded) {
@@ -1518,6 +1704,7 @@ export class PageContextCollector {
1518
1704
  this.pageId = id('page');
1519
1705
  this.revision += 1;
1520
1706
  this.targets.clear();
1707
+ this.resetBoundTargetIds();
1521
1708
  this.recentSelection = null;
1522
1709
  this.pendingNavigation = {
1523
1710
  pageId: this.pageId,
@@ -1537,6 +1724,10 @@ export class PageContextCollector {
1537
1724
  navigation.causalObservationReported = true;
1538
1725
  this.callbacks.onCausalNavigationObserved?.(navigation.pageId, navigation.revision, navigation.url, navigation.causalActionId);
1539
1726
  }
1727
+ resetBoundTargetIds() {
1728
+ this.targetIds = new WeakMap();
1729
+ this.navigationTargetBindings = new WeakMap();
1730
+ }
1540
1731
  installNavigationHooks() {
1541
1732
  this.originalPushState = history.pushState;
1542
1733
  this.originalReplaceState = history.replaceState;
package/lib/index.js CHANGED
@@ -12,8 +12,8 @@ export default function aiLiveAssist(options = {}) {
12
12
  if (document.querySelector('[data-oxvo-ai-live-assist-root]')) {
13
13
  return undefined;
14
14
  }
15
- if (!app.checkRequiredVersion?.('7.4.37')) {
16
- console.warn('OXVO AI Guide requires @oxvo/browser version 7.4.37 or newer.');
15
+ if (!app.checkRequiredVersion?.('7.4.49')) {
16
+ console.warn('OXVO AI Guide requires @oxvo/browser version 7.4.49 or newer.');
17
17
  return undefined;
18
18
  }
19
19
  const instance = new AiLiveAssist(app, options);
package/lib/media.js CHANGED
@@ -154,8 +154,9 @@ export class RealtimeMedia {
154
154
  switchToTextOnly() {
155
155
  this.revokeLocalAudioCapture();
156
156
  for (const sender of this.connection?.getSenders() ?? []) {
157
- if (sender.track?.kind === "audio")
158
- void sender.replaceTrack(null);
157
+ if (sender.track?.kind === "audio") {
158
+ void sender.replaceTrack(null).catch(() => undefined);
159
+ }
159
160
  }
160
161
  }
161
162
  close() {
package/lib/preview.d.ts CHANGED
@@ -2,7 +2,7 @@ import type { AiGuidePreviewBridge, AiGuidePreviewController, AiGuidePreviewCont
2
2
  export declare const AI_GUIDE_PREVIEW_PARENT_SOURCE = "oxvo-ai-guide-settings-preview";
3
3
  export declare const AI_GUIDE_PREVIEW_WIDGET_SOURCE = "oxvo-ai-guide-widget-preview";
4
4
  export declare const AI_GUIDE_PREVIEW_PROTOCOL_VERSION = 1;
5
- export declare const AI_GUIDE_PREVIEW_RENDERER_VERSION = "1.0.36";
5
+ export declare const AI_GUIDE_PREVIEW_RENDERER_VERSION = "1.0.48";
6
6
  export declare const buildAiGuidePreviewBootstrap: (draft: unknown, assetOrigin?: string | null) => BootstrapConfig;
7
7
  export declare class AiGuidePreviewControllerImpl implements AiGuidePreviewController {
8
8
  private readonly port;
package/lib/preview.js CHANGED
@@ -6,7 +6,7 @@ import { VoicePresenceView } from "./voicePresenceUi.js";
6
6
  export const AI_GUIDE_PREVIEW_PARENT_SOURCE = "oxvo-ai-guide-settings-preview";
7
7
  export const AI_GUIDE_PREVIEW_WIDGET_SOURCE = "oxvo-ai-guide-widget-preview";
8
8
  export const AI_GUIDE_PREVIEW_PROTOCOL_VERSION = 1;
9
- export const AI_GUIDE_PREVIEW_RENDERER_VERSION = "1.0.36";
9
+ export const AI_GUIDE_PREVIEW_RENDERER_VERSION = "1.0.48";
10
10
  const DEFAULT_COMPANION = {
11
11
  enabled: true,
12
12
  title: "AI Guide",
@@ -266,6 +266,7 @@ export const buildAiGuidePreviewBootstrap = (draft, assetOrigin = typeof window
266
266
  customDisclosureEnabled,
267
267
  welcomeMessage: boundedNullableString(source.welcomeMessage, 1000),
268
268
  conversationStartersEnabled: booleanValue(appearance.conversationStartersEnabled, true),
269
+ compactEntryEnabled: booleanValue(appearance.compactEntryEnabled, false),
269
270
  suggestedPrompts: boundedStringList(appearance.suggestedPrompts, 5),
270
271
  proactiveEngagement: {
271
272
  enabled: booleanValue(proactive.enabled, false),
package/lib/types.d.ts CHANGED
@@ -189,6 +189,7 @@ export type BootstrapConfig = {
189
189
  customDisclosureEnabled?: boolean;
190
190
  welcomeMessage: string | null;
191
191
  conversationStartersEnabled?: boolean;
192
+ compactEntryEnabled?: boolean;
192
193
  suggestedPrompts?: string[];
193
194
  proactiveEngagement?: ProactiveEngagementConfig;
194
195
  voicePresence?: VoicePresenceConfig;
package/lib/ui.d.ts CHANGED
@@ -96,6 +96,7 @@ export declare class WidgetView {
96
96
  private currentHandoffContextRequest;
97
97
  private handoffRequestPreparing;
98
98
  private currentPageAssistanceRequest;
99
+ private pageAssistancePresentationSnapshot;
99
100
  private safetyInteractionIdentity;
100
101
  private introComposing;
101
102
  private legalOpenedPanel;
@@ -110,6 +111,7 @@ export declare class WidgetView {
110
111
  private tooltipTarget;
111
112
  private tooltipTimer;
112
113
  private ambientHideTimer;
114
+ private voiceCardEffectSettleTimer;
113
115
  private attributionTimer;
114
116
  private feedbackExitTimer;
115
117
  private assistantReadyVisualTimer;
@@ -155,6 +157,7 @@ export declare class WidgetView {
155
157
  setRemoteStream(stream: MediaStream): void;
156
158
  private playRemoteAudio;
157
159
  private invalidateRemotePlayback;
160
+ private pauseRemotePlayback;
158
161
  private resetRemotePlayback;
159
162
  private onPlaybackActivation;
160
163
  private playbackEventIsCurrent;
@@ -167,6 +170,10 @@ export declare class WidgetView {
167
170
  updatePreviewConfig(config: BootstrapConfig): boolean;
168
171
  private disablePreviewNavigation;
169
172
  private applyActivity;
173
+ private effectActivityIsBusy;
174
+ private beginVoiceCardEffectSettle;
175
+ private clearVoiceCardEffectSettle;
176
+ private voiceCardEffectElements;
170
177
  private effectsCanRun;
171
178
  private isReducedMotionRequested;
172
179
  private syncEffectMotion;
@@ -228,6 +235,7 @@ export declare class WidgetView {
228
235
  dismissHandoffContextRequest(): void;
229
236
  showHandoffContextResult(status: HandoffContextStatus): void;
230
237
  showPageAssistanceRequest(value: PageAssistanceRequest): void;
238
+ private syncPageAssistancePresentation;
231
239
  private syncPageAssistanceFooter;
232
240
  dismissPageAssistanceRequest(): void;
233
241
  setPageAssistancePersistentAllowed(value: boolean): void;
@@ -356,6 +364,7 @@ export declare class WidgetView {
356
364
  private removeStoredPanelVisibility;
357
365
  private clearPanelSessionState;
358
366
  private syncLauncherState;
367
+ private compactEntryEnabled;
359
368
  cancelPendingConfirmation(): boolean;
360
369
  resolvePendingConfirmation(approved: boolean, expected?: {
361
370
  actionId: string;