@smartspace/chat-ui 1.14.4-pr.453.d6dd83a → 1.14.6-main.1a6776c
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.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +1 -132
- package/dist/index.js +17 -479
- package/dist/index.js.map +1 -1
- package/package.json +2 -5
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import MuiButton from '@mui/material/Button';
|
|
2
|
-
import
|
|
3
|
-
import { Loader2, ChevronDown, Check, Cpu, SlidersHorizontal, X, Globe, Zap,
|
|
2
|
+
import IconButton from '@mui/material/IconButton';
|
|
3
|
+
import { Loader2, ChevronDown, Check, Cpu, SlidersHorizontal, X, Globe, Zap, Paperclip, Mic, Square, Send, Minimize2, AlertTriangle, FileImage, FileVideo, FileAudio, FileArchive, FileCode, FileSpreadsheet, Presentation, FileText, ChevronUp, ExternalLink, Download, ShieldAlert, Copy } from 'lucide-react';
|
|
4
4
|
import * as React9 from 'react';
|
|
5
5
|
import React9__default, { createContext, forwardRef, useImperativeHandle, useRef, useState, useEffect, useMemo, useCallback, useContext, useSyncExternalStore } from 'react';
|
|
6
6
|
import { createPortal } from 'react-dom';
|
|
@@ -17,7 +17,7 @@ import { codeBlockSchema, commonmark } from '@milkdown/preset-commonmark';
|
|
|
17
17
|
import { Slice, NodeType } from '@milkdown/prose/model';
|
|
18
18
|
import { MilkdownProvider, useEditor, Milkdown } from '@milkdown/react';
|
|
19
19
|
import { PluginKey, Plugin } from '@milkdown/prose/state';
|
|
20
|
-
import {
|
|
20
|
+
import { Decoration, DecorationSet } from '@milkdown/prose/view';
|
|
21
21
|
import 'crypto';
|
|
22
22
|
import '@milkdown/prose';
|
|
23
23
|
import '@milkdown/prose/inputrules';
|
|
@@ -842,37 +842,6 @@ function useMessages(threadId) {
|
|
|
842
842
|
});
|
|
843
843
|
}
|
|
844
844
|
|
|
845
|
-
// src/domains/speech/queryKeys.ts
|
|
846
|
-
var speechKeys = {
|
|
847
|
-
all: ["speech"],
|
|
848
|
-
config: () => [...speechKeys.all, "config"]
|
|
849
|
-
};
|
|
850
|
-
|
|
851
|
-
// src/domains/speech/queries.ts
|
|
852
|
-
var unavailable = { enabled: false, defaultLocale: "en-US" };
|
|
853
|
-
var isNotFound = (error) => error?.type === "NotFound" || error?.response?.status === 404;
|
|
854
|
-
function useSpeechConfig() {
|
|
855
|
-
const service = useChatService();
|
|
856
|
-
const supported = !!service.getSpeechConfig && !!service.getSpeechToken;
|
|
857
|
-
return useQuery({
|
|
858
|
-
...queryOptions({
|
|
859
|
-
queryKey: speechKeys.config(),
|
|
860
|
-
queryFn: async () => {
|
|
861
|
-
try {
|
|
862
|
-
return await service.getSpeechConfig?.() ?? unavailable;
|
|
863
|
-
} catch (error) {
|
|
864
|
-
if (isNotFound(error)) return unavailable;
|
|
865
|
-
throw error;
|
|
866
|
-
}
|
|
867
|
-
},
|
|
868
|
-
staleTime: Infinity,
|
|
869
|
-
retry: (failureCount) => failureCount < 2,
|
|
870
|
-
retryDelay: 1e3
|
|
871
|
-
}),
|
|
872
|
-
enabled: supported
|
|
873
|
-
});
|
|
874
|
-
}
|
|
875
|
-
|
|
876
845
|
// ../../node_modules/.pnpm/@milkdown+exception@7.20.0/node_modules/@milkdown/exception/lib/index.js
|
|
877
846
|
var ErrorCode = /* @__PURE__ */ (function(ErrorCode2) {
|
|
878
847
|
ErrorCode2["docTypeError"] = "docTypeError";
|
|
@@ -1006,75 +975,6 @@ var autolink = $prose(() => {
|
|
|
1006
975
|
}
|
|
1007
976
|
});
|
|
1008
977
|
});
|
|
1009
|
-
var dictationGhostKey = new PluginKey("dictationGhost");
|
|
1010
|
-
function buildDecorations2(state, text6) {
|
|
1011
|
-
const doc = state.doc;
|
|
1012
|
-
const from = state.selection.head;
|
|
1013
|
-
const before = from > 0 ? doc.textBetween(from - 1, from, " ") : "";
|
|
1014
|
-
const display = before !== "" && !/\s/.test(before) ? ` ${text6}` : text6;
|
|
1015
|
-
const widget = Decoration.widget(
|
|
1016
|
-
from,
|
|
1017
|
-
() => {
|
|
1018
|
-
const span = document.createElement("span");
|
|
1019
|
-
span.className = "md-editor__dictation-ghost";
|
|
1020
|
-
span.setAttribute("aria-hidden", "true");
|
|
1021
|
-
span.appendChild(document.createTextNode(display));
|
|
1022
|
-
const dots = document.createElement("span");
|
|
1023
|
-
dots.className = "md-editor__dictation-dots";
|
|
1024
|
-
for (let i = 0; i < 3; i += 1)
|
|
1025
|
-
dots.appendChild(document.createElement("span"));
|
|
1026
|
-
span.appendChild(dots);
|
|
1027
|
-
return span;
|
|
1028
|
-
},
|
|
1029
|
-
{
|
|
1030
|
-
// Render after the caret so typing still lands where the user expects.
|
|
1031
|
-
side: 1,
|
|
1032
|
-
// Keyed by content so ProseMirror reuses the node between renders instead
|
|
1033
|
-
// of tearing it down on every interim result.
|
|
1034
|
-
key: `dictation-ghost:${display}`
|
|
1035
|
-
}
|
|
1036
|
-
);
|
|
1037
|
-
const decorations = [widget];
|
|
1038
|
-
const $head = state.selection.$head;
|
|
1039
|
-
if ($head.depth > 0) {
|
|
1040
|
-
decorations.push(
|
|
1041
|
-
Decoration.node($head.before(), $head.after(), {
|
|
1042
|
-
class: "md-editor__has-dictation-ghost"
|
|
1043
|
-
})
|
|
1044
|
-
);
|
|
1045
|
-
}
|
|
1046
|
-
return DecorationSet.create(doc, decorations);
|
|
1047
|
-
}
|
|
1048
|
-
var dictationGhost = $prose(() => {
|
|
1049
|
-
return new Plugin({
|
|
1050
|
-
key: dictationGhostKey,
|
|
1051
|
-
state: {
|
|
1052
|
-
init: () => "",
|
|
1053
|
-
apply(tr, previous2) {
|
|
1054
|
-
const meta = tr.getMeta(dictationGhostKey);
|
|
1055
|
-
if (meta) return meta.text;
|
|
1056
|
-
if (tr.docChanged || tr.selectionSet) return "";
|
|
1057
|
-
return previous2;
|
|
1058
|
-
}
|
|
1059
|
-
},
|
|
1060
|
-
props: {
|
|
1061
|
-
decorations(state) {
|
|
1062
|
-
const text6 = dictationGhostKey.getState(state) ?? "";
|
|
1063
|
-
if (!text6) return DecorationSet.empty;
|
|
1064
|
-
return buildDecorations2(state, text6);
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
});
|
|
1068
|
-
});
|
|
1069
|
-
function setDictationGhost(view, text6) {
|
|
1070
|
-
const current = dictationGhostKey.getState(view.state) ?? "";
|
|
1071
|
-
if (current === text6) return;
|
|
1072
|
-
const tr = view.state.tr.setMeta(dictationGhostKey, {
|
|
1073
|
-
text: text6
|
|
1074
|
-
});
|
|
1075
|
-
tr.setMeta("addToHistory", false);
|
|
1076
|
-
view.dispatch(tr);
|
|
1077
|
-
}
|
|
1078
978
|
|
|
1079
979
|
// src/shared/markdown/extensions/fileTag.ts
|
|
1080
980
|
var fileTag = $node("fileTag", () => ({
|
|
@@ -1984,7 +1884,7 @@ function EditorInner({
|
|
|
1984
1884
|
} catch {
|
|
1985
1885
|
}
|
|
1986
1886
|
});
|
|
1987
|
-
}).use(commonmark).use(history).use(clipboard).use(listener).use(autolink).use(
|
|
1887
|
+
}).use(commonmark).use(history).use(clipboard).use(listener).use(autolink).use(fileTag).use(ssImageNode).use(ssImageView).use(htmlPreviewView).use(enableMentions ? mention : fileTag);
|
|
1988
1888
|
},
|
|
1989
1889
|
[isEditable]
|
|
1990
1890
|
);
|
|
@@ -2194,25 +2094,6 @@ function EditorInner({
|
|
|
2194
2094
|
return value ?? "";
|
|
2195
2095
|
}
|
|
2196
2096
|
},
|
|
2197
|
-
insertText: (text6) => {
|
|
2198
|
-
const view = viewRef.current;
|
|
2199
|
-
if (!view || !isEditable || !text6) return;
|
|
2200
|
-
try {
|
|
2201
|
-
const { from } = view.state.selection;
|
|
2202
|
-
const before = from > 0 ? view.state.doc.textBetween(from - 1, from, " ") : "";
|
|
2203
|
-
const needsSpace = before !== "" && !/\s/.test(before);
|
|
2204
|
-
insertTextAtSelection(view, (needsSpace ? " " : "") + text6);
|
|
2205
|
-
} catch {
|
|
2206
|
-
}
|
|
2207
|
-
},
|
|
2208
|
-
setDictationGhost: (text6) => {
|
|
2209
|
-
const view = viewRef.current;
|
|
2210
|
-
if (!view || !isEditable) return;
|
|
2211
|
-
try {
|
|
2212
|
-
setDictationGhost(view, text6);
|
|
2213
|
-
} catch {
|
|
2214
|
-
}
|
|
2215
|
-
},
|
|
2216
2097
|
clear: () => {
|
|
2217
2098
|
const view = viewRef.current;
|
|
2218
2099
|
if (!view) return;
|
|
@@ -2556,237 +2437,6 @@ var MarkdownEditor = forwardRef((props, ref) => {
|
|
|
2556
2437
|
return /* @__PURE__ */ jsx(MilkdownProvider, { children: /* @__PURE__ */ jsx(EditorInner, { ...props, editorHandleRef: ref }) });
|
|
2557
2438
|
});
|
|
2558
2439
|
MarkdownEditor.displayName = "MarkdownEditor";
|
|
2559
|
-
var TOKEN_EXPIRY_MARGIN_MS = 15e3;
|
|
2560
|
-
var STALE_TOKEN_FLOOR_MS = 6e4;
|
|
2561
|
-
function kickOff(fn) {
|
|
2562
|
-
let promise;
|
|
2563
|
-
try {
|
|
2564
|
-
promise = Promise.resolve(fn());
|
|
2565
|
-
} catch (e) {
|
|
2566
|
-
promise = Promise.reject(e);
|
|
2567
|
-
}
|
|
2568
|
-
promise.catch(() => void 0);
|
|
2569
|
-
return promise;
|
|
2570
|
-
}
|
|
2571
|
-
var isSupported = () => typeof window !== "undefined" && window.isSecureContext && !!navigator.mediaDevices?.getUserMedia;
|
|
2572
|
-
function classifyTokenFailure(error) {
|
|
2573
|
-
const code3 = error?.code;
|
|
2574
|
-
if (code3 === "SP500") return "unavailable";
|
|
2575
|
-
if (error?.type === "NotFound") {
|
|
2576
|
-
return "unavailable";
|
|
2577
|
-
}
|
|
2578
|
-
return "unavailable-temporarily";
|
|
2579
|
-
}
|
|
2580
|
-
function useDictation({
|
|
2581
|
-
region,
|
|
2582
|
-
locale,
|
|
2583
|
-
getToken,
|
|
2584
|
-
onPhrase,
|
|
2585
|
-
onInterim,
|
|
2586
|
-
maxDurationMs = 18e4,
|
|
2587
|
-
idleTimeoutMs = 2e4
|
|
2588
|
-
}) {
|
|
2589
|
-
const [state, setState] = useState("idle");
|
|
2590
|
-
const [error, setError] = useState(null);
|
|
2591
|
-
const sessionRef = useRef(null);
|
|
2592
|
-
const generationRef = useRef(0);
|
|
2593
|
-
const onPhraseRef = useRef(onPhrase);
|
|
2594
|
-
const onInterimRef = useRef(onInterim);
|
|
2595
|
-
useEffect(() => {
|
|
2596
|
-
onPhraseRef.current = onPhrase;
|
|
2597
|
-
onInterimRef.current = onInterim;
|
|
2598
|
-
});
|
|
2599
|
-
const clearInterim = useCallback(() => onInterimRef.current?.(""), []);
|
|
2600
|
-
const supported = isSupported();
|
|
2601
|
-
const available = supported && !!region && !!getToken;
|
|
2602
|
-
useEffect(() => {
|
|
2603
|
-
if (!available) return;
|
|
2604
|
-
const nav = navigator;
|
|
2605
|
-
if (nav.connection?.saveData) return;
|
|
2606
|
-
const warm = () => void kickOff(() => import('microsoft-cognitiveservices-speech-sdk'));
|
|
2607
|
-
if (typeof window.requestIdleCallback === "function") {
|
|
2608
|
-
const id2 = window.requestIdleCallback(warm, { timeout: 2e3 });
|
|
2609
|
-
return () => window.cancelIdleCallback(id2);
|
|
2610
|
-
}
|
|
2611
|
-
const id = window.setTimeout(warm, 1500);
|
|
2612
|
-
return () => window.clearTimeout(id);
|
|
2613
|
-
}, [available]);
|
|
2614
|
-
const stop = useCallback(() => {
|
|
2615
|
-
generationRef.current += 1;
|
|
2616
|
-
const session = sessionRef.current;
|
|
2617
|
-
sessionRef.current = null;
|
|
2618
|
-
clearInterim();
|
|
2619
|
-
setState("idle");
|
|
2620
|
-
if (!session) return;
|
|
2621
|
-
window.clearTimeout(session.timers.idle);
|
|
2622
|
-
window.clearTimeout(session.timers.max);
|
|
2623
|
-
session.stream.getTracks().forEach((t) => t.stop());
|
|
2624
|
-
session.recognizer.stopContinuousRecognitionAsync(
|
|
2625
|
-
() => session.recognizer.close(),
|
|
2626
|
-
() => session.recognizer.close()
|
|
2627
|
-
);
|
|
2628
|
-
}, [clearInterim]);
|
|
2629
|
-
const start = useCallback(async () => {
|
|
2630
|
-
if (!available || sessionRef.current) return;
|
|
2631
|
-
const generation = ++generationRef.current;
|
|
2632
|
-
const superseded = () => generationRef.current !== generation;
|
|
2633
|
-
setError(null);
|
|
2634
|
-
setState("starting");
|
|
2635
|
-
const streamPromise = kickOff(
|
|
2636
|
-
() => navigator.mediaDevices.getUserMedia({
|
|
2637
|
-
audio: {
|
|
2638
|
-
echoCancellation: true,
|
|
2639
|
-
noiseSuppression: true,
|
|
2640
|
-
autoGainControl: true
|
|
2641
|
-
}
|
|
2642
|
-
})
|
|
2643
|
-
);
|
|
2644
|
-
const tokenPromise = kickOff(getToken);
|
|
2645
|
-
const sdkPromise = kickOff(
|
|
2646
|
-
() => import('microsoft-cognitiveservices-speech-sdk')
|
|
2647
|
-
);
|
|
2648
|
-
let stream;
|
|
2649
|
-
try {
|
|
2650
|
-
stream = await streamPromise;
|
|
2651
|
-
} catch (e) {
|
|
2652
|
-
if (superseded()) return;
|
|
2653
|
-
const name = e?.name;
|
|
2654
|
-
setError(
|
|
2655
|
-
name === "NotAllowedError" || name === "SecurityError" ? "permission-denied" : name === "NotFoundError" || name === "OverconstrainedError" ? "no-microphone" : "unknown"
|
|
2656
|
-
);
|
|
2657
|
-
setState("idle");
|
|
2658
|
-
return;
|
|
2659
|
-
}
|
|
2660
|
-
if (superseded()) {
|
|
2661
|
-
stream.getTracks().forEach((t) => t.stop());
|
|
2662
|
-
return;
|
|
2663
|
-
}
|
|
2664
|
-
let token;
|
|
2665
|
-
try {
|
|
2666
|
-
token = await tokenPromise;
|
|
2667
|
-
if (Date.parse(token.expiresOn) - Date.now() < STALE_TOKEN_FLOOR_MS) {
|
|
2668
|
-
token = await getToken();
|
|
2669
|
-
}
|
|
2670
|
-
} catch (e) {
|
|
2671
|
-
stream.getTracks().forEach((t) => t.stop());
|
|
2672
|
-
if (superseded()) return;
|
|
2673
|
-
setError(classifyTokenFailure(e));
|
|
2674
|
-
setState("idle");
|
|
2675
|
-
return;
|
|
2676
|
-
}
|
|
2677
|
-
if (superseded()) {
|
|
2678
|
-
stream.getTracks().forEach((t) => t.stop());
|
|
2679
|
-
return;
|
|
2680
|
-
}
|
|
2681
|
-
let recognizer = null;
|
|
2682
|
-
let published = null;
|
|
2683
|
-
try {
|
|
2684
|
-
const sdk = await sdkPromise;
|
|
2685
|
-
if (superseded()) {
|
|
2686
|
-
stream.getTracks().forEach((t) => t.stop());
|
|
2687
|
-
return;
|
|
2688
|
-
}
|
|
2689
|
-
const speechConfig = sdk.SpeechConfig.fromAuthorizationToken(
|
|
2690
|
-
token.token,
|
|
2691
|
-
region
|
|
2692
|
-
);
|
|
2693
|
-
speechConfig.speechRecognitionLanguage = locale;
|
|
2694
|
-
speechConfig.setProfanity(sdk.ProfanityOption.Raw);
|
|
2695
|
-
speechConfig.setProperty(
|
|
2696
|
-
sdk.PropertyId.Speech_SegmentationSilenceTimeoutMs,
|
|
2697
|
-
"700"
|
|
2698
|
-
);
|
|
2699
|
-
recognizer = new sdk.SpeechRecognizer(
|
|
2700
|
-
speechConfig,
|
|
2701
|
-
sdk.AudioConfig.fromStreamInput(stream)
|
|
2702
|
-
);
|
|
2703
|
-
const untilExpiry = Date.parse(token.expiresOn) - Date.now() - TOKEN_EXPIRY_MARGIN_MS;
|
|
2704
|
-
const sessionCapMs = Number.isFinite(untilExpiry) && untilExpiry > 0 ? Math.min(maxDurationMs, untilExpiry) : maxDurationMs;
|
|
2705
|
-
const session = { recognizer, stream, timers: {} };
|
|
2706
|
-
const armIdle = () => {
|
|
2707
|
-
window.clearTimeout(session.timers.idle);
|
|
2708
|
-
session.timers.idle = window.setTimeout(stop, idleTimeoutMs);
|
|
2709
|
-
};
|
|
2710
|
-
const isLive = () => sessionRef.current === session;
|
|
2711
|
-
sessionRef.current = session;
|
|
2712
|
-
published = session;
|
|
2713
|
-
const goLive = () => {
|
|
2714
|
-
if (!isLive()) return;
|
|
2715
|
-
session.timers.max ??= window.setTimeout(stop, sessionCapMs);
|
|
2716
|
-
armIdle();
|
|
2717
|
-
setState("listening");
|
|
2718
|
-
};
|
|
2719
|
-
recognizer.sessionStarted = () => goLive();
|
|
2720
|
-
recognizer.recognizing = (_sender, event) => {
|
|
2721
|
-
if (!isLive()) return;
|
|
2722
|
-
onInterimRef.current?.(event.result.text ?? "");
|
|
2723
|
-
armIdle();
|
|
2724
|
-
};
|
|
2725
|
-
recognizer.recognized = (_sender, event) => {
|
|
2726
|
-
if (!isLive()) return;
|
|
2727
|
-
const text6 = event.result.text?.trim();
|
|
2728
|
-
clearInterim();
|
|
2729
|
-
if (event.result.reason === sdk.ResultReason.RecognizedSpeech && text6) {
|
|
2730
|
-
onPhraseRef.current(text6);
|
|
2731
|
-
}
|
|
2732
|
-
armIdle();
|
|
2733
|
-
};
|
|
2734
|
-
recognizer.canceled = (_sender, event) => {
|
|
2735
|
-
if (!isLive()) return;
|
|
2736
|
-
if (event.reason === sdk.CancellationReason.Error) {
|
|
2737
|
-
console.warn("[dictation] cancelled, errorCode:", event.errorCode);
|
|
2738
|
-
setError(
|
|
2739
|
-
event.errorCode === sdk.CancellationErrorCode.ConnectionFailure ? "network" : event.errorCode === sdk.CancellationErrorCode.AuthenticationFailure ? "unavailable-temporarily" : "unknown"
|
|
2740
|
-
);
|
|
2741
|
-
}
|
|
2742
|
-
stop();
|
|
2743
|
-
};
|
|
2744
|
-
recognizer.sessionStopped = () => {
|
|
2745
|
-
if (isLive()) stop();
|
|
2746
|
-
};
|
|
2747
|
-
try {
|
|
2748
|
-
const connection = sdk.Connection.fromRecognizer(recognizer);
|
|
2749
|
-
connection.connected = () => goLive();
|
|
2750
|
-
connection.openConnection();
|
|
2751
|
-
} catch {
|
|
2752
|
-
}
|
|
2753
|
-
await new Promise(
|
|
2754
|
-
(resolve, reject) => session.recognizer.startContinuousRecognitionAsync(resolve, reject)
|
|
2755
|
-
);
|
|
2756
|
-
goLive();
|
|
2757
|
-
} catch (e) {
|
|
2758
|
-
stream.getTracks().forEach((t) => t.stop());
|
|
2759
|
-
try {
|
|
2760
|
-
recognizer?.close();
|
|
2761
|
-
} catch {
|
|
2762
|
-
}
|
|
2763
|
-
if (published) {
|
|
2764
|
-
window.clearTimeout(published.timers.idle);
|
|
2765
|
-
window.clearTimeout(published.timers.max);
|
|
2766
|
-
if (sessionRef.current === published) sessionRef.current = null;
|
|
2767
|
-
}
|
|
2768
|
-
if (superseded()) return;
|
|
2769
|
-
console.warn("[dictation] failed to start:", e);
|
|
2770
|
-
setError((prev) => prev ?? "unavailable-temporarily");
|
|
2771
|
-
setState("idle");
|
|
2772
|
-
}
|
|
2773
|
-
}, [
|
|
2774
|
-
available,
|
|
2775
|
-
clearInterim,
|
|
2776
|
-
getToken,
|
|
2777
|
-
idleTimeoutMs,
|
|
2778
|
-
locale,
|
|
2779
|
-
maxDurationMs,
|
|
2780
|
-
region,
|
|
2781
|
-
stop
|
|
2782
|
-
]);
|
|
2783
|
-
useEffect(() => stop, [stop]);
|
|
2784
|
-
const toggle = useCallback(() => {
|
|
2785
|
-
if (state === "idle") void start();
|
|
2786
|
-
else stop();
|
|
2787
|
-
}, [start, state, stop]);
|
|
2788
|
-
return { supported, available, state, error, start, stop, toggle };
|
|
2789
|
-
}
|
|
2790
2440
|
function useFlowRunVariables(flowRunId) {
|
|
2791
2441
|
const service = useChatService();
|
|
2792
2442
|
return useQuery({
|
|
@@ -4092,56 +3742,6 @@ var ChatVariablesForm = forwardRef(({ workspace, threadId, setVariables }, ref)
|
|
|
4092
3742
|
) }) })
|
|
4093
3743
|
] });
|
|
4094
3744
|
});
|
|
4095
|
-
var dictationErrorMessages = {
|
|
4096
|
-
"permission-denied": "Microphone access is blocked \u2014 allow it in your browser settings and try again",
|
|
4097
|
-
"no-microphone": "No microphone was found",
|
|
4098
|
-
network: "Could not reach the speech service \u2014 try again",
|
|
4099
|
-
"unavailable-temporarily": "Dictation is starting up \u2014 try again in a moment",
|
|
4100
|
-
unavailable: "Dictation is not available on this workspace",
|
|
4101
|
-
unknown: "Dictation stopped unexpectedly \u2014 try again"
|
|
4102
|
-
};
|
|
4103
|
-
function DictationButton({
|
|
4104
|
-
state,
|
|
4105
|
-
error,
|
|
4106
|
-
disabled,
|
|
4107
|
-
onToggle,
|
|
4108
|
-
size = "sm"
|
|
4109
|
-
}) {
|
|
4110
|
-
const listening = state === "listening";
|
|
4111
|
-
const starting = state === "starting";
|
|
4112
|
-
const label = listening ? "Stop dictation" : "Dictate a message";
|
|
4113
|
-
const dims = size === "sm" ? "h-8 w-8" : "h-9 w-9";
|
|
4114
|
-
const icon = size === "sm" ? "h-4 w-4" : "h-5 w-5";
|
|
4115
|
-
return /* @__PURE__ */ jsxs(
|
|
4116
|
-
IconButton2,
|
|
4117
|
-
{
|
|
4118
|
-
type: "button",
|
|
4119
|
-
onClick: onToggle,
|
|
4120
|
-
disabled,
|
|
4121
|
-
"aria-pressed": listening,
|
|
4122
|
-
"aria-label": label,
|
|
4123
|
-
title: error ? dictationErrorMessages[error] : label,
|
|
4124
|
-
className: `relative ${dims} rounded-full transition-colors ${listening ? "bg-destructive text-destructive-foreground hover:bg-destructive/90" : "text-muted-foreground hover:bg-secondary"}`,
|
|
4125
|
-
children: [
|
|
4126
|
-
starting && /* @__PURE__ */ jsx(
|
|
4127
|
-
"span",
|
|
4128
|
-
{
|
|
4129
|
-
"aria-hidden": "true",
|
|
4130
|
-
className: "absolute inset-0 animate-spin rounded-full border-2 border-transparent border-t-current opacity-70"
|
|
4131
|
-
}
|
|
4132
|
-
),
|
|
4133
|
-
listening && /* @__PURE__ */ jsx(
|
|
4134
|
-
"span",
|
|
4135
|
-
{
|
|
4136
|
-
"aria-hidden": "true",
|
|
4137
|
-
className: "absolute inset-0 animate-ping rounded-full bg-destructive/30"
|
|
4138
|
-
}
|
|
4139
|
-
),
|
|
4140
|
-
listening ? /* @__PURE__ */ jsx(Square, { className: `relative ${icon} fill-current` }) : /* @__PURE__ */ jsx(Mic, { className: `relative ${icon}` })
|
|
4141
|
-
]
|
|
4142
|
-
}
|
|
4143
|
-
);
|
|
4144
|
-
}
|
|
4145
3745
|
|
|
4146
3746
|
// src/domains/workspaces/queryKeys.ts
|
|
4147
3747
|
var workspaceKeys = {
|
|
@@ -4374,39 +3974,6 @@ function MessageComposer(_props = {}) {
|
|
|
4374
3974
|
cancelReset();
|
|
4375
3975
|
}
|
|
4376
3976
|
}, [isSending, cancelAccepted, cancelErrored, cancelReset]);
|
|
4377
|
-
const attachEditor = useCallback(
|
|
4378
|
-
(handle2) => {
|
|
4379
|
-
if (handle2) editorRef.current = handle2;
|
|
4380
|
-
},
|
|
4381
|
-
// Both flags matter: the portal mounts on `isMobile && isFullscreen`, and
|
|
4382
|
-
// nothing resets isFullscreen when the breakpoint flips, so crossing it
|
|
4383
|
-
// while fullscreen would unmount the portal editor without re-attaching the
|
|
4384
|
-
// inline one — leaving a destroyed handle and silently swallowing phrases.
|
|
4385
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4386
|
-
[isFullscreen, isMobile]
|
|
4387
|
-
);
|
|
4388
|
-
const { data: speechConfig } = useSpeechConfig();
|
|
4389
|
-
const getSpeechToken = useMemo(
|
|
4390
|
-
() => chatService.getSpeechToken?.bind(chatService),
|
|
4391
|
-
[chatService]
|
|
4392
|
-
);
|
|
4393
|
-
const dictation = useDictation({
|
|
4394
|
-
region: speechConfig?.enabled ? speechConfig.region : null,
|
|
4395
|
-
locale: speechConfig?.defaultLocale ?? "en-US",
|
|
4396
|
-
getToken: getSpeechToken,
|
|
4397
|
-
// Final phrases become real text; provisional ones render as greyed ghost
|
|
4398
|
-
// text at the caret and never enter the document.
|
|
4399
|
-
onPhrase: (text6) => editorRef.current?.insertText(`${text6} `),
|
|
4400
|
-
onInterim: (text6) => editorRef.current?.setDictationGhost(text6)
|
|
4401
|
-
});
|
|
4402
|
-
const { stop: stopDictation } = dictation;
|
|
4403
|
-
const handleDictationToggle = () => {
|
|
4404
|
-
if (dictation.state === "idle") editorRef.current?.focus();
|
|
4405
|
-
dictation.toggle();
|
|
4406
|
-
};
|
|
4407
|
-
useEffect(() => {
|
|
4408
|
-
if (disabled) stopDictation();
|
|
4409
|
-
}, [disabled, stopDictation]);
|
|
4410
3977
|
useEffect(() => {
|
|
4411
3978
|
if (typeof window === "undefined") return;
|
|
4412
3979
|
window.__ssDownloadFile = (id) => getFileBlobUrl(id);
|
|
@@ -4526,7 +4093,6 @@ function MessageComposer(_props = {}) {
|
|
|
4526
4093
|
const latestText = editorRef.current?.getMarkdown() ?? newMessage;
|
|
4527
4094
|
const sent = handleSendMessage(latestText, uploadedAttachments);
|
|
4528
4095
|
if (!sent) return;
|
|
4529
|
-
stopDictation();
|
|
4530
4096
|
handleClearAttachments();
|
|
4531
4097
|
setEditorKey((k) => k + 1);
|
|
4532
4098
|
};
|
|
@@ -4633,7 +4199,7 @@ function MessageComposer(_props = {}) {
|
|
|
4633
4199
|
/* @__PURE__ */ jsx("div", { className: "max-h-[400px] w-full overflow-y-auto", children: /* @__PURE__ */ jsx(
|
|
4634
4200
|
MarkdownEditor,
|
|
4635
4201
|
{
|
|
4636
|
-
ref:
|
|
4202
|
+
ref: editorRef,
|
|
4637
4203
|
value: newMessage,
|
|
4638
4204
|
onChange: (md) => setNewMessage(md),
|
|
4639
4205
|
onKeyDown: handleComposerKeyDown,
|
|
@@ -4650,12 +4216,10 @@ function MessageComposer(_props = {}) {
|
|
|
4650
4216
|
},
|
|
4651
4217
|
`composer-md-${editorKey}`
|
|
4652
4218
|
) }),
|
|
4653
|
-
/* @__PURE__ */ jsx("div", { role: "status", className: "sr-only", children: dictation.state === "listening" ? "Listening" : dictation.state === "starting" ? "Starting dictation" : "" }),
|
|
4654
|
-
dictation.error && /* @__PURE__ */ jsx("div", { role: "alert", className: "px-5 pb-1 text-xs text-destructive", children: dictationErrorMessages[dictation.error] }),
|
|
4655
4219
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-3 pb-3", children: [
|
|
4656
4220
|
/* @__PURE__ */ jsxs("div", { className: "ss-composer__actions flex min-w-0 flex-1 items-center gap-1", children: [
|
|
4657
4221
|
supportsFiles && /* @__PURE__ */ jsx(
|
|
4658
|
-
|
|
4222
|
+
IconButton,
|
|
4659
4223
|
{
|
|
4660
4224
|
type: "button",
|
|
4661
4225
|
onClick: handlePickFilesClick,
|
|
@@ -4676,27 +4240,19 @@ function MessageComposer(_props = {}) {
|
|
|
4676
4240
|
)
|
|
4677
4241
|
] }),
|
|
4678
4242
|
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
{
|
|
4682
|
-
state: dictation.state,
|
|
4683
|
-
error: dictation.error,
|
|
4684
|
-
disabled,
|
|
4685
|
-
onToggle: handleDictationToggle
|
|
4686
|
-
}
|
|
4687
|
-
) : /* @__PURE__ */ jsx(
|
|
4688
|
-
IconButton2,
|
|
4243
|
+
/* @__PURE__ */ jsx(
|
|
4244
|
+
IconButton,
|
|
4689
4245
|
{
|
|
4690
4246
|
type: "button",
|
|
4691
4247
|
disabled: true,
|
|
4692
4248
|
"aria-label": "Dictate a message",
|
|
4693
|
-
title: "Dictation is not available",
|
|
4249
|
+
title: "Dictation is not available yet",
|
|
4694
4250
|
className: "h-8 w-8 cursor-not-allowed rounded-full text-muted-foreground",
|
|
4695
4251
|
children: /* @__PURE__ */ jsx(Mic, { className: "h-4 w-4" })
|
|
4696
4252
|
}
|
|
4697
4253
|
),
|
|
4698
4254
|
canStop ? /* @__PURE__ */ jsx(
|
|
4699
|
-
|
|
4255
|
+
IconButton,
|
|
4700
4256
|
{
|
|
4701
4257
|
onClick: handleStopRun,
|
|
4702
4258
|
className: "chat-send h-8 w-8 rounded-full",
|
|
@@ -4710,7 +4266,7 @@ function MessageComposer(_props = {}) {
|
|
|
4710
4266
|
)
|
|
4711
4267
|
}
|
|
4712
4268
|
) : /* @__PURE__ */ jsx(
|
|
4713
|
-
|
|
4269
|
+
IconButton,
|
|
4714
4270
|
{
|
|
4715
4271
|
onClick: handleSendMessageAndClear,
|
|
4716
4272
|
className: `chat-send h-8 w-8 rounded-full ${sendDisabled ? "cursor-not-allowed" : ""}`,
|
|
@@ -4739,7 +4295,7 @@ function MessageComposer(_props = {}) {
|
|
|
4739
4295
|
},
|
|
4740
4296
|
children: /* @__PURE__ */ jsxs("div", { className: "relative h-full w-full bg-background border shadow-lg", children: [
|
|
4741
4297
|
/* @__PURE__ */ jsx(
|
|
4742
|
-
|
|
4298
|
+
IconButton,
|
|
4743
4299
|
{
|
|
4744
4300
|
type: "button",
|
|
4745
4301
|
size: "small",
|
|
@@ -4757,7 +4313,7 @@ function MessageComposer(_props = {}) {
|
|
|
4757
4313
|
/* @__PURE__ */ jsx("div", { className: "flex-1 p-4", children: /* @__PURE__ */ jsx(
|
|
4758
4314
|
MarkdownEditor,
|
|
4759
4315
|
{
|
|
4760
|
-
ref:
|
|
4316
|
+
ref: editorRef,
|
|
4761
4317
|
value: newMessage,
|
|
4762
4318
|
onChange: (md) => setNewMessage(md),
|
|
4763
4319
|
onKeyDown: handleComposerKeyDown,
|
|
@@ -4772,18 +4328,10 @@ function MessageComposer(_props = {}) {
|
|
|
4772
4328
|
},
|
|
4773
4329
|
`composer-md-${editorKey}`
|
|
4774
4330
|
) }),
|
|
4775
|
-
dictation.error && /* @__PURE__ */ jsx(
|
|
4776
|
-
"div",
|
|
4777
|
-
{
|
|
4778
|
-
"aria-hidden": "true",
|
|
4779
|
-
className: "px-4 pb-1 text-xs text-destructive",
|
|
4780
|
-
children: dictationErrorMessages[dictation.error]
|
|
4781
|
-
}
|
|
4782
|
-
),
|
|
4783
4331
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-t bg-background", children: [
|
|
4784
4332
|
/* @__PURE__ */ jsx("div", { className: "flex-1" }),
|
|
4785
4333
|
supportsFiles && /* @__PURE__ */ jsx(
|
|
4786
|
-
|
|
4334
|
+
IconButton,
|
|
4787
4335
|
{
|
|
4788
4336
|
type: "button",
|
|
4789
4337
|
onClick: handlePickFilesClick,
|
|
@@ -4798,18 +4346,8 @@ function MessageComposer(_props = {}) {
|
|
|
4798
4346
|
)
|
|
4799
4347
|
}
|
|
4800
4348
|
),
|
|
4801
|
-
dictation.available && /* @__PURE__ */ jsx(
|
|
4802
|
-
DictationButton,
|
|
4803
|
-
{
|
|
4804
|
-
size: "md",
|
|
4805
|
-
state: dictation.state,
|
|
4806
|
-
error: dictation.error,
|
|
4807
|
-
disabled,
|
|
4808
|
-
onToggle: handleDictationToggle
|
|
4809
|
-
}
|
|
4810
|
-
),
|
|
4811
4349
|
canStop ? /* @__PURE__ */ jsx(
|
|
4812
|
-
|
|
4350
|
+
IconButton,
|
|
4813
4351
|
{
|
|
4814
4352
|
onClick: handleStopRun,
|
|
4815
4353
|
className: "chat-send h-9 w-9 rounded-full",
|
|
@@ -4823,7 +4361,7 @@ function MessageComposer(_props = {}) {
|
|
|
4823
4361
|
)
|
|
4824
4362
|
}
|
|
4825
4363
|
) : /* @__PURE__ */ jsx(
|
|
4826
|
-
|
|
4364
|
+
IconButton,
|
|
4827
4365
|
{
|
|
4828
4366
|
onClick: handleSendMessageAndClear,
|
|
4829
4367
|
className: `chat-send h-9 w-9 rounded-full ${sendDisabled ? "cursor-not-allowed" : ""}`,
|
|
@@ -21158,6 +20696,6 @@ function getUserPhotoUrl(userId) {
|
|
|
21158
20696
|
return `${base2}/users/${userId}/photo`;
|
|
21159
20697
|
}
|
|
21160
20698
|
|
|
21161
|
-
export { ChatProvider, ChatVariablesForm, DRAFT_THREAD_PREFIX, DateFromApi,
|
|
20699
|
+
export { ChatProvider, ChatVariablesForm, DRAFT_THREAD_PREFIX, DateFromApi, MarkdownEditor, MessageComposer, MessageList, MessageListSkeleton, MessageMarkdown, MessageValueType, NEW_THREAD_ID, THREAD_LIST_PAGE_SIZE, applyDeltaToMessage, applyThreadToCache, createDraftThreadId, createThreadId, downloadFileBlobOptions, filesKeys, flowRunsKeys, getMessageErrorText, getModelIcon, getRetryStatusText, getThreadPlaceholderFromListCache, getUserPhotoUrl, invalidateWorkspaceThreadLists, isDraftThreadId, mapFileInfoDtoToModel, mapMentionUserDtoToModel, mapMessageDtoToModel, mapMessageErrorDtoToModel, mapMessageValueDtoToModel, mapMessagesDtoToModels, mapSignalRThreadSummaryToModel, mapThreadDtoToModel, mapThreadsResponseDtoToModel, mapWorkspaceDtoToModel, mapWorkspacesDtoToModels, markDraftThreadId, messagesKeys, messagesListOptions, messagesMutationsKeys, modelsKeys, parseDateTime, parseDateTimeHuman, parseRetryStatus, randomUUID, setThreadOptimisticRunning, setThreadRunningInLists, taggableUsersOptions, threadDetailOptions, threadsKeys, unmarkDraftThreadId, useAddInputToMessage, useChatContext, useChatIdentity, useChatService, useDownloadFileBlobQuery, useFileMutations, useFlowRunVariables, useIsDraftThreadId, useMessages, useModels, useSendMessage, useTaggableWorkspaceUsers, useThread, useThreadIsRunning, useUpdateFlowRunVariable, useWorkspace, utcDate, workspaceDetailOptions, workspaceKeys };
|
|
21162
20700
|
//# sourceMappingURL=index.js.map
|
|
21163
20701
|
//# sourceMappingURL=index.js.map
|