@emblemvault/hustle-react 1.4.11 → 1.5.1
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/README.md +54 -0
- package/dist/browser/hustle-react.js +295 -27
- package/dist/browser/hustle-react.js.map +1 -1
- package/dist/components/index.cjs +270 -2
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +7 -1
- package/dist/components/index.d.ts +7 -1
- package/dist/components/index.js +270 -2
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.cjs +129 -0
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +82 -1
- package/dist/hooks/index.d.ts +82 -1
- package/dist/hooks/index.js +129 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +271 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +271 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,6 +109,7 @@ Complete chat UI component.
|
|
|
109
109
|
showDebug // Show tool call debug info
|
|
110
110
|
placeholder="Message" // Input placeholder
|
|
111
111
|
initialSystemPrompt="" // Initial system prompt
|
|
112
|
+
enableSpeechToText // Enable voice input via microphone (default: false)
|
|
112
113
|
|
|
113
114
|
// Callbacks
|
|
114
115
|
onMessage={(msg) => {}} // When user sends message
|
|
@@ -283,6 +284,59 @@ function App() {
|
|
|
283
284
|
|
|
284
285
|
Each instance has separate settings and plugins stored under its unique `instanceId`.
|
|
285
286
|
|
|
287
|
+
## Speech-to-Text
|
|
288
|
+
|
|
289
|
+
Enable voice input in `HustleChat` via prop, settings modal, or use the hook directly for custom implementations.
|
|
290
|
+
|
|
291
|
+
### Using HustleChat
|
|
292
|
+
|
|
293
|
+
**Via prop:**
|
|
294
|
+
```tsx
|
|
295
|
+
<HustleChat enableSpeechToText />
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Via settings modal:**
|
|
299
|
+
When `showSettings` is enabled, users can toggle "Voice Input" in the settings modal. This preference is persisted to localStorage.
|
|
300
|
+
|
|
301
|
+
```tsx
|
|
302
|
+
<HustleChat showSettings />
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
When enabled, a microphone button appears next to the send button. Click to start listening, click again to stop. The button pulses red while actively listening.
|
|
306
|
+
|
|
307
|
+
### Using the Hook Directly
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
import { useSpeechRecognition } from '@emblemvault/hustle-react';
|
|
311
|
+
|
|
312
|
+
function CustomInput() {
|
|
313
|
+
const [message, setMessage] = useState('');
|
|
314
|
+
|
|
315
|
+
const {
|
|
316
|
+
isSupported, // Browser supports Web Speech API
|
|
317
|
+
isListening, // Currently listening
|
|
318
|
+
toggleListening,
|
|
319
|
+
} = useSpeechRecognition({
|
|
320
|
+
onTranscript: (text) => setMessage(prev => prev + ' ' + text),
|
|
321
|
+
onInterimTranscript: (text) => console.log('Interim:', text),
|
|
322
|
+
onError: (error) => console.error('Speech error:', error),
|
|
323
|
+
continuous: true, // Keep listening (default: true)
|
|
324
|
+
language: 'en-US', // Recognition language (default: 'en-US')
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
if (!isSupported) return <p>Speech not supported</p>;
|
|
328
|
+
|
|
329
|
+
return (
|
|
330
|
+
<div>
|
|
331
|
+
<input value={message} onChange={e => setMessage(e.target.value)} />
|
|
332
|
+
<button onClick={toggleListening}>
|
|
333
|
+
{isListening ? 'Stop' : 'Speak'}
|
|
334
|
+
</button>
|
|
335
|
+
</div>
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
286
340
|
## Underlying SDK
|
|
287
341
|
|
|
288
342
|
This package wraps [hustle-incognito](https://github.com/nicktaylor-/hustle-incognito) for React. The SDK handles:
|
|
@@ -31,9 +31,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
));
|
|
32
32
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
33
33
|
|
|
34
|
-
//
|
|
34
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/lib/core.js
|
|
35
35
|
var require_core = __commonJS({
|
|
36
|
-
"
|
|
36
|
+
"node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/lib/core.js"(exports$1, module) {
|
|
37
37
|
function deepFreeze(obj) {
|
|
38
38
|
if (obj instanceof Map) {
|
|
39
39
|
obj.clear = obj.delete = obj.set = function() {
|
|
@@ -2341,6 +2341,134 @@ function useHustle() {
|
|
|
2341
2341
|
}
|
|
2342
2342
|
return context;
|
|
2343
2343
|
}
|
|
2344
|
+
function useSpeechRecognition({
|
|
2345
|
+
onTranscript,
|
|
2346
|
+
onInterimTranscript,
|
|
2347
|
+
onError,
|
|
2348
|
+
continuous = true,
|
|
2349
|
+
language = "en-US"
|
|
2350
|
+
} = {}) {
|
|
2351
|
+
const [isListening, setIsListening] = useState(false);
|
|
2352
|
+
const [isSupported, setIsSupported] = useState(false);
|
|
2353
|
+
const recognitionRef = useRef(null);
|
|
2354
|
+
const finalTranscriptRef = useRef("");
|
|
2355
|
+
const onTranscriptRef = useRef(onTranscript);
|
|
2356
|
+
const onInterimTranscriptRef = useRef(onInterimTranscript);
|
|
2357
|
+
const onErrorRef = useRef(onError);
|
|
2358
|
+
useEffect(() => {
|
|
2359
|
+
onTranscriptRef.current = onTranscript;
|
|
2360
|
+
onInterimTranscriptRef.current = onInterimTranscript;
|
|
2361
|
+
onErrorRef.current = onError;
|
|
2362
|
+
}, [onTranscript, onInterimTranscript, onError]);
|
|
2363
|
+
useEffect(() => {
|
|
2364
|
+
if (typeof window === "undefined") {
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
const SpeechRecognitionAPI = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
2368
|
+
if (!SpeechRecognitionAPI) {
|
|
2369
|
+
console.warn("Speech recognition not supported in this browser");
|
|
2370
|
+
return;
|
|
2371
|
+
}
|
|
2372
|
+
setIsSupported(true);
|
|
2373
|
+
const recognition = new SpeechRecognitionAPI();
|
|
2374
|
+
recognition.continuous = continuous;
|
|
2375
|
+
recognition.interimResults = true;
|
|
2376
|
+
recognition.lang = language;
|
|
2377
|
+
recognition.onstart = () => {
|
|
2378
|
+
console.log("Speech recognition started");
|
|
2379
|
+
setIsListening(true);
|
|
2380
|
+
finalTranscriptRef.current = "";
|
|
2381
|
+
};
|
|
2382
|
+
recognition.onresult = (event) => {
|
|
2383
|
+
let interimTranscript = "";
|
|
2384
|
+
let finalTranscript = "";
|
|
2385
|
+
const resultIndex = event.resultIndex || 0;
|
|
2386
|
+
for (let i = resultIndex; i < event.results.length; i++) {
|
|
2387
|
+
const transcript = event.results[i][0].transcript;
|
|
2388
|
+
if (event.results[i].isFinal) {
|
|
2389
|
+
finalTranscript += transcript;
|
|
2390
|
+
} else {
|
|
2391
|
+
interimTranscript += transcript;
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
if (finalTranscript) {
|
|
2395
|
+
finalTranscriptRef.current += finalTranscript;
|
|
2396
|
+
onTranscriptRef.current?.(finalTranscript);
|
|
2397
|
+
}
|
|
2398
|
+
if (interimTranscript) {
|
|
2399
|
+
onInterimTranscriptRef.current?.(interimTranscript);
|
|
2400
|
+
}
|
|
2401
|
+
};
|
|
2402
|
+
recognition.onerror = (event) => {
|
|
2403
|
+
console.error("Speech recognition error:", event.error);
|
|
2404
|
+
if (event.error !== "aborted" && event.error !== "no-speech") {
|
|
2405
|
+
onErrorRef.current?.(event.error);
|
|
2406
|
+
}
|
|
2407
|
+
setIsListening(false);
|
|
2408
|
+
};
|
|
2409
|
+
recognition.onend = () => {
|
|
2410
|
+
console.log("Speech recognition ended");
|
|
2411
|
+
setIsListening(false);
|
|
2412
|
+
};
|
|
2413
|
+
recognitionRef.current = recognition;
|
|
2414
|
+
return () => {
|
|
2415
|
+
if (recognitionRef.current) {
|
|
2416
|
+
try {
|
|
2417
|
+
recognitionRef.current.abort();
|
|
2418
|
+
} catch (e) {
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
};
|
|
2422
|
+
}, [continuous, language]);
|
|
2423
|
+
const startListening = useCallback(() => {
|
|
2424
|
+
const recognition = recognitionRef.current;
|
|
2425
|
+
if (!recognition) {
|
|
2426
|
+
console.error("Speech recognition not available");
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
if (isListening) {
|
|
2430
|
+
return;
|
|
2431
|
+
}
|
|
2432
|
+
console.log("Starting speech recognition...");
|
|
2433
|
+
try {
|
|
2434
|
+
finalTranscriptRef.current = "";
|
|
2435
|
+
recognition.start();
|
|
2436
|
+
} catch (error2) {
|
|
2437
|
+
console.error("Error starting:", error2);
|
|
2438
|
+
onErrorRef.current?.("Failed to start speech recognition");
|
|
2439
|
+
}
|
|
2440
|
+
}, [isListening]);
|
|
2441
|
+
const stopListening = useCallback(() => {
|
|
2442
|
+
const recognition = recognitionRef.current;
|
|
2443
|
+
if (!recognition) {
|
|
2444
|
+
return;
|
|
2445
|
+
}
|
|
2446
|
+
if (!isListening) {
|
|
2447
|
+
return;
|
|
2448
|
+
}
|
|
2449
|
+
console.log("Stopping speech recognition...");
|
|
2450
|
+
try {
|
|
2451
|
+
recognition.stop();
|
|
2452
|
+
} catch (error2) {
|
|
2453
|
+
console.warn("Error stopping:", error2);
|
|
2454
|
+
setIsListening(false);
|
|
2455
|
+
}
|
|
2456
|
+
}, [isListening]);
|
|
2457
|
+
const toggleListening = useCallback(() => {
|
|
2458
|
+
if (isListening) {
|
|
2459
|
+
stopListening();
|
|
2460
|
+
} else {
|
|
2461
|
+
startListening();
|
|
2462
|
+
}
|
|
2463
|
+
}, [isListening, startListening, stopListening]);
|
|
2464
|
+
return {
|
|
2465
|
+
isSupported,
|
|
2466
|
+
isListening,
|
|
2467
|
+
startListening,
|
|
2468
|
+
stopListening,
|
|
2469
|
+
toggleListening
|
|
2470
|
+
};
|
|
2471
|
+
}
|
|
2344
2472
|
|
|
2345
2473
|
// src/plugins/predictionMarket.ts
|
|
2346
2474
|
var DOME_API_BASE = "https://api.domeapi.io/v1";
|
|
@@ -4648,7 +4776,7 @@ var animations = `
|
|
|
4648
4776
|
}
|
|
4649
4777
|
`;
|
|
4650
4778
|
|
|
4651
|
-
//
|
|
4779
|
+
// node_modules/.pnpm/marked@17.0.1/node_modules/marked/lib/marked.esm.js
|
|
4652
4780
|
function L() {
|
|
4653
4781
|
return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
|
|
4654
4782
|
}
|
|
@@ -5823,11 +5951,11 @@ d.parseInline;
|
|
|
5823
5951
|
b.parse;
|
|
5824
5952
|
x.lex;
|
|
5825
5953
|
|
|
5826
|
-
//
|
|
5954
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/core.js
|
|
5827
5955
|
var import_core = __toESM(require_core());
|
|
5828
5956
|
var core_default = import_core.default;
|
|
5829
5957
|
|
|
5830
|
-
//
|
|
5958
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/javascript.js
|
|
5831
5959
|
var IDENT_RE = "[A-Za-z$_][0-9A-Za-z$_]*";
|
|
5832
5960
|
var KEYWORDS = [
|
|
5833
5961
|
"as",
|
|
@@ -6528,7 +6656,7 @@ function javascript(hljs) {
|
|
|
6528
6656
|
};
|
|
6529
6657
|
}
|
|
6530
6658
|
|
|
6531
|
-
//
|
|
6659
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/typescript.js
|
|
6532
6660
|
var IDENT_RE2 = "[A-Za-z$_][0-9A-Za-z$_]*";
|
|
6533
6661
|
var KEYWORDS2 = [
|
|
6534
6662
|
"as",
|
|
@@ -7342,7 +7470,7 @@ function typescript(hljs) {
|
|
|
7342
7470
|
return tsLanguage;
|
|
7343
7471
|
}
|
|
7344
7472
|
|
|
7345
|
-
//
|
|
7473
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/python.js
|
|
7346
7474
|
function python(hljs) {
|
|
7347
7475
|
const regex = hljs.regex;
|
|
7348
7476
|
const IDENT_RE3 = /[\p{XID_Start}_]\p{XID_Continue}*/u;
|
|
@@ -7757,7 +7885,7 @@ function python(hljs) {
|
|
|
7757
7885
|
};
|
|
7758
7886
|
}
|
|
7759
7887
|
|
|
7760
|
-
//
|
|
7888
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/json.js
|
|
7761
7889
|
function json(hljs) {
|
|
7762
7890
|
const ATTRIBUTE = {
|
|
7763
7891
|
className: "attr",
|
|
@@ -7797,7 +7925,7 @@ function json(hljs) {
|
|
|
7797
7925
|
};
|
|
7798
7926
|
}
|
|
7799
7927
|
|
|
7800
|
-
//
|
|
7928
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/bash.js
|
|
7801
7929
|
function bash(hljs) {
|
|
7802
7930
|
const regex = hljs.regex;
|
|
7803
7931
|
const VAR = {};
|
|
@@ -8191,7 +8319,7 @@ function bash(hljs) {
|
|
|
8191
8319
|
};
|
|
8192
8320
|
}
|
|
8193
8321
|
|
|
8194
|
-
//
|
|
8322
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/shell.js
|
|
8195
8323
|
function shell(hljs) {
|
|
8196
8324
|
return {
|
|
8197
8325
|
name: "Shell Session",
|
|
@@ -8215,7 +8343,7 @@ function shell(hljs) {
|
|
|
8215
8343
|
};
|
|
8216
8344
|
}
|
|
8217
8345
|
|
|
8218
|
-
//
|
|
8346
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/css.js
|
|
8219
8347
|
var MODES = (hljs) => {
|
|
8220
8348
|
return {
|
|
8221
8349
|
IMPORTANT: {
|
|
@@ -9152,7 +9280,7 @@ function css(hljs) {
|
|
|
9152
9280
|
};
|
|
9153
9281
|
}
|
|
9154
9282
|
|
|
9155
|
-
//
|
|
9283
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/xml.js
|
|
9156
9284
|
function xml(hljs) {
|
|
9157
9285
|
const regex = hljs.regex;
|
|
9158
9286
|
const TAG_NAME_RE = regex.concat(/[\p{L}_]/u, regex.optional(/[\p{L}0-9_.-]*:/u), /[\p{L}0-9_.-]*/u);
|
|
@@ -9378,7 +9506,7 @@ function xml(hljs) {
|
|
|
9378
9506
|
};
|
|
9379
9507
|
}
|
|
9380
9508
|
|
|
9381
|
-
//
|
|
9509
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/markdown.js
|
|
9382
9510
|
function markdown(hljs) {
|
|
9383
9511
|
const regex = hljs.regex;
|
|
9384
9512
|
const INLINE_HTML = {
|
|
@@ -9610,7 +9738,7 @@ function markdown(hljs) {
|
|
|
9610
9738
|
};
|
|
9611
9739
|
}
|
|
9612
9740
|
|
|
9613
|
-
//
|
|
9741
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/sql.js
|
|
9614
9742
|
function sql(hljs) {
|
|
9615
9743
|
const regex = hljs.regex;
|
|
9616
9744
|
const COMMENT_MODE = hljs.COMMENT("--", "$");
|
|
@@ -10253,7 +10381,7 @@ function sql(hljs) {
|
|
|
10253
10381
|
};
|
|
10254
10382
|
}
|
|
10255
10383
|
|
|
10256
|
-
//
|
|
10384
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/yaml.js
|
|
10257
10385
|
function yaml(hljs) {
|
|
10258
10386
|
const LITERALS3 = "true false yes no null";
|
|
10259
10387
|
const URI_CHARACTERS = "[\\w#;/?:@&=+$,.~*'()[\\]]+";
|
|
@@ -10454,7 +10582,7 @@ function yaml(hljs) {
|
|
|
10454
10582
|
};
|
|
10455
10583
|
}
|
|
10456
10584
|
|
|
10457
|
-
//
|
|
10585
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/rust.js
|
|
10458
10586
|
function rust(hljs) {
|
|
10459
10587
|
const regex = hljs.regex;
|
|
10460
10588
|
const RAW_IDENTIFIER = /(r#)?/;
|
|
@@ -10767,7 +10895,7 @@ function rust(hljs) {
|
|
|
10767
10895
|
};
|
|
10768
10896
|
}
|
|
10769
10897
|
|
|
10770
|
-
//
|
|
10898
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/go.js
|
|
10771
10899
|
function go(hljs) {
|
|
10772
10900
|
const LITERALS3 = [
|
|
10773
10901
|
"true",
|
|
@@ -10921,7 +11049,7 @@ function go(hljs) {
|
|
|
10921
11049
|
};
|
|
10922
11050
|
}
|
|
10923
11051
|
|
|
10924
|
-
//
|
|
11052
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/java.js
|
|
10925
11053
|
var decimalDigits = "[0-9](_*[0-9])*";
|
|
10926
11054
|
var frac = `\\.(${decimalDigits})`;
|
|
10927
11055
|
var hexDigits = "[0-9a-fA-F](_*[0-9a-fA-F])*";
|
|
@@ -11175,7 +11303,7 @@ function java(hljs) {
|
|
|
11175
11303
|
};
|
|
11176
11304
|
}
|
|
11177
11305
|
|
|
11178
|
-
//
|
|
11306
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/cpp.js
|
|
11179
11307
|
function cpp(hljs) {
|
|
11180
11308
|
const regex = hljs.regex;
|
|
11181
11309
|
const C_LINE_COMMENT_MODE = hljs.COMMENT("//", "$", { contains: [{ begin: /\\\n/ }] });
|
|
@@ -11718,7 +11846,7 @@ function cpp(hljs) {
|
|
|
11718
11846
|
};
|
|
11719
11847
|
}
|
|
11720
11848
|
|
|
11721
|
-
//
|
|
11849
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/csharp.js
|
|
11722
11850
|
function csharp(hljs) {
|
|
11723
11851
|
const BUILT_IN_KEYWORDS = [
|
|
11724
11852
|
"bool",
|
|
@@ -12118,7 +12246,7 @@ function csharp(hljs) {
|
|
|
12118
12246
|
};
|
|
12119
12247
|
}
|
|
12120
12248
|
|
|
12121
|
-
//
|
|
12249
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/php.js
|
|
12122
12250
|
function php(hljs) {
|
|
12123
12251
|
const regex = hljs.regex;
|
|
12124
12252
|
const NOT_PERL_ETC = /(?![A-Za-z0-9])(?![$])/;
|
|
@@ -12719,7 +12847,7 @@ function php(hljs) {
|
|
|
12719
12847
|
};
|
|
12720
12848
|
}
|
|
12721
12849
|
|
|
12722
|
-
//
|
|
12850
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/ruby.js
|
|
12723
12851
|
function ruby(hljs) {
|
|
12724
12852
|
const regex = hljs.regex;
|
|
12725
12853
|
const RUBY_METHOD_RE = "([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)";
|
|
@@ -13132,7 +13260,7 @@ function ruby(hljs) {
|
|
|
13132
13260
|
};
|
|
13133
13261
|
}
|
|
13134
13262
|
|
|
13135
|
-
//
|
|
13263
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/swift.js
|
|
13136
13264
|
function source(re2) {
|
|
13137
13265
|
if (!re2) return null;
|
|
13138
13266
|
if (typeof re2 === "string") return re2;
|
|
@@ -14007,7 +14135,7 @@ function swift(hljs) {
|
|
|
14007
14135
|
};
|
|
14008
14136
|
}
|
|
14009
14137
|
|
|
14010
|
-
//
|
|
14138
|
+
// node_modules/.pnpm/highlight.js@11.11.1/node_modules/highlight.js/es/languages/kotlin.js
|
|
14011
14139
|
var decimalDigits2 = "[0-9](_*[0-9])*";
|
|
14012
14140
|
var frac2 = `\\.(${decimalDigits2})`;
|
|
14013
14141
|
var hexDigits2 = "[0-9a-fA-F](_*[0-9a-fA-F])*";
|
|
@@ -14945,6 +15073,28 @@ var styles = {
|
|
|
14945
15073
|
borderRadius: tokens.radius.full,
|
|
14946
15074
|
animation: "hustle-spin 0.8s linear infinite"
|
|
14947
15075
|
},
|
|
15076
|
+
// Mic button
|
|
15077
|
+
micBtn: {
|
|
15078
|
+
width: "40px",
|
|
15079
|
+
height: "40px",
|
|
15080
|
+
padding: 0,
|
|
15081
|
+
background: tokens.colors.bgTertiary,
|
|
15082
|
+
border: `1px solid ${tokens.colors.borderSecondary}`,
|
|
15083
|
+
borderRadius: tokens.radius.lg,
|
|
15084
|
+
color: tokens.colors.textSecondary,
|
|
15085
|
+
flexShrink: 0,
|
|
15086
|
+
display: "flex",
|
|
15087
|
+
alignItems: "center",
|
|
15088
|
+
justifyContent: "center",
|
|
15089
|
+
cursor: "pointer",
|
|
15090
|
+
transition: `all ${tokens.transitions.fast}`
|
|
15091
|
+
},
|
|
15092
|
+
micBtnListening: {
|
|
15093
|
+
background: "rgba(239, 68, 68, 0.1)",
|
|
15094
|
+
borderColor: "rgba(239, 68, 68, 0.3)",
|
|
15095
|
+
color: "#ef4444",
|
|
15096
|
+
animation: "hustle-pulse 1s ease-in-out infinite"
|
|
15097
|
+
},
|
|
14948
15098
|
// Error display
|
|
14949
15099
|
errorBox: {
|
|
14950
15100
|
marginTop: tokens.spacing.sm,
|
|
@@ -15115,9 +15265,12 @@ function HustleChat({
|
|
|
15115
15265
|
className = "",
|
|
15116
15266
|
placeholder = "Type a message...",
|
|
15117
15267
|
showSettings = false,
|
|
15268
|
+
settingsPanelOpen: controlledSettingsPanelOpen,
|
|
15269
|
+
onSettingsPanelOpenChange,
|
|
15118
15270
|
showDebug = false,
|
|
15119
15271
|
hideHeader = false,
|
|
15120
15272
|
initialSystemPrompt = "",
|
|
15273
|
+
enableSpeechToText = false,
|
|
15121
15274
|
onMessage,
|
|
15122
15275
|
onToolCall,
|
|
15123
15276
|
onResponse
|
|
@@ -15153,7 +15306,41 @@ function HustleChat({
|
|
|
15153
15306
|
const [isStreaming, setIsStreaming] = useState(false);
|
|
15154
15307
|
const [attachments, setAttachments] = useState([]);
|
|
15155
15308
|
const [currentToolCalls, setCurrentToolCalls] = useState([]);
|
|
15156
|
-
const [
|
|
15309
|
+
const [internalShowSettingsPanel, setInternalShowSettingsPanel] = useState(false);
|
|
15310
|
+
const isSettingsControlled = controlledSettingsPanelOpen !== void 0;
|
|
15311
|
+
const showSettingsPanel = isSettingsControlled ? controlledSettingsPanelOpen : internalShowSettingsPanel;
|
|
15312
|
+
const setShowSettingsPanel = (open) => {
|
|
15313
|
+
const newValue = typeof open === "function" ? open(showSettingsPanel) : open;
|
|
15314
|
+
if (isSettingsControlled) {
|
|
15315
|
+
onSettingsPanelOpenChange?.(newValue);
|
|
15316
|
+
} else {
|
|
15317
|
+
setInternalShowSettingsPanel(newValue);
|
|
15318
|
+
}
|
|
15319
|
+
};
|
|
15320
|
+
const [speechToTextEnabled, setSpeechToTextEnabled] = useState(() => {
|
|
15321
|
+
if (typeof window !== "undefined") {
|
|
15322
|
+
const stored = localStorage.getItem(`hustle-stt-enabled-${instanceId}`);
|
|
15323
|
+
return stored === "true";
|
|
15324
|
+
}
|
|
15325
|
+
return false;
|
|
15326
|
+
});
|
|
15327
|
+
useEffect(() => {
|
|
15328
|
+
if (typeof window !== "undefined") {
|
|
15329
|
+
localStorage.setItem(`hustle-stt-enabled-${instanceId}`, String(speechToTextEnabled));
|
|
15330
|
+
}
|
|
15331
|
+
}, [speechToTextEnabled, instanceId]);
|
|
15332
|
+
const {
|
|
15333
|
+
isSupported: isSpeechSupported,
|
|
15334
|
+
isListening,
|
|
15335
|
+
toggleListening
|
|
15336
|
+
} = useSpeechRecognition({
|
|
15337
|
+
onTranscript: useCallback((transcript) => {
|
|
15338
|
+
setInputValue((prev) => prev + (prev ? " " : "") + transcript);
|
|
15339
|
+
}, []),
|
|
15340
|
+
onError: useCallback((error3) => {
|
|
15341
|
+
console.error("Speech recognition error:", error3);
|
|
15342
|
+
}, [])
|
|
15343
|
+
});
|
|
15157
15344
|
const messagesEndRef = useRef(null);
|
|
15158
15345
|
const fileInputRef = useRef(null);
|
|
15159
15346
|
const messagesRef = useRef(messages);
|
|
@@ -15622,6 +15809,27 @@ function HustleChat({
|
|
|
15622
15809
|
}
|
|
15623
15810
|
)
|
|
15624
15811
|
] }),
|
|
15812
|
+
isSpeechSupported && /* @__PURE__ */ jsxs("div", { style: styles.settingGroup, children: [
|
|
15813
|
+
/* @__PURE__ */ jsx("label", { style: styles.settingLabel, children: "Voice Input" }),
|
|
15814
|
+
/* @__PURE__ */ jsxs(
|
|
15815
|
+
"div",
|
|
15816
|
+
{
|
|
15817
|
+
style: styles.toggleRow,
|
|
15818
|
+
onClick: () => setSpeechToTextEnabled(!speechToTextEnabled),
|
|
15819
|
+
children: [
|
|
15820
|
+
/* @__PURE__ */ jsx("span", { style: styles.toggleLabel, children: "Enable speech-to-text" }),
|
|
15821
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
15822
|
+
...styles.toggleSwitch,
|
|
15823
|
+
...speechToTextEnabled ? styles.toggleSwitchActive : {}
|
|
15824
|
+
}, children: /* @__PURE__ */ jsx("div", { style: {
|
|
15825
|
+
...styles.toggleKnob,
|
|
15826
|
+
...speechToTextEnabled ? styles.toggleKnobActive : {}
|
|
15827
|
+
} }) })
|
|
15828
|
+
]
|
|
15829
|
+
}
|
|
15830
|
+
),
|
|
15831
|
+
/* @__PURE__ */ jsx("p", { style: styles.settingDescription, children: "Use your microphone to dictate messages" })
|
|
15832
|
+
] }),
|
|
15625
15833
|
/* @__PURE__ */ jsx("div", { style: styles.settingDivider }),
|
|
15626
15834
|
/* @__PURE__ */ jsxs("div", { style: { ...styles.settingGroup, marginBottom: 0 }, children: [
|
|
15627
15835
|
/* @__PURE__ */ jsx("label", { style: styles.settingLabel, children: "Plugins" }),
|
|
@@ -15758,6 +15966,21 @@ function HustleChat({
|
|
|
15758
15966
|
}
|
|
15759
15967
|
) })
|
|
15760
15968
|
] }),
|
|
15969
|
+
(enableSpeechToText || speechToTextEnabled) && isSpeechSupported && /* @__PURE__ */ jsx(
|
|
15970
|
+
"button",
|
|
15971
|
+
{
|
|
15972
|
+
type: "button",
|
|
15973
|
+
onClick: toggleListening,
|
|
15974
|
+
disabled: !canChat || isStreaming || isLoading,
|
|
15975
|
+
style: {
|
|
15976
|
+
...styles.micBtn,
|
|
15977
|
+
...isListening ? styles.micBtnListening : {},
|
|
15978
|
+
...!canChat || isStreaming || isLoading ? { opacity: 0.5, cursor: "not-allowed" } : {}
|
|
15979
|
+
},
|
|
15980
|
+
title: isListening ? "Stop listening" : "Start voice input",
|
|
15981
|
+
children: isListening ? /* @__PURE__ */ jsx(MicOffIcon, {}) : /* @__PURE__ */ jsx(MicIcon, {})
|
|
15982
|
+
}
|
|
15983
|
+
),
|
|
15761
15984
|
/* @__PURE__ */ jsx(
|
|
15762
15985
|
"button",
|
|
15763
15986
|
{
|
|
@@ -15817,6 +16040,23 @@ function SettingsIcon() {
|
|
|
15817
16040
|
function AttachIcon() {
|
|
15818
16041
|
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" }) });
|
|
15819
16042
|
}
|
|
16043
|
+
function MicIcon() {
|
|
16044
|
+
return /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
16045
|
+
/* @__PURE__ */ jsx("path", { d: "M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" }),
|
|
16046
|
+
/* @__PURE__ */ jsx("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
|
|
16047
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }),
|
|
16048
|
+
/* @__PURE__ */ jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })
|
|
16049
|
+
] });
|
|
16050
|
+
}
|
|
16051
|
+
function MicOffIcon() {
|
|
16052
|
+
return /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
16053
|
+
/* @__PURE__ */ jsx("line", { x1: "1", y1: "1", x2: "23", y2: "23" }),
|
|
16054
|
+
/* @__PURE__ */ jsx("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6" }),
|
|
16055
|
+
/* @__PURE__ */ jsx("path", { d: "M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23" }),
|
|
16056
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }),
|
|
16057
|
+
/* @__PURE__ */ jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })
|
|
16058
|
+
] });
|
|
16059
|
+
}
|
|
15820
16060
|
|
|
15821
16061
|
// src/constants/index.ts
|
|
15822
16062
|
var AGENT_HUSTLE_ICON = "data:image/jpeg;base64,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";
|
|
@@ -15949,6 +16189,12 @@ function CloseIcon() {
|
|
|
15949
16189
|
/* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
15950
16190
|
] });
|
|
15951
16191
|
}
|
|
16192
|
+
function SettingsIcon2() {
|
|
16193
|
+
return /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
16194
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" }),
|
|
16195
|
+
/* @__PURE__ */ jsx("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" })
|
|
16196
|
+
] });
|
|
16197
|
+
}
|
|
15952
16198
|
function ExpandIcon() {
|
|
15953
16199
|
return /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
15954
16200
|
/* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
@@ -15997,6 +16243,8 @@ function HustleChatWidget({
|
|
|
15997
16243
|
const [isHovered, setIsHovered] = useState(false);
|
|
15998
16244
|
const [closeHovered, setCloseHovered] = useState(false);
|
|
15999
16245
|
const [mounted, setMounted] = useState(false);
|
|
16246
|
+
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
16247
|
+
const { showSettings, ...restChatProps } = chatProps;
|
|
16000
16248
|
useEffect(() => {
|
|
16001
16249
|
setMounted(true);
|
|
16002
16250
|
if (storageKey && typeof window !== "undefined") {
|
|
@@ -16106,6 +16354,18 @@ function HustleChatWidget({
|
|
|
16106
16354
|
] })
|
|
16107
16355
|
] }),
|
|
16108
16356
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.xs }, children: [
|
|
16357
|
+
showSettings && /* @__PURE__ */ jsx(
|
|
16358
|
+
"button",
|
|
16359
|
+
{
|
|
16360
|
+
onClick: () => setSettingsOpen(!settingsOpen),
|
|
16361
|
+
style: {
|
|
16362
|
+
...widgetStyles.closeBtn,
|
|
16363
|
+
...settingsOpen ? { background: tokens.colors.bgSecondary } : {}
|
|
16364
|
+
},
|
|
16365
|
+
title: "Settings",
|
|
16366
|
+
children: /* @__PURE__ */ jsx(SettingsIcon2, {})
|
|
16367
|
+
}
|
|
16368
|
+
),
|
|
16109
16369
|
size === "sideDock" && /* @__PURE__ */ jsx(
|
|
16110
16370
|
"button",
|
|
16111
16371
|
{
|
|
@@ -16140,7 +16400,15 @@ function HustleChatWidget({
|
|
|
16140
16400
|
]
|
|
16141
16401
|
}
|
|
16142
16402
|
),
|
|
16143
|
-
/* @__PURE__ */ jsx("div", { style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }, children: /* @__PURE__ */ jsx(
|
|
16403
|
+
/* @__PURE__ */ jsx("div", { style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }, children: /* @__PURE__ */ jsx(
|
|
16404
|
+
HustleChatInner,
|
|
16405
|
+
{
|
|
16406
|
+
...restChatProps,
|
|
16407
|
+
showSettings,
|
|
16408
|
+
settingsPanelOpen: settingsOpen,
|
|
16409
|
+
onSettingsPanelOpenChange: setSettingsOpen
|
|
16410
|
+
}
|
|
16411
|
+
) })
|
|
16144
16412
|
]
|
|
16145
16413
|
}
|
|
16146
16414
|
),
|
|
@@ -16256,6 +16524,6 @@ var DEFAULTS = {
|
|
|
16256
16524
|
EMBLEM_MODAL_URL: "https://emblemvault.ai/connect"
|
|
16257
16525
|
};
|
|
16258
16526
|
|
|
16259
|
-
export { AGENT_HUSTLE_ICON, DEFAULTS, HustleChat, HustleChatWidget, HustleProvider, MarkdownContent, STORAGE_KEYS, availablePlugins, debounce, formatFileSize, getAvailablePlugin, hydratePlugin, migrateFunPlugin, pluginRegistry, predictionMarketPlugin, tokens, useHustle, usePlugins };
|
|
16527
|
+
export { AGENT_HUSTLE_ICON, DEFAULTS, HustleChat, HustleChatWidget, HustleProvider, MarkdownContent, STORAGE_KEYS, availablePlugins, debounce, formatFileSize, getAvailablePlugin, hydratePlugin, migrateFunPlugin, pluginRegistry, predictionMarketPlugin, tokens, useHustle, usePlugins, useSpeechRecognition };
|
|
16260
16528
|
//# sourceMappingURL=hustle-react.js.map
|
|
16261
16529
|
//# sourceMappingURL=hustle-react.js.map
|