@emblemvault/hustle-react 1.4.11 → 1.5.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.d.cts CHANGED
@@ -3,7 +3,7 @@ export { HustleChat, HustleChatProps, HustleChatWidget, HustleChatWidgetConfig,
3
3
  export { A as Attachment, C as ChatMessage, b as ChatOptions, d as ChatResponse, H as HustleConfig, h as HustleContextValue, i as HustleProviderProps, M as Model, c as StreamChunk, g as StreamEndEvent, S as StreamOptions, T as ToolCall, f as ToolEndEvent, a as ToolResult, e as ToolStartEvent } from './hustle-C0Ltl5k4.cjs';
4
4
  import { S as StoredPlugin, H as HustlePlugin, a as HydratedPlugin } from './plugin-COr42J6-.cjs';
5
5
  export { C as ClientToolDefinition, E as ErrorContext, d as HustleRequest, J as JSONSchema, b as JSONSchemaProperty, e as PluginHooks, P as ProcessedResponse, f as SerializedHooks, c as SerializedToolDefinition, T as ToolExecutor } from './plugin-COr42J6-.cjs';
6
- export { UsePluginsReturn, usePlugins } from './hooks/index.cjs';
6
+ export { UsePluginsReturn, UseSpeechRecognitionOptions, UseSpeechRecognitionReturn, usePlugins, useSpeechRecognition } from './hooks/index.cjs';
7
7
  export { AvailablePlugin, availablePlugins, getAvailablePlugin, migrateFunPlugin, predictionMarketPlugin } from './plugins/index.cjs';
8
8
  import 'react/jsx-runtime';
9
9
  import 'react';
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { HustleChat, HustleChatProps, HustleChatWidget, HustleChatWidgetConfig,
3
3
  export { A as Attachment, C as ChatMessage, b as ChatOptions, d as ChatResponse, H as HustleConfig, h as HustleContextValue, i as HustleProviderProps, M as Model, c as StreamChunk, g as StreamEndEvent, S as StreamOptions, T as ToolCall, f as ToolEndEvent, a as ToolResult, e as ToolStartEvent } from './hustle-C0Ltl5k4.js';
4
4
  import { S as StoredPlugin, H as HustlePlugin, a as HydratedPlugin } from './plugin-COr42J6-.js';
5
5
  export { C as ClientToolDefinition, E as ErrorContext, d as HustleRequest, J as JSONSchema, b as JSONSchemaProperty, e as PluginHooks, P as ProcessedResponse, f as SerializedHooks, c as SerializedToolDefinition, T as ToolExecutor } from './plugin-COr42J6-.js';
6
- export { UsePluginsReturn, usePlugins } from './hooks/index.js';
6
+ export { UsePluginsReturn, UseSpeechRecognitionOptions, UseSpeechRecognitionReturn, usePlugins, useSpeechRecognition } from './hooks/index.js';
7
7
  export { AvailablePlugin, availablePlugins, getAvailablePlugin, migrateFunPlugin, predictionMarketPlugin } from './plugins/index.js';
8
8
  import 'react/jsx-runtime';
9
9
  import 'react';
package/dist/index.js CHANGED
@@ -800,6 +800,134 @@ function useHustle() {
800
800
  }
801
801
  return context;
802
802
  }
803
+ function useSpeechRecognition({
804
+ onTranscript,
805
+ onInterimTranscript,
806
+ onError,
807
+ continuous = true,
808
+ language = "en-US"
809
+ } = {}) {
810
+ const [isListening, setIsListening] = useState(false);
811
+ const [isSupported, setIsSupported] = useState(false);
812
+ const recognitionRef = useRef(null);
813
+ const finalTranscriptRef = useRef("");
814
+ const onTranscriptRef = useRef(onTranscript);
815
+ const onInterimTranscriptRef = useRef(onInterimTranscript);
816
+ const onErrorRef = useRef(onError);
817
+ useEffect(() => {
818
+ onTranscriptRef.current = onTranscript;
819
+ onInterimTranscriptRef.current = onInterimTranscript;
820
+ onErrorRef.current = onError;
821
+ }, [onTranscript, onInterimTranscript, onError]);
822
+ useEffect(() => {
823
+ if (typeof window === "undefined") {
824
+ return;
825
+ }
826
+ const SpeechRecognitionAPI = window.SpeechRecognition || window.webkitSpeechRecognition;
827
+ if (!SpeechRecognitionAPI) {
828
+ console.warn("Speech recognition not supported in this browser");
829
+ return;
830
+ }
831
+ setIsSupported(true);
832
+ const recognition = new SpeechRecognitionAPI();
833
+ recognition.continuous = continuous;
834
+ recognition.interimResults = true;
835
+ recognition.lang = language;
836
+ recognition.onstart = () => {
837
+ console.log("Speech recognition started");
838
+ setIsListening(true);
839
+ finalTranscriptRef.current = "";
840
+ };
841
+ recognition.onresult = (event) => {
842
+ let interimTranscript = "";
843
+ let finalTranscript = "";
844
+ const resultIndex = event.resultIndex || 0;
845
+ for (let i = resultIndex; i < event.results.length; i++) {
846
+ const transcript = event.results[i][0].transcript;
847
+ if (event.results[i].isFinal) {
848
+ finalTranscript += transcript;
849
+ } else {
850
+ interimTranscript += transcript;
851
+ }
852
+ }
853
+ if (finalTranscript) {
854
+ finalTranscriptRef.current += finalTranscript;
855
+ onTranscriptRef.current?.(finalTranscript);
856
+ }
857
+ if (interimTranscript) {
858
+ onInterimTranscriptRef.current?.(interimTranscript);
859
+ }
860
+ };
861
+ recognition.onerror = (event) => {
862
+ console.error("Speech recognition error:", event.error);
863
+ if (event.error !== "aborted" && event.error !== "no-speech") {
864
+ onErrorRef.current?.(event.error);
865
+ }
866
+ setIsListening(false);
867
+ };
868
+ recognition.onend = () => {
869
+ console.log("Speech recognition ended");
870
+ setIsListening(false);
871
+ };
872
+ recognitionRef.current = recognition;
873
+ return () => {
874
+ if (recognitionRef.current) {
875
+ try {
876
+ recognitionRef.current.abort();
877
+ } catch (e) {
878
+ }
879
+ }
880
+ };
881
+ }, [continuous, language]);
882
+ const startListening = useCallback(() => {
883
+ const recognition = recognitionRef.current;
884
+ if (!recognition) {
885
+ console.error("Speech recognition not available");
886
+ return;
887
+ }
888
+ if (isListening) {
889
+ return;
890
+ }
891
+ console.log("Starting speech recognition...");
892
+ try {
893
+ finalTranscriptRef.current = "";
894
+ recognition.start();
895
+ } catch (error2) {
896
+ console.error("Error starting:", error2);
897
+ onErrorRef.current?.("Failed to start speech recognition");
898
+ }
899
+ }, [isListening]);
900
+ const stopListening = useCallback(() => {
901
+ const recognition = recognitionRef.current;
902
+ if (!recognition) {
903
+ return;
904
+ }
905
+ if (!isListening) {
906
+ return;
907
+ }
908
+ console.log("Stopping speech recognition...");
909
+ try {
910
+ recognition.stop();
911
+ } catch (error2) {
912
+ console.warn("Error stopping:", error2);
913
+ setIsListening(false);
914
+ }
915
+ }, [isListening]);
916
+ const toggleListening = useCallback(() => {
917
+ if (isListening) {
918
+ stopListening();
919
+ } else {
920
+ startListening();
921
+ }
922
+ }, [isListening, startListening, stopListening]);
923
+ return {
924
+ isSupported,
925
+ isListening,
926
+ startListening,
927
+ stopListening,
928
+ toggleListening
929
+ };
930
+ }
803
931
 
804
932
  // src/plugins/predictionMarket.ts
805
933
  var DOME_API_BASE = "https://api.domeapi.io/v1";
@@ -3790,6 +3918,28 @@ var styles = {
3790
3918
  borderRadius: tokens.radius.full,
3791
3919
  animation: "hustle-spin 0.8s linear infinite"
3792
3920
  },
3921
+ // Mic button
3922
+ micBtn: {
3923
+ width: "40px",
3924
+ height: "40px",
3925
+ padding: 0,
3926
+ background: tokens.colors.bgTertiary,
3927
+ border: `1px solid ${tokens.colors.borderSecondary}`,
3928
+ borderRadius: tokens.radius.lg,
3929
+ color: tokens.colors.textSecondary,
3930
+ flexShrink: 0,
3931
+ display: "flex",
3932
+ alignItems: "center",
3933
+ justifyContent: "center",
3934
+ cursor: "pointer",
3935
+ transition: `all ${tokens.transitions.fast}`
3936
+ },
3937
+ micBtnListening: {
3938
+ background: "rgba(239, 68, 68, 0.1)",
3939
+ borderColor: "rgba(239, 68, 68, 0.3)",
3940
+ color: "#ef4444",
3941
+ animation: "hustle-pulse 1s ease-in-out infinite"
3942
+ },
3793
3943
  // Error display
3794
3944
  errorBox: {
3795
3945
  marginTop: tokens.spacing.sm,
@@ -3963,6 +4113,7 @@ function HustleChat({
3963
4113
  showDebug = false,
3964
4114
  hideHeader = false,
3965
4115
  initialSystemPrompt = "",
4116
+ enableSpeechToText = false,
3966
4117
  onMessage,
3967
4118
  onToolCall,
3968
4119
  onResponse
@@ -3999,6 +4150,30 @@ function HustleChat({
3999
4150
  const [attachments, setAttachments] = useState([]);
4000
4151
  const [currentToolCalls, setCurrentToolCalls] = useState([]);
4001
4152
  const [showSettingsPanel, setShowSettingsPanel] = useState(false);
4153
+ const [speechToTextEnabled, setSpeechToTextEnabled] = useState(() => {
4154
+ if (typeof window !== "undefined") {
4155
+ const stored = localStorage.getItem(`hustle-stt-enabled-${instanceId}`);
4156
+ return stored === "true";
4157
+ }
4158
+ return false;
4159
+ });
4160
+ useEffect(() => {
4161
+ if (typeof window !== "undefined") {
4162
+ localStorage.setItem(`hustle-stt-enabled-${instanceId}`, String(speechToTextEnabled));
4163
+ }
4164
+ }, [speechToTextEnabled, instanceId]);
4165
+ const {
4166
+ isSupported: isSpeechSupported,
4167
+ isListening,
4168
+ toggleListening
4169
+ } = useSpeechRecognition({
4170
+ onTranscript: useCallback((transcript) => {
4171
+ setInputValue((prev) => prev + (prev ? " " : "") + transcript);
4172
+ }, []),
4173
+ onError: useCallback((error3) => {
4174
+ console.error("Speech recognition error:", error3);
4175
+ }, [])
4176
+ });
4002
4177
  const messagesEndRef = useRef(null);
4003
4178
  const fileInputRef = useRef(null);
4004
4179
  const messagesRef = useRef(messages);
@@ -4467,6 +4642,27 @@ function HustleChat({
4467
4642
  }
4468
4643
  )
4469
4644
  ] }),
4645
+ isSpeechSupported && /* @__PURE__ */ jsxs("div", { style: styles.settingGroup, children: [
4646
+ /* @__PURE__ */ jsx("label", { style: styles.settingLabel, children: "Voice Input" }),
4647
+ /* @__PURE__ */ jsxs(
4648
+ "div",
4649
+ {
4650
+ style: styles.toggleRow,
4651
+ onClick: () => setSpeechToTextEnabled(!speechToTextEnabled),
4652
+ children: [
4653
+ /* @__PURE__ */ jsx("span", { style: styles.toggleLabel, children: "Enable speech-to-text" }),
4654
+ /* @__PURE__ */ jsx("div", { style: {
4655
+ ...styles.toggleSwitch,
4656
+ ...speechToTextEnabled ? styles.toggleSwitchActive : {}
4657
+ }, children: /* @__PURE__ */ jsx("div", { style: {
4658
+ ...styles.toggleKnob,
4659
+ ...speechToTextEnabled ? styles.toggleKnobActive : {}
4660
+ } }) })
4661
+ ]
4662
+ }
4663
+ ),
4664
+ /* @__PURE__ */ jsx("p", { style: styles.settingDescription, children: "Use your microphone to dictate messages" })
4665
+ ] }),
4470
4666
  /* @__PURE__ */ jsx("div", { style: styles.settingDivider }),
4471
4667
  /* @__PURE__ */ jsxs("div", { style: { ...styles.settingGroup, marginBottom: 0 }, children: [
4472
4668
  /* @__PURE__ */ jsx("label", { style: styles.settingLabel, children: "Plugins" }),
@@ -4603,6 +4799,21 @@ function HustleChat({
4603
4799
  }
4604
4800
  ) })
4605
4801
  ] }),
4802
+ (enableSpeechToText || speechToTextEnabled) && isSpeechSupported && /* @__PURE__ */ jsx(
4803
+ "button",
4804
+ {
4805
+ type: "button",
4806
+ onClick: toggleListening,
4807
+ disabled: !canChat || isStreaming || isLoading,
4808
+ style: {
4809
+ ...styles.micBtn,
4810
+ ...isListening ? styles.micBtnListening : {},
4811
+ ...!canChat || isStreaming || isLoading ? { opacity: 0.5, cursor: "not-allowed" } : {}
4812
+ },
4813
+ title: isListening ? "Stop listening" : "Start voice input",
4814
+ children: isListening ? /* @__PURE__ */ jsx(MicOffIcon, {}) : /* @__PURE__ */ jsx(MicIcon, {})
4815
+ }
4816
+ ),
4606
4817
  /* @__PURE__ */ jsx(
4607
4818
  "button",
4608
4819
  {
@@ -4662,6 +4873,23 @@ function SettingsIcon() {
4662
4873
  function AttachIcon() {
4663
4874
  return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
4664
4875
  }
4876
+ function MicIcon() {
4877
+ return /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
4878
+ /* @__PURE__ */ jsx("path", { d: "M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" }),
4879
+ /* @__PURE__ */ jsx("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
4880
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }),
4881
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })
4882
+ ] });
4883
+ }
4884
+ function MicOffIcon() {
4885
+ return /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
4886
+ /* @__PURE__ */ jsx("line", { x1: "1", y1: "1", x2: "23", y2: "23" }),
4887
+ /* @__PURE__ */ jsx("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6" }),
4888
+ /* @__PURE__ */ jsx("path", { d: "M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23" }),
4889
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }),
4890
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })
4891
+ ] });
4892
+ }
4665
4893
 
4666
4894
  // src/constants/index.ts
4667
4895
  var AGENT_HUSTLE_ICON = "data:image/jpeg;base64,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";
@@ -5101,6 +5329,6 @@ var DEFAULTS = {
5101
5329
  EMBLEM_MODAL_URL: "https://emblemvault.ai/connect"
5102
5330
  };
5103
5331
 
5104
- export { AGENT_HUSTLE_ICON, DEFAULTS, HustleChat, HustleChatWidget, HustleProvider, MarkdownContent, STORAGE_KEYS, availablePlugins, debounce, formatFileSize, getAvailablePlugin, hydratePlugin, migrateFunPlugin, pluginRegistry, predictionMarketPlugin, tokens, useHustle, usePlugins };
5332
+ export { AGENT_HUSTLE_ICON, DEFAULTS, HustleChat, HustleChatWidget, HustleProvider, MarkdownContent, STORAGE_KEYS, availablePlugins, debounce, formatFileSize, getAvailablePlugin, hydratePlugin, migrateFunPlugin, pluginRegistry, predictionMarketPlugin, tokens, useHustle, usePlugins, useSpeechRecognition };
5105
5333
  //# sourceMappingURL=index.js.map
5106
5334
  //# sourceMappingURL=index.js.map