@cuekit-ai/react 1.3.0 → 1.3.1
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.
|
@@ -22668,7 +22668,7 @@ var setWebRTCConnectionState = (state) => {
|
|
|
22668
22668
|
};
|
|
22669
22669
|
|
|
22670
22670
|
// src/constants/index.ts
|
|
22671
|
-
var WEBRTC_BACKEND_SERVER_URL = "https://api-webrtc-dev.
|
|
22671
|
+
var WEBRTC_BACKEND_SERVER_URL = "https://api-webrtc-dev.ansyr.ai";
|
|
22672
22672
|
|
|
22673
22673
|
// src/utils/jsx-encoder.ts
|
|
22674
22674
|
function generateStableDOMId(element) {
|
|
@@ -22713,88 +22713,6 @@ function getElementPath(element) {
|
|
|
22713
22713
|
return "not_found";
|
|
22714
22714
|
}
|
|
22715
22715
|
|
|
22716
|
-
// src/utils/patch-react.ts
|
|
22717
|
-
function getImmediateText(element) {
|
|
22718
|
-
let text = "";
|
|
22719
|
-
if (element.childNodes) {
|
|
22720
|
-
for (const node of Array.from(element.childNodes)) {
|
|
22721
|
-
if (node.nodeType === 3) {
|
|
22722
|
-
text += node.textContent || "";
|
|
22723
|
-
}
|
|
22724
|
-
}
|
|
22725
|
-
}
|
|
22726
|
-
return text.trim();
|
|
22727
|
-
}
|
|
22728
|
-
function captureFullDOMStructure() {
|
|
22729
|
-
console.log("\u{1F333} Capturing full DOM structure...");
|
|
22730
|
-
const components = [];
|
|
22731
|
-
const interactiveElements = document.querySelectorAll(
|
|
22732
|
-
'a, button, input, textarea, select, [role="button"], [onclick]'
|
|
22733
|
-
);
|
|
22734
|
-
interactiveElements.forEach((element) => {
|
|
22735
|
-
if (element instanceof HTMLElement && !element.closest("[data-cuekit-ignore]")) {
|
|
22736
|
-
const nodeData = buildFlatDOMNode(element);
|
|
22737
|
-
if (nodeData) {
|
|
22738
|
-
components.push(nodeData);
|
|
22739
|
-
}
|
|
22740
|
-
}
|
|
22741
|
-
});
|
|
22742
|
-
const result = { components };
|
|
22743
|
-
console.log("\u{1F333} Full DOM structure captured:", result);
|
|
22744
|
-
return result;
|
|
22745
|
-
}
|
|
22746
|
-
function buildFlatDOMNode(element) {
|
|
22747
|
-
if (element.tagName.toLowerCase() === "script" || element.hasAttribute("data-cuekit-ignore") || element.style.display === "none" || element.style.visibility === "hidden") {
|
|
22748
|
-
return null;
|
|
22749
|
-
}
|
|
22750
|
-
const hash = generateStableDOMId(element);
|
|
22751
|
-
const text = getImmediateText(element).substring(0, 100);
|
|
22752
|
-
const isClickable = isElementClickable(element);
|
|
22753
|
-
const componentType = element.tagName.toLowerCase();
|
|
22754
|
-
return {
|
|
22755
|
-
hash,
|
|
22756
|
-
text,
|
|
22757
|
-
isClickable,
|
|
22758
|
-
componentType,
|
|
22759
|
-
children: []
|
|
22760
|
-
// No children in a flat structure
|
|
22761
|
-
};
|
|
22762
|
-
}
|
|
22763
|
-
function isElementClickable(element) {
|
|
22764
|
-
const interactiveSelectors = [
|
|
22765
|
-
"button",
|
|
22766
|
-
"a",
|
|
22767
|
-
"input",
|
|
22768
|
-
"select",
|
|
22769
|
-
"textarea",
|
|
22770
|
-
'[role="button"]',
|
|
22771
|
-
'[role="link"]',
|
|
22772
|
-
'[role="tab"]',
|
|
22773
|
-
"[data-onclick-id]",
|
|
22774
|
-
"[data-on-press-id]",
|
|
22775
|
-
"[onclick]",
|
|
22776
|
-
"[onmousedown]",
|
|
22777
|
-
"[onmouseup]",
|
|
22778
|
-
"[ontouchstart]",
|
|
22779
|
-
"[ontouchend]",
|
|
22780
|
-
"[onkeydown]",
|
|
22781
|
-
"[onkeyup]",
|
|
22782
|
-
"[onkeypress]"
|
|
22783
|
-
];
|
|
22784
|
-
for (const selector of interactiveSelectors) {
|
|
22785
|
-
if (element.matches(selector)) {
|
|
22786
|
-
return true;
|
|
22787
|
-
}
|
|
22788
|
-
}
|
|
22789
|
-
const hasClickEvents = element.onclick !== null || element.getAttribute("onclick") !== null;
|
|
22790
|
-
const hasInteractiveEvents = element.ontouchstart !== null || element.getAttribute("ontouchstart") !== null || element.ontouchend !== null || element.getAttribute("ontouchend") !== null || element.onkeydown !== null || element.getAttribute("onkeydown") !== null || element.onkeyup !== null || element.getAttribute("onkeyup") !== null || element.onkeypress !== null || element.getAttribute("onkeypress") !== null;
|
|
22791
|
-
const hasPointerCursor = element.style.cursor === "pointer" || getComputedStyle(element).cursor === "pointer";
|
|
22792
|
-
const hasTabIndex = element.hasAttribute("tabindex") && parseInt(element.getAttribute("tabindex") || "0") >= 0;
|
|
22793
|
-
const hasInteractiveDataAttrs = element.hasAttribute("data-clickable") || element.hasAttribute("data-interactive") || element.hasAttribute("data-action") || element.hasAttribute("data-handler");
|
|
22794
|
-
const hasInteractiveAria = element.hasAttribute("aria-pressed") || element.hasAttribute("aria-expanded") || element.hasAttribute("aria-selected") || element.hasAttribute("aria-checked");
|
|
22795
|
-
return hasClickEvents || hasInteractiveEvents || hasPointerCursor || hasTabIndex || hasInteractiveDataAttrs || hasInteractiveAria;
|
|
22796
|
-
}
|
|
22797
|
-
|
|
22798
22716
|
// src/core/intent-store.ts
|
|
22799
22717
|
var store = {
|
|
22800
22718
|
screenMetadata: {},
|
|
@@ -22994,6 +22912,213 @@ function getElementPath2(element) {
|
|
|
22994
22912
|
return path.join("/");
|
|
22995
22913
|
}
|
|
22996
22914
|
|
|
22915
|
+
// src/utils/element-service.ts
|
|
22916
|
+
var INTERACTIVE_ELEMENT_SELECTOR = 'a, button, input, textarea, select, [role="button"], [onclick]';
|
|
22917
|
+
function getInteractiveElements() {
|
|
22918
|
+
return document.querySelectorAll(INTERACTIVE_ELEMENT_SELECTOR);
|
|
22919
|
+
}
|
|
22920
|
+
function getImmediateText(element) {
|
|
22921
|
+
let text = "";
|
|
22922
|
+
if (element.childNodes) {
|
|
22923
|
+
for (const node of Array.from(element.childNodes)) {
|
|
22924
|
+
if (node.nodeType === 3) {
|
|
22925
|
+
text += node.textContent || "";
|
|
22926
|
+
}
|
|
22927
|
+
}
|
|
22928
|
+
}
|
|
22929
|
+
return text.trim();
|
|
22930
|
+
}
|
|
22931
|
+
function captureFullDOMStructure() {
|
|
22932
|
+
console.log("\u{1F333} Capturing full DOM structure...");
|
|
22933
|
+
const components = [];
|
|
22934
|
+
const interactiveElements = getInteractiveElements();
|
|
22935
|
+
interactiveElements.forEach((element) => {
|
|
22936
|
+
if (element instanceof HTMLElement && !element.closest("[data-cuekit-ignore]")) {
|
|
22937
|
+
const nodeData = buildFlatDOMNode(element);
|
|
22938
|
+
if (nodeData) {
|
|
22939
|
+
components.push(nodeData);
|
|
22940
|
+
}
|
|
22941
|
+
}
|
|
22942
|
+
});
|
|
22943
|
+
const result = { components };
|
|
22944
|
+
console.log("\u{1F333} Full DOM structure captured:", result);
|
|
22945
|
+
return result;
|
|
22946
|
+
}
|
|
22947
|
+
function buildFlatDOMNode(element) {
|
|
22948
|
+
if (element.tagName.toLowerCase() === "script" || element.hasAttribute("data-cuekit-ignore") || element.style.display === "none" || element.style.visibility === "hidden") {
|
|
22949
|
+
return null;
|
|
22950
|
+
}
|
|
22951
|
+
const hash = generateStableDOMId(element);
|
|
22952
|
+
const text = getImmediateText(element).substring(0, 100);
|
|
22953
|
+
const isClickable = isElementClickable(element);
|
|
22954
|
+
const componentType = element.tagName.toLowerCase();
|
|
22955
|
+
return {
|
|
22956
|
+
hash,
|
|
22957
|
+
text,
|
|
22958
|
+
isClickable,
|
|
22959
|
+
componentType,
|
|
22960
|
+
children: []
|
|
22961
|
+
// No children in a flat structure
|
|
22962
|
+
};
|
|
22963
|
+
}
|
|
22964
|
+
function isElementClickable(element) {
|
|
22965
|
+
const interactiveSelectors = [
|
|
22966
|
+
"button",
|
|
22967
|
+
"a",
|
|
22968
|
+
"input",
|
|
22969
|
+
"select",
|
|
22970
|
+
"textarea",
|
|
22971
|
+
'[role="button"]',
|
|
22972
|
+
'[role="link"]',
|
|
22973
|
+
'[role="tab"]',
|
|
22974
|
+
"[data-onclick-id]",
|
|
22975
|
+
"[data-on-press-id]",
|
|
22976
|
+
"[onclick]",
|
|
22977
|
+
"[onmousedown]",
|
|
22978
|
+
"[onmouseup]",
|
|
22979
|
+
"[ontouchstart]",
|
|
22980
|
+
"[ontouchend]",
|
|
22981
|
+
"[onkeydown]",
|
|
22982
|
+
"[onkeyup]",
|
|
22983
|
+
"[onkeypress]"
|
|
22984
|
+
];
|
|
22985
|
+
for (const selector of interactiveSelectors) {
|
|
22986
|
+
if (element.matches(selector)) {
|
|
22987
|
+
return true;
|
|
22988
|
+
}
|
|
22989
|
+
}
|
|
22990
|
+
const hasClickEvents = element.onclick !== null || element.getAttribute("onclick") !== null;
|
|
22991
|
+
const hasInteractiveEvents = element.ontouchstart !== null || element.getAttribute("ontouchstart") !== null || element.ontouchend !== null || element.getAttribute("ontouchend") !== null || element.onkeydown !== null || element.getAttribute("onkeydown") !== null || element.onkeyup !== null || element.getAttribute("onkeyup") !== null || element.onkeypress !== null || element.getAttribute("onkeypress") !== null;
|
|
22992
|
+
const hasPointerCursor = element.style.cursor === "pointer" || getComputedStyle(element).cursor === "pointer";
|
|
22993
|
+
const hasTabIndex = element.hasAttribute("tabindex") && parseInt(element.getAttribute("tabindex") || "0") >= 0;
|
|
22994
|
+
const hasInteractiveDataAttrs = element.hasAttribute("data-clickable") || element.hasAttribute("data-interactive") || element.hasAttribute("data-action") || element.hasAttribute("data-handler");
|
|
22995
|
+
const hasInteractiveAria = element.hasAttribute("aria-pressed") || element.hasAttribute("aria-expanded") || element.hasAttribute("aria-selected") || element.hasAttribute("aria-checked");
|
|
22996
|
+
return hasClickEvents || hasInteractiveEvents || hasPointerCursor || hasTabIndex || hasInteractiveDataAttrs || hasInteractiveAria;
|
|
22997
|
+
}
|
|
22998
|
+
function executeAction(action) {
|
|
22999
|
+
console.log("\u{1F3AF} Executing element action:", action);
|
|
23000
|
+
const { action_type, target_element, target } = action;
|
|
23001
|
+
switch (action_type) {
|
|
23002
|
+
case "click":
|
|
23003
|
+
return clickElement(target_element);
|
|
23004
|
+
case "navigate":
|
|
23005
|
+
return navigateToElement(target_element || target);
|
|
23006
|
+
case "input":
|
|
23007
|
+
case "focus":
|
|
23008
|
+
return focusElement(target_element);
|
|
23009
|
+
case "toggle":
|
|
23010
|
+
return toggleElement(target_element);
|
|
23011
|
+
default:
|
|
23012
|
+
console.warn(`\u26A0\uFE0F Unknown action type: ${action_type}`);
|
|
23013
|
+
return false;
|
|
23014
|
+
}
|
|
23015
|
+
}
|
|
23016
|
+
function getFullDOMStructure() {
|
|
23017
|
+
console.log("\u{1F333} ElementService: Getting full DOM structure...");
|
|
23018
|
+
return captureFullDOMStructure();
|
|
23019
|
+
}
|
|
23020
|
+
function clickElement(elementId) {
|
|
23021
|
+
if (!elementId) {
|
|
23022
|
+
console.warn("\u26A0\uFE0F No element ID provided for click action");
|
|
23023
|
+
return false;
|
|
23024
|
+
}
|
|
23025
|
+
const domStructure = getFullDOMStructure();
|
|
23026
|
+
const elementToClick = findElementById(domStructure, elementId);
|
|
23027
|
+
if (elementToClick) {
|
|
23028
|
+
console.log(`\u{1F3AF} Clicking element: ${elementId}`);
|
|
23029
|
+
const domElement = findDOMElementById(elementId);
|
|
23030
|
+
if (domElement) {
|
|
23031
|
+
domElement.click();
|
|
23032
|
+
return true;
|
|
23033
|
+
}
|
|
23034
|
+
} else {
|
|
23035
|
+
console.warn(`\u26A0\uFE0F Element not found: ${elementId}`);
|
|
23036
|
+
}
|
|
23037
|
+
return false;
|
|
23038
|
+
}
|
|
23039
|
+
function navigateToElement(target) {
|
|
23040
|
+
if (!target) {
|
|
23041
|
+
console.warn("\u26A0\uFE0F No target provided for navigation action");
|
|
23042
|
+
return false;
|
|
23043
|
+
}
|
|
23044
|
+
console.log(`\u{1F9ED} Navigating to: ${target}`);
|
|
23045
|
+
if (target.includes("/") || target.startsWith("http")) {
|
|
23046
|
+
safeNavigate(target, {});
|
|
23047
|
+
} else {
|
|
23048
|
+
handleNavigationAndClick(target, target);
|
|
23049
|
+
}
|
|
23050
|
+
return true;
|
|
23051
|
+
}
|
|
23052
|
+
function focusElement(elementId) {
|
|
23053
|
+
if (!elementId) {
|
|
23054
|
+
console.warn("\u26A0\uFE0F No element ID provided for focus action");
|
|
23055
|
+
return false;
|
|
23056
|
+
}
|
|
23057
|
+
const domElement = findDOMElementById(elementId);
|
|
23058
|
+
if (domElement instanceof HTMLInputElement || domElement instanceof HTMLTextAreaElement || domElement instanceof HTMLSelectElement) {
|
|
23059
|
+
console.log(`\u{1F4DD} Focusing element: ${elementId}`);
|
|
23060
|
+
domElement.focus();
|
|
23061
|
+
return true;
|
|
23062
|
+
} else {
|
|
23063
|
+
console.warn(`\u26A0\uFE0F Focusable element not found: ${elementId}`);
|
|
23064
|
+
return false;
|
|
23065
|
+
}
|
|
23066
|
+
}
|
|
23067
|
+
function toggleElement(elementId) {
|
|
23068
|
+
if (!elementId) {
|
|
23069
|
+
console.warn("\u26A0\uFE0F No element ID provided for toggle action");
|
|
23070
|
+
return false;
|
|
23071
|
+
}
|
|
23072
|
+
const domElement = findDOMElementById(elementId);
|
|
23073
|
+
if (domElement instanceof HTMLElement) {
|
|
23074
|
+
console.log(`\u{1F504} Toggling element: ${elementId}`);
|
|
23075
|
+
if (domElement instanceof HTMLInputElement) {
|
|
23076
|
+
if (domElement.type === "checkbox") {
|
|
23077
|
+
domElement.checked = !domElement.checked;
|
|
23078
|
+
} else if (domElement.type === "radio") {
|
|
23079
|
+
domElement.checked = true;
|
|
23080
|
+
}
|
|
23081
|
+
domElement.dispatchEvent(new Event("change", { bubbles: true }));
|
|
23082
|
+
} else {
|
|
23083
|
+
domElement.click();
|
|
23084
|
+
}
|
|
23085
|
+
return true;
|
|
23086
|
+
} else {
|
|
23087
|
+
console.warn(`\u26A0\uFE0F Toggleable element not found: ${elementId}`);
|
|
23088
|
+
return false;
|
|
23089
|
+
}
|
|
23090
|
+
}
|
|
23091
|
+
function findElementById(domStructure, elementId) {
|
|
23092
|
+
const searchInComponents = (components) => {
|
|
23093
|
+
for (const component of components) {
|
|
23094
|
+
if (component.hash === elementId) {
|
|
23095
|
+
return component;
|
|
23096
|
+
}
|
|
23097
|
+
if (component.children.length > 0) {
|
|
23098
|
+
const found = searchInComponents(component.children);
|
|
23099
|
+
if (found) return found;
|
|
23100
|
+
}
|
|
23101
|
+
}
|
|
23102
|
+
return null;
|
|
23103
|
+
};
|
|
23104
|
+
return searchInComponents(domStructure.components);
|
|
23105
|
+
}
|
|
23106
|
+
function findDOMElementById(elementId) {
|
|
23107
|
+
const interactiveElements = getInteractiveElements();
|
|
23108
|
+
for (const element of interactiveElements) {
|
|
23109
|
+
if (element instanceof HTMLElement) {
|
|
23110
|
+
console.log("\u{1F50D} Checking element:", element);
|
|
23111
|
+
const hash = generateStableDOMId(element);
|
|
23112
|
+
console.log("\u{1F50D} Generated hash:", hash);
|
|
23113
|
+
if (hash === elementId) {
|
|
23114
|
+
console.log("\u{1F50D} Found element:", element);
|
|
23115
|
+
return element;
|
|
23116
|
+
}
|
|
23117
|
+
}
|
|
23118
|
+
}
|
|
23119
|
+
return null;
|
|
23120
|
+
}
|
|
23121
|
+
|
|
22997
23122
|
// src/utils/webrtc-service.ts
|
|
22998
23123
|
var room = null;
|
|
22999
23124
|
var reconnectTimeout = null;
|
|
@@ -23115,8 +23240,10 @@ function setupEventListeners() {
|
|
|
23115
23240
|
}).on(RoomEvent.TrackUnsubscribed, (track) => {
|
|
23116
23241
|
track.detach().forEach((element) => element.remove());
|
|
23117
23242
|
}).on(RoomEvent.DataReceived, (payload, participant) => {
|
|
23243
|
+
console.log("\u{1F4E1} LiveKit data received:", new TextDecoder().decode(payload));
|
|
23118
23244
|
try {
|
|
23119
23245
|
const message = JSON.parse(new TextDecoder().decode(payload));
|
|
23246
|
+
console.log("\u{1F4E1} LiveKit data received:", message);
|
|
23120
23247
|
callbacks.onNavigationCommand?.(message);
|
|
23121
23248
|
} catch (error) {
|
|
23122
23249
|
const message = new TextDecoder().decode(payload);
|
|
@@ -23138,6 +23265,7 @@ function updateParticipantsList() {
|
|
|
23138
23265
|
async function sendData(data, reliable = true) {
|
|
23139
23266
|
if (!room) throw new Error("Not connected to room");
|
|
23140
23267
|
try {
|
|
23268
|
+
console.log("\u{1F4E1} LiveKit data sending:", data);
|
|
23141
23269
|
const encoder = new TextEncoder();
|
|
23142
23270
|
const encodedData = encoder.encode(data);
|
|
23143
23271
|
await room.localParticipant.publishData(encodedData, {
|
|
@@ -23171,6 +23299,7 @@ function getParticipants() {
|
|
|
23171
23299
|
}
|
|
23172
23300
|
async function sendUserCommand(command) {
|
|
23173
23301
|
if (!room) return;
|
|
23302
|
+
console.log(`\u{1F4AC} Sending user command: "${command}"`);
|
|
23174
23303
|
await sendData(command);
|
|
23175
23304
|
}
|
|
23176
23305
|
async function sendRuntimeData() {
|
|
@@ -23188,6 +23317,7 @@ async function sendRuntimeData() {
|
|
|
23188
23317
|
current_screen: screenName
|
|
23189
23318
|
}
|
|
23190
23319
|
};
|
|
23320
|
+
console.log("\u{1F4E6} Sending runtime data response");
|
|
23191
23321
|
await sendData(JSON.stringify(response));
|
|
23192
23322
|
console.log("\u{1F4E6} Runtime data sent successfully");
|
|
23193
23323
|
} catch (error) {
|
|
@@ -23248,9 +23378,7 @@ export {
|
|
|
23248
23378
|
setWebRTCConfig,
|
|
23249
23379
|
GlobalStore,
|
|
23250
23380
|
setNavigationHandler,
|
|
23251
|
-
safeNavigate,
|
|
23252
23381
|
onStateChange,
|
|
23253
|
-
handleNavigationAndClick,
|
|
23254
23382
|
WEBRTC_BACKEND_SERVER_URL,
|
|
23255
23383
|
RoomEvent,
|
|
23256
23384
|
ParticipantEvent,
|
|
@@ -23259,6 +23387,8 @@ export {
|
|
|
23259
23387
|
Participant,
|
|
23260
23388
|
ConnectionState,
|
|
23261
23389
|
captureFullDOMStructure,
|
|
23390
|
+
executeAction,
|
|
23391
|
+
getFullDOMStructure,
|
|
23262
23392
|
setServerUrl,
|
|
23263
23393
|
setAudioContainer,
|
|
23264
23394
|
setWebRTCCallbacks,
|
package/dist/index.d.mts
CHANGED
|
@@ -265,6 +265,10 @@ type FullDOMStructure = {
|
|
|
265
265
|
components: DOMNodeData[];
|
|
266
266
|
};
|
|
267
267
|
|
|
268
|
+
/**
|
|
269
|
+
* Capture the full DOM structure as a flat list of interactive elements
|
|
270
|
+
*/
|
|
271
|
+
declare function captureFullDOMStructure(): FullDOMStructure;
|
|
268
272
|
interface ElementAction {
|
|
269
273
|
action_type: 'click' | 'navigate' | 'input' | 'focus' | 'toggle';
|
|
270
274
|
target_element?: string;
|
|
@@ -274,9 +278,4 @@ interface ElementAction {
|
|
|
274
278
|
declare function executeAction(action: ElementAction): boolean;
|
|
275
279
|
declare function getFullDOMStructure(): FullDOMStructure;
|
|
276
280
|
|
|
277
|
-
/**
|
|
278
|
-
* Capture the full DOM structure as a flat list of interactive elements
|
|
279
|
-
*/
|
|
280
|
-
declare function captureFullDOMStructure(): FullDOMStructure;
|
|
281
|
-
|
|
282
281
|
export { BorderGlow, ChatPopup, type ChatPopupProps, CuekitProvider, type DOMNodeData, type ElementAction, type FullDOMStructure, InitCuekit, MicButton, type MicButtonProps, type MicState$1 as MicState, type NavigationCommand, type ServerConfig, type TokenRequest, type TokenResponse, VoiceIntensityVisualizer, type WebRTCServerConfig, captureFullDOMStructure, configureWebRTCServer, executeAction, getFullDOMStructure, getWebRTCServerConfig, initWebRTC, initWebRTCWithDeployedBackend, useCuekit, useQubeContext, useWebRTC };
|
package/dist/index.d.ts
CHANGED
|
@@ -265,6 +265,10 @@ type FullDOMStructure = {
|
|
|
265
265
|
components: DOMNodeData[];
|
|
266
266
|
};
|
|
267
267
|
|
|
268
|
+
/**
|
|
269
|
+
* Capture the full DOM structure as a flat list of interactive elements
|
|
270
|
+
*/
|
|
271
|
+
declare function captureFullDOMStructure(): FullDOMStructure;
|
|
268
272
|
interface ElementAction {
|
|
269
273
|
action_type: 'click' | 'navigate' | 'input' | 'focus' | 'toggle';
|
|
270
274
|
target_element?: string;
|
|
@@ -274,9 +278,4 @@ interface ElementAction {
|
|
|
274
278
|
declare function executeAction(action: ElementAction): boolean;
|
|
275
279
|
declare function getFullDOMStructure(): FullDOMStructure;
|
|
276
280
|
|
|
277
|
-
/**
|
|
278
|
-
* Capture the full DOM structure as a flat list of interactive elements
|
|
279
|
-
*/
|
|
280
|
-
declare function captureFullDOMStructure(): FullDOMStructure;
|
|
281
|
-
|
|
282
281
|
export { BorderGlow, ChatPopup, type ChatPopupProps, CuekitProvider, type DOMNodeData, type ElementAction, type FullDOMStructure, InitCuekit, MicButton, type MicButtonProps, type MicState$1 as MicState, type NavigationCommand, type ServerConfig, type TokenRequest, type TokenResponse, VoiceIntensityVisualizer, type WebRTCServerConfig, captureFullDOMStructure, configureWebRTCServer, executeAction, getFullDOMStructure, getWebRTCServerConfig, initWebRTC, initWebRTCWithDeployedBackend, useCuekit, useQubeContext, useWebRTC };
|
package/dist/index.js
CHANGED
|
@@ -271,7 +271,7 @@ var WEBRTC_BACKEND_SERVER_URL;
|
|
|
271
271
|
var init_constants = __esm({
|
|
272
272
|
"src/constants/index.ts"() {
|
|
273
273
|
"use strict";
|
|
274
|
-
WEBRTC_BACKEND_SERVER_URL = "https://api-webrtc-dev.
|
|
274
|
+
WEBRTC_BACKEND_SERVER_URL = "https://api-webrtc-dev.ansyr.ai";
|
|
275
275
|
}
|
|
276
276
|
});
|
|
277
277
|
|
|
@@ -22916,7 +22916,10 @@ var init_jsx_encoder = __esm({
|
|
|
22916
22916
|
}
|
|
22917
22917
|
});
|
|
22918
22918
|
|
|
22919
|
-
// src/utils/
|
|
22919
|
+
// src/utils/element-service.ts
|
|
22920
|
+
function getInteractiveElements() {
|
|
22921
|
+
return document.querySelectorAll(INTERACTIVE_ELEMENT_SELECTOR);
|
|
22922
|
+
}
|
|
22920
22923
|
function getImmediateText(element3) {
|
|
22921
22924
|
let text7 = "";
|
|
22922
22925
|
if (element3.childNodes) {
|
|
@@ -22931,9 +22934,7 @@ function getImmediateText(element3) {
|
|
|
22931
22934
|
function captureFullDOMStructure() {
|
|
22932
22935
|
console.log("\u{1F333} Capturing full DOM structure...");
|
|
22933
22936
|
const components = [];
|
|
22934
|
-
const interactiveElements =
|
|
22935
|
-
'a, button, input, textarea, select, [role="button"], [onclick]'
|
|
22936
|
-
);
|
|
22937
|
+
const interactiveElements = getInteractiveElements();
|
|
22937
22938
|
interactiveElements.forEach((element3) => {
|
|
22938
22939
|
if (element3 instanceof HTMLElement && !element3.closest("[data-cuekit-ignore]")) {
|
|
22939
22940
|
const nodeData = buildFlatDOMNode(element3);
|
|
@@ -22997,10 +22998,136 @@ function isElementClickable(element3) {
|
|
|
22997
22998
|
const hasInteractiveAria = element3.hasAttribute("aria-pressed") || element3.hasAttribute("aria-expanded") || element3.hasAttribute("aria-selected") || element3.hasAttribute("aria-checked");
|
|
22998
22999
|
return hasClickEvents || hasInteractiveEvents || hasPointerCursor || hasTabIndex || hasInteractiveDataAttrs || hasInteractiveAria;
|
|
22999
23000
|
}
|
|
23000
|
-
|
|
23001
|
-
|
|
23001
|
+
function executeAction(action) {
|
|
23002
|
+
console.log("\u{1F3AF} Executing element action:", action);
|
|
23003
|
+
const { action_type, target_element, target } = action;
|
|
23004
|
+
switch (action_type) {
|
|
23005
|
+
case "click":
|
|
23006
|
+
return clickElement(target_element);
|
|
23007
|
+
case "navigate":
|
|
23008
|
+
return navigateToElement(target_element || target);
|
|
23009
|
+
case "input":
|
|
23010
|
+
case "focus":
|
|
23011
|
+
return focusElement(target_element);
|
|
23012
|
+
case "toggle":
|
|
23013
|
+
return toggleElement(target_element);
|
|
23014
|
+
default:
|
|
23015
|
+
console.warn(`\u26A0\uFE0F Unknown action type: ${action_type}`);
|
|
23016
|
+
return false;
|
|
23017
|
+
}
|
|
23018
|
+
}
|
|
23019
|
+
function getFullDOMStructure() {
|
|
23020
|
+
console.log("\u{1F333} ElementService: Getting full DOM structure...");
|
|
23021
|
+
return captureFullDOMStructure();
|
|
23022
|
+
}
|
|
23023
|
+
function clickElement(elementId) {
|
|
23024
|
+
if (!elementId) {
|
|
23025
|
+
console.warn("\u26A0\uFE0F No element ID provided for click action");
|
|
23026
|
+
return false;
|
|
23027
|
+
}
|
|
23028
|
+
const domStructure = getFullDOMStructure();
|
|
23029
|
+
const elementToClick = findElementById(domStructure, elementId);
|
|
23030
|
+
if (elementToClick) {
|
|
23031
|
+
console.log(`\u{1F3AF} Clicking element: ${elementId}`);
|
|
23032
|
+
const domElement = findDOMElementById(elementId);
|
|
23033
|
+
if (domElement) {
|
|
23034
|
+
domElement.click();
|
|
23035
|
+
return true;
|
|
23036
|
+
}
|
|
23037
|
+
} else {
|
|
23038
|
+
console.warn(`\u26A0\uFE0F Element not found: ${elementId}`);
|
|
23039
|
+
}
|
|
23040
|
+
return false;
|
|
23041
|
+
}
|
|
23042
|
+
function navigateToElement(target) {
|
|
23043
|
+
if (!target) {
|
|
23044
|
+
console.warn("\u26A0\uFE0F No target provided for navigation action");
|
|
23045
|
+
return false;
|
|
23046
|
+
}
|
|
23047
|
+
console.log(`\u{1F9ED} Navigating to: ${target}`);
|
|
23048
|
+
if (target.includes("/") || target.startsWith("http")) {
|
|
23049
|
+
safeNavigate(target, {});
|
|
23050
|
+
} else {
|
|
23051
|
+
handleNavigationAndClick(target, target);
|
|
23052
|
+
}
|
|
23053
|
+
return true;
|
|
23054
|
+
}
|
|
23055
|
+
function focusElement(elementId) {
|
|
23056
|
+
if (!elementId) {
|
|
23057
|
+
console.warn("\u26A0\uFE0F No element ID provided for focus action");
|
|
23058
|
+
return false;
|
|
23059
|
+
}
|
|
23060
|
+
const domElement = findDOMElementById(elementId);
|
|
23061
|
+
if (domElement instanceof HTMLInputElement || domElement instanceof HTMLTextAreaElement || domElement instanceof HTMLSelectElement) {
|
|
23062
|
+
console.log(`\u{1F4DD} Focusing element: ${elementId}`);
|
|
23063
|
+
domElement.focus();
|
|
23064
|
+
return true;
|
|
23065
|
+
} else {
|
|
23066
|
+
console.warn(`\u26A0\uFE0F Focusable element not found: ${elementId}`);
|
|
23067
|
+
return false;
|
|
23068
|
+
}
|
|
23069
|
+
}
|
|
23070
|
+
function toggleElement(elementId) {
|
|
23071
|
+
if (!elementId) {
|
|
23072
|
+
console.warn("\u26A0\uFE0F No element ID provided for toggle action");
|
|
23073
|
+
return false;
|
|
23074
|
+
}
|
|
23075
|
+
const domElement = findDOMElementById(elementId);
|
|
23076
|
+
if (domElement instanceof HTMLElement) {
|
|
23077
|
+
console.log(`\u{1F504} Toggling element: ${elementId}`);
|
|
23078
|
+
if (domElement instanceof HTMLInputElement) {
|
|
23079
|
+
if (domElement.type === "checkbox") {
|
|
23080
|
+
domElement.checked = !domElement.checked;
|
|
23081
|
+
} else if (domElement.type === "radio") {
|
|
23082
|
+
domElement.checked = true;
|
|
23083
|
+
}
|
|
23084
|
+
domElement.dispatchEvent(new Event("change", { bubbles: true }));
|
|
23085
|
+
} else {
|
|
23086
|
+
domElement.click();
|
|
23087
|
+
}
|
|
23088
|
+
return true;
|
|
23089
|
+
} else {
|
|
23090
|
+
console.warn(`\u26A0\uFE0F Toggleable element not found: ${elementId}`);
|
|
23091
|
+
return false;
|
|
23092
|
+
}
|
|
23093
|
+
}
|
|
23094
|
+
function findElementById(domStructure, elementId) {
|
|
23095
|
+
const searchInComponents = (components) => {
|
|
23096
|
+
for (const component of components) {
|
|
23097
|
+
if (component.hash === elementId) {
|
|
23098
|
+
return component;
|
|
23099
|
+
}
|
|
23100
|
+
if (component.children.length > 0) {
|
|
23101
|
+
const found = searchInComponents(component.children);
|
|
23102
|
+
if (found) return found;
|
|
23103
|
+
}
|
|
23104
|
+
}
|
|
23105
|
+
return null;
|
|
23106
|
+
};
|
|
23107
|
+
return searchInComponents(domStructure.components);
|
|
23108
|
+
}
|
|
23109
|
+
function findDOMElementById(elementId) {
|
|
23110
|
+
const interactiveElements = getInteractiveElements();
|
|
23111
|
+
for (const element3 of interactiveElements) {
|
|
23112
|
+
if (element3 instanceof HTMLElement) {
|
|
23113
|
+
console.log("\u{1F50D} Checking element:", element3);
|
|
23114
|
+
const hash = generateStableDOMId(element3);
|
|
23115
|
+
console.log("\u{1F50D} Generated hash:", hash);
|
|
23116
|
+
if (hash === elementId) {
|
|
23117
|
+
console.log("\u{1F50D} Found element:", element3);
|
|
23118
|
+
return element3;
|
|
23119
|
+
}
|
|
23120
|
+
}
|
|
23121
|
+
}
|
|
23122
|
+
return null;
|
|
23123
|
+
}
|
|
23124
|
+
var INTERACTIVE_ELEMENT_SELECTOR;
|
|
23125
|
+
var init_element_service = __esm({
|
|
23126
|
+
"src/utils/element-service.ts"() {
|
|
23002
23127
|
"use strict";
|
|
23003
23128
|
init_jsx_encoder();
|
|
23129
|
+
init_navigation();
|
|
23130
|
+
INTERACTIVE_ELEMENT_SELECTOR = 'a, button, input, textarea, select, [role="button"], [onclick]';
|
|
23004
23131
|
}
|
|
23005
23132
|
});
|
|
23006
23133
|
|
|
@@ -23135,8 +23262,10 @@ function setupEventListeners() {
|
|
|
23135
23262
|
}).on(RoomEvent.TrackUnsubscribed, (track) => {
|
|
23136
23263
|
track.detach().forEach((element3) => element3.remove());
|
|
23137
23264
|
}).on(RoomEvent.DataReceived, (payload, participant) => {
|
|
23265
|
+
console.log("\u{1F4E1} LiveKit data received:", new TextDecoder().decode(payload));
|
|
23138
23266
|
try {
|
|
23139
23267
|
const message = JSON.parse(new TextDecoder().decode(payload));
|
|
23268
|
+
console.log("\u{1F4E1} LiveKit data received:", message);
|
|
23140
23269
|
callbacks.onNavigationCommand?.(message);
|
|
23141
23270
|
} catch (error) {
|
|
23142
23271
|
const message = new TextDecoder().decode(payload);
|
|
@@ -23158,6 +23287,7 @@ function updateParticipantsList() {
|
|
|
23158
23287
|
async function sendData(data, reliable = true) {
|
|
23159
23288
|
if (!room) throw new Error("Not connected to room");
|
|
23160
23289
|
try {
|
|
23290
|
+
console.log("\u{1F4E1} LiveKit data sending:", data);
|
|
23161
23291
|
const encoder = new TextEncoder();
|
|
23162
23292
|
const encodedData = encoder.encode(data);
|
|
23163
23293
|
await room.localParticipant.publishData(encodedData, {
|
|
@@ -23191,6 +23321,7 @@ function getParticipants() {
|
|
|
23191
23321
|
}
|
|
23192
23322
|
async function sendUserCommand(command) {
|
|
23193
23323
|
if (!room) return;
|
|
23324
|
+
console.log(`\u{1F4AC} Sending user command: "${command}"`);
|
|
23194
23325
|
await sendData(command);
|
|
23195
23326
|
}
|
|
23196
23327
|
async function sendRuntimeData() {
|
|
@@ -23208,6 +23339,7 @@ async function sendRuntimeData() {
|
|
|
23208
23339
|
current_screen: screenName
|
|
23209
23340
|
}
|
|
23210
23341
|
};
|
|
23342
|
+
console.log("\u{1F4E6} Sending runtime data response");
|
|
23211
23343
|
await sendData(JSON.stringify(response));
|
|
23212
23344
|
console.log("\u{1F4E6} Runtime data sent successfully");
|
|
23213
23345
|
} catch (error) {
|
|
@@ -23263,7 +23395,7 @@ var init_webrtc_service = __esm({
|
|
|
23263
23395
|
init_livekit_client_esm();
|
|
23264
23396
|
init_globals();
|
|
23265
23397
|
init_constants();
|
|
23266
|
-
|
|
23398
|
+
init_element_service();
|
|
23267
23399
|
init_navigation();
|
|
23268
23400
|
room = null;
|
|
23269
23401
|
reconnectTimeout = null;
|
|
@@ -23881,7 +24013,7 @@ init_livekit_client_esm();
|
|
|
23881
24013
|
init_webrtc_service();
|
|
23882
24014
|
init_globals();
|
|
23883
24015
|
var useWebRTC = (options) => {
|
|
23884
|
-
const [
|
|
24016
|
+
const [isConnected2, setIsConnected] = (0, import_react2.useState)(false);
|
|
23885
24017
|
const [isConnecting, setIsConnecting] = (0, import_react2.useState)(false);
|
|
23886
24018
|
const [connectionState, setConnectionState] = (0, import_react2.useState)(null);
|
|
23887
24019
|
const [participants, setParticipants] = (0, import_react2.useState)([]);
|
|
@@ -23945,7 +24077,7 @@ var useWebRTC = (options) => {
|
|
|
23945
24077
|
return getParticipants().map((p) => p.identity);
|
|
23946
24078
|
}, [participants]);
|
|
23947
24079
|
return {
|
|
23948
|
-
isConnected:
|
|
24080
|
+
isConnected: isConnected2,
|
|
23949
24081
|
isConnecting,
|
|
23950
24082
|
connectionState,
|
|
23951
24083
|
room: room2,
|
|
@@ -23964,144 +24096,7 @@ var useWebRTC = (options) => {
|
|
|
23964
24096
|
|
|
23965
24097
|
// src/hooks/use-cuekit.ts
|
|
23966
24098
|
init_webrtc_service();
|
|
23967
|
-
|
|
23968
|
-
// src/utils/element-service.ts
|
|
23969
|
-
init_patch_react();
|
|
23970
|
-
init_navigation();
|
|
23971
|
-
function executeAction(action) {
|
|
23972
|
-
console.log("\u{1F3AF} Executing element action:", action);
|
|
23973
|
-
const { action_type, target_element, target } = action;
|
|
23974
|
-
switch (action_type) {
|
|
23975
|
-
case "click":
|
|
23976
|
-
return clickElement(target_element);
|
|
23977
|
-
case "navigate":
|
|
23978
|
-
return navigateToElement(target_element || target);
|
|
23979
|
-
case "input":
|
|
23980
|
-
case "focus":
|
|
23981
|
-
return focusElement(target_element);
|
|
23982
|
-
case "toggle":
|
|
23983
|
-
return toggleElement(target_element);
|
|
23984
|
-
default:
|
|
23985
|
-
console.warn(`\u26A0\uFE0F Unknown action type: ${action_type}`);
|
|
23986
|
-
return false;
|
|
23987
|
-
}
|
|
23988
|
-
}
|
|
23989
|
-
function getFullDOMStructure() {
|
|
23990
|
-
console.log("\u{1F333} ElementService: Getting full DOM structure...");
|
|
23991
|
-
return captureFullDOMStructure();
|
|
23992
|
-
}
|
|
23993
|
-
function clickElement(elementId) {
|
|
23994
|
-
if (!elementId) {
|
|
23995
|
-
console.warn("\u26A0\uFE0F No element ID provided for click action");
|
|
23996
|
-
return false;
|
|
23997
|
-
}
|
|
23998
|
-
const domStructure = getFullDOMStructure();
|
|
23999
|
-
const elementToClick = findElementById(domStructure, elementId);
|
|
24000
|
-
if (elementToClick) {
|
|
24001
|
-
console.log(`\u{1F3AF} Clicking element: ${elementId}`);
|
|
24002
|
-
const domElement = findDOMElementById(elementId);
|
|
24003
|
-
if (domElement) {
|
|
24004
|
-
domElement.click();
|
|
24005
|
-
return true;
|
|
24006
|
-
}
|
|
24007
|
-
} else {
|
|
24008
|
-
console.warn(`\u26A0\uFE0F Element not found: ${elementId}`);
|
|
24009
|
-
}
|
|
24010
|
-
return false;
|
|
24011
|
-
}
|
|
24012
|
-
function navigateToElement(target) {
|
|
24013
|
-
if (!target) {
|
|
24014
|
-
console.warn("\u26A0\uFE0F No target provided for navigation action");
|
|
24015
|
-
return false;
|
|
24016
|
-
}
|
|
24017
|
-
console.log(`\u{1F9ED} Navigating to: ${target}`);
|
|
24018
|
-
if (target.includes("/") || target.startsWith("http")) {
|
|
24019
|
-
safeNavigate(target, {});
|
|
24020
|
-
} else {
|
|
24021
|
-
handleNavigationAndClick(target, target);
|
|
24022
|
-
}
|
|
24023
|
-
return true;
|
|
24024
|
-
}
|
|
24025
|
-
function focusElement(elementId) {
|
|
24026
|
-
if (!elementId) {
|
|
24027
|
-
console.warn("\u26A0\uFE0F No element ID provided for focus action");
|
|
24028
|
-
return false;
|
|
24029
|
-
}
|
|
24030
|
-
const domElement = findDOMElementById(elementId);
|
|
24031
|
-
if (domElement instanceof HTMLInputElement || domElement instanceof HTMLTextAreaElement || domElement instanceof HTMLSelectElement) {
|
|
24032
|
-
console.log(`\u{1F4DD} Focusing element: ${elementId}`);
|
|
24033
|
-
domElement.focus();
|
|
24034
|
-
return true;
|
|
24035
|
-
} else {
|
|
24036
|
-
console.warn(`\u26A0\uFE0F Focusable element not found: ${elementId}`);
|
|
24037
|
-
return false;
|
|
24038
|
-
}
|
|
24039
|
-
}
|
|
24040
|
-
function toggleElement(elementId) {
|
|
24041
|
-
if (!elementId) {
|
|
24042
|
-
console.warn("\u26A0\uFE0F No element ID provided for toggle action");
|
|
24043
|
-
return false;
|
|
24044
|
-
}
|
|
24045
|
-
const domElement = findDOMElementById(elementId);
|
|
24046
|
-
if (domElement instanceof HTMLElement) {
|
|
24047
|
-
console.log(`\u{1F504} Toggling element: ${elementId}`);
|
|
24048
|
-
if (domElement instanceof HTMLInputElement) {
|
|
24049
|
-
if (domElement.type === "checkbox") {
|
|
24050
|
-
domElement.checked = !domElement.checked;
|
|
24051
|
-
} else if (domElement.type === "radio") {
|
|
24052
|
-
domElement.checked = true;
|
|
24053
|
-
}
|
|
24054
|
-
domElement.dispatchEvent(new Event("change", { bubbles: true }));
|
|
24055
|
-
} else {
|
|
24056
|
-
domElement.click();
|
|
24057
|
-
}
|
|
24058
|
-
return true;
|
|
24059
|
-
} else {
|
|
24060
|
-
console.warn(`\u26A0\uFE0F Toggleable element not found: ${elementId}`);
|
|
24061
|
-
return false;
|
|
24062
|
-
}
|
|
24063
|
-
}
|
|
24064
|
-
function findElementById(domStructure, elementId) {
|
|
24065
|
-
const searchInComponents = (components) => {
|
|
24066
|
-
for (const component of components) {
|
|
24067
|
-
if (component.hash === elementId) {
|
|
24068
|
-
return component;
|
|
24069
|
-
}
|
|
24070
|
-
if (component.children.length > 0) {
|
|
24071
|
-
const found = searchInComponents(component.children);
|
|
24072
|
-
if (found) return found;
|
|
24073
|
-
}
|
|
24074
|
-
}
|
|
24075
|
-
return null;
|
|
24076
|
-
};
|
|
24077
|
-
return searchInComponents(domStructure.components);
|
|
24078
|
-
}
|
|
24079
|
-
function findDOMElementById(elementId) {
|
|
24080
|
-
const allElements = document.querySelectorAll("*");
|
|
24081
|
-
for (const element3 of allElements) {
|
|
24082
|
-
if (element3 instanceof HTMLElement) {
|
|
24083
|
-
const hash = generateHash(element3);
|
|
24084
|
-
if (hash === elementId) {
|
|
24085
|
-
return element3;
|
|
24086
|
-
}
|
|
24087
|
-
}
|
|
24088
|
-
}
|
|
24089
|
-
return null;
|
|
24090
|
-
}
|
|
24091
|
-
function generateHash(element3) {
|
|
24092
|
-
const tagName = element3.tagName.toLowerCase();
|
|
24093
|
-
const text7 = (element3.textContent || "").trim().substring(0, 50);
|
|
24094
|
-
const idString = `${tagName}_${text7}_${element3.tagName}`;
|
|
24095
|
-
let hash = 0;
|
|
24096
|
-
for (let i2 = 0; i2 < idString.length; i2++) {
|
|
24097
|
-
const char = idString.charCodeAt(i2);
|
|
24098
|
-
hash = (hash << 5) - hash + char;
|
|
24099
|
-
hash |= 0;
|
|
24100
|
-
}
|
|
24101
|
-
return hash.toString(36);
|
|
24102
|
-
}
|
|
24103
|
-
|
|
24104
|
-
// src/hooks/use-cuekit.ts
|
|
24099
|
+
init_element_service();
|
|
24105
24100
|
var useCuekit = (options) => {
|
|
24106
24101
|
const [messages, setMessages] = (0, import_react3.useState)([]);
|
|
24107
24102
|
const currentUserMessageRef = (0, import_react3.useRef)(null);
|
|
@@ -24153,6 +24148,7 @@ var useCuekit = (options) => {
|
|
|
24153
24148
|
const [micState, setMicState] = (0, import_react3.useState)("idle");
|
|
24154
24149
|
const [status, setStatus] = (0, import_react3.useState)("");
|
|
24155
24150
|
const handleNavigationCommand = (event) => {
|
|
24151
|
+
console.log(`\u{1F9E0} Processing event in useCuekit: ${event.type}`, event);
|
|
24156
24152
|
switch (event.type) {
|
|
24157
24153
|
case "user_speech_chunk":
|
|
24158
24154
|
case "ai_speech_chunk": {
|
|
@@ -24203,6 +24199,7 @@ var useCuekit = (options) => {
|
|
|
24203
24199
|
break;
|
|
24204
24200
|
}
|
|
24205
24201
|
case "request_runtime_data": {
|
|
24202
|
+
console.log("\u{1F9E0} Requesting runtime data");
|
|
24206
24203
|
sendRuntimeData();
|
|
24207
24204
|
break;
|
|
24208
24205
|
}
|
|
@@ -37033,7 +37030,7 @@ var ChatPopup = ({
|
|
|
37033
37030
|
onSendText,
|
|
37034
37031
|
onEndCall,
|
|
37035
37032
|
messages,
|
|
37036
|
-
isConnected:
|
|
37033
|
+
isConnected: isConnected2,
|
|
37037
37034
|
micState,
|
|
37038
37035
|
error,
|
|
37039
37036
|
currentTheme = "dark",
|
|
@@ -37620,7 +37617,7 @@ var ChatPopup = ({
|
|
|
37620
37617
|
}
|
|
37621
37618
|
}
|
|
37622
37619
|
),
|
|
37623
|
-
|
|
37620
|
+
isConnected2 && onEndCall && /* @__PURE__ */ import_react9.default.createElement(
|
|
37624
37621
|
"button",
|
|
37625
37622
|
{
|
|
37626
37623
|
type: "submit",
|
|
@@ -39819,7 +39816,7 @@ var MicButton = ({
|
|
|
39819
39816
|
const aiSpeechTimeoutRef = (0, import_react15.useRef)(null);
|
|
39820
39817
|
const activeAITracksRef = (0, import_react15.useRef)(/* @__PURE__ */ new Set());
|
|
39821
39818
|
const {
|
|
39822
|
-
isConnected:
|
|
39819
|
+
isConnected: isConnected2,
|
|
39823
39820
|
isConnecting,
|
|
39824
39821
|
error: voiceError,
|
|
39825
39822
|
connect: voiceConnect,
|
|
@@ -39904,8 +39901,8 @@ var MicButton = ({
|
|
|
39904
39901
|
console.log("\u{1F3A4} MicButton: Current active AI tracks:", Array.from(activeAITracksRef.current));
|
|
39905
39902
|
console.log("\u{1F3A4} MicButton: Current status:", status);
|
|
39906
39903
|
console.log("\u{1F3A4} MicButton: Current mic state:", micState);
|
|
39907
|
-
console.log("\u{1F3A4} MicButton: Is listening:",
|
|
39908
|
-
console.log("\u{1F3A4} MicButton: Is connected:",
|
|
39904
|
+
console.log("\u{1F3A4} MicButton: Is listening:", isConnected2);
|
|
39905
|
+
console.log("\u{1F3A4} MicButton: Is connected:", isConnected2);
|
|
39909
39906
|
if (isSpeaking && trackId) {
|
|
39910
39907
|
console.log("\u{1F3A4} MicButton: ===== AI SPEECH START =====");
|
|
39911
39908
|
console.log("\u{1F3A4} MicButton: Adding track to active set:", trackId);
|
|
@@ -39960,7 +39957,7 @@ var MicButton = ({
|
|
|
39960
39957
|
console.log("\u{1F3A4} MicButton: - Status:", status);
|
|
39961
39958
|
console.log("\u{1F3A4} MicButton: ================================");
|
|
39962
39959
|
},
|
|
39963
|
-
[status, micState,
|
|
39960
|
+
[status, micState, isConnected2]
|
|
39964
39961
|
);
|
|
39965
39962
|
(0, import_react15.useEffect)(() => {
|
|
39966
39963
|
if (audioContainerRef2.current) {
|
|
@@ -39973,9 +39970,9 @@ var MicButton = ({
|
|
|
39973
39970
|
}
|
|
39974
39971
|
};
|
|
39975
39972
|
}, [handleAISpeech]);
|
|
39976
|
-
const isListening =
|
|
39977
|
-
const getUserFriendlyStatus = (micState2,
|
|
39978
|
-
if (!
|
|
39973
|
+
const isListening = isConnected2;
|
|
39974
|
+
const getUserFriendlyStatus = (micState2, isConnected3) => {
|
|
39975
|
+
if (!isConnected3) {
|
|
39979
39976
|
return "Connecting...";
|
|
39980
39977
|
}
|
|
39981
39978
|
if (status && !status.includes("error") && !status.includes("failed") && !status.includes("Connection error") && !status.includes("Unable to")) {
|
|
@@ -39985,28 +39982,28 @@ var MicButton = ({
|
|
|
39985
39982
|
if (micState2 === "thinking") return "Thinking...";
|
|
39986
39983
|
if (micState2 === "replying") return "Responding...";
|
|
39987
39984
|
if (micState2 === "idle") {
|
|
39988
|
-
if (
|
|
39985
|
+
if (isConnected3) return "Listening...";
|
|
39989
39986
|
return "Connecting...";
|
|
39990
39987
|
}
|
|
39991
|
-
return
|
|
39988
|
+
return isConnected3 ? "Ready" : "Connecting...";
|
|
39992
39989
|
};
|
|
39993
39990
|
(0, import_react15.useEffect)(() => {
|
|
39994
|
-
if (
|
|
39991
|
+
if (isConnected2) {
|
|
39995
39992
|
console.log("\u{1F3A4} MicButton: WebRTC and SSE connections established - ready for commands");
|
|
39996
39993
|
} else {
|
|
39997
39994
|
console.log("\u{1F3A4} MicButton: WebRTC not yet connected - ignoring speech");
|
|
39998
39995
|
}
|
|
39999
|
-
}, [
|
|
39996
|
+
}, [isConnected2]);
|
|
40000
39997
|
(0, import_react15.useEffect)(() => {
|
|
40001
39998
|
console.log("\u{1F3A4} MicButton: Auto-open check:", {
|
|
40002
|
-
isConnected:
|
|
39999
|
+
isConnected: isConnected2,
|
|
40003
40000
|
chatIsOpen: isChatOpen
|
|
40004
40001
|
});
|
|
40005
|
-
if (
|
|
40002
|
+
if (isConnected2 && !isChatOpen) {
|
|
40006
40003
|
console.log("\u{1F3A4} MicButton: Auto-opening chat popup");
|
|
40007
40004
|
openChat();
|
|
40008
40005
|
}
|
|
40009
|
-
}, [
|
|
40006
|
+
}, [isConnected2, isChatOpen, openChat]);
|
|
40010
40007
|
(0, import_react15.useEffect)(() => {
|
|
40011
40008
|
if (messageManagerMessages.length > 0 && !isChatOpen) {
|
|
40012
40009
|
console.log("\u{1F3A4} MicButton: Auto-opening chat popup due to messages");
|
|
@@ -40014,7 +40011,7 @@ var MicButton = ({
|
|
|
40014
40011
|
}
|
|
40015
40012
|
}, [messageManagerMessages.length, isChatOpen, openChat]);
|
|
40016
40013
|
const handleMicClick = (0, import_react15.useCallback)(() => {
|
|
40017
|
-
const shouldStop = micState === "listening" &&
|
|
40014
|
+
const shouldStop = micState === "listening" && isConnected2;
|
|
40018
40015
|
if (shouldStop) {
|
|
40019
40016
|
console.log("\u{1F3A4} MicButton: User wants to stop - closing everything");
|
|
40020
40017
|
voiceDisconnect().then(() => {
|
|
@@ -40039,7 +40036,7 @@ var MicButton = ({
|
|
|
40039
40036
|
}
|
|
40040
40037
|
}, [
|
|
40041
40038
|
micState,
|
|
40042
|
-
|
|
40039
|
+
isConnected2,
|
|
40043
40040
|
voiceDisconnect,
|
|
40044
40041
|
voiceConnect,
|
|
40045
40042
|
apiKey,
|
|
@@ -40054,7 +40051,7 @@ var MicButton = ({
|
|
|
40054
40051
|
if (!isChatOpen) {
|
|
40055
40052
|
openChat();
|
|
40056
40053
|
}
|
|
40057
|
-
if (
|
|
40054
|
+
if (isConnected2) {
|
|
40058
40055
|
console.log("\u{1F3A4} MicButton: Sending via WebRTC");
|
|
40059
40056
|
try {
|
|
40060
40057
|
await sendUserCommand2(textToSend);
|
|
@@ -40251,13 +40248,13 @@ var MicButton = ({
|
|
|
40251
40248
|
text: msg.text,
|
|
40252
40249
|
sender: msg.role === "ai" ? "assistant" : "user"
|
|
40253
40250
|
})),
|
|
40254
|
-
isConnected:
|
|
40251
|
+
isConnected: isConnected2 ?? false,
|
|
40255
40252
|
micState,
|
|
40256
40253
|
participants,
|
|
40257
40254
|
error: voiceError,
|
|
40258
40255
|
currentTheme,
|
|
40259
40256
|
onThemeToggle: setCurrentTheme,
|
|
40260
|
-
status: getUserFriendlyStatus(micState,
|
|
40257
|
+
status: getUserFriendlyStatus(micState, isConnected2 ?? false),
|
|
40261
40258
|
anchor: { position: screenPosition, bottom: bottomSpace, size: buttonSize }
|
|
40262
40259
|
}
|
|
40263
40260
|
), isChatOpen && isChatMinimized && /* @__PURE__ */ import_react15.default.createElement(
|
|
@@ -40286,4 +40283,5 @@ var MicButton = ({
|
|
|
40286
40283
|
};
|
|
40287
40284
|
|
|
40288
40285
|
// src/index.ts
|
|
40289
|
-
|
|
40286
|
+
init_element_service();
|
|
40287
|
+
init_element_service();
|
package/dist/index.mjs
CHANGED
|
@@ -16,12 +16,12 @@ import {
|
|
|
16
16
|
connectToRoom,
|
|
17
17
|
createAudioAnalyser,
|
|
18
18
|
disconnectFromRoom,
|
|
19
|
+
executeAction,
|
|
20
|
+
getFullDOMStructure,
|
|
19
21
|
getParticipants,
|
|
20
22
|
getRoom,
|
|
21
23
|
getRoomName,
|
|
22
|
-
handleNavigationAndClick,
|
|
23
24
|
onStateChange,
|
|
24
|
-
safeNavigate,
|
|
25
25
|
sendData,
|
|
26
26
|
sendRuntimeData,
|
|
27
27
|
sendScreenStatus,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
setServerUrl,
|
|
35
35
|
setWebRTCCallbacks,
|
|
36
36
|
setWebRTCConfig
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-PLOG3DEN.mjs";
|
|
38
38
|
|
|
39
39
|
// node_modules/inline-style-parser/index.js
|
|
40
40
|
var require_inline_style_parser = __commonJS({
|
|
@@ -492,7 +492,7 @@ var CuekitProvider = ({
|
|
|
492
492
|
};
|
|
493
493
|
}, [navigationHandler]);
|
|
494
494
|
useEffect(() => {
|
|
495
|
-
import("./webrtc-service-
|
|
495
|
+
import("./webrtc-service-BHI4M7YJ.mjs").then(({ setWebRTCCallbacks: setWebRTCCallbacks2 }) => {
|
|
496
496
|
setWebRTCCallbacks2({
|
|
497
497
|
onNavigationCommand: (command) => {
|
|
498
498
|
console.log("\u{1F9ED} Processing navigation command:", command);
|
|
@@ -609,7 +609,7 @@ import { useState as useState3, useCallback as useCallback2, useRef as useRef2 }
|
|
|
609
609
|
// src/hooks/use-webrtc.ts
|
|
610
610
|
import { useState as useState2, useEffect as useEffect2, useCallback, useRef, useMemo } from "react";
|
|
611
611
|
var useWebRTC = (options) => {
|
|
612
|
-
const [
|
|
612
|
+
const [isConnected, setIsConnected] = useState2(false);
|
|
613
613
|
const [isConnecting, setIsConnecting] = useState2(false);
|
|
614
614
|
const [connectionState, setConnectionState] = useState2(null);
|
|
615
615
|
const [participants, setParticipants] = useState2([]);
|
|
@@ -673,7 +673,7 @@ var useWebRTC = (options) => {
|
|
|
673
673
|
return getParticipants().map((p) => p.identity);
|
|
674
674
|
}, [participants]);
|
|
675
675
|
return {
|
|
676
|
-
isConnected
|
|
676
|
+
isConnected,
|
|
677
677
|
isConnecting,
|
|
678
678
|
connectionState,
|
|
679
679
|
room,
|
|
@@ -690,140 +690,6 @@ var useWebRTC = (options) => {
|
|
|
690
690
|
};
|
|
691
691
|
};
|
|
692
692
|
|
|
693
|
-
// src/utils/element-service.ts
|
|
694
|
-
function executeAction(action) {
|
|
695
|
-
console.log("\u{1F3AF} Executing element action:", action);
|
|
696
|
-
const { action_type, target_element, target } = action;
|
|
697
|
-
switch (action_type) {
|
|
698
|
-
case "click":
|
|
699
|
-
return clickElement(target_element);
|
|
700
|
-
case "navigate":
|
|
701
|
-
return navigateToElement(target_element || target);
|
|
702
|
-
case "input":
|
|
703
|
-
case "focus":
|
|
704
|
-
return focusElement(target_element);
|
|
705
|
-
case "toggle":
|
|
706
|
-
return toggleElement(target_element);
|
|
707
|
-
default:
|
|
708
|
-
console.warn(`\u26A0\uFE0F Unknown action type: ${action_type}`);
|
|
709
|
-
return false;
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
function getFullDOMStructure() {
|
|
713
|
-
console.log("\u{1F333} ElementService: Getting full DOM structure...");
|
|
714
|
-
return captureFullDOMStructure();
|
|
715
|
-
}
|
|
716
|
-
function clickElement(elementId) {
|
|
717
|
-
if (!elementId) {
|
|
718
|
-
console.warn("\u26A0\uFE0F No element ID provided for click action");
|
|
719
|
-
return false;
|
|
720
|
-
}
|
|
721
|
-
const domStructure = getFullDOMStructure();
|
|
722
|
-
const elementToClick = findElementById(domStructure, elementId);
|
|
723
|
-
if (elementToClick) {
|
|
724
|
-
console.log(`\u{1F3AF} Clicking element: ${elementId}`);
|
|
725
|
-
const domElement = findDOMElementById(elementId);
|
|
726
|
-
if (domElement) {
|
|
727
|
-
domElement.click();
|
|
728
|
-
return true;
|
|
729
|
-
}
|
|
730
|
-
} else {
|
|
731
|
-
console.warn(`\u26A0\uFE0F Element not found: ${elementId}`);
|
|
732
|
-
}
|
|
733
|
-
return false;
|
|
734
|
-
}
|
|
735
|
-
function navigateToElement(target) {
|
|
736
|
-
if (!target) {
|
|
737
|
-
console.warn("\u26A0\uFE0F No target provided for navigation action");
|
|
738
|
-
return false;
|
|
739
|
-
}
|
|
740
|
-
console.log(`\u{1F9ED} Navigating to: ${target}`);
|
|
741
|
-
if (target.includes("/") || target.startsWith("http")) {
|
|
742
|
-
safeNavigate(target, {});
|
|
743
|
-
} else {
|
|
744
|
-
handleNavigationAndClick(target, target);
|
|
745
|
-
}
|
|
746
|
-
return true;
|
|
747
|
-
}
|
|
748
|
-
function focusElement(elementId) {
|
|
749
|
-
if (!elementId) {
|
|
750
|
-
console.warn("\u26A0\uFE0F No element ID provided for focus action");
|
|
751
|
-
return false;
|
|
752
|
-
}
|
|
753
|
-
const domElement = findDOMElementById(elementId);
|
|
754
|
-
if (domElement instanceof HTMLInputElement || domElement instanceof HTMLTextAreaElement || domElement instanceof HTMLSelectElement) {
|
|
755
|
-
console.log(`\u{1F4DD} Focusing element: ${elementId}`);
|
|
756
|
-
domElement.focus();
|
|
757
|
-
return true;
|
|
758
|
-
} else {
|
|
759
|
-
console.warn(`\u26A0\uFE0F Focusable element not found: ${elementId}`);
|
|
760
|
-
return false;
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
function toggleElement(elementId) {
|
|
764
|
-
if (!elementId) {
|
|
765
|
-
console.warn("\u26A0\uFE0F No element ID provided for toggle action");
|
|
766
|
-
return false;
|
|
767
|
-
}
|
|
768
|
-
const domElement = findDOMElementById(elementId);
|
|
769
|
-
if (domElement instanceof HTMLElement) {
|
|
770
|
-
console.log(`\u{1F504} Toggling element: ${elementId}`);
|
|
771
|
-
if (domElement instanceof HTMLInputElement) {
|
|
772
|
-
if (domElement.type === "checkbox") {
|
|
773
|
-
domElement.checked = !domElement.checked;
|
|
774
|
-
} else if (domElement.type === "radio") {
|
|
775
|
-
domElement.checked = true;
|
|
776
|
-
}
|
|
777
|
-
domElement.dispatchEvent(new Event("change", { bubbles: true }));
|
|
778
|
-
} else {
|
|
779
|
-
domElement.click();
|
|
780
|
-
}
|
|
781
|
-
return true;
|
|
782
|
-
} else {
|
|
783
|
-
console.warn(`\u26A0\uFE0F Toggleable element not found: ${elementId}`);
|
|
784
|
-
return false;
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
function findElementById(domStructure, elementId) {
|
|
788
|
-
const searchInComponents = (components) => {
|
|
789
|
-
for (const component of components) {
|
|
790
|
-
if (component.hash === elementId) {
|
|
791
|
-
return component;
|
|
792
|
-
}
|
|
793
|
-
if (component.children.length > 0) {
|
|
794
|
-
const found = searchInComponents(component.children);
|
|
795
|
-
if (found) return found;
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
return null;
|
|
799
|
-
};
|
|
800
|
-
return searchInComponents(domStructure.components);
|
|
801
|
-
}
|
|
802
|
-
function findDOMElementById(elementId) {
|
|
803
|
-
const allElements = document.querySelectorAll("*");
|
|
804
|
-
for (const element3 of allElements) {
|
|
805
|
-
if (element3 instanceof HTMLElement) {
|
|
806
|
-
const hash = generateHash(element3);
|
|
807
|
-
if (hash === elementId) {
|
|
808
|
-
return element3;
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
return null;
|
|
813
|
-
}
|
|
814
|
-
function generateHash(element3) {
|
|
815
|
-
const tagName = element3.tagName.toLowerCase();
|
|
816
|
-
const text7 = (element3.textContent || "").trim().substring(0, 50);
|
|
817
|
-
const idString = `${tagName}_${text7}_${element3.tagName}`;
|
|
818
|
-
let hash = 0;
|
|
819
|
-
for (let i2 = 0; i2 < idString.length; i2++) {
|
|
820
|
-
const char = idString.charCodeAt(i2);
|
|
821
|
-
hash = (hash << 5) - hash + char;
|
|
822
|
-
hash |= 0;
|
|
823
|
-
}
|
|
824
|
-
return hash.toString(36);
|
|
825
|
-
}
|
|
826
|
-
|
|
827
693
|
// src/hooks/use-cuekit.ts
|
|
828
694
|
var useCuekit = (options) => {
|
|
829
695
|
const [messages, setMessages] = useState3([]);
|
|
@@ -876,6 +742,7 @@ var useCuekit = (options) => {
|
|
|
876
742
|
const [micState, setMicState] = useState3("idle");
|
|
877
743
|
const [status, setStatus] = useState3("");
|
|
878
744
|
const handleNavigationCommand = (event) => {
|
|
745
|
+
console.log(`\u{1F9E0} Processing event in useCuekit: ${event.type}`, event);
|
|
879
746
|
switch (event.type) {
|
|
880
747
|
case "user_speech_chunk":
|
|
881
748
|
case "ai_speech_chunk": {
|
|
@@ -926,6 +793,7 @@ var useCuekit = (options) => {
|
|
|
926
793
|
break;
|
|
927
794
|
}
|
|
928
795
|
case "request_runtime_data": {
|
|
796
|
+
console.log("\u{1F9E0} Requesting runtime data");
|
|
929
797
|
sendRuntimeData();
|
|
930
798
|
break;
|
|
931
799
|
}
|
|
@@ -13756,7 +13624,7 @@ var ChatPopup = ({
|
|
|
13756
13624
|
onSendText,
|
|
13757
13625
|
onEndCall,
|
|
13758
13626
|
messages,
|
|
13759
|
-
isConnected
|
|
13627
|
+
isConnected,
|
|
13760
13628
|
micState,
|
|
13761
13629
|
error,
|
|
13762
13630
|
currentTheme = "dark",
|
|
@@ -14343,7 +14211,7 @@ var ChatPopup = ({
|
|
|
14343
14211
|
}
|
|
14344
14212
|
}
|
|
14345
14213
|
),
|
|
14346
|
-
|
|
14214
|
+
isConnected && onEndCall && /* @__PURE__ */ React6.createElement(
|
|
14347
14215
|
"button",
|
|
14348
14216
|
{
|
|
14349
14217
|
type: "submit",
|
|
@@ -16533,7 +16401,7 @@ var MicButton = ({
|
|
|
16533
16401
|
const aiSpeechTimeoutRef = useRef7(null);
|
|
16534
16402
|
const activeAITracksRef = useRef7(/* @__PURE__ */ new Set());
|
|
16535
16403
|
const {
|
|
16536
|
-
isConnected
|
|
16404
|
+
isConnected,
|
|
16537
16405
|
isConnecting,
|
|
16538
16406
|
error: voiceError,
|
|
16539
16407
|
connect: voiceConnect,
|
|
@@ -16618,8 +16486,8 @@ var MicButton = ({
|
|
|
16618
16486
|
console.log("\u{1F3A4} MicButton: Current active AI tracks:", Array.from(activeAITracksRef.current));
|
|
16619
16487
|
console.log("\u{1F3A4} MicButton: Current status:", status);
|
|
16620
16488
|
console.log("\u{1F3A4} MicButton: Current mic state:", micState);
|
|
16621
|
-
console.log("\u{1F3A4} MicButton: Is listening:",
|
|
16622
|
-
console.log("\u{1F3A4} MicButton: Is connected:",
|
|
16489
|
+
console.log("\u{1F3A4} MicButton: Is listening:", isConnected);
|
|
16490
|
+
console.log("\u{1F3A4} MicButton: Is connected:", isConnected);
|
|
16623
16491
|
if (isSpeaking && trackId) {
|
|
16624
16492
|
console.log("\u{1F3A4} MicButton: ===== AI SPEECH START =====");
|
|
16625
16493
|
console.log("\u{1F3A4} MicButton: Adding track to active set:", trackId);
|
|
@@ -16674,7 +16542,7 @@ var MicButton = ({
|
|
|
16674
16542
|
console.log("\u{1F3A4} MicButton: - Status:", status);
|
|
16675
16543
|
console.log("\u{1F3A4} MicButton: ================================");
|
|
16676
16544
|
},
|
|
16677
|
-
[status, micState,
|
|
16545
|
+
[status, micState, isConnected]
|
|
16678
16546
|
);
|
|
16679
16547
|
useEffect10(() => {
|
|
16680
16548
|
if (audioContainerRef.current) {
|
|
@@ -16687,9 +16555,9 @@ var MicButton = ({
|
|
|
16687
16555
|
}
|
|
16688
16556
|
};
|
|
16689
16557
|
}, [handleAISpeech]);
|
|
16690
|
-
const isListening =
|
|
16691
|
-
const getUserFriendlyStatus = (micState2,
|
|
16692
|
-
if (!
|
|
16558
|
+
const isListening = isConnected;
|
|
16559
|
+
const getUserFriendlyStatus = (micState2, isConnected2) => {
|
|
16560
|
+
if (!isConnected2) {
|
|
16693
16561
|
return "Connecting...";
|
|
16694
16562
|
}
|
|
16695
16563
|
if (status && !status.includes("error") && !status.includes("failed") && !status.includes("Connection error") && !status.includes("Unable to")) {
|
|
@@ -16699,28 +16567,28 @@ var MicButton = ({
|
|
|
16699
16567
|
if (micState2 === "thinking") return "Thinking...";
|
|
16700
16568
|
if (micState2 === "replying") return "Responding...";
|
|
16701
16569
|
if (micState2 === "idle") {
|
|
16702
|
-
if (
|
|
16570
|
+
if (isConnected2) return "Listening...";
|
|
16703
16571
|
return "Connecting...";
|
|
16704
16572
|
}
|
|
16705
|
-
return
|
|
16573
|
+
return isConnected2 ? "Ready" : "Connecting...";
|
|
16706
16574
|
};
|
|
16707
16575
|
useEffect10(() => {
|
|
16708
|
-
if (
|
|
16576
|
+
if (isConnected) {
|
|
16709
16577
|
console.log("\u{1F3A4} MicButton: WebRTC and SSE connections established - ready for commands");
|
|
16710
16578
|
} else {
|
|
16711
16579
|
console.log("\u{1F3A4} MicButton: WebRTC not yet connected - ignoring speech");
|
|
16712
16580
|
}
|
|
16713
|
-
}, [
|
|
16581
|
+
}, [isConnected]);
|
|
16714
16582
|
useEffect10(() => {
|
|
16715
16583
|
console.log("\u{1F3A4} MicButton: Auto-open check:", {
|
|
16716
|
-
isConnected
|
|
16584
|
+
isConnected,
|
|
16717
16585
|
chatIsOpen: isChatOpen
|
|
16718
16586
|
});
|
|
16719
|
-
if (
|
|
16587
|
+
if (isConnected && !isChatOpen) {
|
|
16720
16588
|
console.log("\u{1F3A4} MicButton: Auto-opening chat popup");
|
|
16721
16589
|
openChat();
|
|
16722
16590
|
}
|
|
16723
|
-
}, [
|
|
16591
|
+
}, [isConnected, isChatOpen, openChat]);
|
|
16724
16592
|
useEffect10(() => {
|
|
16725
16593
|
if (messageManagerMessages.length > 0 && !isChatOpen) {
|
|
16726
16594
|
console.log("\u{1F3A4} MicButton: Auto-opening chat popup due to messages");
|
|
@@ -16728,7 +16596,7 @@ var MicButton = ({
|
|
|
16728
16596
|
}
|
|
16729
16597
|
}, [messageManagerMessages.length, isChatOpen, openChat]);
|
|
16730
16598
|
const handleMicClick = useCallback5(() => {
|
|
16731
|
-
const shouldStop = micState === "listening" &&
|
|
16599
|
+
const shouldStop = micState === "listening" && isConnected;
|
|
16732
16600
|
if (shouldStop) {
|
|
16733
16601
|
console.log("\u{1F3A4} MicButton: User wants to stop - closing everything");
|
|
16734
16602
|
voiceDisconnect().then(() => {
|
|
@@ -16753,7 +16621,7 @@ var MicButton = ({
|
|
|
16753
16621
|
}
|
|
16754
16622
|
}, [
|
|
16755
16623
|
micState,
|
|
16756
|
-
|
|
16624
|
+
isConnected,
|
|
16757
16625
|
voiceDisconnect,
|
|
16758
16626
|
voiceConnect,
|
|
16759
16627
|
apiKey,
|
|
@@ -16768,7 +16636,7 @@ var MicButton = ({
|
|
|
16768
16636
|
if (!isChatOpen) {
|
|
16769
16637
|
openChat();
|
|
16770
16638
|
}
|
|
16771
|
-
if (
|
|
16639
|
+
if (isConnected) {
|
|
16772
16640
|
console.log("\u{1F3A4} MicButton: Sending via WebRTC");
|
|
16773
16641
|
try {
|
|
16774
16642
|
await sendUserCommand2(textToSend);
|
|
@@ -16965,13 +16833,13 @@ var MicButton = ({
|
|
|
16965
16833
|
text: msg.text,
|
|
16966
16834
|
sender: msg.role === "ai" ? "assistant" : "user"
|
|
16967
16835
|
})),
|
|
16968
|
-
isConnected:
|
|
16836
|
+
isConnected: isConnected ?? false,
|
|
16969
16837
|
micState,
|
|
16970
16838
|
participants,
|
|
16971
16839
|
error: voiceError,
|
|
16972
16840
|
currentTheme,
|
|
16973
16841
|
onThemeToggle: setCurrentTheme,
|
|
16974
|
-
status: getUserFriendlyStatus(micState,
|
|
16842
|
+
status: getUserFriendlyStatus(micState, isConnected ?? false),
|
|
16975
16843
|
anchor: { position: screenPosition, bottom: bottomSpace, size: buttonSize }
|
|
16976
16844
|
}
|
|
16977
16845
|
), isChatOpen && isChatMinimized && /* @__PURE__ */ React11.createElement(
|