@cuekit-ai/react 1.2.2 → 1.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.
package/dist/index.js CHANGED
@@ -55,12 +55,223 @@ var init_globals = __esm({
55
55
  }
56
56
  });
57
57
 
58
+ // src/core/intent-store.ts
59
+ var store, GlobalStore;
60
+ var init_intent_store = __esm({
61
+ "src/core/intent-store.ts"() {
62
+ "use strict";
63
+ store = {
64
+ screenMetadata: {},
65
+ allElementsData: []
66
+ };
67
+ GlobalStore = {
68
+ // 🔹 Screen Metadata Methods
69
+ setMetadata(screen, metadata) {
70
+ store.screenMetadata[screen] = metadata;
71
+ },
72
+ getMetadata(screen) {
73
+ return store.screenMetadata[screen];
74
+ },
75
+ clearMetadata(screen) {
76
+ delete store.screenMetadata[screen];
77
+ },
78
+ // 🔹 Generic Store Access Methods
79
+ setData(key, value) {
80
+ store[key] = value;
81
+ },
82
+ getData(key) {
83
+ return store[key];
84
+ },
85
+ clearData(key) {
86
+ delete store[key];
87
+ },
88
+ // 🔹 Element Data Management
89
+ setElement(elementData) {
90
+ const index2 = store.allElementsData.findIndex((e3) => e3.elementId === elementData.elementId);
91
+ if (index2 >= 0) {
92
+ console.log("Updating existing element");
93
+ store.allElementsData[index2] = elementData;
94
+ } else {
95
+ console.log("Adding new element");
96
+ store.allElementsData.push(elementData);
97
+ }
98
+ },
99
+ getElementById(elementId) {
100
+ const match = store.allElementsData.find((e3) => e3.elementId === elementId);
101
+ if (!match) {
102
+ console.warn(`[GlobalStore] No element found for ID: ${elementId}`);
103
+ console.log("All elements in store:", store.allElementsData);
104
+ }
105
+ return match;
106
+ },
107
+ deleteElementById(id) {
108
+ store.allElementsData = store.allElementsData.filter((e3) => e3.elementId !== id);
109
+ },
110
+ clearAllElements() {
111
+ store.allElementsData = [];
112
+ }
113
+ };
114
+ }
115
+ });
116
+
117
+ // src/core/navigation.ts
118
+ function setNavigationHandler(handler) {
119
+ navigationHandler = handler;
120
+ }
121
+ function navigate(path2, params) {
122
+ const safeParams = params || {};
123
+ const absolutePath = path2.startsWith("/") ? path2 : `/${path2}`;
124
+ if (navigationHandler) {
125
+ try {
126
+ navigationHandler(absolutePath, safeParams);
127
+ } catch (error) {
128
+ console.error("[CueKit] navigation handler failed, falling back to default:", error);
129
+ }
130
+ return;
131
+ }
132
+ let fullPath = absolutePath;
133
+ if (safeParams) {
134
+ const searchParams = new URLSearchParams(safeParams).toString();
135
+ if (searchParams) {
136
+ fullPath += `?${searchParams}`;
137
+ }
138
+ }
139
+ if (navigation) {
140
+ navigation.push(fullPath);
141
+ } else {
142
+ if (typeof window !== "undefined") {
143
+ window.location.href = fullPath;
144
+ }
145
+ }
146
+ }
147
+ function getCurrentScreenName() {
148
+ try {
149
+ const path2 = getCurrentPath();
150
+ return path2 || "UnknownScreen";
151
+ } catch (e3) {
152
+ return "UnknownScreen";
153
+ }
154
+ }
155
+ function getCurrentRouteParams() {
156
+ try {
157
+ const params = {};
158
+ const searchParams = getSearchParams();
159
+ if (searchParams instanceof URLSearchParams) {
160
+ searchParams.forEach((value, key) => {
161
+ params[key] = value;
162
+ });
163
+ } else {
164
+ return searchParams;
165
+ }
166
+ return params;
167
+ } catch (e3) {
168
+ return {};
169
+ }
170
+ }
171
+ function onStateChange() {
172
+ const routeName = getCurrentScreenName();
173
+ const params = getCurrentRouteParams();
174
+ if (params && params.metadata) {
175
+ try {
176
+ const metadata = JSON.parse(params.metadata);
177
+ GlobalStore.setMetadata(routeName, metadata);
178
+ } catch (error) {
179
+ console.error("Failed to parse metadata from URL:", error);
180
+ }
181
+ }
182
+ }
183
+ function getElementPath(element3) {
184
+ if (element3.id) {
185
+ return `id(${element3.id})`;
186
+ }
187
+ const path2 = [];
188
+ let current = element3;
189
+ while (current && current !== document.body) {
190
+ let index2 = 1;
191
+ let sibling = current.previousElementSibling;
192
+ while (sibling) {
193
+ if (sibling.tagName === current.tagName) {
194
+ index2++;
195
+ }
196
+ sibling = sibling.previousElementSibling;
197
+ }
198
+ path2.unshift(`${current.tagName.toLowerCase()}[${index2}]`);
199
+ current = current.parentElement;
200
+ }
201
+ return path2.join("/");
202
+ }
203
+ var navigation, navigationHandler, getCurrentPath, getSearchParams, safeNavigate, handleNavigationAndClick;
204
+ var init_navigation = __esm({
205
+ "src/core/navigation.ts"() {
206
+ "use strict";
207
+ init_intent_store();
208
+ navigationHandler = null;
209
+ getCurrentPath = () => {
210
+ if (typeof window === "undefined") return "";
211
+ return window.location.pathname;
212
+ };
213
+ getSearchParams = () => {
214
+ if (typeof window === "undefined") return new URLSearchParams();
215
+ return new URLSearchParams(window.location.search);
216
+ };
217
+ safeNavigate = (name2, params = {}) => {
218
+ if (name2) {
219
+ navigate(name2, params);
220
+ } else {
221
+ console.warn("[CueKit] route name not provided");
222
+ }
223
+ };
224
+ handleNavigationAndClick = (routeName, elementHash) => {
225
+ safeNavigate(routeName);
226
+ if (typeof MutationObserver === "undefined" || typeof document === "undefined") return;
227
+ const observer = new MutationObserver((mutationsList, observer2) => {
228
+ setTimeout(() => {
229
+ const allElements = document.querySelectorAll("*");
230
+ let elementToClick = null;
231
+ for (const element3 of allElements) {
232
+ if (element3 instanceof HTMLElement) {
233
+ const tagName = element3.tagName.toLowerCase();
234
+ const text7 = (element3.textContent || "").trim().substring(0, 50);
235
+ let sibling = element3.previousElementSibling;
236
+ let position3 = 1;
237
+ while (sibling) {
238
+ if (sibling.tagName === element3.tagName) {
239
+ position3++;
240
+ }
241
+ sibling = sibling.previousElementSibling;
242
+ }
243
+ const path2 = getElementPath(element3);
244
+ const idString = `${tagName}[${position3}]_(${text7})_${path2}`;
245
+ let hash = 0;
246
+ for (let i2 = 0; i2 < idString.length; i2++) {
247
+ const char = idString.charCodeAt(i2);
248
+ hash = (hash << 5) - hash + char;
249
+ hash |= 0;
250
+ }
251
+ const elementHashValue = hash.toString(36);
252
+ if (elementHashValue === elementHash) {
253
+ elementToClick = element3;
254
+ break;
255
+ }
256
+ }
257
+ }
258
+ if (elementToClick) {
259
+ elementToClick.click();
260
+ observer2.disconnect();
261
+ }
262
+ }, 100);
263
+ });
264
+ observer.observe(document.body, { childList: true, subtree: true });
265
+ };
266
+ }
267
+ });
268
+
58
269
  // src/constants/index.ts
59
270
  var WEBRTC_BACKEND_SERVER_URL;
60
271
  var init_constants = __esm({
61
272
  "src/constants/index.ts"() {
62
273
  "use strict";
63
- WEBRTC_BACKEND_SERVER_URL = "https://api-webrtc.cuekit.ai";
274
+ WEBRTC_BACKEND_SERVER_URL = "https://api-webrtc-dev.cuekit.ai";
64
275
  }
65
276
  });
66
277
 
@@ -4472,15 +4683,15 @@ function requireSdp() {
4472
4683
  return Math.random().toString().substr(2, 22);
4473
4684
  };
4474
4685
  SDPUtils2.writeSessionBoilerplate = function(sessId, sessVer, sessUser) {
4475
- let sessionId2;
4686
+ let sessionId;
4476
4687
  const version2 = sessVer !== void 0 ? sessVer : 2;
4477
4688
  if (sessId) {
4478
- sessionId2 = sessId;
4689
+ sessionId = sessId;
4479
4690
  } else {
4480
- sessionId2 = SDPUtils2.generateSessionId();
4691
+ sessionId = SDPUtils2.generateSessionId();
4481
4692
  }
4482
4693
  const user = sessUser || "thisisadapterortc";
4483
- return "v=0\r\no=" + user + " " + sessionId2 + " " + version2 + " IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n";
4694
+ return "v=0\r\no=" + user + " " + sessionId + " " + version2 + " IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n";
4484
4695
  };
