@contentgrowth/llm-service 0.9.97 → 0.9.99

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.
@@ -219,7 +219,7 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
219
219
  console.log("[useSpeechRecognition] Creating NEW recognition instance within user gesture context. Timestamp:", Date.now());
220
220
  const recognition = new SpeechRecognition();
221
221
  const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || "ontouchstart" in window || navigator.maxTouchPoints > 0;
222
- recognition.continuous = !isMobile;
222
+ recognition.continuous = true;
223
223
  recognition.interimResults = true;
224
224
  recognition.lang = languageRef.current;
225
225
  console.log("[useSpeechRecognition] Instance created. continuous:", recognition.continuous, "interimResults:", recognition.interimResults, "lang:", recognition.lang, "isMobile:", isMobile, "instanceId:", instanceIdRef.current);
@@ -258,6 +258,10 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
258
258
  recognition.onend = () => {
259
259
  console.log("[useSpeechRecognition] Native onend event fired. Timestamp:", Date.now());
260
260
  isStartingRef.current = false;
261
+ if (recognitionRef.current === recognition) {
262
+ console.log("[useSpeechRecognition] Nullifying recognitionRef (onend)");
263
+ recognitionRef.current = null;
264
+ }
261
265
  if (isSimulatingRef.current) {
262
266
  console.log("[useSpeechRecognition] onend ignored - simulating");
263
267
  return;
@@ -303,6 +307,10 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
303
307
  } else if (event.error === "network") {
304
308
  console.error("[useSpeechRecognition] - network: Network error during recognition");
305
309
  }
310
+ if (recognitionRef.current === recognition) {
311
+ console.log("[useSpeechRecognition] Nullifying recognitionRef (onerror)");
312
+ recognitionRef.current = null;
313
+ }
306
314
  isStartingRef.current = false;
307
315
  if (event.error === "not-allowed" && process.env.NODE_ENV === "development") {
308
316
  console.warn("Speech recognition blocked. Simulating input for development...");
@@ -363,6 +371,8 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
363
371
  if (recognitionRef.current) {
364
372
  console.log("[useSpeechRecognition] Stopping existing instance before creating new one");
365
373
  try {
374
+ recognitionRef.current.onend = null;
375
+ recognitionRef.current.onerror = null;
366
376
  recognitionRef.current.stop();
367
377
  } catch (e) {
368
378
  }
@@ -969,7 +979,6 @@ var TapToTalk = ({
969
979
  const globalConfig = useChatConfig();
970
980
  const voiceConfig = propVoiceConfig || ((_a = globalConfig.voice) == null ? void 0 : _a.config);
971
981
  const [isTranscribing, setIsTranscribing] = useState4(false);
972
- const [voiceTrigger, setVoiceTrigger] = useState4(null);
973
982
  const [errorMsg, setErrorMsg] = useState4(null);
974
983
  const [showDebug, setShowDebug] = useState4(false);
975
984
  const [logs, setLogs] = useState4([]);
@@ -1015,14 +1024,14 @@ var TapToTalk = ({
1015
1024
  navigator.clipboard.writeText(logs.join("\n")).then(() => alert("Logs copied to clipboard")).catch((err) => console.error("Failed to copy logs", err));
1016
1025
  }, [logs]);
1017
1026
  const handleVoiceResult = useCallback4((text, isFinal) => {
1027
+ console.log("[TapToTalk] Native speech result:", text, isFinal);
1018
1028
  if (isFinal) {
1019
1029
  onResult(text);
1020
1030
  setErrorMsg(null);
1021
- setVoiceTrigger(null);
1022
1031
  }
1023
1032
  }, [onResult]);
1024
1033
  const handleVoiceEnd = useCallback4(() => {
1025
- setVoiceTrigger(null);
1034
+ console.log("[TapToTalk] Native speech ended");
1026
1035
  }, []);
1027
1036
  const nativeSpeech = useSpeechRecognition(handleVoiceResult, handleVoiceEnd, voiceConfig == null ? void 0 : voiceConfig.language);
1028
1037
  React3.useEffect(() => {
@@ -1032,7 +1041,6 @@ var TapToTalk = ({
1032
1041
  }
1033
1042
  }, [nativeSpeech.error]);
1034
1043
  const customRecorder = useAudioRecorder(async (blob) => {
1035
- setVoiceTrigger(null);
1036
1044
  setIsTranscribing(true);
1037
1045
  setErrorMsg(null);
1038
1046
  if (blob.type === "audio/simulated") {
@@ -1056,7 +1064,7 @@ var TapToTalk = ({
1056
1064
  setIsTranscribing(false);
1057
1065
  }
1058
1066
  });
1059
- const isListening = !!voiceTrigger || nativeSpeech.isListening || customRecorder.isRecording;
1067
+ const isListening = nativeSpeech.isListening || customRecorder.isRecording;
1060
1068
  const isActive = isListening || isTranscribing;
1061
1069
  const processingRef = useRef4(false);
1062
1070
  const isMobile = useCallback4(() => {
@@ -1064,10 +1072,6 @@ var TapToTalk = ({
1064
1072
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || "ontouchstart" in window || navigator.maxTouchPoints > 0;
1065
1073
  }, []);
1066
1074
  const toggleVoice = async (e) => {
1067
- if (e) {
1068
- e.preventDefault();
1069
- e.stopPropagation();
1070
- }
1071
1075
  const now = Date.now();
1072
1076
  if (now - tapCountRef.current.lastTap < 500) {
1073
1077
  tapCountRef.current.count++;
@@ -1082,7 +1086,6 @@ var TapToTalk = ({
1082
1086
  console.log("[TapToTalk] Debug trigger force-stop");
1083
1087
  if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") nativeSpeech.stop();
1084
1088
  else customRecorder.stop();
1085
- setVoiceTrigger(null);
1086
1089
  }
1087
1090
  return;
1088
1091
  }
@@ -1105,12 +1108,9 @@ var TapToTalk = ({
1105
1108
  } else {
1106
1109
  customRecorder.stop();
1107
1110
  }
1108
- setVoiceTrigger(null);
1109
1111
  } else {
1110
1112
  console.log("[TapToTalk] Starting voice... mode:", voiceConfig == null ? void 0 : voiceConfig.mode);
1111
1113
  setErrorMsg(null);
1112
- setVoiceTrigger("click");
1113
- console.log("[TapToTalk] voiceTrigger set to click");
1114
1114
  if (!isMobile() && onFocusTarget) {
1115
1115
  console.log("[TapToTalk] Desktop: calling onFocusTarget()");
1116
1116
  onFocusTarget();
@@ -1123,14 +1123,12 @@ var TapToTalk = ({
1123
1123
  } catch (e2) {
1124
1124
  console.error("[TapToTalk] Custom recorder failed:", e2);
1125
1125
  setErrorMsg("Mic access denied");
1126
- setVoiceTrigger(null);
1127
1126
  }
1128
1127
  } else {
1129
1128
  console.log("[TapToTalk] Starting native speech recognition...");
1130
1129
  if (!nativeSpeech.isSupported) {
1131
1130
  console.error("[TapToTalk] Native speech not supported");
1132
1131
  setErrorMsg("Speech not supported");
1133
- setVoiceTrigger(null);
1134
1132
  return;
1135
1133
  }
1136
1134
  console.log("[TapToTalk] Calling nativeSpeech.start()...");
@@ -1181,7 +1179,9 @@ var TapToTalk = ({
1181
1179
  /* @__PURE__ */ jsxs4(
1182
1180
  "button",
1183
1181
  {
1182
+ type: "button",
1184
1183
  onClick: toggleVoice,
1184
+ style: { touchAction: "manipulation" },
1185
1185
  disabled: disabled || isTranscribing && !isListening,
1186
1186
  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]
1187
1187
  ${bgColor} text-white
@@ -1189,9 +1189,9 @@ var TapToTalk = ({
1189
1189
  ${className}`,
1190
1190
  title: label,
1191
1191
  children: [
1192
- /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center shrink-0", children: Icon }),
1193
- /* @__PURE__ */ jsx6("span", { className: "truncate", children: label }),
1194
- errorMsg && /* @__PURE__ */ jsx6("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 })
1192
+ /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center shrink-0 pointer-events-none", children: Icon }),
1193
+ /* @__PURE__ */ jsx6("span", { className: "truncate pointer-events-none", children: label }),
1194
+ errorMsg && /* @__PURE__ */ jsx6("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 })
1195
1195
  ]
1196
1196
  }
1197
1197
  )