@docyrus/ui-pro-ai-assistant 0.2.7 → 0.2.9
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/components/agent-trigger-widget/agent-trigger-prompt.d.ts +4 -2
- package/dist/components/agent-trigger-widget/index.d.ts +1 -1
- package/dist/docy-assistant.d.ts +1 -1
- package/dist/hooks/use-agents-data.d.ts +1 -0
- package/dist/index.js +252 -24
- package/dist/index.js.map +1 -1
- package/dist/styles.css +13 -0
- package/dist/types/index.d.ts +13 -0
- package/package.json +1 -1
|
@@ -9,10 +9,12 @@ export interface PromptFeatureFlags {
|
|
|
9
9
|
files: boolean;
|
|
10
10
|
}
|
|
11
11
|
export interface AgentTriggerPromptProps {
|
|
12
|
+
agentId: string | null;
|
|
12
13
|
capabilities: AgentCapabilities | null;
|
|
13
14
|
models: Model[];
|
|
14
15
|
suggestions: string[];
|
|
15
16
|
placeholder?: string;
|
|
16
|
-
|
|
17
|
+
promptOptimizationChoice?: string | null;
|
|
18
|
+
onSubmit: (prompt: string, features: PromptFeatureFlags, modelId?: string, files?: File[]) => void;
|
|
17
19
|
}
|
|
18
|
-
export declare function AgentTriggerPrompt({ capabilities, models, suggestions, placeholder, onSubmit }: AgentTriggerPromptProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export declare function AgentTriggerPrompt({ agentId, capabilities, models, suggestions, placeholder, promptOptimizationChoice, onSubmit }: AgentTriggerPromptProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,6 +3,6 @@ export interface AgentTriggerWidgetProps {
|
|
|
3
3
|
agentIds: string[];
|
|
4
4
|
className?: string;
|
|
5
5
|
placeholder?: string;
|
|
6
|
-
onSubmit?: (agentId: string, prompt: string, features: PromptFeatureFlags, modelId?: string) => void;
|
|
6
|
+
onSubmit?: (agentId: string, prompt: string, features: PromptFeatureFlags, modelId?: string, files?: File[]) => void;
|
|
7
7
|
}
|
|
8
8
|
export declare function AgentTriggerWidget({ agentIds, className, placeholder, onSubmit }: AgentTriggerWidgetProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/docy-assistant.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type RefObject } from 'react';
|
|
2
2
|
import { type DocyAssistantProps } from './types';
|
|
3
|
-
export declare const DocyAssistant: ({ ref, isOpen, onClose, supportWebSearch, supportThinking, supportFiles, supportDocumentSearch, supportDeepResearch, supportMultiModels, supportWorkCanvas, apiEndpoint, title: titleProp, description: descriptionProp, placeholder: placeholderProp, logo, footerText: footerTextProp, variant, renderMode, enableSidebar, enableNavDropdown, enableVoice, enableMicrophone, tenantAiAgentId, onMessageSend, onVoiceStart, onVoiceEnd, className, defaultFullscreen, hideExpand, hideCloseButton, hideAgentSelector, hideBorder, showHeader, agentSelectorUrl, baseAgentSelectorUrl, onAgentChange, initialPrompt, ...props }: DocyAssistantProps & {
|
|
3
|
+
export declare const DocyAssistant: ({ ref, isOpen, onClose, supportWebSearch, supportThinking, supportFiles, supportDocumentSearch, supportDeepResearch, supportMultiModels, supportWorkCanvas, apiEndpoint, title: titleProp, description: descriptionProp, placeholder: placeholderProp, logo, footerText: footerTextProp, variant, renderMode, enableSidebar, enableNavDropdown, enableVoice, enableMicrophone, tenantAiAgentId, onMessageSend, onVoiceStart, onVoiceEnd, className, defaultFullscreen, hideExpand, hideCloseButton, hideAgentSelector, hideBorder, showHeader, agentSelectorUrl, baseAgentSelectorUrl, onAgentChange, initialPrompt, initialModelId, initialFeatures, initialFiles, ...props }: DocyAssistantProps & {
|
|
4
4
|
ref?: RefObject<HTMLDivElement | null>;
|
|
5
5
|
}) => import("react/jsx-runtime").JSX.Element;
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { Input } from '@docyrus/ui-pro-shared/components/input';
|
|
|
9
9
|
import { Tabs as Tabs$1, TabsList as TabsList$1, TabsTrigger as TabsTrigger$1, TabsContent as TabsContent$1 } from '@docyrus/ui-pro-shared/components/tabs';
|
|
10
10
|
import { cn } from '@docyrus/ui-pro-shared/lib/utils';
|
|
11
11
|
import { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls } from 'ai';
|
|
12
|
-
import { PilcrowIcon, Heading1Icon, Heading2Icon, Heading3Icon, SquareIcon, ListIcon, ListOrderedIcon, ChevronDownIcon, Code2Icon, QuoteIcon, LightbulbIcon, Columns3Icon, GripVertical, FileUpIcon, TableIcon, ImageIcon, FilmIcon, AudioLinesIcon, TableOfContentsIcon, RadicalIcon, RectangleVerticalIcon, CalendarIcon, PlusIcon, FileCodeIcon, MinusIcon, ChevronRightIcon, ListTree, PenToolIcon, Link2Icon, Check, Copy, FilesIcon, Link, Text, ExternalLink, Unlink, Bold, Italic, Underline, Strikethrough, Code2, MoreHorizontal, ArrowLeftIcon, ArrowRightIcon, Minus, Plus, CircleArrowDown, Minimize2, Trash2, FileUp, CheckCircle2, FileText, Loader2, CornerDownLeftIcon, PencilLineIcon, MessageSquareTextIcon, MessagesSquareIcon, ArrowUpIcon, CheckIcon, CaptionsIcon, ZoomInIcon, CircleArrowDownIcon, MoveUpRightIcon, MoreHorizontalIcon, Eye, Pencil, PlusCircle, HelpCircle, Maximize2, X, Download, FileSpreadsheet, ChevronDown, Search, Globe, CheckCircle, FolderOpen, User, ArrowRight, MapPin, CalendarClock, List, RefreshCw, FilePlus, XIcon, CornerUpLeftIcon, AlbumIcon, FeatherIcon, ListMinusIcon, ListPlusIcon, ListEnd, Wand, LanguagesIcon, BadgeHelpIcon, PenLineIcon, SearchIcon, MusicIcon, CompassIcon, SmileIcon, LeafIcon, ClockIcon, AppleIcon, FlagIcon, StarIcon, DeleteIcon, AlignLeft, AlignCenter, AlignRight, RotateCcw, AlertTriangle, XCircle, AlertCircle, ArrowUpDown, ArrowDownToLine, PenLine, PencilIcon, TrashIcon, RefreshCwIcon, PaintRoller, MessageSquareText, ArrowLeft, ChevronLeft, Bot, ChevronRight, Brain, Lightbulb, BookOpen, PenTool, SlidersHorizontal, Mic, RefreshCcw, Code, Star, Trash, Edit, FolderInput, Archive, Sparkles, PanelLeft, MessageSquare, NotebookText, CirclePlus, MoreVertical, FileSearch, Microscope, Ruler, AudioLines, BrainCircuit, File as File$1, Plug, Inbox, Menu, LayoutDashboard, Table2, WandSparklesIcon, ArrowUpToLineIcon, BoldIcon, ItalicIcon, UnderlineIcon, StrikethroughIcon, HighlighterIcon, Undo2Icon, Redo2Icon, ArrowDownToLineIcon, AlignLeftIcon, AlignCenterIcon, AlignRightIcon, AlignJustifyIcon, ListOrdered, ListTodoIcon, ListCollapseIcon, Table, Grid3x3Icon, Combine, Ungroup, ArrowUp, ArrowDown, Trash2Icon, LinkIcon, WrapText, OutdentIcon, IndentIcon, EyeIcon, PenIcon } from 'lucide-react';
|
|
12
|
+
import { PilcrowIcon, Heading1Icon, Heading2Icon, Heading3Icon, SquareIcon, ListIcon, ListOrderedIcon, ChevronDownIcon, Code2Icon, QuoteIcon, LightbulbIcon, Columns3Icon, GripVertical, FileUpIcon, TableIcon, ImageIcon, FilmIcon, AudioLinesIcon, TableOfContentsIcon, RadicalIcon, RectangleVerticalIcon, CalendarIcon, PlusIcon, FileCodeIcon, MinusIcon, ChevronRightIcon, ListTree, PenToolIcon, Link2Icon, Check, Copy, FilesIcon, Link, Text, ExternalLink, Unlink, Bold, Italic, Underline, Strikethrough, Code2, MoreHorizontal, ArrowLeftIcon, ArrowRightIcon, Minus, Plus, CircleArrowDown, Minimize2, Trash2, FileUp, CheckCircle2, FileText, Loader2, CornerDownLeftIcon, PencilLineIcon, MessageSquareTextIcon, MessagesSquareIcon, ArrowUpIcon, CheckIcon, CaptionsIcon, ZoomInIcon, CircleArrowDownIcon, MoveUpRightIcon, MoreHorizontalIcon, Eye, Pencil, PlusCircle, HelpCircle, Maximize2, X, Download, FileSpreadsheet, ChevronDown, Search, Globe, CheckCircle, FolderOpen, User, ArrowRight, MapPin, CalendarClock, List, RefreshCw, FilePlus, XIcon, CornerUpLeftIcon, AlbumIcon, FeatherIcon, ListMinusIcon, ListPlusIcon, ListEnd, Wand, LanguagesIcon, BadgeHelpIcon, PenLineIcon, SearchIcon, MusicIcon, CompassIcon, SmileIcon, LeafIcon, ClockIcon, AppleIcon, FlagIcon, StarIcon, DeleteIcon, AlignLeft, AlignCenter, AlignRight, RotateCcw, AlertTriangle, XCircle, AlertCircle, ArrowUpDown, ArrowDownToLine, PenLine, PencilIcon, TrashIcon, RefreshCwIcon, PaintRoller, MessageSquareText, ArrowLeft, ChevronLeft, Bot, ChevronRight, Brain, Lightbulb, BookOpen, PenTool, SlidersHorizontal, Wand2, Mic, RefreshCcw, Code, Star, Trash, Edit, FolderInput, Archive, Sparkles, PanelLeft, MessageSquare, NotebookText, CirclePlus, MoreVertical, FileSearch, Microscope, Ruler, AudioLines, BrainCircuit, File as File$1, Plug, Inbox, Menu, LayoutDashboard, Table2, WandSparklesIcon, ArrowUpToLineIcon, BoldIcon, ItalicIcon, UnderlineIcon, StrikethroughIcon, HighlighterIcon, Undo2Icon, Redo2Icon, ArrowDownToLineIcon, AlignLeftIcon, AlignCenterIcon, AlignRightIcon, AlignJustifyIcon, ListOrdered, ListTodoIcon, ListCollapseIcon, Table, Grid3x3Icon, Combine, Ungroup, ArrowUp, ArrowDown, Trash2Icon, LinkIcon, WrapText, OutdentIcon, IndentIcon, EyeIcon, PenIcon } from 'lucide-react';
|
|
13
13
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
14
14
|
import { AsyncTokenManager, RestApiClient } from '@docyrus/api-client';
|
|
15
15
|
import { TooltipProvider, Tooltip as Tooltip$1, TooltipTrigger, TooltipContent } from '@docyrus/ui-pro-shared/components/tooltip';
|
|
@@ -2552,7 +2552,8 @@ function toAgentTriggerData(id, data) {
|
|
|
2552
2552
|
description: agent.description ?? null,
|
|
2553
2553
|
capabilities: extractCapabilities(agent),
|
|
2554
2554
|
models: agent.models ?? [],
|
|
2555
|
-
standardSuggestions: agent.standardSuggestions ?? agent.standard_suggestions ?? []
|
|
2555
|
+
standardSuggestions: agent.standardSuggestions ?? agent.standard_suggestions ?? [],
|
|
2556
|
+
promptOptimizationChoice: agent.promptOptimizationChoice ?? agent.prompt_optimization_choice ?? null
|
|
2556
2557
|
};
|
|
2557
2558
|
}
|
|
2558
2559
|
function useAgentsData(agentIds) {
|
|
@@ -24677,6 +24678,9 @@ var DocyAssistant = ({
|
|
|
24677
24678
|
baseAgentSelectorUrl = "/ai/agent-deployments/base",
|
|
24678
24679
|
onAgentChange,
|
|
24679
24680
|
initialPrompt,
|
|
24681
|
+
initialModelId,
|
|
24682
|
+
initialFeatures,
|
|
24683
|
+
initialFiles,
|
|
24680
24684
|
...props
|
|
24681
24685
|
}) => {
|
|
24682
24686
|
const config3 = useAssistantConfig();
|
|
@@ -24949,11 +24953,11 @@ var DocyAssistant = ({
|
|
|
24949
24953
|
uiActions.setActiveTab(0);
|
|
24950
24954
|
setMessages([]);
|
|
24951
24955
|
};
|
|
24952
|
-
const handleSendMessage = async (e, options3) => {
|
|
24956
|
+
const handleSendMessage = async (e, options3, overrideText) => {
|
|
24953
24957
|
e?.preventDefault();
|
|
24954
|
-
|
|
24958
|
+
const messageText = (overrideText ?? input).trim();
|
|
24959
|
+
if (!messageText) return;
|
|
24955
24960
|
messageOptionsRef.current = options3;
|
|
24956
|
-
const messageText = input.trim();
|
|
24957
24961
|
let currentThreadId = selectedSessionIdRef.current;
|
|
24958
24962
|
if (!currentThreadId) {
|
|
24959
24963
|
const subject = messageText.substring(0, 100);
|
|
@@ -25024,9 +25028,42 @@ var DocyAssistant = ({
|
|
|
25024
25028
|
if (!initialPrompt || initialPromptSentRef.current) return;
|
|
25025
25029
|
initialPromptSentRef.current = true;
|
|
25026
25030
|
setInput(initialPrompt);
|
|
25027
|
-
|
|
25028
|
-
|
|
25029
|
-
|
|
25031
|
+
const buildOptionsAndSend = async () => {
|
|
25032
|
+
const initialOptions = {};
|
|
25033
|
+
if (initialModelId) initialOptions.modelId = initialModelId;
|
|
25034
|
+
if (initialFeatures) {
|
|
25035
|
+
initialOptions.supportWebSearch = initialFeatures.webSearch;
|
|
25036
|
+
initialOptions.supportThinking = initialFeatures.thinking;
|
|
25037
|
+
initialOptions.supportDeepResearch = initialFeatures.deepResearch;
|
|
25038
|
+
initialOptions.supportDocumentSearch = initialFeatures.documentSearch;
|
|
25039
|
+
initialOptions.supportWorkCanvas = initialFeatures.workCanvas;
|
|
25040
|
+
initialOptions.supportFiles = initialFeatures.files;
|
|
25041
|
+
}
|
|
25042
|
+
if (initialFiles && initialFiles.length > 0) {
|
|
25043
|
+
const fileData = [];
|
|
25044
|
+
for (const file of initialFiles) {
|
|
25045
|
+
try {
|
|
25046
|
+
const url = await new Promise((resolve, reject) => {
|
|
25047
|
+
const reader = new FileReader();
|
|
25048
|
+
reader.onload = () => resolve(reader.result);
|
|
25049
|
+
reader.onerror = reject;
|
|
25050
|
+
reader.readAsDataURL(file);
|
|
25051
|
+
});
|
|
25052
|
+
fileData.push({ url, mediaType: file.type, filename: file.name });
|
|
25053
|
+
} catch {
|
|
25054
|
+
}
|
|
25055
|
+
}
|
|
25056
|
+
if (fileData.length > 0) {
|
|
25057
|
+
initialOptions.files = fileData;
|
|
25058
|
+
}
|
|
25059
|
+
}
|
|
25060
|
+
void handleSendMessage(
|
|
25061
|
+
void 0,
|
|
25062
|
+
Object.keys(initialOptions).length > 0 ? initialOptions : void 0,
|
|
25063
|
+
initialPrompt
|
|
25064
|
+
);
|
|
25065
|
+
};
|
|
25066
|
+
void buildOptionsAndSend();
|
|
25030
25067
|
}, [initialPrompt]);
|
|
25031
25068
|
const handleInputChange = useCallback((e) => {
|
|
25032
25069
|
setInput(e.target.value);
|
|
@@ -25847,6 +25884,7 @@ var CAPABILITY_TOGGLES = [
|
|
|
25847
25884
|
labelKey: "tools.file_upload"
|
|
25848
25885
|
}
|
|
25849
25886
|
];
|
|
25887
|
+
var ACCEPTED_FILE_TYPES = ".pdf,.doc,.docx,.txt,.csv,.xlsx,.xls,.json,.xml,.png,.jpg,.jpeg,.gif,.webp";
|
|
25850
25888
|
function ToggleSwitch({
|
|
25851
25889
|
checked,
|
|
25852
25890
|
onChange,
|
|
@@ -25889,13 +25927,16 @@ function useClickOutside(ref, open, onClose) {
|
|
|
25889
25927
|
}, [ref, open, onClose]);
|
|
25890
25928
|
}
|
|
25891
25929
|
function AgentTriggerPrompt({
|
|
25930
|
+
agentId,
|
|
25892
25931
|
capabilities,
|
|
25893
25932
|
models,
|
|
25894
25933
|
suggestions,
|
|
25895
25934
|
placeholder,
|
|
25935
|
+
promptOptimizationChoice,
|
|
25896
25936
|
onSubmit
|
|
25897
25937
|
}) {
|
|
25898
25938
|
const { t } = useAssistantTranslation();
|
|
25939
|
+
const apiClient = useApiClient();
|
|
25899
25940
|
const [prompt, setPrompt] = useState("");
|
|
25900
25941
|
const [selectedModel, setSelectedModel] = useState(
|
|
25901
25942
|
models[0]
|
|
@@ -25915,9 +25956,24 @@ function AgentTriggerPrompt({
|
|
|
25915
25956
|
const settingsRef = useRef(null);
|
|
25916
25957
|
const modelRef = useRef(null);
|
|
25917
25958
|
const reasoningRef = useRef(null);
|
|
25959
|
+
const [attachedFiles, setAttachedFiles] = useState([]);
|
|
25960
|
+
const fileInputRef = useRef(null);
|
|
25961
|
+
const [generatedSuggestions, setGeneratedSuggestions] = useState([]);
|
|
25962
|
+
const [isGeneratingSuggestions, setIsGeneratingSuggestions] = useState(false);
|
|
25963
|
+
const [isRecording, setIsRecording] = useState(false);
|
|
25964
|
+
const [isTranscribing, setIsTranscribing] = useState(false);
|
|
25965
|
+
const mediaRecorderRef = useRef(null);
|
|
25966
|
+
const audioChunksRef = useRef([]);
|
|
25967
|
+
const [isOptimizing, setIsOptimizing] = useState(false);
|
|
25968
|
+
const showOptimize = promptOptimizationChoice === "manual";
|
|
25918
25969
|
useClickOutside(settingsRef, settingsOpen, () => setSettingsOpen(false));
|
|
25919
25970
|
useClickOutside(modelRef, modelDropdownOpen, () => setModelDropdownOpen(false));
|
|
25920
25971
|
useClickOutside(reasoningRef, reasoningDropdownOpen, () => setReasoningDropdownOpen(false));
|
|
25972
|
+
useEffect(() => {
|
|
25973
|
+
if (models.length > 0 && !models.find((m) => m.id === selectedModel?.id)) {
|
|
25974
|
+
setSelectedModel(models[0]);
|
|
25975
|
+
}
|
|
25976
|
+
}, [models, selectedModel?.id]);
|
|
25921
25977
|
const hasThinking = capabilities?.supportThinking || selectedModel?.supportThinking;
|
|
25922
25978
|
const reasoningLevels = useMemo(
|
|
25923
25979
|
() => hasThinking ? selectedModel?.reasoningLevels ?? [] : [],
|
|
@@ -25934,16 +25990,130 @@ function AgentTriggerPrompt({
|
|
|
25934
25990
|
const toggleFeature = useCallback((key) => {
|
|
25935
25991
|
setFeatures((prev) => ({ ...prev, [key]: !prev[key] }));
|
|
25936
25992
|
}, []);
|
|
25993
|
+
const allSuggestions = useMemo(() => {
|
|
25994
|
+
const set = /* @__PURE__ */ new Set([...suggestions, ...generatedSuggestions]);
|
|
25995
|
+
return [...set];
|
|
25996
|
+
}, [suggestions, generatedSuggestions]);
|
|
25997
|
+
const generateSuggestions = useCallback(async () => {
|
|
25998
|
+
if (!agentId || isGeneratingSuggestions) return;
|
|
25999
|
+
setIsGeneratingSuggestions(true);
|
|
26000
|
+
try {
|
|
26001
|
+
const res = await apiClient.post(`/ai/agents/${agentId}/suggestions`, {
|
|
26002
|
+
prompt: prompt || void 0
|
|
26003
|
+
});
|
|
26004
|
+
if (res.success && res.data) {
|
|
26005
|
+
const data = res.data;
|
|
26006
|
+
if (data.promptSuggestions?.length) {
|
|
26007
|
+
setGeneratedSuggestions(data.promptSuggestions);
|
|
26008
|
+
}
|
|
26009
|
+
}
|
|
26010
|
+
} catch {
|
|
26011
|
+
} finally {
|
|
26012
|
+
setIsGeneratingSuggestions(false);
|
|
26013
|
+
}
|
|
26014
|
+
}, [
|
|
26015
|
+
agentId,
|
|
26016
|
+
apiClient,
|
|
26017
|
+
isGeneratingSuggestions,
|
|
26018
|
+
prompt
|
|
26019
|
+
]);
|
|
26020
|
+
const handleFileSelect = useCallback(() => {
|
|
26021
|
+
fileInputRef.current?.click();
|
|
26022
|
+
}, []);
|
|
26023
|
+
const handleFileChange = useCallback((e) => {
|
|
26024
|
+
const { files } = e.target;
|
|
26025
|
+
if (!files) return;
|
|
26026
|
+
setAttachedFiles((prev) => [...prev, ...Array.from(files)]);
|
|
26027
|
+
e.target.value = "";
|
|
26028
|
+
}, []);
|
|
26029
|
+
const removeFile = useCallback((index) => {
|
|
26030
|
+
setAttachedFiles((prev) => prev.filter((_, i) => i !== index));
|
|
26031
|
+
}, []);
|
|
26032
|
+
const startRecording = useCallback(async () => {
|
|
26033
|
+
try {
|
|
26034
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
26035
|
+
const mediaRecorder = new MediaRecorder(stream);
|
|
26036
|
+
audioChunksRef.current = [];
|
|
26037
|
+
mediaRecorder.ondataavailable = (e) => {
|
|
26038
|
+
if (e.data.size > 0) {
|
|
26039
|
+
audioChunksRef.current.push(e.data);
|
|
26040
|
+
}
|
|
26041
|
+
};
|
|
26042
|
+
mediaRecorder.onstop = async () => {
|
|
26043
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
26044
|
+
const audioBlob = new Blob(audioChunksRef.current, { type: "audio/webm" });
|
|
26045
|
+
if (audioBlob.size === 0) return;
|
|
26046
|
+
setIsTranscribing(true);
|
|
26047
|
+
try {
|
|
26048
|
+
const formData = new FormData();
|
|
26049
|
+
formData.append("file", audioBlob, "recording.webm");
|
|
26050
|
+
const res = await apiClient.post("/ai/transcribe", formData);
|
|
26051
|
+
if (res.success && res.data) {
|
|
26052
|
+
const data = res.data;
|
|
26053
|
+
const transcript = data.transcription?.text || "";
|
|
26054
|
+
if (transcript) {
|
|
26055
|
+
setPrompt((prev) => prev ? `${prev} ${transcript}` : transcript);
|
|
26056
|
+
}
|
|
26057
|
+
}
|
|
26058
|
+
} catch {
|
|
26059
|
+
} finally {
|
|
26060
|
+
setIsTranscribing(false);
|
|
26061
|
+
}
|
|
26062
|
+
};
|
|
26063
|
+
mediaRecorderRef.current = mediaRecorder;
|
|
26064
|
+
mediaRecorder.start();
|
|
26065
|
+
setIsRecording(true);
|
|
26066
|
+
} catch {
|
|
26067
|
+
}
|
|
26068
|
+
}, [apiClient]);
|
|
26069
|
+
const stopRecording = useCallback(() => {
|
|
26070
|
+
if (mediaRecorderRef.current && mediaRecorderRef.current.state === "recording") {
|
|
26071
|
+
mediaRecorderRef.current.stop();
|
|
26072
|
+
setIsRecording(false);
|
|
26073
|
+
}
|
|
26074
|
+
}, []);
|
|
26075
|
+
const handleMicClick = useCallback(() => {
|
|
26076
|
+
if (isRecording) {
|
|
26077
|
+
stopRecording();
|
|
26078
|
+
} else {
|
|
26079
|
+
void startRecording();
|
|
26080
|
+
}
|
|
26081
|
+
}, [isRecording, startRecording, stopRecording]);
|
|
26082
|
+
const optimizePrompt = useCallback(async () => {
|
|
26083
|
+
if (!agentId || !prompt.trim() || isOptimizing) return;
|
|
26084
|
+
setIsOptimizing(true);
|
|
26085
|
+
try {
|
|
26086
|
+
const res = await apiClient.post(`/ai/agents/${agentId}/optimize`, {
|
|
26087
|
+
prompt: prompt.trim()
|
|
26088
|
+
});
|
|
26089
|
+
if (res.success && res.data) {
|
|
26090
|
+
const data = res.data;
|
|
26091
|
+
if (data.optimizedPrompt) {
|
|
26092
|
+
setPrompt(data.optimizedPrompt);
|
|
26093
|
+
}
|
|
26094
|
+
}
|
|
26095
|
+
} catch {
|
|
26096
|
+
} finally {
|
|
26097
|
+
setIsOptimizing(false);
|
|
26098
|
+
}
|
|
26099
|
+
}, [
|
|
26100
|
+
agentId,
|
|
26101
|
+
apiClient,
|
|
26102
|
+
isOptimizing,
|
|
26103
|
+
prompt
|
|
26104
|
+
]);
|
|
25937
26105
|
const handleSubmit = useCallback(() => {
|
|
25938
26106
|
const trimmed = prompt.trim();
|
|
25939
26107
|
if (!trimmed) return;
|
|
25940
|
-
onSubmit(trimmed, features, selectedModel?.id);
|
|
26108
|
+
onSubmit(trimmed, features, selectedModel?.id, attachedFiles.length > 0 ? attachedFiles : void 0);
|
|
25941
26109
|
setPrompt("");
|
|
26110
|
+
setAttachedFiles([]);
|
|
25942
26111
|
}, [
|
|
25943
26112
|
prompt,
|
|
25944
26113
|
features,
|
|
25945
26114
|
selectedModel,
|
|
25946
|
-
onSubmit
|
|
26115
|
+
onSubmit,
|
|
26116
|
+
attachedFiles
|
|
25947
26117
|
]);
|
|
25948
26118
|
const handleKeyDown = useCallback(
|
|
25949
26119
|
(e) => {
|
|
@@ -25966,17 +26136,32 @@ function AgentTriggerPrompt({
|
|
|
25966
26136
|
return true;
|
|
25967
26137
|
}) : [];
|
|
25968
26138
|
return /* @__PURE__ */ jsxs("div", { className: "mt-4 mb-1 w-full max-w-[54rem]", children: [
|
|
25969
|
-
|
|
25970
|
-
|
|
26139
|
+
/* @__PURE__ */ jsx(
|
|
26140
|
+
"input",
|
|
26141
|
+
{
|
|
26142
|
+
ref: fileInputRef,
|
|
26143
|
+
type: "file",
|
|
26144
|
+
multiple: true,
|
|
26145
|
+
accept: ACCEPTED_FILE_TYPES,
|
|
26146
|
+
className: "hidden",
|
|
26147
|
+
onChange: handleFileChange
|
|
26148
|
+
}
|
|
26149
|
+
),
|
|
26150
|
+
agentId && /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2", children: [
|
|
26151
|
+
isGeneratingSuggestions ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs font-medium text-muted-foreground", children: [
|
|
26152
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }),
|
|
26153
|
+
/* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children: "Generating suggestions..." })
|
|
26154
|
+
] }) : /* @__PURE__ */ jsx(
|
|
25971
26155
|
"button",
|
|
25972
26156
|
{
|
|
25973
26157
|
type: "button",
|
|
25974
|
-
title:
|
|
26158
|
+
title: "Generate Suggestions",
|
|
26159
|
+
onClick: generateSuggestions,
|
|
25975
26160
|
className: "flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground transition-colors hover:bg-muted/80 hover:text-foreground",
|
|
25976
26161
|
children: /* @__PURE__ */ jsx(Plus, { className: "size-4" })
|
|
25977
26162
|
}
|
|
25978
26163
|
),
|
|
25979
|
-
/* @__PURE__ */ jsx("div", { className: "suggestions-container flex items-center gap-2 overflow-x-auto", children:
|
|
26164
|
+
allSuggestions.length > 0 && /* @__PURE__ */ jsx("div", { className: "suggestions-container flex items-center gap-2 overflow-x-auto", children: allSuggestions.map((s) => /* @__PURE__ */ jsx(
|
|
25980
26165
|
"button",
|
|
25981
26166
|
{
|
|
25982
26167
|
type: "button",
|
|
@@ -26000,6 +26185,26 @@ function AgentTriggerPrompt({
|
|
|
26000
26185
|
rows: 2
|
|
26001
26186
|
}
|
|
26002
26187
|
),
|
|
26188
|
+
attachedFiles.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 px-3 pb-2", children: attachedFiles.map((file, index) => /* @__PURE__ */ jsxs(
|
|
26189
|
+
"div",
|
|
26190
|
+
{
|
|
26191
|
+
className: "flex items-center gap-1.5 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground",
|
|
26192
|
+
children: [
|
|
26193
|
+
/* @__PURE__ */ jsx(FileUp, { className: "size-3.5 text-muted-foreground" }),
|
|
26194
|
+
/* @__PURE__ */ jsx("span", { className: "max-w-32 truncate", children: file.name }),
|
|
26195
|
+
/* @__PURE__ */ jsx(
|
|
26196
|
+
"button",
|
|
26197
|
+
{
|
|
26198
|
+
type: "button",
|
|
26199
|
+
onClick: () => removeFile(index),
|
|
26200
|
+
className: "ml-0.5 text-muted-foreground transition-colors hover:text-foreground",
|
|
26201
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-3" })
|
|
26202
|
+
}
|
|
26203
|
+
)
|
|
26204
|
+
]
|
|
26205
|
+
},
|
|
26206
|
+
`${file.name}-${index}`
|
|
26207
|
+
)) }),
|
|
26003
26208
|
/* @__PURE__ */ jsxs("div", { className: "flex h-10 items-center justify-between px-2", children: [
|
|
26004
26209
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
26005
26210
|
capabilities?.supportFiles && /* @__PURE__ */ jsx(
|
|
@@ -26007,6 +26212,7 @@ function AgentTriggerPrompt({
|
|
|
26007
26212
|
{
|
|
26008
26213
|
type: "button",
|
|
26009
26214
|
title: t("tools.file_upload"),
|
|
26215
|
+
onClick: handleFileSelect,
|
|
26010
26216
|
className: "flex size-7 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground",
|
|
26011
26217
|
children: /* @__PURE__ */ jsx(Plus, { className: "size-5" })
|
|
26012
26218
|
}
|
|
@@ -26120,14 +26326,34 @@ function AgentTriggerPrompt({
|
|
|
26120
26326
|
)) })
|
|
26121
26327
|
] })
|
|
26122
26328
|
] }),
|
|
26123
|
-
/* @__PURE__ */
|
|
26124
|
-
|
|
26125
|
-
|
|
26126
|
-
|
|
26127
|
-
|
|
26128
|
-
|
|
26129
|
-
|
|
26130
|
-
|
|
26329
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
26330
|
+
showOptimize && /* @__PURE__ */ jsx(
|
|
26331
|
+
"button",
|
|
26332
|
+
{
|
|
26333
|
+
type: "button",
|
|
26334
|
+
title: t("common.optimize_prompt") || "Optimize Prompt",
|
|
26335
|
+
disabled: isOptimizing || !prompt.trim(),
|
|
26336
|
+
onClick: () => void optimizePrompt(),
|
|
26337
|
+
className: "flex size-7 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground disabled:opacity-50",
|
|
26338
|
+
children: isOptimizing ? /* @__PURE__ */ jsx(Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ jsx(Wand2, { className: "size-5" })
|
|
26339
|
+
}
|
|
26340
|
+
),
|
|
26341
|
+
/* @__PURE__ */ jsx(
|
|
26342
|
+
"button",
|
|
26343
|
+
{
|
|
26344
|
+
type: "button",
|
|
26345
|
+
title: isRecording ? t("common.stop_recording") || "Stop Recording" : t("common.start_recording") || "Start Recording",
|
|
26346
|
+
disabled: isTranscribing,
|
|
26347
|
+
onClick: handleMicClick,
|
|
26348
|
+
className: cn(
|
|
26349
|
+
"flex size-7 items-center justify-center rounded transition-colors",
|
|
26350
|
+
isRecording ? "text-red-500 animate-pulse hover:text-red-600" : "text-muted-foreground hover:text-foreground",
|
|
26351
|
+
isTranscribing && "opacity-50"
|
|
26352
|
+
),
|
|
26353
|
+
children: isTranscribing ? /* @__PURE__ */ jsx(Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ jsx(Mic, { className: "size-5" })
|
|
26354
|
+
}
|
|
26355
|
+
)
|
|
26356
|
+
] })
|
|
26131
26357
|
] })
|
|
26132
26358
|
] })
|
|
26133
26359
|
] });
|
|
@@ -26158,9 +26384,9 @@ function AgentTriggerWidget({
|
|
|
26158
26384
|
[agents.length]
|
|
26159
26385
|
);
|
|
26160
26386
|
const handlePromptSubmit = useCallback(
|
|
26161
|
-
(prompt, features, modelId) => {
|
|
26387
|
+
(prompt, features, modelId, files) => {
|
|
26162
26388
|
if (!currentAgent) return;
|
|
26163
|
-
onSubmit?.(currentAgent.id, prompt, features, modelId);
|
|
26389
|
+
onSubmit?.(currentAgent.id, prompt, features, modelId, files);
|
|
26164
26390
|
},
|
|
26165
26391
|
[currentAgent, onSubmit]
|
|
26166
26392
|
);
|
|
@@ -26244,9 +26470,11 @@ function AgentTriggerWidget({
|
|
|
26244
26470
|
/* @__PURE__ */ jsx("div", { className: "flex h-fit w-full grow items-end justify-center px-6 pb-6", children: /* @__PURE__ */ jsx(
|
|
26245
26471
|
AgentTriggerPrompt,
|
|
26246
26472
|
{
|
|
26473
|
+
agentId: currentAgent?.id ?? null,
|
|
26247
26474
|
capabilities: currentAgent?.capabilities ?? null,
|
|
26248
26475
|
models: currentAgent?.models ?? [],
|
|
26249
26476
|
suggestions: currentAgent?.standardSuggestions ?? [],
|
|
26477
|
+
promptOptimizationChoice: currentAgent?.promptOptimizationChoice,
|
|
26250
26478
|
placeholder,
|
|
26251
26479
|
onSubmit: handlePromptSubmit
|
|
26252
26480
|
}
|