4485
4696
  SDPUtils2.getDirection = function(mediaSection, sessionpart) {
4486
4697
  const lines = SDPUtils2.splitLines(mediaSection);
@@ -5204,8 +5415,8 @@ function isWeb() {
5204
5415
  function isReactNative() {
5205
5416
  return navigator.product == "ReactNative";
5206
5417
  }
5207
- function isCloud(serverUrl3) {
5208
- return serverUrl3.hostname.endsWith(".livekit.cloud") || serverUrl3.hostname.endsWith(".livekit.run");
5418
+ function isCloud(serverUrl2) {
5419
+ return serverUrl2.hostname.endsWith(".livekit.cloud") || serverUrl2.hostname.endsWith(".livekit.run");
5209
5420
  }
5210
5421
  function getLKReactNativeInfo() {
5211
5422
  if (global && global.LiveKitReactNativeGlobal) {
@@ -7127,8 +7338,8 @@ function applyUserDataCompat(newObj, oldObj) {
7127
7338
  newObj.destinationIdentities = destinationIdentities;
7128
7339
  oldObj.destinationIdentities = destinationIdentities;
7129
7340
  }
7130
- function getCloudConfigUrl(serverUrl3) {
7131
- return "".concat(serverUrl3.protocol.replace("ws", "http"), "//").concat(serverUrl3.host, "/settings");
7341
+ function getCloudConfigUrl(serverUrl2) {
7342
+ return "".concat(serverUrl2.protocol.replace("ws", "http"), "//").concat(serverUrl2.host, "/settings");
7132
7343
  }
7133
7344
  function isElementInPiP(el) {
7134
7345
  var _a, _b;
@@ -22657,6 +22868,142 @@ var init_livekit_client_esm = __esm({
22657
22868
  }
22658
22869
  });
22659
22870
 
22871
+ // src/utils/jsx-encoder.ts
22872
+ function generateStableDOMId(element3) {
22873
+ const tagName = element3.tagName.toLowerCase();
22874
+ const text7 = (element3.textContent || "").trim().substring(0, 50);
22875
+ let sibling = element3.previousElementSibling;
22876
+ let position3 = 1;
22877
+ while (sibling) {
22878
+ if (sibling.tagName === element3.tagName) {
22879
+ position3++;
22880
+ }
22881
+ sibling = sibling.previousElementSibling;
22882
+ }
22883
+ const path2 = getElementPath2(element3);
22884
+ const idString = `${tagName}[${position3}]_(${text7})_${path2}`;
22885
+ let hash = 0;
22886
+ for (let i2 = 0; i2 < idString.length; i2++) {
22887
+ const char = idString.charCodeAt(i2);
22888
+ hash = (hash << 5) - hash + char;
22889
+ hash |= 0;
22890
+ }
22891
+ return hash.toString(36);
22892
+ }
22893
+ function getElementPath2(element3) {
22894
+ if (element3.id) {
22895
+ return `id(${element3.id})`;
22896
+ }
22897
+ if (element3.tagName.toLowerCase() === "body") {
22898
+ return "/body";
22899
+ }
22900
+ let ix = 0;
22901
+ const siblings = element3.parentNode?.children || new HTMLCollection();
22902
+ for (let i2 = 0; i2 < siblings.length; i2++) {
22903
+ const sibling = siblings[i2];
22904
+ if (sibling === element3) {
22905
+ return `${getElementPath2(element3.parentNode)}/${element3.tagName}[${ix + 1}]`;
22906
+ }
22907
+ if (sibling.nodeType === 1 && sibling.tagName === element3.tagName) {
22908
+ ix++;
22909
+ }
22910
+ }
22911
+ return "not_found";
22912
+ }
22913
+ var init_jsx_encoder = __esm({
22914
+ "src/utils/jsx-encoder.ts"() {
22915
+ "use strict";
22916
+ }
22917
+ });
22918
+
22919
+ // src/utils/patch-react.ts
22920
+ function getImmediateText(element3) {
22921
+ let text7 = "";
22922
+ if (element3.childNodes) {
22923
+ for (const node2 of Array.from(element3.childNodes)) {
22924
+ if (node2.nodeType === 3) {
22925
+ text7 += node2.textContent || "";
22926
+ }
22927
+ }
22928
+ }
22929
+ return text7.trim();
22930
+ }
22931
+ function captureFullDOMStructure() {
22932
+ console.log("\u{1F333} Capturing full DOM structure...");
22933
+ const components = [];
22934
+ const interactiveElements = document.querySelectorAll(
22935
+ 'a, button, input, textarea, select, [role="button"], [onclick]'
22936
+ );
22937
+ interactiveElements.forEach((element3) => {
22938
+ if (element3 instanceof HTMLElement && !element3.closest("[data-cuekit-ignore]")) {
22939
+ const nodeData = buildFlatDOMNode(element3);
22940
+ if (nodeData) {
22941
+ components.push(nodeData);
22942
+ }
22943
+ }
22944
+ });
22945
+ const result = { components };
22946
+ console.log("\u{1F333} Full DOM structure captured:", result);
22947
+ return result;
22948
+ }
22949
+ function buildFlatDOMNode(element3) {
22950
+ if (element3.tagName.toLowerCase() === "script" || element3.hasAttribute("data-cuekit-ignore") || element3.style.display === "none" || element3.style.visibility === "hidden") {
22951
+ return null;
22952
+ }
22953
+ const hash = generateStableDOMId(element3);
22954
+ const text7 = getImmediateText(element3).substring(0, 100);
22955
+ const isClickable = isElementClickable(element3);
22956
+ const componentType = element3.tagName.toLowerCase();
22957
+ return {
22958
+ hash,
22959
+ text: text7,
22960
+ isClickable,
22961
+ componentType,
22962
+ children: []
22963
+ // No children in a flat structure
22964
+ };
22965
+ }
22966
+ function isElementClickable(element3) {
22967
+ const interactiveSelectors = [
22968
+ "button",
22969
+ "a",
22970
+ "input",
22971
+ "select",
22972
+ "textarea",
22973
+ '[role="button"]',
22974
+ '[role="link"]',
22975
+ '[role="tab"]',
22976
+ "[data-onclick-id]",
22977
+ "[data-on-press-id]",
22978
+ "[onclick]",
22979
+ "[onmousedown]",
22980
+ "[onmouseup]",
22981
+ "[ontouchstart]",
22982
+ "[ontouchend]",
22983
+ "[onkeydown]",
22984
+ "[onkeyup]",
22985
+ "[onkeypress]"
22986
+ ];
22987
+ for (const selector of interactiveSelectors) {
22988
+ if (element3.matches(selector)) {
22989
+ return true;
22990
+ }
22991
+ }
22992
+ const hasClickEvents = element3.onclick !== null || element3.getAttribute("onclick") !== null;
22993
+ const hasInteractiveEvents = element3.ontouchstart !== null || element3.getAttribute("ontouchstart") !== null || element3.ontouchend !== null || element3.getAttribute("ontouchend") !== null || element3.onkeydown !== null || element3.getAttribute("onkeydown") !== null || element3.onkeyup !== null || element3.getAttribute("onkeyup") !== null || element3.onkeypress !== null || element3.getAttribute("onkeypress") !== null;
22994
+ const hasPointerCursor = element3.style.cursor === "pointer" || getComputedStyle(element3).cursor === "pointer";
22995
+ const hasTabIndex = element3.hasAttribute("tabindex") && parseInt(element3.getAttribute("tabindex") || "0") >= 0;
22996
+ const hasInteractiveDataAttrs = element3.hasAttribute("data-clickable") || element3.hasAttribute("data-interactive") || element3.hasAttribute("data-action") || element3.hasAttribute("data-handler");
22997
+ const hasInteractiveAria = element3.hasAttribute("aria-pressed") || element3.hasAttribute("aria-expanded") || element3.hasAttribute("aria-selected") || element3.hasAttribute("aria-checked");
22998
+ return hasClickEvents || hasInteractiveEvents || hasPointerCursor || hasTabIndex || hasInteractiveDataAttrs || hasInteractiveAria;
22999
+ }
23000
+ var init_patch_react = __esm({
23001
+ "src/utils/patch-react.ts"() {
23002
+ "use strict";
23003
+ init_jsx_encoder();
23004
+ }
23005
+ });
23006
+
22660
23007
  // src/utils/webrtc-service.ts
22661
23008
  var webrtc_service_exports = {};
22662
23009
  __export(webrtc_service_exports, {
@@ -22668,6 +23015,7 @@ __export(webrtc_service_exports, {
22668
23015
  getRoomName: () => getRoomName,
22669
23016
  isConnected: () => isConnected,
22670
23017
  sendData: () => sendData,
23018
+ sendRuntimeData: () => sendRuntimeData,
22671
23019
  sendScreenStatus: () => sendScreenStatus,
22672
23020
  sendStaticData: () => sendStaticData,
22673
23021
  sendUserCommand: () => sendUserCommand,
@@ -22787,19 +23135,17 @@ function setupEventListeners() {
22787
23135
  }).on(RoomEvent.TrackUnsubscribed, (track) => {
22788
23136
  track.detach().forEach((element3) => element3.remove());
22789
23137
  }).on(RoomEvent.DataReceived, (payload, participant) => {
22790
- handleDataReceived(payload, participant);
23138
+ try {
23139
+ const message = JSON.parse(new TextDecoder().decode(payload));
23140
+ callbacks.onNavigationCommand?.(message);
23141
+ } catch (error) {
23142
+ const message = new TextDecoder().decode(payload);
23143
+ callbacks.onNavigationCommand?.({ type: "raw_text", data: message });
23144
+ }
22791
23145
  }).on(RoomEvent.Disconnected, () => {
22792
23146
  setWebRTCConnectionState({ isConnected: false, isConnecting: false });
22793
23147
  });
22794
23148
  }
22795
- function handleDataReceived(payload, participant) {
22796
- try {
22797
- const message = JSON.parse(new TextDecoder().decode(payload));
22798
- callbacks.onNavigationCommand?.(message);
22799
- } catch (error) {
22800
- console.error("\u{1F3A4} WebRTCService: Error parsing data:", error);
22801
- }
22802
- }
22803
23149
  function updateParticipantsList() {
22804
23150
  if (!room) return;
22805
23151
  const participants = [
@@ -22812,7 +23158,9 @@ function updateParticipantsList() {
22812
23158
  async function sendData(data, reliable = true) {
22813
23159
  if (!room) throw new Error("Not connected to room");
22814
23160
  try {
22815
- await room.localParticipant.publishData(new TextEncoder().encode(JSON.stringify(data)), {
23161
+ const encoder = new TextEncoder();
23162
+ const encodedData = encoder.encode(data);
23163
+ await room.localParticipant.publishData(encodedData, {
22816
23164
  reliable
22817
23165
  });
22818
23166
  } catch (error) {
@@ -22843,14 +23191,28 @@ function getParticipants() {
22843
23191
  }
22844
23192
  async function sendUserCommand(command) {
22845
23193
  if (!room) return;
22846
- const userCommand = {
22847
- type: "user_command",
22848
- data: {
22849
- command,
22850
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
22851
- }
22852
- };
22853
- await sendData(userCommand);
23194
+ await sendData(command);
23195
+ }
23196
+ async function sendRuntimeData() {
23197
+ if (!room) {
23198
+ console.error("\u274C Cannot send runtime data without a room connection");
23199
+ return;
23200
+ }
23201
+ try {
23202
+ const domStructure = captureFullDOMStructure();
23203
+ const screenName = getCurrentScreenName();
23204
+ const response = {
23205
+ type: "runtime_data_response",
23206
+ data: {
23207
+ components: domStructure.components,
23208
+ current_screen: screenName
23209
+ }
23210
+ };
23211
+ await sendData(JSON.stringify(response));
23212
+ console.log("\u{1F4E6} Runtime data sent successfully");
23213
+ } catch (error) {
23214
+ console.error("\u274C Failed to send runtime data:", error);
23215
+ }
22854
23216
  }
22855
23217
  async function sendStaticData(componentData, appId = "default") {
22856
23218
  try {
@@ -22881,10 +23243,6 @@ async function disconnectFromRoom() {
22881
23243
  await room.disconnect();
22882
23244
  room = null;
22883
23245
  }
22884
- if (eventSource) {
22885
- eventSource.close();
22886
- eventSource = null;
22887
- }
22888
23246
  if (reconnectTimeout) {
22889
23247
  clearTimeout(reconnectTimeout);
22890
23248
  reconnectTimeout = null;
@@ -22898,15 +23256,16 @@ async function disconnectFromRoom() {
22898
23256
  function getRoom() {
22899
23257
  return room;
22900
23258
  }
22901
- var room, eventSource, reconnectTimeout, serverUrl, callbacks, audioContainerRef, livekitUrl, token, roomName;
23259
+ var room, reconnectTimeout, serverUrl, callbacks, audioContainerRef, livekitUrl, token, roomName;
22902
23260
  var init_webrtc_service = __esm({
22903
23261
  "src/utils/webrtc-service.ts"() {
22904
23262
  "use strict";
22905
23263
  init_livekit_client_esm();
22906
23264
  init_globals();
22907
23265
  init_constants();
23266
+ init_patch_react();
23267
+ init_navigation();
22908
23268
  room = null;
22909
- eventSource = null;
22910
23269
  reconnectTimeout = null;
22911
23270
  serverUrl = WEBRTC_BACKEND_SERVER_URL || "https://bdd4c945f073.ngrok-free.app";
22912
23271
  callbacks = {};
@@ -23258,19 +23617,11 @@ __export(index_exports, {
23258
23617
  VoiceIntensityVisualizer: () => VoiceIntensityVisualizer,
23259
23618
  captureFullDOMStructure: () => captureFullDOMStructure,
23260
23619
  configureWebRTCServer: () => configureWebRTCServer,
23261
- connectSSE: () => connectSSE,
23262
- disconnectSSE: () => disconnectSSE,
23263
23620
  executeAction: () => executeAction,
23264
23621
  getFullDOMStructure: () => getFullDOMStructure,
23265
- getSSEConnectionState: () => getSSEConnectionState,
23266
- getSSEConnectionStatus: () => getSSEConnectionStatus,
23267
23622
  getWebRTCServerConfig: () => getWebRTCServerConfig,
23268
23623
  initWebRTC: () => initWebRTC,
23269
23624
  initWebRTCWithDeployedBackend: () => initWebRTCWithDeployedBackend,
23270
- sendDashboardData: () => sendDashboardData,
23271
- sendElementData: () => sendElementData,
23272
- sendRuntimeData: () => sendRuntimeData,
23273
- setSSECallbacks: () => setSSECallbacks,
23274
23625
  useCuekit: () => useCuekit,
23275
23626
  useQubeContext: () => useQubeContext,
23276
23627
  useWebRTC: () => useWebRTC
@@ -23296,204 +23647,9 @@ function InitCuekit(config) {
23296
23647
  setWebRTCConfig(webRTCConfig);
23297
23648
  }
23298
23649
 
23299
- // src/core/intent-store.ts
23300
- var store = {
23301
- screenMetadata: {},
23302
- allElementsData: []
23303
- };
23304
- var GlobalStore = {
23305
- // 🔹 Screen Metadata Methods
23306
- setMetadata(screen, metadata) {
23307
- store.screenMetadata[screen] = metadata;
23308
- },
23309
- getMetadata(screen) {
23310
- return store.screenMetadata[screen];
23311
- },
23312
- clearMetadata(screen) {
23313
- delete store.screenMetadata[screen];
23314
- },
23315
- // 🔹 Generic Store Access Methods
23316
- setData(key, value) {
23317
- store[key] = value;
23318
- },
23319
- getData(key) {
23320
- return store[key];
23321
- },
23322
- clearData(key) {
23323
- delete store[key];
23324
- },
23325
- // 🔹 Element Data Management
23326
- setElement(elementData) {
23327
- const index2 = store.allElementsData.findIndex((e3) => e3.elementId === elementData.elementId);
23328
- if (index2 >= 0) {
23329
- console.log("Updating existing element");
23330
- store.allElementsData[index2] = elementData;
23331
- } else {
23332
- console.log("Adding new element");
23333
- store.allElementsData.push(elementData);
23334
- }
23335
- },
23336
- getElementById(elementId) {
23337
- const match = store.allElementsData.find((e3) => e3.elementId === elementId);
23338
- if (!match) {
23339
- console.warn(`[GlobalStore] No element found for ID: ${elementId}`);
23340
- console.log("All elements in store:", store.allElementsData);
23341
- }
23342
- return match;
23343
- },
23344
- deleteElementById(id) {
23345
- store.allElementsData = store.allElementsData.filter((e3) => e3.elementId !== id);
23346
- },
23347
- clearAllElements() {
23348
- store.allElementsData = [];
23349
- }
23350
- };
23351
-
23352
- // src/core/navigation.ts
23353
- var navigation;
23354
- var navigationHandler = null;
23355
- function setNavigationHandler(handler) {
23356
- navigationHandler = handler;
23357
- }
23358
- function navigate(path2, params) {
23359
- const safeParams = params || {};
23360
- const absolutePath = path2.startsWith("/") ? path2 : `/${path2}`;
23361
- if (navigationHandler) {
23362
- try {
23363
- navigationHandler(absolutePath, safeParams);
23364
- } catch (error) {
23365
- console.error("[CueKit] navigation handler failed, falling back to default:", error);
23366
- }
23367
- return;
23368
- }
23369
- let fullPath = absolutePath;
23370
- if (safeParams) {
23371
- const searchParams = new URLSearchParams(safeParams).toString();
23372
- if (searchParams) {
23373
- fullPath += `?${searchParams}`;
23374
- }
23375
- }
23376
- if (navigation) {
23377
- navigation.push(fullPath);
23378
- } else {
23379
- if (typeof window !== "undefined") {
23380
- window.location.href = fullPath;
23381
- }
23382
- }
23383
- }
23384
- var getCurrentPath = () => {
23385
- if (typeof window === "undefined") return "";
23386
- return window.location.pathname;
23387
- };
23388
- var getSearchParams = () => {
23389
- if (typeof window === "undefined") return new URLSearchParams();
23390
- return new URLSearchParams(window.location.search);
23391
- };
23392
- var safeNavigate = (name2, params = {}) => {
23393
- if (name2) {
23394
- navigate(name2, params);
23395
- } else {
23396
- console.warn("[CueKit] route name not provided");
23397
- }
23398
- };
23399
- function getCurrentScreenName() {
23400
- try {
23401
- const path2 = getCurrentPath();
23402
- return path2 || "UnknownScreen";
23403
- } catch (e3) {
23404
- return "UnknownScreen";
23405
- }
23406
- }
23407
- function getCurrentRouteParams() {
23408
- try {
23409
- const params = {};
23410
- const searchParams = getSearchParams();
23411
- if (searchParams instanceof URLSearchParams) {
23412
- searchParams.forEach((value, key) => {
23413
- params[key] = value;
23414
- });
23415
- } else {
23416
- return searchParams;
23417
- }
23418
- return params;
23419
- } catch (e3) {
23420
- return {};
23421
- }
23422
- }
23423
- function onStateChange() {
23424
- const routeName = getCurrentScreenName();
23425
- const params = getCurrentRouteParams();
23426
- if (params && params.metadata) {
23427
- try {
23428
- const metadata = JSON.parse(params.metadata);
23429
- GlobalStore.setMetadata(routeName, metadata);
23430
- } catch (error) {
23431
- console.error("Failed to parse metadata from URL:", error);
23432
- }
23433
- }
23434
- }
23435
- var handleNavigationAndClick = (routeName, elementHash) => {
23436
- safeNavigate(routeName);
23437
- if (typeof MutationObserver === "undefined" || typeof document === "undefined") return;
23438
- const observer = new MutationObserver((mutationsList, observer2) => {
23439
- setTimeout(() => {
23440
- const allElements = document.querySelectorAll("*");
23441
- let elementToClick = null;
23442
- for (const element3 of allElements) {
23443
- if (element3 instanceof HTMLElement) {
23444
- const tagName = element3.tagName.toLowerCase();
23445
- const text7 = (element3.textContent || "").trim().substring(0, 50);
23446
- let sibling = element3.previousElementSibling;
23447
- let position3 = 1;
23448
- while (sibling) {
23449
- if (sibling.tagName === element3.tagName) {
23450
- position3++;
23451
- }
23452
- sibling = sibling.previousElementSibling;
23453
- }
23454
- const path2 = getElementPath(element3);
23455
- const idString = `${tagName}[${position3}]_(${text7})_${path2}`;
23456
- let hash = 0;
23457
- for (let i2 = 0; i2 < idString.length; i2++) {
23458
- const char = idString.charCodeAt(i2);
23459
- hash = (hash << 5) - hash + char;
23460
- hash |= 0;
23461
- }
23462
- const elementHashValue = hash.toString(36);
23463
- if (elementHashValue === elementHash) {
23464
- elementToClick = element3;
23465
- break;
23466
- }
23467
- }
23468
- }
23469
- if (elementToClick) {
23470
- elementToClick.click();
23471
- observer2.disconnect();
23472
- }
23473
- }, 100);
23474
- });
23475
- observer.observe(document.body, { childList: true, subtree: true });
23476
- };
23477
- function getElementPath(element3) {
23478
- if (element3.id) {
23479
- return `id(${element3.id})`;
23480
- }
23481
- const path2 = [];
23482
- let current = element3;
23483
- while (current && current !== document.body) {
23484
- let index2 = 1;
23485
- let sibling = current.previousElementSibling;
23486
- while (sibling) {
23487
- if (sibling.tagName === current.tagName) {
23488
- index2++;
23489
- }
23490
- sibling = sibling.previousElementSibling;
23491
- }
23492
- path2.unshift(`${current.tagName.toLowerCase()}[${index2}]`);
23493
- current = current.parentElement;
23494
- }
23495
- return path2.join("/");
23496
- }
23650
+ // src/providers/cuekit-provider.tsx
23651
+ init_navigation();
23652
+ init_intent_store();
23497
23653
 
23498
23654
  // src/utils/webrtc-config.ts
23499
23655
  init_constants();
@@ -23714,8 +23870,7 @@ var CuekitProvider = ({
23714
23870
  };
23715
23871
 
23716
23872
  // src/components/mic-button.tsx
23717
- var import_react9 = __toESM(require("react"));
23718
- var import_lucide_react2 = require("lucide-react");
23873
+ var import_react15 = __toESM(require("react"));
23719
23874
 
23720
23875
  // src/hooks/use-cuekit.ts
23721
23876
  var import_react3 = require("react");
@@ -23726,7 +23881,7 @@ init_livekit_client_esm();
23726
23881
  init_webrtc_service();
23727
23882
  init_globals();
23728
23883
  var useWebRTC = (options) => {
23729
- const [isConnected4, setIsConnected] = (0, import_react2.useState)(false);
23884
+ const [isConnected3, setIsConnected] = (0, import_react2.useState)(false);
23730
23885
  const [isConnecting, setIsConnecting] = (0, import_react2.useState)(false);
23731
23886
  const [connectionState, setConnectionState] = (0, import_react2.useState)(null);
23732
23887
  const [participants, setParticipants] = (0, import_react2.useState)([]);
@@ -23790,7 +23945,7 @@ var useWebRTC = (options) => {
23790
23945
  return getParticipants().map((p) => p.identity);
23791
23946
  }, [participants]);
23792
23947
  return {
23793
- isConnected: isConnected4,
23948
+ isConnected: isConnected3,
23794
23949
  isConnecting,
23795
23950
  connectionState,
23796
23951
  room: room2,
@@ -23807,335 +23962,12 @@ var useWebRTC = (options) => {
23807
23962
  };
23808
23963
  };
23809
23964
 
23810
- // src/utils/sse-service.ts
23811
- init_constants();
23812
-
23813
- // src/utils/jsx-encoder.ts
23814
- function generateStableDOMId(element3) {
23815
- const tagName = element3.tagName.toLowerCase();
23816
- const text7 = (element3.textContent || "").trim().substring(0, 50);
23817
- let sibling = element3.previousElementSibling;
23818
- let position3 = 1;
23819
- while (sibling) {
23820
- if (sibling.tagName === element3.tagName) {
23821
- position3++;
23822
- }
23823
- sibling = sibling.previousElementSibling;
23824
- }
23825
- const path2 = getElementPath2(element3);
23826
- const idString = `${tagName}[${position3}]_(${text7})_${path2}`;
23827
- let hash = 0;
23828
- for (let i2 = 0; i2 < idString.length; i2++) {
23829
- const char = idString.charCodeAt(i2);
23830
- hash = (hash << 5) - hash + char;
23831
- hash |= 0;
23832
- }
23833
- return hash.toString(36);
23834
- }
23835
- function getElementPath2(element3) {
23836
- if (element3.id) {
23837
- return `id(${element3.id})`;
23838
- }
23839
- if (element3.tagName.toLowerCase() === "body") {
23840
- return "/body";
23841
- }
23842
- let ix = 0;
23843
- const siblings = element3.parentNode?.children || new HTMLCollection();
23844
- for (let i2 = 0; i2 < siblings.length; i2++) {
23845
- const sibling = siblings[i2];
23846
- if (sibling === element3) {
23847
- return `${getElementPath2(element3.parentNode)}/${element3.tagName}[${ix + 1}]`;
23848
- }
23849
- if (sibling.nodeType === 1 && sibling.tagName === element3.tagName) {
23850
- ix++;
23851
- }
23852
- }
23853
- return "not_found";
23854
- }
23855
-
23856
- // src/utils/patch-react.ts
23857
- function getImmediateText(element3) {
23858
- let text7 = "";
23859
- if (element3.childNodes) {
23860
- for (const node2 of Array.from(element3.childNodes)) {
23861
- if (node2.nodeType === 3) {
23862
- text7 += node2.textContent || "";
23863
- }
23864
- }
23865
- }
23866
- return text7.trim();
23867
- }
23868
- function captureFullDOMStructure() {
23869
- console.log("\u{1F333} Capturing full DOM structure...");
23870
- const components = [];
23871
- const interactiveElements = document.querySelectorAll(
23872
- 'a, button, input, textarea, select, [role="button"], [onclick]'
23873
- );
23874
- interactiveElements.forEach((element3) => {
23875
- if (element3 instanceof HTMLElement && !element3.closest("[data-cuekit-ignore]")) {
23876
- const nodeData = buildFlatDOMNode(element3);
23877
- if (nodeData) {
23878
- components.push(nodeData);
23879
- }
23880
- }
23881
- });
23882
- const result = { components };
23883
- console.log("\u{1F333} Full DOM structure captured:", result);
23884
- return result;
23885
- }
23886
- function buildFlatDOMNode(element3) {
23887
- if (element3.tagName.toLowerCase() === "script" || element3.hasAttribute("data-cuekit-ignore") || element3.style.display === "none" || element3.style.visibility === "hidden") {
23888
- return null;
23889
- }
23890
- const hash = generateStableDOMId(element3);
23891
- const text7 = getImmediateText(element3).substring(0, 100);
23892
- const isClickable = isElementClickable(element3);
23893
- const componentType = element3.tagName.toLowerCase();
23894
- return {
23895
- hash,
23896
- text: text7,
23897
- isClickable,
23898
- componentType,
23899
- children: []
23900
- // No children in a flat structure
23901
- };
23902
- }
23903
- function isElementClickable(element3) {
23904
- const interactiveSelectors = [
23905
- "button",
23906
- "a",
23907
- "input",
23908
- "select",
23909
- "textarea",
23910
- '[role="button"]',
23911
- '[role="link"]',
23912
- '[role="tab"]',
23913
- "[data-onclick-id]",
23914
- "[data-on-press-id]",
23915
- "[onclick]",
23916
- "[onmousedown]",
23917
- "[onmouseup]",
23918
- "[ontouchstart]",
23919
- "[ontouchend]",
23920
- "[onkeydown]",
23921
- "[onkeyup]",
23922
- "[onkeypress]"
23923
- ];
23924
- for (const selector of interactiveSelectors) {
23925
- if (element3.matches(selector)) {
23926
- return true;
23927
- }
23928
- }
23929
- const hasClickEvents = element3.onclick !== null || element3.getAttribute("onclick") !== null;
23930
- const hasInteractiveEvents = element3.ontouchstart !== null || element3.getAttribute("ontouchstart") !== null || element3.ontouchend !== null || element3.getAttribute("ontouchend") !== null || element3.onkeydown !== null || element3.getAttribute("onkeydown") !== null || element3.onkeyup !== null || element3.getAttribute("onkeyup") !== null || element3.onkeypress !== null || element3.getAttribute("onkeypress") !== null;
23931
- const hasPointerCursor = element3.style.cursor === "pointer" || getComputedStyle(element3).cursor === "pointer";
23932
- const hasTabIndex = element3.hasAttribute("tabindex") && parseInt(element3.getAttribute("tabindex") || "0") >= 0;
23933
- const hasInteractiveDataAttrs = element3.hasAttribute("data-clickable") || element3.hasAttribute("data-interactive") || element3.hasAttribute("data-action") || element3.hasAttribute("data-handler");
23934
- const hasInteractiveAria = element3.hasAttribute("aria-pressed") || element3.hasAttribute("aria-expanded") || element3.hasAttribute("aria-selected") || element3.hasAttribute("aria-checked");
23935
- return hasClickEvents || hasInteractiveEvents || hasPointerCursor || hasTabIndex || hasInteractiveDataAttrs || hasInteractiveAria;
23936
- }
23937
-
23938
- // src/utils/sse-service.ts
23939
- init_globals();
23940
- var eventSource2 = null;
23941
- var isConnected3 = false;
23942
- var serverUrl2 = WEBRTC_BACKEND_SERVER_URL || "https://bdd4c945f073.ngrok-free.app";
23943
- var callbacks2 = {};
23944
- var sessionId = null;
23945
- function setSSECallbacks(newCallbacks) {
23946
- callbacks2 = newCallbacks;
23947
- }
23948
- async function connectSSE(newSessionId) {
23949
- if (eventSource2) {
23950
- eventSource2.close();
23951
- }
23952
- if (typeof EventSource === "undefined") {
23953
- console.warn("\u{1F527} EventSource not available, SSE functionality disabled");
23954
- callbacks2.onError?.("EventSource not available");
23955
- return;
23956
- }
23957
- try {
23958
- const url = `${serverUrl2}/navigation/stream?session_id=${newSessionId}`;
23959
- eventSource2 = new EventSource(url);
23960
- sessionId = newSessionId;
23961
- eventSource2.onopen = () => {
23962
- console.log("\u{1F517} SSE connection opened");
23963
- isConnected3 = true;
23964
- callbacks2.onConnectionChange?.(true);
23965
- };
23966
- eventSource2.onmessage = (event) => {
23967
- console.log("\u{1F4E1} SSE MESSAGE RECEIVED:", event.data);
23968
- try {
23969
- const data = JSON.parse(event.data);
23970
- console.log("\u{1F4E1} SSE MESSAGE PARSED:", data);
23971
- handleSSEMessage(data);
23972
- } catch (error) {
23973
- console.error("\u274C Failed to parse SSE message:", error);
23974
- }
23975
- };
23976
- eventSource2.onerror = (error) => {
23977
- console.error("\u274C SSE connection error:", error);
23978
- isConnected3 = false;
23979
- callbacks2.onConnectionChange?.(false);
23980
- callbacks2.onError?.("SSE connection failed");
23981
- };
23982
- } catch (error) {
23983
- console.error("\u274C Failed to create SSE connection:", error);
23984
- callbacks2.onError?.("Failed to create SSE connection");
23985
- }
23986
- }
23987
- function handleSSEMessage(data) {
23988
- console.log("\u{1F50D} Processing SSE message type:", data.type);
23989
- console.log("\u{1F50D} Full SSE data:", data);
23990
- console.log("\u{1F50D} SSE data.data:", data.data);
23991
- const actionEvent = data;
23992
- console.log("\u{1F50D} Created action event:", actionEvent);
23993
- callbacks2.onActionEvent?.(actionEvent);
23994
- switch (actionEvent.type) {
23995
- case "static_data_ready":
23996
- console.log("\u{1F4E6} Handling static_data_ready event");
23997
- callbacks2.onStaticDataUpdate?.(actionEvent.data);
23998
- break;
23999
- case "ai_intent":
24000
- console.log("\u{1F3AF} Handling ai_intent event");
24001
- callbacks2.onIntentUpdate?.(actionEvent.data);
24002
- break;
24003
- case "request_runtime_data":
24004
- console.log("\u{1F4E6} Handling request_runtime_data event");
24005
- sendRuntimeData();
24006
- break;
24007
- case "user_speech_chunk":
24008
- console.log("\u{1F464} Handling user_speech_chunk event");
24009
- const userSpeechEntry = {
24010
- speaker: "user",
24011
- text: actionEvent.data?.text_chunk,
24012
- is_final: actionEvent.data?.is_final
24013
- };
24014
- callbacks2.onConversationUpdate?.(userSpeechEntry);
24015
- break;
24016
- case "ai_speech_chunk":
24017
- console.log("\u{1F916} Handling ai_speech_chunk event");
24018
- callbacks2.onConversationUpdate?.({
24019
- speaker: "ai",
24020
- text: actionEvent.data?.text_chunk,
24021
- is_final: actionEvent.data?.is_final
24022
- });
24023
- break;
24024
- case "ai_interrupted":
24025
- console.log("\u{1F507} Handling ai_interrupted event");
24026
- break;
24027
- case "tool_log":
24028
- console.log("\u{1F527} Handling tool_log event");
24029
- callbacks2.onToolStatusUpdate?.(actionEvent.data);
24030
- break;
24031
- case "connection":
24032
- console.log("\u{1F517} Handling connection event");
24033
- break;
24034
- case "keepalive":
24035
- console.log("\u{1F493} Handling keepalive event");
24036
- break;
24037
- default:
24038
- console.log("\u{1F50D} Unknown SSE message type:", data.type);
24039
- }
24040
- }
24041
- async function sendRuntimeData() {
24042
- if (!sessionId) {
24043
- console.error("\u274C Cannot send runtime data without a session ID");
24044
- return;
24045
- }
24046
- try {
24047
- const domStructure = captureFullDOMStructure();
24048
- const screenName = getCurrentScreenName();
24049
- const response = await fetch(`${serverUrl2}/api/runtime/data/${sessionId}`, {
24050
- method: "POST",
24051
- headers: {
24052
- "Content-Type": "application/json",
24053
- Authorization: `Bearer ${_apiKey}`
24054
- },
24055
- body: JSON.stringify({
24056
- session_id: sessionId,
24057
- components: domStructure.components,
24058
- screen: screenName
24059
- })
24060
- });
24061
- if (!response.ok) {
24062
- const errorData = await response.json();
24063
- throw new Error(errorData.detail || "Failed to send runtime data");
24064
- }
24065
- console.log("\u{1F4E6} Runtime data sent successfully");
24066
- } catch (error) {
24067
- console.error("\u274C Failed to send runtime data:", error);
24068
- callbacks2.onError?.("Failed to send runtime data");
24069
- }
24070
- }
24071
- async function sendDashboardData(dashboardData) {
24072
- try {
24073
- console.log("\u{1F4E4} SSEService: Sending dashboard data...");
24074
- const response = await fetch(`${serverUrl2}/ai/data`, {
24075
- method: "POST",
24076
- headers: {
24077
- "Content-Type": "application/json"
24078
- },
24079
- body: JSON.stringify({
24080
- type: "dashboard_data",
24081
- data: dashboardData
24082
- })
24083
- });
24084
- if (!response.ok) {
24085
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
24086
- }
24087
- console.log("\u2705 SSEService: Dashboard data sent successfully");
24088
- } catch (error) {
24089
- console.error("\u274C SSEService: Failed to send dashboard data:", error);
24090
- }
24091
- }
24092
- async function sendElementData(appId = "default") {
24093
- try {
24094
- console.log("\u{1F4E4} SSEService: Sending element data...");
24095
- const domStructure = captureFullDOMStructure();
24096
- const currentPage = getCurrentScreenName();
24097
- const elementData = {
24098
- app_id: appId,
24099
- current_page: currentPage,
24100
- dom_structure: domStructure,
24101
- timestamp: Date.now()
24102
- };
24103
- const response = await fetch(`${serverUrl2}/ai/data`, {
24104
- method: "POST",
24105
- headers: {
24106
- "Content-Type": "application/json"
24107
- },
24108
- body: JSON.stringify(elementData)
24109
- });
24110
- if (!response.ok) {
24111
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
24112
- }
24113
- console.log("\u2705 SSEService: Element data sent successfully");
24114
- return elementData;
24115
- } catch (error) {
24116
- console.error("\u274C SSEService: Failed to send element data:", error);
24117
- throw error;
24118
- }
24119
- }
24120
- function disconnectSSE() {
24121
- console.log("\u{1F50C} SSEService: Disconnecting SSE...");
24122
- if (eventSource2) {
24123
- eventSource2.close();
24124
- eventSource2 = null;
24125
- }
24126
- isConnected3 = false;
24127
- callbacks2.onConnectionChange?.(false);
24128
- }
24129
- function getSSEConnectionStatus() {
24130
- return isConnected3 && eventSource2?.readyState === EventSource.OPEN;
24131
- }
24132
- function getSSEConnectionState() {
24133
- if (isConnected3 && eventSource2?.readyState === EventSource.OPEN) return "connected";
24134
- if (eventSource2?.readyState === EventSource.CONNECTING) return "connecting";
24135
- return "disconnected";
24136
- }
23965
+ // src/hooks/use-cuekit.ts
23966
+ init_webrtc_service();
24137
23967
 
24138
23968
  // src/utils/element-service.ts
23969
+ init_patch_react();
23970
+ init_navigation();
24139
23971
  function executeAction(action) {
24140
23972
  console.log("\u{1F3AF} Executing element action:", action);
24141
23973
  const { action_type, target_element, target } = action;
@@ -24320,89 +24152,83 @@ var useCuekit = (options) => {
24320
24152
  }, []);
24321
24153
  const [micState, setMicState] = (0, import_react3.useState)("idle");
24322
24154
  const [status, setStatus] = (0, import_react3.useState)("");
24323
- const [isSseConnected, setIsSseConnected] = (0, import_react3.useState)(false);
24324
- const [lastActionEvent, setLastActionEvent] = (0, import_react3.useState)(null);
24325
- (0, import_react3.useEffect)(() => {
24326
- setSSECallbacks({
24327
- onActionEvent: (event) => {
24328
- setLastActionEvent(event);
24329
- switch (event.type) {
24330
- case "user_speech_chunk":
24331
- case "ai_speech_chunk": {
24332
- const role = event.type === "user_speech_chunk" ? "user" : "ai";
24333
- if (role === "user" && currentAIMessageRef.current) {
24334
- const finalMessageId = currentAIMessageRef.current.id;
24335
- setMessages(
24336
- (prev) => prev.map((m) => m.id === finalMessageId ? { ...m, isFinal: true } : m)
24337
- );
24338
- currentAIMessageRef.current = null;
24339
- }
24340
- if (role === "ai" && currentUserMessageRef.current) {
24341
- const finalMessageId = currentUserMessageRef.current.id;
24342
- setMessages(
24343
- (prev) => prev.map((m) => m.id === finalMessageId ? { ...m, isFinal: true } : m)
24344
- );
24345
- currentUserMessageRef.current = null;
24346
- }
24347
- const entry = {
24348
- speaker: role,
24349
- text: event.data.text_chunk,
24350
- is_final: event.data.is_final,
24351
- timestamp: new Date(event.timestamp || Date.now()).toISOString()
24352
- };
24353
- handleMessageChunk(entry.text, entry.speaker, entry.is_final);
24354
- if (entry.is_final) {
24355
- if (entry.speaker === "user") {
24356
- setMicState("thinking");
24357
- } else if (entry.speaker === "ai") {
24358
- setTimeout(() => setMicState("listening"), 1e3);
24359
- }
24360
- }
24361
- break;
24362
- }
24363
- case "ai_intent": {
24364
- const intent = event.data;
24365
- if (intent.actionType === "click" && intent.actionMetadata.elementId) {
24366
- executeAction({
24367
- action_type: "click",
24368
- target_element: intent.actionMetadata.elementId
24369
- });
24370
- } else if (intent.actionType === "navigate" && intent.actionMetadata.routeName) {
24371
- executeAction({
24372
- action_type: "navigate",
24373
- target_element: intent.actionMetadata.routeName
24374
- });
24375
- }
24376
- break;
24377
- }
24378
- case "ai_interrupted": {
24379
- handleAIInterruption();
24380
- break;
24381
- }
24382
- case "keepalive": {
24383
- if (currentUserMessageRef.current) {
24384
- const finalMessageId = currentUserMessageRef.current.id;
24385
- setMessages(
24386
- (prev) => prev.map((m) => m.id === finalMessageId ? { ...m, isFinal: true } : m)
24387
- );
24388
- currentUserMessageRef.current = null;
24389
- }
24390
- if (currentAIMessageRef.current) {
24391
- const finalMessageId = currentAIMessageRef.current.id;
24392
- setMessages(
24393
- (prev) => prev.map((m) => m.id === finalMessageId ? { ...m, isFinal: true } : m)
24394
- );
24395
- currentAIMessageRef.current = null;
24396
- }
24397
- break;
24155
+ const handleNavigationCommand = (event) => {
24156
+ switch (event.type) {
24157
+ case "user_speech_chunk":
24158
+ case "ai_speech_chunk": {
24159
+ const role = event.type === "user_speech_chunk" ? "user" : "ai";
24160
+ if (role === "user" && currentAIMessageRef.current) {
24161
+ const finalMessageId = currentAIMessageRef.current.id;
24162
+ setMessages(
24163
+ (prev) => prev.map((m) => m.id === finalMessageId ? { ...m, isFinal: true } : m)
24164
+ );
24165
+ currentAIMessageRef.current = null;
24166
+ }
24167
+ if (role === "ai" && currentUserMessageRef.current) {
24168
+ const finalMessageId = currentUserMessageRef.current.id;
24169
+ setMessages(
24170
+ (prev) => prev.map((m) => m.id === finalMessageId ? { ...m, isFinal: true } : m)
24171
+ );
24172
+ currentUserMessageRef.current = null;
24173
+ }
24174
+ const entry = {
24175
+ speaker: role,
24176
+ text: event.data.text_chunk,
24177
+ is_final: event.data.is_final,
24178
+ timestamp: new Date(event.timestamp || Date.now()).toISOString()
24179
+ };
24180
+ handleMessageChunk(entry.text, entry.speaker, entry.is_final);
24181
+ if (entry.is_final) {
24182
+ if (entry.speaker === "user") {
24183
+ setMicState("thinking");
24184
+ } else if (entry.speaker === "ai") {
24185
+ setTimeout(() => setMicState("listening"), 1e3);
24398
24186
  }
24399
24187
  }
24400
- },
24401
- onConnectionChange: (isConnected4) => {
24402
- setIsSseConnected(isConnected4);
24188
+ break;
24403
24189
  }
24404
- });
24405
- }, [handleMessageChunk, handleAIInterruption]);
24190
+ case "ai_intent": {
24191
+ const intent = event.data;
24192
+ if (intent.actionType === "click" && intent.actionMetadata.elementId) {
24193
+ executeAction({
24194
+ action_type: "click",
24195
+ target_element: intent.actionMetadata.elementId
24196
+ });
24197
+ } else if (intent.actionType === "navigate" && intent.actionMetadata.routeName) {
24198
+ executeAction({
24199
+ action_type: "navigate",
24200
+ target_element: intent.actionMetadata.routeName
24201
+ });
24202
+ }
24203
+ break;
24204
+ }
24205
+ case "request_runtime_data": {
24206
+ sendRuntimeData();
24207
+ break;
24208
+ }
24209
+ case "ai_interrupted": {
24210
+ handleAIInterruption();
24211
+ break;
24212
+ }
24213
+ case "keepalive": {
24214
+ if (currentUserMessageRef.current) {
24215
+ const finalMessageId = currentUserMessageRef.current.id;
24216
+ setMessages(
24217
+ (prev) => prev.map((m) => m.id === finalMessageId ? { ...m, isFinal: true } : m)
24218
+ );
24219
+ currentUserMessageRef.current = null;
24220
+ }
24221
+ if (currentAIMessageRef.current) {
24222
+ const finalMessageId = currentAIMessageRef.current.id;
24223
+ setMessages(
24224
+ (prev) => prev.map((m) => m.id === finalMessageId ? { ...m, isFinal: true } : m)
24225
+ );
24226
+ currentAIMessageRef.current = null;
24227
+ }
24228
+ break;
24229
+ }
24230
+ }
24231
+ };
24406
24232
  const handleConnectionStateChange = (state) => {
24407
24233
  switch (state) {
24408
24234
  case "connecting":
@@ -24426,32 +24252,22 @@ var useCuekit = (options) => {
24426
24252
  };
24427
24253
  const webrtc = useWebRTC({
24428
24254
  ...options,
24429
- onConnectionStateChange: handleConnectionStateChange
24255
+ onConnectionStateChange: handleConnectionStateChange,
24256
+ onNavigationCommand: handleNavigationCommand
24430
24257
  });
24431
24258
  const connect = (0, import_react3.useCallback)(
24432
24259
  async (identity, apiKey, appId) => {
24433
- const authData = await webrtc.connect(identity, apiKey, appId);
24434
- if (authData?.session_id) {
24435
- connectSSE(authData.session_id);
24436
- }
24260
+ await webrtc.connect(identity, apiKey, appId);
24437
24261
  },
24438
24262
  [webrtc]
24439
24263
  );
24440
24264
  const disconnect = (0, import_react3.useCallback)(async () => {
24441
24265
  await webrtc.disconnect();
24442
- disconnectSSE();
24443
24266
  clearMessages();
24444
24267
  setMicState("idle");
24445
24268
  }, [webrtc, clearMessages]);
24446
- (0, import_react3.useEffect)(() => {
24447
- if (lastActionEvent?.type === "ai_interrupted") {
24448
- handleAIInterruption();
24449
- }
24450
- }, [lastActionEvent, handleAIInterruption]);
24451
24269
  return {
24452
24270
  ...webrtc,
24453
- isSseConnected,
24454
- lastActionEvent,
24455
24271
  messages,
24456
24272
  micState,
24457
24273
  setMicState,
@@ -24463,8 +24279,7 @@ var useCuekit = (options) => {
24463
24279
  };
24464
24280
 
24465
24281
  // src/components/chat-popup.tsx
24466
- var import_react5 = __toESM(require("react"));
24467
- var import_lucide_react = require("lucide-react");
24282
+ var import_react9 = __toESM(require("react"));
24468
24283
 
24469
24284
  // node_modules/devlop/lib/default.js
24470
24285
  function ok() {
@@ -37105,6 +36920,109 @@ function remarkGfm(options) {
37105
36920
  toMarkdownExtensions.push(gfmToMarkdown(settings));
37106
36921
  }
37107
36922
 
36923
+ // src/components/svgs/sun.tsx
36924
+ var import_react5 = __toESM(require("react"));
36925
+ var SunIcon = ({ width = 24, height = 24, className, ...props }) => {
36926
+ return /* @__PURE__ */ import_react5.default.createElement(
36927
+ "svg",
36928
+ {
36929
+ xmlns: "http://www.w3.org/2000/svg",
36930
+ width: "24",
36931
+ height: "24",
36932
+ viewBox: "0 0 24 24",
36933
+ fill: "none",
36934
+ stroke: "currentColor",
36935
+ "stroke-width": "2",
36936
+ "stroke-linecap": "round",
36937
+ "stroke-linejoin": "round",
36938
+ className,
36939
+ ...props
36940
+ },
36941
+ /* @__PURE__ */ import_react5.default.createElement("circle", { cx: "12", cy: "12", r: "4" }),
36942
+ /* @__PURE__ */ import_react5.default.createElement("path", { d: "M12 2v2" }),
36943
+ /* @__PURE__ */ import_react5.default.createElement("path", { d: "M12 20v2" }),
36944
+ /* @__PURE__ */ import_react5.default.createElement("path", { d: "m4.93 4.93 1.41 1.41" }),
36945
+ /* @__PURE__ */ import_react5.default.createElement("path", { d: "m17.66 17.66 1.41 1.41" }),
36946
+ /* @__PURE__ */ import_react5.default.createElement("path", { d: "M2 12h2" }),
36947
+ /* @__PURE__ */ import_react5.default.createElement("path", { d: "M20 12h2" }),
36948
+ /* @__PURE__ */ import_react5.default.createElement("path", { d: "m6.34 17.66-1.41 1.41" }),
36949
+ /* @__PURE__ */ import_react5.default.createElement("path", { d: "m19.07 4.93-1.41 1.41" })
36950
+ );
36951
+ };
36952
+ var sun_default = SunIcon;
36953
+
36954
+ // src/components/svgs/moon.tsx
36955
+ var import_react6 = __toESM(require("react"));
36956
+ var MoonIcon = ({ width = 24, height = 24, className, ...props }) => {
36957
+ return /* @__PURE__ */ import_react6.default.createElement(
36958
+ "svg",
36959
+ {
36960
+ xmlns: "http://www.w3.org/2000/svg",
36961
+ width: "24",
36962
+ height: "24",
36963
+ viewBox: "0 0 24 24",
36964
+ fill: "none",
36965
+ stroke: "currentColor",
36966
+ "stroke-width": "2",
36967
+ "stroke-linecap": "round",
36968
+ "stroke-linejoin": "round",
36969
+ className,
36970
+ ...props
36971
+ },
36972
+ /* @__PURE__ */ import_react6.default.createElement("path", { d: "M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401" })
36973
+ );
36974
+ };
36975
+ var moon_default = MoonIcon;
36976
+
36977
+ // src/components/svgs/close.tsx
36978
+ var import_react7 = __toESM(require("react"));
36979
+ var CloseIcon = ({ width = 24, height = 24, className, ...props }) => {
36980
+ return /* @__PURE__ */ import_react7.default.createElement(
36981
+ "svg",
36982
+ {
36983
+ xmlns: "http://www.w3.org/2000/svg",
36984
+ width: "24",
36985
+ height: "24",
36986
+ viewBox: "0 0 24 24",
36987
+ fill: "none",
36988
+ stroke: "currentColor",
36989
+ "stroke-width": "2",
36990
+ "stroke-linecap": "round",
36991
+ "stroke-linejoin": "round",
36992
+ className,
36993
+ ...props
36994
+ },
36995
+ /* @__PURE__ */ import_react7.default.createElement("path", { d: "M18 6 6 18" }),
36996
+ /* @__PURE__ */ import_react7.default.createElement("path", { d: "m6 6 12 12" })
36997
+ );
36998
+ };
36999
+ var close_default = CloseIcon;
37000
+
37001
+ // src/components/svgs/phone-off.tsx
37002
+ var import_react8 = __toESM(require("react"));
37003
+ var PhoneOffIcon = ({ width = 24, height = 24, className, ...props }) => {
37004
+ return /* @__PURE__ */ import_react8.default.createElement(
37005
+ "svg",
37006
+ {
37007
+ xmlns: "http://www.w3.org/2000/svg",
37008
+ width: "24",
37009
+ height: "24",
37010
+ viewBox: "0 0 24 24",
37011
+ fill: "none",
37012
+ stroke: "currentColor",
37013
+ "stroke-width": "2",
37014
+ "stroke-linecap": "round",
37015
+ "stroke-linejoin": "round",
37016
+ className,
37017
+ ...props
37018
+ },
37019
+ /* @__PURE__ */ import_react8.default.createElement("path", { d: "M10.1 13.9a14 14 0 0 0 3.732 2.668 1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2 18 18 0 0 1-12.728-5.272" }),
37020
+ /* @__PURE__ */ import_react8.default.createElement("path", { d: "M22 2 2 22" }),
37021
+ /* @__PURE__ */ import_react8.default.createElement("path", { d: "M4.76 13.582A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 .244.473" })
37022
+ );
37023
+ };
37024
+ var phone_off_default = PhoneOffIcon;
37025
+
37108
37026
  // src/components/chat-popup.tsx
37109
37027
  var ChatPopup = ({
37110
37028
  isOpen,
@@ -37115,7 +37033,7 @@ var ChatPopup = ({
37115
37033
  onSendText,
37116
37034
  onEndCall,
37117
37035
  messages,
37118
- isConnected: isConnected4,
37036
+ isConnected: isConnected3,
37119
37037
  micState,
37120
37038
  error,
37121
37039
  currentTheme = "dark",
@@ -37123,13 +37041,13 @@ var ChatPopup = ({
37123
37041
  status,
37124
37042
  anchor
37125
37043
  }) => {
37126
- const [inputText, setInputText] = (0, import_react5.useState)("");
37127
- const [isSending, setIsSending] = (0, import_react5.useState)(false);
37128
- const messagesEndRef = (0, import_react5.useRef)(null);
37044
+ const [inputText, setInputText] = (0, import_react9.useState)("");
37045
+ const [isSending, setIsSending] = (0, import_react9.useState)(false);
37046
+ const messagesEndRef = (0, import_react9.useRef)(null);
37129
37047
  const scrollToBottom = () => {
37130
37048
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
37131
37049
  };
37132
- (0, import_react5.useEffect)(() => {
37050
+ (0, import_react9.useEffect)(() => {
37133
37051
  console.log("\u{1F4EC} ChatPopup received messages:", JSON.stringify(messages, null, 2));
37134
37052
  scrollToBottom();
37135
37053
  }, [messages]);
@@ -37191,7 +37109,7 @@ var ChatPopup = ({
37191
37109
  }
37192
37110
  };
37193
37111
  const positionStyle = getPositionStyle();
37194
- return /* @__PURE__ */ import_react5.default.createElement(
37112
+ return /* @__PURE__ */ import_react9.default.createElement(
37195
37113
  "div",
37196
37114
  {
37197
37115
  "data-cuekit-ignore": true,
@@ -37214,7 +37132,7 @@ var ChatPopup = ({
37214
37132
  ...positionStyle
37215
37133
  }
37216
37134
  },
37217
- /* @__PURE__ */ import_react5.default.createElement(
37135
+ /* @__PURE__ */ import_react9.default.createElement(
37218
37136
  "div",
37219
37137
  {
37220
37138
  style: {
@@ -37225,14 +37143,14 @@ var ChatPopup = ({
37225
37143
  justifyContent: "space-between"
37226
37144
  }
37227
37145
  },
37228
- /* @__PURE__ */ import_react5.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: 0 } }, /* @__PURE__ */ import_react5.default.createElement(
37146
+ /* @__PURE__ */ import_react9.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: 0 } }, /* @__PURE__ */ import_react9.default.createElement(
37229
37147
  "img",
37230
37148
  {
37231
37149
  src: "https://dashboard.cuekit.ai/_next/image?url=%2Fimages%2Fcuekit-logo-2.png&w=256&q=100",
37232
37150
  alt: "Cuekit AI",
37233
37151
  style: { width: 58, objectFit: "cover" }
37234
37152
  }
37235
- ), /* @__PURE__ */ import_react5.default.createElement(
37153
+ ), /* @__PURE__ */ import_react9.default.createElement(
37236
37154
  "div",
37237
37155
  {
37238
37156
  style: {
@@ -37243,7 +37161,7 @@ var ChatPopup = ({
37243
37161
  justifyContent: "center"
37244
37162
  }
37245
37163
  },
37246
- /* @__PURE__ */ import_react5.default.createElement(
37164
+ /* @__PURE__ */ import_react9.default.createElement(
37247
37165
  "span",
37248
37166
  {
37249
37167
  style: {
@@ -37260,7 +37178,7 @@ var ChatPopup = ({
37260
37178
  },
37261
37179
  "Cuekit.ai"
37262
37180
  ),
37263
- /* @__PURE__ */ import_react5.default.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 4 } }, /* @__PURE__ */ import_react5.default.createElement(
37181
+ /* @__PURE__ */ import_react9.default.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 4 } }, /* @__PURE__ */ import_react9.default.createElement(
37264
37182
  "div",
37265
37183
  {
37266
37184
  style: {
@@ -37276,7 +37194,7 @@ var ChatPopup = ({
37276
37194
  fontWeight: "500"
37277
37195
  }
37278
37196
  },
37279
- /* @__PURE__ */ import_react5.default.createElement(
37197
+ /* @__PURE__ */ import_react9.default.createElement(
37280
37198
  "span",
37281
37199
  {
37282
37200
  style: {
@@ -37287,8 +37205,8 @@ var ChatPopup = ({
37287
37205
  )
37288
37206
  ))
37289
37207
  )),
37290
- /* @__PURE__ */ import_react5.default.createElement("div", { style: { minWidth: 100, textAlign: "center" } }),
37291
- /* @__PURE__ */ import_react5.default.createElement(
37208
+ /* @__PURE__ */ import_react9.default.createElement("div", { style: { minWidth: 100, textAlign: "center" } }),
37209
+ /* @__PURE__ */ import_react9.default.createElement(
37292
37210
  "div",
37293
37211
  {
37294
37212
  style: {
@@ -37300,7 +37218,7 @@ var ChatPopup = ({
37300
37218
  top: 16
37301
37219
  }
37302
37220
  },
37303
- onThemeToggle && /* @__PURE__ */ import_react5.default.createElement(
37221
+ onThemeToggle && /* @__PURE__ */ import_react9.default.createElement(
37304
37222
  "button",
37305
37223
  {
37306
37224
  onClick: () => {
@@ -37330,8 +37248,8 @@ var ChatPopup = ({
37330
37248
  "aria-label": "Toggle theme",
37331
37249
  title: `Switch to ${currentTheme === "dark" ? "light" : "dark"} mode`
37332
37250
  },
37333
- currentTheme === "dark" ? /* @__PURE__ */ import_react5.default.createElement(
37334
- import_lucide_react.Sun,
37251
+ currentTheme === "dark" ? /* @__PURE__ */ import_react9.default.createElement(
37252
+ sun_default,
37335
37253
  {
37336
37254
  style: {
37337
37255
  width: 16,
@@ -37340,8 +37258,8 @@ var ChatPopup = ({
37340
37258
  animation: "themeToggleEnter 0.3s ease-in-out"
37341
37259
  }
37342
37260
  }
37343
- ) : /* @__PURE__ */ import_react5.default.createElement(
37344
- import_lucide_react.Moon,
37261
+ ) : /* @__PURE__ */ import_react9.default.createElement(
37262
+ moon_default,
37345
37263
  {
37346
37264
  style: {
37347
37265
  width: 16,
@@ -37352,7 +37270,7 @@ var ChatPopup = ({
37352
37270
  }
37353
37271
  )
37354
37272
  ),
37355
- /* @__PURE__ */ import_react5.default.createElement(
37273
+ /* @__PURE__ */ import_react9.default.createElement(
37356
37274
  "button",
37357
37275
  {
37358
37276
  onClick: onMinimize,
@@ -37379,11 +37297,11 @@ var ChatPopup = ({
37379
37297
  "aria-label": "Minimize",
37380
37298
  title: "Minimize chat"
37381
37299
  },
37382
- /* @__PURE__ */ import_react5.default.createElement(import_lucide_react.X, { style: { width: 16, height: 16, color: "hsl(var(--voice-text-muted))" } })
37300
+ /* @__PURE__ */ import_react9.default.createElement(close_default, { style: { width: 16, height: 16, color: "hsl(var(--voice-text-muted))" } })
37383
37301
  )
37384
37302
  )
37385
37303
  ),
37386
- /* @__PURE__ */ import_react5.default.createElement(
37304
+ /* @__PURE__ */ import_react9.default.createElement(
37387
37305
  "div",
37388
37306
  {
37389
37307
  style: {
@@ -37396,7 +37314,7 @@ var ChatPopup = ({
37396
37314
  color: "hsl(var(--voice-text))"
37397
37315
  }
37398
37316
  },
37399
- messages.length === 0 ? /* @__PURE__ */ import_react5.default.createElement(
37317
+ messages.length === 0 ? /* @__PURE__ */ import_react9.default.createElement(
37400
37318
  "div",
37401
37319
  {
37402
37320
  style: {
@@ -37406,7 +37324,7 @@ var ChatPopup = ({
37406
37324
  }
37407
37325
  },
37408
37326
  "Start a conversation with CueKit AI"
37409
- ) : messages.map((message, index2) => /* @__PURE__ */ import_react5.default.createElement(
37327
+ ) : messages.map((message, index2) => /* @__PURE__ */ import_react9.default.createElement(
37410
37328
  "div",
37411
37329
  {
37412
37330
  key: index2,
@@ -37420,7 +37338,7 @@ var ChatPopup = ({
37420
37338
  justifyContent: message.sender === "user" ? "flex-end" : "flex-start"
37421
37339
  }
37422
37340
  },
37423
- message.sender === "assistant" && /* @__PURE__ */ import_react5.default.createElement(
37341
+ message.sender === "assistant" && /* @__PURE__ */ import_react9.default.createElement(
37424
37342
  "div",
37425
37343
  {
37426
37344
  style: {
@@ -37435,7 +37353,7 @@ var ChatPopup = ({
37435
37353
  overflow: "hidden"
37436
37354
  }
37437
37355
  },
37438
- /* @__PURE__ */ import_react5.default.createElement(
37356
+ /* @__PURE__ */ import_react9.default.createElement(
37439
37357
  "img",
37440
37358
  {
37441
37359
  src: "https://dashboard.cuekit.ai/_next/image?url=%2Fimages%2Fcuekit-logo-2.png&w=256&q=100",
@@ -37449,7 +37367,7 @@ var ChatPopup = ({
37449
37367
  }
37450
37368
  )
37451
37369
  ),
37452
- /* @__PURE__ */ import_react5.default.createElement(
37370
+ /* @__PURE__ */ import_react9.default.createElement(
37453
37371
  "div",
37454
37372
  {
37455
37373
  style: {
@@ -37460,7 +37378,7 @@ var ChatPopup = ({
37460
37378
  flex: 1
37461
37379
  }
37462
37380
  },
37463
- /* @__PURE__ */ import_react5.default.createElement(
37381
+ /* @__PURE__ */ import_react9.default.createElement(
37464
37382
  "div",
37465
37383
  {
37466
37384
  style: {
@@ -37478,12 +37396,12 @@ var ChatPopup = ({
37478
37396
  marginLeft: message.sender === "user" ? "auto" : 0
37479
37397
  }
37480
37398
  },
37481
- /* @__PURE__ */ import_react5.default.createElement("div", null, /* @__PURE__ */ import_react5.default.createElement(
37399
+ /* @__PURE__ */ import_react9.default.createElement("div", null, /* @__PURE__ */ import_react9.default.createElement(
37482
37400
  Markdown,
37483
37401
  {
37484
37402
  remarkPlugins: [remarkGfm],
37485
37403
  components: {
37486
- p: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37404
+ p: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37487
37405
  "p",
37488
37406
  {
37489
37407
  style: {
@@ -37494,7 +37412,7 @@ var ChatPopup = ({
37494
37412
  },
37495
37413
  children
37496
37414
  ),
37497
- h1: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37415
+ h1: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37498
37416
  "h1",
37499
37417
  {
37500
37418
  style: {
@@ -37506,7 +37424,7 @@ var ChatPopup = ({
37506
37424
  },
37507
37425
  children
37508
37426
  ),
37509
- h2: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37427
+ h2: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37510
37428
  "h2",
37511
37429
  {
37512
37430
  style: {
@@ -37518,7 +37436,7 @@ var ChatPopup = ({
37518
37436
  },
37519
37437
  children
37520
37438
  ),
37521
- h3: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37439
+ h3: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37522
37440
  "h3",
37523
37441
  {
37524
37442
  style: {
@@ -37530,7 +37448,7 @@ var ChatPopup = ({
37530
37448
  },
37531
37449
  children
37532
37450
  ),
37533
- ul: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37451
+ ul: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37534
37452
  "ul",
37535
37453
  {
37536
37454
  style: {
@@ -37542,7 +37460,7 @@ var ChatPopup = ({
37542
37460
  },
37543
37461
  children
37544
37462
  ),
37545
- ol: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37463
+ ol: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37546
37464
  "ol",
37547
37465
  {
37548
37466
  style: {
@@ -37554,7 +37472,7 @@ var ChatPopup = ({
37554
37472
  },
37555
37473
  children
37556
37474
  ),
37557
- li: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37475
+ li: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37558
37476
  "li",
37559
37477
  {
37560
37478
  style: {
@@ -37565,7 +37483,7 @@ var ChatPopup = ({
37565
37483
  },
37566
37484
  children
37567
37485
  ),
37568
- strong: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37486
+ strong: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37569
37487
  "strong",
37570
37488
  {
37571
37489
  style: {
@@ -37576,7 +37494,7 @@ var ChatPopup = ({
37576
37494
  },
37577
37495
  children
37578
37496
  ),
37579
- em: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37497
+ em: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37580
37498
  "em",
37581
37499
  {
37582
37500
  style: {
@@ -37587,7 +37505,7 @@ var ChatPopup = ({
37587
37505
  },
37588
37506
  children
37589
37507
  ),
37590
- code: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37508
+ code: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37591
37509
  "code",
37592
37510
  {
37593
37511
  style: {
@@ -37600,7 +37518,7 @@ var ChatPopup = ({
37600
37518
  },
37601
37519
  children
37602
37520
  ),
37603
- pre: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37521
+ pre: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37604
37522
  "pre",
37605
37523
  {
37606
37524
  style: {
@@ -37615,7 +37533,7 @@ var ChatPopup = ({
37615
37533
  },
37616
37534
  children
37617
37535
  ),
37618
- blockquote: ({ children }) => /* @__PURE__ */ import_react5.default.createElement(
37536
+ blockquote: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
37619
37537
  "blockquote",
37620
37538
  {
37621
37539
  style: {
@@ -37634,7 +37552,7 @@ var ChatPopup = ({
37634
37552
  message.text
37635
37553
  ))
37636
37554
  ),
37637
- message.sender === "user" && /* @__PURE__ */ import_react5.default.createElement(
37555
+ message.sender === "user" && /* @__PURE__ */ import_react9.default.createElement(
37638
37556
  "div",
37639
37557
  {
37640
37558
  style: {
@@ -37655,9 +37573,9 @@ var ChatPopup = ({
37655
37573
  )
37656
37574
  )
37657
37575
  )),
37658
- /* @__PURE__ */ import_react5.default.createElement("div", { ref: messagesEndRef })
37576
+ /* @__PURE__ */ import_react9.default.createElement("div", { ref: messagesEndRef })
37659
37577
  ),
37660
- /* @__PURE__ */ import_react5.default.createElement(
37578
+ /* @__PURE__ */ import_react9.default.createElement(
37661
37579
  "div",
37662
37580
  {
37663
37581
  style: {
@@ -37666,7 +37584,7 @@ var ChatPopup = ({
37666
37584
  background: "hsl(var(--voice-bg))"
37667
37585
  }
37668
37586
  },
37669
- /* @__PURE__ */ import_react5.default.createElement(
37587
+ /* @__PURE__ */ import_react9.default.createElement(
37670
37588
  "form",
37671
37589
  {
37672
37590
  onSubmit: (e3) => {
@@ -37675,7 +37593,7 @@ var ChatPopup = ({
37675
37593
  },
37676
37594
  style: { display: "flex", alignItems: "center", gap: 8, margin: 0 }
37677
37595
  },
37678
- /* @__PURE__ */ import_react5.default.createElement(
37596
+ /* @__PURE__ */ import_react9.default.createElement(
37679
37597
  "input",
37680
37598
  {
37681
37599
  type: "text",
@@ -37702,7 +37620,7 @@ var ChatPopup = ({
37702
37620
  }
37703
37621
  }
37704
37622
  ),
37705
- isConnected4 && onEndCall && /* @__PURE__ */ import_react5.default.createElement(
37623
+ isConnected3 && onEndCall && /* @__PURE__ */ import_react9.default.createElement(
37706
37624
  "button",
37707
37625
  {
37708
37626
  type: "submit",
@@ -37721,7 +37639,7 @@ var ChatPopup = ({
37721
37639
  cursor: "pointer"
37722
37640
  }
37723
37641
  },
37724
- /* @__PURE__ */ import_react5.default.createElement(import_lucide_react.PhoneOff, { size: 16 })
37642
+ /* @__PURE__ */ import_react9.default.createElement(phone_off_default, { style: { width: 16, height: 16 } })
37725
37643
  )
37726
37644
  )
37727
37645
  )
@@ -37729,7 +37647,7 @@ var ChatPopup = ({
37729
37647
  };
37730
37648
 
37731
37649
  // src/components/border-glow.tsx
37732
- var import_react6 = __toESM(require("react"));
37650
+ var import_react10 = __toESM(require("react"));
37733
37651
  var BorderGlow = ({ isActive }) => {
37734
37652
  if (!isActive) return null;
37735
37653
  const styles = {
@@ -37856,7 +37774,7 @@ var BorderGlow = ({ isActive }) => {
37856
37774
  opacity: 0.6
37857
37775
  }
37858
37776
  };
37859
- return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement("style", null, `
37777
+ return /* @__PURE__ */ import_react10.default.createElement(import_react10.default.Fragment, null, /* @__PURE__ */ import_react10.default.createElement("style", null, `
37860
37778
  @keyframes borderPulse {
37861
37779
  0%, 100% {
37862
37780
  opacity: 1;
@@ -37865,12 +37783,12 @@ var BorderGlow = ({ isActive }) => {
37865
37783
  opacity: 0.5;
37866
37784
  }
37867
37785
  }
37868
- `), /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.container }, /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.rightBorder1 }), /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.rightBorder2 }), /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.rightBorder3 }), /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.leftBorder1 }), /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.leftBorder2 }), /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.leftBorder3 }), /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.cornerTopLeft }), /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.cornerTopRight }), /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.cornerBottomRight }), /* @__PURE__ */ import_react6.default.createElement("div", { style: styles.cornerBottomLeft })));
37786
+ `), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.container }, /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.rightBorder1 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.rightBorder2 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.rightBorder3 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.leftBorder1 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.leftBorder2 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.leftBorder3 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.cornerTopLeft }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.cornerTopRight }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.cornerBottomRight }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.cornerBottomLeft })));
37869
37787
  };
37870
37788
  var border_glow_default = BorderGlow;
37871
37789
 
37872
37790
  // src/components/voice-intensity-visualizer.tsx
37873
- var import_react8 = __toESM(require("react"));
37791
+ var import_react12 = __toESM(require("react"));
37874
37792
 
37875
37793
  // node_modules/@livekit/components-react/dist/hooks-C2Bp5v2q.mjs
37876
37794
  var r2 = __toESM(require("react"), 1);
@@ -39516,7 +39434,7 @@ function Yt(e3, t = {}) {
39516
39434
 
39517
39435
  // node_modules/@livekit/components-react/dist/components-Bz2b1Fa9.mjs
39518
39436
  var e2 = __toESM(require("react"), 1);
39519
- var import_react7 = require("react");
39437
+ var import_react11 = require("react");
39520
39438
  init_livekit_client_esm();
39521
39439
  var Y;
39522
39440
  var ue;
@@ -39611,8 +39529,8 @@ var Dt = (t) => {
39611
39529
  };
39612
39530
  var fe2 = (t) => [[Math.floor(t / 2)], [-1]];
39613
39531
  var Ut2 = (t, n, a) => {
39614
- const [r3, c] = (0, import_react7.useState)(0), [s, o2] = (0, import_react7.useState)([[]]);
39615
- (0, import_react7.useEffect)(() => {
39532
+ const [r3, c] = (0, import_react11.useState)(0), [s, o2] = (0, import_react11.useState)([[]]);
39533
+ (0, import_react11.useEffect)(() => {
39616
39534
  if (t === "thinking")
39617
39535
  o2(fe2(n));
39618
39536
  else if (t === "connecting" || t === "initializing") {
@@ -39621,8 +39539,8 @@ var Ut2 = (t, n, a) => {
39621
39539
  } else o2(t === "listening" ? fe2(n) : t === void 0 || t === "speaking" ? [new Array(n).fill(0).map((i2, u) => u)] : [[]]);
39622
39540
  c(0);
39623
39541
  }, [t, n]);
39624
- const l = (0, import_react7.useRef)(null);
39625
- return (0, import_react7.useEffect)(() => {
39542
+ const l = (0, import_react11.useRef)(null);
39543
+ return (0, import_react11.useEffect)(() => {
39626
39544
  let i2 = performance.now();
39627
39545
  const u = (d) => {
39628
39546
  d - i2 >= a && (c((f) => f + 1), i2 = d), l.current = requestAnimationFrame(u);
@@ -39692,8 +39610,8 @@ var Xt = /* @__PURE__ */ e2.forwardRef(
39692
39610
  init_livekit_client_esm();
39693
39611
  init_webrtc_service();
39694
39612
  var VoiceIntensityWithRoom = (props) => {
39695
- const [room2, setRoom] = (0, import_react8.useState)(null);
39696
- (0, import_react8.useEffect)(() => {
39613
+ const [room2, setRoom] = (0, import_react12.useState)(null);
39614
+ (0, import_react12.useEffect)(() => {
39697
39615
  if (props.isActive) {
39698
39616
  const currentRoom = getRoom();
39699
39617
  if (currentRoom) {
@@ -39706,7 +39624,7 @@ var VoiceIntensityWithRoom = (props) => {
39706
39624
  if (!room2) {
39707
39625
  return null;
39708
39626
  }
39709
- return /* @__PURE__ */ import_react8.default.createElement(Wn.Provider, { value: room2 }, /* @__PURE__ */ import_react8.default.createElement(VoiceIntensityBars, { ...props }));
39627
+ return /* @__PURE__ */ import_react12.default.createElement(Wn.Provider, { value: room2 }, /* @__PURE__ */ import_react12.default.createElement(VoiceIntensityBars, { ...props }));
39710
39628
  };
39711
39629
  var VoiceIntensityBars = ({
39712
39630
  isActive,
@@ -39769,7 +39687,7 @@ var VoiceIntensityBars = ({
39769
39687
  if (!trackRef) {
39770
39688
  return null;
39771
39689
  }
39772
- return /* @__PURE__ */ import_react8.default.createElement(
39690
+ return /* @__PURE__ */ import_react12.default.createElement(
39773
39691
  "div",
39774
39692
  {
39775
39693
  className: `voice-intensity-visualizer ${className}`,
@@ -39786,16 +39704,21 @@ var VoiceIntensityBars = ({
39786
39704
  pointerEvents: "none"
39787
39705
  }
39788
39706
  },
39789
- /* @__PURE__ */ import_react8.default.createElement(
39707
+ /* @__PURE__ */ import_react12.default.createElement(
39790
39708
  Xt,
39791
39709
  {
39792
39710
  barCount,
39793
39711
  state: "speaking",
39794
39712
  options: { minHeight },
39795
39713
  trackRef,
39796
- className: "flex items-center justify-center gap-1"
39714
+ style: {
39715
+ display: "flex",
39716
+ alignItems: "center",
39717
+ justifyContent: "center",
39718
+ gap: "0.25rem"
39719
+ }
39797
39720
  },
39798
- /* @__PURE__ */ import_react8.default.createElement("span", { className: "bg-muted min-h-4 w-4 rounded-full origin-center transition-colors duration-250 ease-linear data-[lk-highlighted=true]:bg-foreground data-[lk-muted=true]:bg-muted" })
39721
+ /* @__PURE__ */ import_react12.default.createElement("span", { className: "cuekit-voice-intensity-bar" })
39799
39722
  )
39800
39723
  );
39801
39724
  };
@@ -39803,12 +39726,62 @@ var VoiceIntensityVisualizer = VoiceIntensityWithRoom;
39803
39726
 
39804
39727
  // src/components/mic-button.tsx
39805
39728
  init_webrtc_service();
39729
+
39730
+ // src/components/svgs/mic.tsx
39731
+ var import_react13 = __toESM(require("react"));
39732
+ var MicIcon = ({ width = 24, height = 24, className, ...props }) => {
39733
+ return /* @__PURE__ */ import_react13.default.createElement(
39734
+ "svg",
39735
+ {
39736
+ xmlns: "http://www.w3.org/2000/svg",
39737
+ width,
39738
+ height,
39739
+ viewBox: "0 0 24 24",
39740
+ fill: "none",
39741
+ stroke: "currentColor",
39742
+ "stroke-width": "2",
39743
+ "stroke-linecap": "round",
39744
+ "stroke-linejoin": "round",
39745
+ className,
39746
+ ...props
39747
+ },
39748
+ /* @__PURE__ */ import_react13.default.createElement("path", { d: "M12 19v3" }),
39749
+ /* @__PURE__ */ import_react13.default.createElement("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
39750
+ /* @__PURE__ */ import_react13.default.createElement("rect", { x: "9", y: "2", width: "6", height: "13", rx: "3" })
39751
+ );
39752
+ };
39753
+ var mic_default = MicIcon;
39754
+
39755
+ // src/components/svgs/loader.tsx
39756
+ var import_react14 = __toESM(require("react"));
39757
+ var LoaderIcon = ({ width = 24, height = 24, className, ...props }) => {
39758
+ return /* @__PURE__ */ import_react14.default.createElement(
39759
+ "svg",
39760
+ {
39761
+ xmlns: "http://www.w3.org/2000/svg",
39762
+ width: "24",
39763
+ height: "24",
39764
+ viewBox: "0 0 24 24",
39765
+ fill: "none",
39766
+ stroke: "currentColor",
39767
+ "stroke-width": "2",
39768
+ "stroke-linecap": "round",
39769
+ "stroke-linejoin": "round",
39770
+ className,
39771
+ ...props
39772
+ },
39773
+ /* @__PURE__ */ import_react14.default.createElement("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
39774
+ );
39775
+ };
39776
+ var loader_default = LoaderIcon;
39777
+
39778
+ // src/components/mic-button.tsx
39806
39779
  var chatState = {
39807
39780
  isOpen: false,
39808
39781
  isMinimized: false
39809
39782
  };
39810
39783
  var VoiceIntensityWrapper = ({ active, buttonSize }) => {
39811
- return /* @__PURE__ */ import_react9.default.createElement(
39784
+ return /* @__PURE__ */ import_react15.default.createElement(
39812
39785
  VoiceIntensityVisualizer,
39813
39786
  {
39814
39787
  isActive: active,
@@ -39832,27 +39805,26 @@ var MicButton = ({
39832
39805
  showBorderGlow = false
39833
39806
  }) => {
39834
39807
  const { apiKey, appId } = useQubeContext();
39835
- const [showBodyGlow, setShowBodyGlow] = (0, import_react9.useState)(false);
39836
- const [currentTheme, setCurrentTheme] = (0, import_react9.useState)("dark");
39837
- const [isChatOpen, setIsChatOpen] = (0, import_react9.useState)(chatState.isOpen);
39838
- const [isChatMinimized, setIsChatMinimized] = (0, import_react9.useState)(chatState.isMinimized);
39839
- (0, import_react9.useEffect)(() => {
39808
+ const [showBodyGlow, setShowBodyGlow] = (0, import_react15.useState)(false);
39809
+ const [currentTheme, setCurrentTheme] = (0, import_react15.useState)("dark");
39810
+ const [isChatOpen, setIsChatOpen] = (0, import_react15.useState)(chatState.isOpen);
39811
+ const [isChatMinimized, setIsChatMinimized] = (0, import_react15.useState)(chatState.isMinimized);
39812
+ (0, import_react15.useEffect)(() => {
39840
39813
  chatState.isOpen = isChatOpen;
39841
39814
  chatState.isMinimized = isChatMinimized;
39842
39815
  }, [isChatOpen, isChatMinimized]);
39843
- const audioContainerRef2 = (0, import_react9.useRef)(null);
39844
- const silenceTimerRef = (0, import_react9.useRef)(null);
39845
- const aiSpeakingRef = (0, import_react9.useRef)(false);
39846
- const aiSpeechTimeoutRef = (0, import_react9.useRef)(null);
39847
- const activeAITracksRef = (0, import_react9.useRef)(/* @__PURE__ */ new Set());
39816
+ const audioContainerRef2 = (0, import_react15.useRef)(null);
39817
+ const silenceTimerRef = (0, import_react15.useRef)(null);
39818
+ const aiSpeakingRef = (0, import_react15.useRef)(false);
39819
+ const aiSpeechTimeoutRef = (0, import_react15.useRef)(null);
39820
+ const activeAITracksRef = (0, import_react15.useRef)(/* @__PURE__ */ new Set());
39848
39821
  const {
39849
- isConnected: isConnected4,
39822
+ isConnected: isConnected3,
39850
39823
  isConnecting,
39851
39824
  error: voiceError,
39852
39825
  connect: voiceConnect,
39853
39826
  disconnect: voiceDisconnect,
39854
39827
  sendUserCommand: sendUserCommand2,
39855
- lastActionEvent,
39856
39828
  messages: messageManagerMessages,
39857
39829
  micState,
39858
39830
  setMicState,
@@ -39873,10 +39845,10 @@ var MicButton = ({
39873
39845
  onAISpeechEnd: (trackId) => handleAISpeech(false, trackId),
39874
39846
  appId
39875
39847
  });
39876
- (0, import_react9.useEffect)(() => {
39848
+ (0, import_react15.useEffect)(() => {
39877
39849
  console.log("\u{1F3A4} MicButton received messages:", JSON.stringify(messageManagerMessages, null, 2));
39878
39850
  }, [messageManagerMessages]);
39879
- (0, import_react9.useEffect)(() => {
39851
+ (0, import_react15.useEffect)(() => {
39880
39852
  const checkTheme = () => {
39881
39853
  if (typeof document !== "undefined") {
39882
39854
  let newTheme;
@@ -39899,31 +39871,31 @@ var MicButton = ({
39899
39871
  return () => observer.disconnect();
39900
39872
  }
39901
39873
  }, [defaultTheme]);
39902
- const openChat = (0, import_react9.useCallback)(() => {
39874
+ const openChat = (0, import_react15.useCallback)(() => {
39903
39875
  setIsChatOpen(true);
39904
39876
  setIsChatMinimized(false);
39905
39877
  }, []);
39906
- const minimizeChat = (0, import_react9.useCallback)(() => {
39878
+ const minimizeChat = (0, import_react15.useCallback)(() => {
39907
39879
  setIsChatMinimized(true);
39908
39880
  if (showBorderGlow) {
39909
39881
  setShowBodyGlow(false);
39910
39882
  }
39911
39883
  }, [showBorderGlow]);
39912
- const restoreChat = (0, import_react9.useCallback)(() => {
39884
+ const restoreChat = (0, import_react15.useCallback)(() => {
39913
39885
  setIsChatMinimized(false);
39914
39886
  setIsChatOpen(true);
39915
39887
  if (showBorderGlow && (micState === "listening" || micState === "thinking" || micState === "replying")) {
39916
39888
  setShowBodyGlow(true);
39917
39889
  }
39918
39890
  }, [showBorderGlow, micState]);
39919
- const closeChat = (0, import_react9.useCallback)(() => {
39891
+ const closeChat = (0, import_react15.useCallback)(() => {
39920
39892
  setIsChatOpen(false);
39921
39893
  setIsChatMinimized(false);
39922
39894
  if (showBorderGlow) {
39923
39895
  setShowBodyGlow(false);
39924
39896
  }
39925
39897
  }, [showBorderGlow]);
39926
- const handleAISpeech = (0, import_react9.useCallback)(
39898
+ const handleAISpeech = (0, import_react15.useCallback)(
39927
39899
  (isSpeaking, trackId) => {
39928
39900
  console.log("\u{1F3A4} MicButton: ===== AI SPEECH EVENT START =====");
39929
39901
  console.log("\u{1F3A4} MicButton: Event type:", isSpeaking ? "START" : "END");
@@ -39932,8 +39904,8 @@ var MicButton = ({
39932
39904
  console.log("\u{1F3A4} MicButton: Current active AI tracks:", Array.from(activeAITracksRef.current));
39933
39905
  console.log("\u{1F3A4} MicButton: Current status:", status);
39934
39906
  console.log("\u{1F3A4} MicButton: Current mic state:", micState);
39935
- console.log("\u{1F3A4} MicButton: Is listening:", isConnected4);
39936
- console.log("\u{1F3A4} MicButton: Is connected:", isConnected4);
39907
+ console.log("\u{1F3A4} MicButton: Is listening:", isConnected3);
39908
+ console.log("\u{1F3A4} MicButton: Is connected:", isConnected3);
39937
39909
  if (isSpeaking && trackId) {
39938
39910
  console.log("\u{1F3A4} MicButton: ===== AI SPEECH START =====");
39939
39911
  console.log("\u{1F3A4} MicButton: Adding track to active set:", trackId);
@@ -39988,9 +39960,9 @@ var MicButton = ({
39988
39960
  console.log("\u{1F3A4} MicButton: - Status:", status);
39989
39961
  console.log("\u{1F3A4} MicButton: ================================");
39990
39962
  },
39991
- [status, micState, isConnected4]
39963
+ [status, micState, isConnected3]
39992
39964
  );
39993
- (0, import_react9.useEffect)(() => {
39965
+ (0, import_react15.useEffect)(() => {
39994
39966
  if (audioContainerRef2.current) {
39995
39967
  console.log("\u{1F3A4} MicButton: Setting up audio container on mount");
39996
39968
  setAudioContainer(audioContainerRef2);
@@ -40001,10 +39973,9 @@ var MicButton = ({
40001
39973
  }
40002
39974
  };
40003
39975
  }, [handleAISpeech]);
40004
- const isListening = isConnected4;
40005
- const transcript = (lastActionEvent?.type === "user_speech_chunk" || lastActionEvent?.type === "ai_speech_chunk") && lastActionEvent?.data?.text_chunk ? lastActionEvent.data.text_chunk : "";
40006
- const getUserFriendlyStatus = (micState2, isConnected5) => {
40007
- if (!isConnected5) {
39976
+ const isListening = isConnected3;
39977
+ const getUserFriendlyStatus = (micState2, isConnected4) => {
39978
+ if (!isConnected4) {
40008
39979
  return "Connecting...";
40009
39980
  }
40010
39981
  if (status && !status.includes("error") && !status.includes("failed") && !status.includes("Connection error") && !status.includes("Unable to")) {
@@ -40014,36 +39985,36 @@ var MicButton = ({
40014
39985
  if (micState2 === "thinking") return "Thinking...";
40015
39986
  if (micState2 === "replying") return "Responding...";
40016
39987
  if (micState2 === "idle") {
40017
- if (isConnected5) return "Listening...";
39988
+ if (isConnected4) return "Listening...";
40018
39989
  return "Connecting...";
40019
39990
  }
40020
- return isConnected5 ? "Ready" : "Connecting...";
39991
+ return isConnected4 ? "Ready" : "Connecting...";
40021
39992
  };
40022
- (0, import_react9.useEffect)(() => {
40023
- if (isConnected4) {
39993
+ (0, import_react15.useEffect)(() => {
39994
+ if (isConnected3) {
40024
39995
  console.log("\u{1F3A4} MicButton: WebRTC and SSE connections established - ready for commands");
40025
39996
  } else {
40026
39997
  console.log("\u{1F3A4} MicButton: WebRTC not yet connected - ignoring speech");
40027
39998
  }
40028
- }, [isConnected4]);
40029
- (0, import_react9.useEffect)(() => {
39999
+ }, [isConnected3]);
40000
+ (0, import_react15.useEffect)(() => {
40030
40001
  console.log("\u{1F3A4} MicButton: Auto-open check:", {
40031
- isConnected: isConnected4,
40002
+ isConnected: isConnected3,
40032
40003
  chatIsOpen: isChatOpen
40033
40004
  });
40034
- if (isConnected4 && !isChatOpen) {
40005
+ if (isConnected3 && !isChatOpen) {
40035
40006
  console.log("\u{1F3A4} MicButton: Auto-opening chat popup");
40036
40007
  openChat();
40037
40008
  }
40038
- }, [isConnected4, isChatOpen, openChat]);
40039
- (0, import_react9.useEffect)(() => {
40009
+ }, [isConnected3, isChatOpen, openChat]);
40010
+ (0, import_react15.useEffect)(() => {
40040
40011
  if (messageManagerMessages.length > 0 && !isChatOpen) {
40041
40012
  console.log("\u{1F3A4} MicButton: Auto-opening chat popup due to messages");
40042
40013
  openChat();
40043
40014
  }
40044
40015
  }, [messageManagerMessages.length, isChatOpen, openChat]);
40045
- const handleMicClick = (0, import_react9.useCallback)(() => {
40046
- const shouldStop = micState === "listening" && isConnected4;
40016
+ const handleMicClick = (0, import_react15.useCallback)(() => {
40017
+ const shouldStop = micState === "listening" && isConnected3;
40047
40018
  if (shouldStop) {
40048
40019
  console.log("\u{1F3A4} MicButton: User wants to stop - closing everything");
40049
40020
  voiceDisconnect().then(() => {
@@ -40068,7 +40039,7 @@ var MicButton = ({
40068
40039
  }
40069
40040
  }, [
40070
40041
  micState,
40071
- isConnected4,
40042
+ isConnected3,
40072
40043
  voiceDisconnect,
40073
40044
  voiceConnect,
40074
40045
  apiKey,
@@ -40076,19 +40047,6 @@ var MicButton = ({
40076
40047
  openChat,
40077
40048
  showBorderGlow
40078
40049
  ]);
40079
- (0, import_react9.useEffect)(() => {
40080
- if (!isConnected4) {
40081
- return;
40082
- }
40083
- if (transcript && transcript.trim() && !aiSpeakingRef.current) {
40084
- console.log("\u{1F3A4} MicButton: Processing new transcript:", transcript);
40085
- sendUserCommand2(transcript).then(() => {
40086
- console.log("\u{1F3A4} MicButton: User command sent successfully");
40087
- }).catch((error) => {
40088
- console.error("\u{1F3A4} MicButton: Failed to send user command:", error);
40089
- });
40090
- }
40091
- }, [transcript, isConnected4, sendUserCommand2]);
40092
40050
  const handleSendText = async (textToSend) => {
40093
40051
  console.log("\u{1F3A4} MicButton: handleSendText called with:", textToSend);
40094
40052
  setMicState("thinking");
@@ -40096,7 +40054,7 @@ var MicButton = ({
40096
40054
  if (!isChatOpen) {
40097
40055
  openChat();
40098
40056
  }
40099
- if (isConnected4) {
40057
+ if (isConnected3) {
40100
40058
  console.log("\u{1F3A4} MicButton: Sending via WebRTC");
40101
40059
  try {
40102
40060
  await sendUserCommand2(textToSend);
@@ -40139,7 +40097,7 @@ var MicButton = ({
40139
40097
  ...imageStyle
40140
40098
  };
40141
40099
  const animatedImageStyle = micState === "thinking" ? { ...baseImageStyle, animation: "spin 1s linear infinite" } : micState === "replying" ? { ...baseImageStyle, animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite" } : baseImageStyle;
40142
- return /* @__PURE__ */ import_react9.default.createElement("img", { src: imageSource, alt: "Voice Assistant", style: animatedImageStyle });
40100
+ return /* @__PURE__ */ import_react15.default.createElement("img", { src: imageSource, alt: "Voice Assistant", style: animatedImageStyle });
40143
40101
  }
40144
40102
  const iconStyle = {
40145
40103
  width: `100%`,
@@ -40149,13 +40107,13 @@ var MicButton = ({
40149
40107
  };
40150
40108
  switch (micState) {
40151
40109
  case "thinking":
40152
- return /* @__PURE__ */ import_react9.default.createElement(import_lucide_react2.Loader2, { style: { ...iconStyle, animation: "spin 1s linear infinite" } });
40110
+ return /* @__PURE__ */ import_react15.default.createElement(loader_default, { style: { ...iconStyle, animation: "spin 1s linear infinite" } });
40153
40111
  case "replying":
40154
- return /* @__PURE__ */ import_react9.default.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
40112
+ return /* @__PURE__ */ import_react15.default.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
40155
40113
  case "listening":
40156
- return /* @__PURE__ */ import_react9.default.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
40114
+ return /* @__PURE__ */ import_react15.default.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
40157
40115
  default:
40158
- return /* @__PURE__ */ import_react9.default.createElement(import_lucide_react2.Mic, { style: iconStyle });
40116
+ return /* @__PURE__ */ import_react15.default.createElement(mic_default, { style: iconStyle });
40159
40117
  }
40160
40118
  };
40161
40119
  const getPositionStyle = () => {
@@ -40235,7 +40193,7 @@ var MicButton = ({
40235
40193
  }
40236
40194
  return baseStyle;
40237
40195
  };
40238
- return /* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, /* @__PURE__ */ import_react9.default.createElement("div", { "data-cuekit-ignore": true, style: { ...buttonStyles.container, ...getPositionStyle() } }, /* @__PURE__ */ import_react9.default.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "8px" } }, /* @__PURE__ */ import_react9.default.createElement(
40196
+ return /* @__PURE__ */ import_react15.default.createElement(import_react15.default.Fragment, null, /* @__PURE__ */ import_react15.default.createElement("div", { "data-cuekit-ignore": true, style: { ...buttonStyles.container, ...getPositionStyle() } }, /* @__PURE__ */ import_react15.default.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "8px" } }, /* @__PURE__ */ import_react15.default.createElement(
40239
40197
  "button",
40240
40198
  {
40241
40199
  "data-testid": "ignore",
@@ -40256,8 +40214,8 @@ var MicButton = ({
40256
40214
  },
40257
40215
  "aria-label": micState === "thinking" ? "Processing..." : micState === "replying" ? "AI is responding..." : isListening ? "Stop listening" : "Start listening"
40258
40216
  },
40259
- /* @__PURE__ */ import_react9.default.createElement("div", { style: buttonStyles.iconContainer }, getIcon())
40260
- ), hasText && text7 && /* @__PURE__ */ import_react9.default.createElement(
40217
+ /* @__PURE__ */ import_react15.default.createElement("div", { style: buttonStyles.iconContainer }, getIcon())
40218
+ ), hasText && text7 && /* @__PURE__ */ import_react15.default.createElement(
40261
40219
  "div",
40262
40220
  {
40263
40221
  style: {
@@ -40278,8 +40236,8 @@ var MicButton = ({
40278
40236
  ...textStyle
40279
40237
  }
40280
40238
  },
40281
- /* @__PURE__ */ import_react9.default.createElement("span", null, text7)
40282
- ))), /* @__PURE__ */ import_react9.default.createElement(
40239
+ /* @__PURE__ */ import_react15.default.createElement("span", null, text7)
40240
+ ))), /* @__PURE__ */ import_react15.default.createElement(
40283
40241
  ChatPopup,
40284
40242
  {
40285
40243
  isOpen: isChatOpen,
@@ -40293,16 +40251,16 @@ var MicButton = ({
40293
40251
  text: msg.text,
40294
40252
  sender: msg.role === "ai" ? "assistant" : "user"
40295
40253
  })),
40296
- isConnected: isConnected4 ?? false,
40254
+ isConnected: isConnected3 ?? false,
40297
40255
  micState,
40298
40256
  participants,
40299
40257
  error: voiceError,
40300
40258
  currentTheme,
40301
40259
  onThemeToggle: setCurrentTheme,
40302
- status: getUserFriendlyStatus(micState, isConnected4 ?? false),
40260
+ status: getUserFriendlyStatus(micState, isConnected3 ?? false),
40303
40261
  anchor: { position: screenPosition, bottom: bottomSpace, size: buttonSize }
40304
40262
  }
40305
- ), isChatOpen && isChatMinimized && /* @__PURE__ */ import_react9.default.createElement(
40263
+ ), isChatOpen && isChatMinimized && /* @__PURE__ */ import_react15.default.createElement(
40306
40264
  "button",
40307
40265
  {
40308
40266
  onClick: restoreChat,
@@ -40323,6 +40281,9 @@ var MicButton = ({
40323
40281
  className: `cuekit-voice-popup ${currentTheme === "dark" ? "cuekit-dark" : ""}`,
40324
40282
  "aria-label": "Open chat"
40325
40283
  },
40326
- /* @__PURE__ */ import_react9.default.createElement("span", { style: { fontSize: 12, fontWeight: 600, color: "hsl(var(--voice-text))" } }, "Open chat")
40327
- ), /* @__PURE__ */ import_react9.default.createElement("div", { ref: audioContainerRef2, style: { display: "none" } }), showBorderGlow && showBodyGlow && /* @__PURE__ */ import_react9.default.createElement(border_glow_default, { isActive: true }));
40284
+ /* @__PURE__ */ import_react15.default.createElement("span", { style: { fontSize: 12, fontWeight: 600, color: "hsl(var(--voice-text))" } }, "Open chat")
40285
+ ), /* @__PURE__ */ import_react15.default.createElement("div", { ref: audioContainerRef2, style: { display: "none" } }), showBorderGlow && showBodyGlow && /* @__PURE__ */ import_react15.default.createElement(border_glow_default, { isActive: true }));
40328
40286
  };
40287
+
40288
+ // src/index.ts
40289
+ init_patch_react();