@contentgrowth/llm-service 0.9.5 → 0.9.7

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.
@@ -149,7 +149,7 @@ function ChatHeader({
149
149
 
150
150
  // src/ui/react/components/ChatInputArea.tsx
151
151
  import { useState as useState3, useRef as useRef3, useImperativeHandle, forwardRef, useEffect as useEffect3, useCallback as useCallback3, useLayoutEffect } from "react";
152
- import { MicrophoneIcon, StopIcon, PaperAirplaneIcon, XMarkIcon } from "@heroicons/react/24/outline";
152
+ import { MicrophoneIcon, StopIcon, PaperAirplaneIcon, XMarkIcon, Square2StackIcon } from "@heroicons/react/24/outline";
153
153
 
154
154
  // src/ui/react/hooks/useSpeechRecognition.ts
155
155
  import { useState, useEffect, useCallback, useRef } from "react";
@@ -175,7 +175,6 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
175
175
  const recognition = new SpeechRecognition();
176
176
  recognition.continuous = true;
177
177
  recognition.interimResults = true;
178
- recognition.lang = language;
179
178
  recognition.onstart = () => {
180
179
  setIsListening(true);
181
180
  setError(null);
@@ -236,6 +235,11 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
236
235
  recognitionRef.current.stop();
237
236
  }
238
237
  };
238
+ }, []);
239
+ useEffect(() => {
240
+ if (recognitionRef.current) {
241
+ recognitionRef.current.lang = language;
242
+ }
239
243
  }, [language]);
240
244
  const start = useCallback(() => {
241
245
  if (recognitionRef.current && !isListening) {
@@ -431,6 +435,9 @@ var ChatInputArea = forwardRef(({
431
435
  console.error = originalError;
432
436
  };
433
437
  }, []);
438
+ const copyLogs = useCallback3(() => {
439
+ navigator.clipboard.writeText(logs.join("\n")).then(() => alert("Logs copied to clipboard")).catch((err) => console.error("Failed to copy logs", err));
440
+ }, [logs]);
434
441
  const textareaRef = useRef3(null);
435
442
  const measurementRef = useRef3(null);
436
443
  const pendingSelectionRef = useRef3(null);
@@ -623,7 +630,13 @@ var ChatInputArea = forwardRef(({
623
630
  showDebug && /* @__PURE__ */ jsxs3("div", { className: "absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto", children: [
624
631
  /* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
625
632
  /* @__PURE__ */ jsx5("span", { children: "Debug Logs" }),
626
- /* @__PURE__ */ jsx5("button", { onClick: () => setShowDebug(false), className: "text-white hover:text-red-400", children: /* @__PURE__ */ jsx5(XMarkIcon, { className: "w-4 h-4" }) })
633
+ /* @__PURE__ */ jsxs3("div", { className: "flex gap-2", children: [
634
+ /* @__PURE__ */ jsx5("button", { onClick: copyLogs, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ jsx5(Square2StackIcon, { className: "w-4 h-4" }) }),
635
+ /* @__PURE__ */ jsx5("button", { onClick: () => {
636
+ copyLogs();
637
+ setShowDebug(false);
638
+ }, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ jsx5(XMarkIcon, { className: "w-4 h-4" }) })
639
+ ] })
627
640
  ] }),
628
641
  logs.map((log, i) => /* @__PURE__ */ jsx5("div", { className: "mb-0.5 border-b border-gray-700/50 pb-0.5 break-all", children: log }, i)),
629
642
  logs.length === 0 && /* @__PURE__ */ jsx5("div", { children: "No logs yet..." })
@@ -644,6 +657,7 @@ var ChatInputArea = forwardRef(({
644
657
  if (tapCountRef.current.count >= 5) {
645
658
  setShowDebug((prev) => !prev);
646
659
  tapCountRef.current.count = 0;
660
+ stopRecording();
647
661
  return;
648
662
  }
649
663
  if (voiceTrigger) {
@@ -765,7 +779,7 @@ ChatInputArea.displayName = "ChatInputArea";
765
779
 
766
780
  // src/ui/react/components/TapToTalk.tsx
767
781
  import React3, { useState as useState4, useCallback as useCallback4, useRef as useRef4 } from "react";
768
- import { MicrophoneIcon as MicrophoneIcon2, XMarkIcon as XMarkIcon2 } from "@heroicons/react/24/outline";
782
+ import { MicrophoneIcon as MicrophoneIcon2, XMarkIcon as XMarkIcon2, Square2StackIcon as Square2StackIcon2 } from "@heroicons/react/24/outline";
769
783
  import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
770
784
  var TapToTalk = ({
771
785
  onResult,
@@ -818,6 +832,9 @@ var TapToTalk = ({
818
832
  console.error = originalError;
819
833
  };
820
834
  }, []);
835
+ const copyLogs = useCallback4(() => {
836
+ navigator.clipboard.writeText(logs.join("\n")).then(() => alert("Logs copied to clipboard")).catch((err) => console.error("Failed to copy logs", err));
837
+ }, [logs]);
821
838
  const handleVoiceResult = useCallback4((text, isFinal) => {
822
839
  if (isFinal) {
823
840
  onResult(text);
@@ -873,6 +890,11 @@ var TapToTalk = ({
873
890
  if (tapCountRef.current.count >= 5) {
874
891
  setShowDebug((prev) => !prev);
875
892
  tapCountRef.current.count = 0;
893
+ if (isActive) {
894
+ if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") nativeSpeech.stop();
895
+ else customRecorder.stop();
896
+ setVoiceTrigger(null);
897
+ }
876
898
  return;
877
899
  }
878
900
  if (isActive) {
@@ -923,10 +945,17 @@ var TapToTalk = ({
923
945
  showDebug && /* @__PURE__ */ jsxs4("div", { className: "absolute bottom-full left-0 right-0 mb-2 p-2 bg-black/80 text-green-400 text-xs font-mono h-48 overflow-y-auto rounded z-50 pointer-events-auto", children: [
924
946
  /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center bg-gray-800 p-1 mb-1", children: [
925
947
  /* @__PURE__ */ jsx6("span", { children: "Debug Logs" }),
926
- /* @__PURE__ */ jsx6("button", { onClick: (e) => {
927
- e.stopPropagation();
928
- setShowDebug(false);
929
- }, className: "text-white hover:text-red-400", children: /* @__PURE__ */ jsx6(XMarkIcon2, { className: "w-4 h-4" }) })
948
+ /* @__PURE__ */ jsxs4("div", { className: "flex gap-2", children: [
949
+ /* @__PURE__ */ jsx6("button", { onClick: (e) => {
950
+ e.stopPropagation();
951
+ copyLogs();
952
+ }, className: "text-white hover:text-blue-400", title: "Copy Logs", children: /* @__PURE__ */ jsx6(Square2StackIcon2, { className: "w-4 h-4" }) }),
953
+ /* @__PURE__ */ jsx6("button", { onClick: (e) => {
954
+ e.stopPropagation();
955
+ copyLogs();
956
+ setShowDebug(false);
957
+ }, className: "text-white hover:text-red-400", title: "Copy & Close", children: /* @__PURE__ */ jsx6(XMarkIcon2, { className: "w-4 h-4" }) })
958
+ ] })
930
959
  ] }),
931
960
  logs.map((log, i) => /* @__PURE__ */ jsx6("div", { className: "mb-0.5 border-b border-gray-700/50 pb-0.5 break-all", children: log }, i)),
932
961
  logs.length === 0 && /* @__PURE__ */ jsx6("div", { children: "No logs yet..." })