@contentgrowth/llm-service 0.9.96 → 0.9.98

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.
@@ -300,6 +300,10 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
300
300
  recognition.onend = () => {
301
301
  console.log("[useSpeechRecognition] Native onend event fired. Timestamp:", Date.now());
302
302
  isStartingRef.current = false;
303
+ if (recognitionRef.current === recognition) {
304
+ console.log("[useSpeechRecognition] Nullifying recognitionRef (onend)");
305
+ recognitionRef.current = null;
306
+ }
303
307
  if (isSimulatingRef.current) {
304
308
  console.log("[useSpeechRecognition] onend ignored - simulating");
305
309
  return;
@@ -345,6 +349,10 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
345
349
  } else if (event.error === "network") {
346
350
  console.error("[useSpeechRecognition] - network: Network error during recognition");
347
351
  }
352
+ if (recognitionRef.current === recognition) {
353
+ console.log("[useSpeechRecognition] Nullifying recognitionRef (onerror)");
354
+ recognitionRef.current = null;
355
+ }
348
356
  isStartingRef.current = false;
349
357
  if (event.error === "not-allowed" && process.env.NODE_ENV === "development") {
350
358
  console.warn("Speech recognition blocked. Simulating input for development...");
@@ -405,6 +413,8 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
405
413
  if (recognitionRef.current) {
406
414
  console.log("[useSpeechRecognition] Stopping existing instance before creating new one");
407
415
  try {
416
+ recognitionRef.current.onend = null;
417
+ recognitionRef.current.onerror = null;
408
418
  recognitionRef.current.stop();
409
419
  } catch (e) {
410
420
  }
@@ -599,7 +609,7 @@ var ChatInputArea = (0, import_react5.forwardRef)(({
599
609
  if (typeof arg === "object") return JSON.stringify(arg);
600
610
  return String(arg);
601
611
  }).join(" ");
602
- setLogs((prev) => [`[${formatTime()}] [${type}] ${msg}`, ...prev].slice(0, 50));
612
+ setLogs((prev) => [...prev, `[${formatTime()}] [${type}] ${msg}`].slice(-50));
603
613
  } catch (e) {
604
614
  }
605
615
  };
@@ -763,63 +773,50 @@ var ChatInputArea = (0, import_react5.forwardRef)(({
763
773
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || "ontouchstart" in window || navigator.maxTouchPoints > 0;
764
774
  }, []);
765
775
  const startRecording = async (trigger) => {
776
+ var _a2, _b2;
766
777
  console.log("[ChatInputArea] startRecording called. trigger:", trigger, "isMobile:", isMobile());
767
778
  console.log("[ChatInputArea] Current state - voiceTrigger:", voiceTrigger, "isTranscribing:", isTranscribing);
768
779
  if (voiceTrigger || isTranscribing) {
769
780
  console.log("[ChatInputArea] startRecording ignored - already active");
770
781
  return;
771
782
  }
772
- const performStart = async () => {
773
- var _a2, _b2;
774
- setVoiceTrigger(trigger);
775
- setVoiceError(null);
776
- if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") {
777
- console.log("[ChatInputArea] Using native speech recognition");
778
- if (!nativeSpeech.isSupported) {
779
- console.error("[ChatInputArea] Native speech not supported");
780
- alert("Speech recognition is not supported in this browser.");
781
- setVoiceTrigger(null);
782
- return;
783
- }
784
- console.log("[ChatInputArea] Calling nativeSpeech.start()...");
785
- nativeSpeech.start();
786
- console.log("[ChatInputArea] nativeSpeech.start() called");
787
- console.log("[ChatInputArea] Calling voiceConfig.onVoiceStart if exists (after nativeSpeech.start)...");
788
- try {
789
- (_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceStart) == null ? void 0 : _a2.call(voiceConfig);
790
- console.log("[ChatInputArea] voiceConfig.onVoiceStart completed");
791
- } catch (e) {
792
- console.error("[ChatInputArea] voiceConfig.onVoiceStart threw error", e);
793
- }
794
- } else {
795
- console.log("[ChatInputArea] Using custom recorder");
796
- console.log("[ChatInputArea] Calling voiceConfig.onVoiceStart if exists (custom mode)...");
797
- try {
798
- (_b2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceStart) == null ? void 0 : _b2.call(voiceConfig);
799
- console.log("[ChatInputArea] voiceConfig.onVoiceStart completed");
800
- } catch (e) {
801
- console.error("[ChatInputArea] voiceConfig.onVoiceStart threw error", e);
802
- }
803
- await customRecorder.start();
804
- console.log("[ChatInputArea] Custom recorder started");
783
+ setVoiceTrigger(trigger);
784
+ setVoiceError(null);
785
+ if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") {
786
+ console.log("[ChatInputArea] Using native speech recognition");
787
+ if (!nativeSpeech.isSupported) {
788
+ console.error("[ChatInputArea] Native speech not supported");
789
+ alert("Speech recognition is not supported in this browser.");
790
+ setVoiceTrigger(null);
791
+ return;
805
792
  }
806
- };
807
- if (isMobile()) {
808
- console.log("[ChatInputArea] SKIPPING textarea focus on mobile to prevent keyboard conflict");
809
- if (document.activeElement instanceof HTMLElement) {
810
- console.log("[ChatInputArea] Blur active element on mobile BEFORE start");
811
- document.activeElement.blur();
793
+ console.log("[ChatInputArea] Calling nativeSpeech.start()...");
794
+ nativeSpeech.start();
795
+ console.log("[ChatInputArea] nativeSpeech.start() called");
796
+ console.log("[ChatInputArea] Calling voiceConfig.onVoiceStart if exists...");
797
+ try {
798
+ (_a2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceStart) == null ? void 0 : _a2.call(voiceConfig);
799
+ console.log("[ChatInputArea] voiceConfig.onVoiceStart completed");
800
+ } catch (e) {
801
+ console.error("[ChatInputArea] voiceConfig.onVoiceStart threw error", e);
812
802
  }
813
- console.log("[ChatInputArea] Mobile: Waiting 300ms before starting recognition...");
814
- setTimeout(() => {
815
- performStart();
816
- }, 300);
817
803
  } else {
818
- await performStart();
804
+ console.log("[ChatInputArea] Using custom recorder");
805
+ console.log("[ChatInputArea] Calling voiceConfig.onVoiceStart if exists (custom mode)...");
806
+ try {
807
+ (_b2 = voiceConfig == null ? void 0 : voiceConfig.onVoiceStart) == null ? void 0 : _b2.call(voiceConfig);
808
+ console.log("[ChatInputArea] voiceConfig.onVoiceStart completed");
809
+ } catch (e) {
810
+ console.error("[ChatInputArea] voiceConfig.onVoiceStart threw error", e);
811
+ }
812
+ await customRecorder.start();
813
+ console.log("[ChatInputArea] Custom recorder started");
814
+ }
815
+ if (!isMobile()) {
819
816
  console.log("[ChatInputArea] Re-focusing textarea (desktop only)");
820
817
  setTimeout(() => {
821
- var _a2;
822
- return (_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
818
+ var _a3;
819
+ return (_a3 = textareaRef.current) == null ? void 0 : _a3.focus();
823
820
  }, 0);
824
821
  }
825
822
  };
@@ -1044,7 +1041,7 @@ var TapToTalk = ({
1044
1041
  if (typeof arg === "object") return JSON.stringify(arg);
1045
1042
  return String(arg);
1046
1043
  }).join(" ");
1047
- setLogs((prev) => [`[${formatTime()}] [${type}] ${msg}`, ...prev].slice(0, 50));
1044
+ setLogs((prev) => [...prev, `[${formatTime()}] [${type}] ${msg}`].slice(-50));
1048
1045
  } catch (e) {
1049
1046
  }
1050
1047
  };
@@ -1119,10 +1116,6 @@ var TapToTalk = ({
1119
1116
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || "ontouchstart" in window || navigator.maxTouchPoints > 0;
1120
1117
  }, []);
1121
1118
  const toggleVoice = async (e) => {
1122
- if (e) {
1123
- e.preventDefault();
1124
- e.stopPropagation();
1125
- }
1126
1119
  const now = Date.now();
1127
1120
  if (now - tapCountRef.current.lastTap < 500) {
1128
1121
  tapCountRef.current.count++;
@@ -1164,47 +1157,33 @@ var TapToTalk = ({
1164
1157
  } else {
1165
1158
  console.log("[TapToTalk] Starting voice... mode:", voiceConfig == null ? void 0 : voiceConfig.mode);
1166
1159
  setErrorMsg(null);
1167
- const performStart = async () => {
1168
- setVoiceTrigger("click");
1169
- console.log("[TapToTalk] voiceTrigger set to click");
1170
- if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "custom") {
1171
- console.log("[TapToTalk] Starting custom recorder...");
1172
- try {
1173
- await customRecorder.start();
1174
- console.log("[TapToTalk] Custom recorder started successfully");
1175
- } catch (e2) {
1176
- console.error("[TapToTalk] Custom recorder failed:", e2);
1177
- setErrorMsg("Mic access denied");
1178
- setVoiceTrigger(null);
1179
- }
1180
- } else {
1181
- console.log("[TapToTalk] Starting native speech recognition...");
1182
- if (!nativeSpeech.isSupported) {
1183
- console.error("[TapToTalk] Native speech not supported");
1184
- setErrorMsg("Speech not supported");
1185
- setVoiceTrigger(null);
1186
- return;
1187
- }
1188
- console.log("[TapToTalk] Calling nativeSpeech.start()...");
1189
- nativeSpeech.start();
1190
- console.log("[TapToTalk] nativeSpeech.start() called");
1191
- }
1192
- };
1193
- if (isMobile()) {
1194
- console.log("[TapToTalk] Mobile: Blurring active element and skipping onFocusTarget");
1195
- if (document.activeElement instanceof HTMLElement) {
1196
- document.activeElement.blur();
1160
+ setVoiceTrigger("click");
1161
+ console.log("[TapToTalk] voiceTrigger set to click");
1162
+ if (!isMobile() && onFocusTarget) {
1163
+ console.log("[TapToTalk] Desktop: calling onFocusTarget()");
1164
+ onFocusTarget();
1165
+ }
1166
+ if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "custom") {
1167
+ console.log("[TapToTalk] Starting custom recorder...");
1168
+ try {
1169
+ await customRecorder.start();
1170
+ console.log("[TapToTalk] Custom recorder started successfully");
1171
+ } catch (e2) {
1172
+ console.error("[TapToTalk] Custom recorder failed:", e2);
1173
+ setErrorMsg("Mic access denied");
1174
+ setVoiceTrigger(null);
1197
1175
  }
1198
- console.log("[TapToTalk] Mobile: Waiting 300ms before starting recognition...");
1199
- setTimeout(() => {
1200
- performStart();
1201
- }, 300);
1202
1176
  } else {
1203
- if (onFocusTarget) {
1204
- console.log("[TapToTalk] Desktop: calling onFocusTarget()");
1205
- onFocusTarget();
1177
+ console.log("[TapToTalk] Starting native speech recognition...");
1178
+ if (!nativeSpeech.isSupported) {
1179
+ console.error("[TapToTalk] Native speech not supported");
1180
+ setErrorMsg("Speech not supported");
1181
+ setVoiceTrigger(null);
1182
+ return;
1206
1183
  }
1207
- performStart();
1184
+ console.log("[TapToTalk] Calling nativeSpeech.start()...");
1185
+ nativeSpeech.start();
1186
+ console.log("[TapToTalk] nativeSpeech.start() called");
1208
1187
  }
1209
1188
  }
1210
1189
  } finally {
@@ -1250,6 +1229,7 @@ var TapToTalk = ({
1250
1229
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1251
1230
  "button",
1252
1231
  {
1232
+ type: "button",
1253
1233
  onClick: toggleVoice,
1254
1234
  disabled: disabled || isTranscribing && !isListening,
1255
1235
  className: `flex items-center justify-center gap-3 px-6 py-3 rounded-xl transition-all duration-300 w-full font-medium shadow-md active:scale-[0.98]
@@ -1258,9 +1238,9 @@ var TapToTalk = ({
1258
1238
  ${className}`,
1259
1239
  title: label,
1260
1240
  children: [
1261
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex items-center justify-center shrink-0", children: Icon }),
1262
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate", children: label }),
1263
- errorMsg && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-[10px] bg-white/20 px-1.5 py-0.5 rounded text-red-100 animate-in fade-in slide-in-from-right-1", children: errorMsg })
1241
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex items-center justify-center shrink-0 pointer-events-none", children: Icon }),
1242
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "truncate pointer-events-none", children: label }),
1243
+ errorMsg && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-[10px] bg-white/20 px-1.5 py-0.5 rounded text-red-100 animate-in fade-in slide-in-from-right-1 pointer-events-none", children: errorMsg })
1264
1244
  ]
1265
1245
  }
1266
1246
  )