@docyrus/ui-pro-ai-assistant 0.2.8 → 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 +249 -19
- 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();
|
|
@@ -25024,7 +25028,42 @@ var DocyAssistant = ({
|
|
|
25024
25028
|
if (!initialPrompt || initialPromptSentRef.current) return;
|
|
25025
25029
|
initialPromptSentRef.current = true;
|
|
25026
25030
|
setInput(initialPrompt);
|
|
25027
|
-
|
|
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();
|
|
25028
25067
|
}, [initialPrompt]);
|
|
25029
25068
|
const handleInputChange = useCallback((e) => {
|
|
25030
25069
|
setInput(e.target.value);
|
|
@@ -25845,6 +25884,7 @@ var CAPABILITY_TOGGLES = [
|
|
|
25845
25884
|
labelKey: "tools.file_upload"
|
|
25846
25885
|
}
|
|
25847
25886
|
];
|
|
25887
|
+
var ACCEPTED_FILE_TYPES = ".pdf,.doc,.docx,.txt,.csv,.xlsx,.xls,.json,.xml,.png,.jpg,.jpeg,.gif,.webp";
|
|
25848
25888
|
function ToggleSwitch({
|
|
25849
25889
|
checked,
|
|
25850
25890
|
onChange,
|
|
@@ -25887,13 +25927,16 @@ function useClickOutside(ref, open, onClose) {
|
|
|
25887
25927
|
}, [ref, open, onClose]);
|
|
25888
25928
|
}
|
|
25889
25929
|
function AgentTriggerPrompt({
|
|
25930
|
+
agentId,
|
|
25890
25931
|
capabilities,
|
|
25891
25932
|
models,
|
|
25892
25933
|
suggestions,
|
|
25893
25934
|
placeholder,
|
|
25935
|
+
promptOptimizationChoice,
|
|
25894
25936
|
onSubmit
|
|
25895
25937
|
}) {
|
|
25896
25938
|
const { t } = useAssistantTranslation();
|
|
25939
|
+
const apiClient = useApiClient();
|
|
25897
25940
|
const [prompt, setPrompt] = useState("");
|
|
25898
25941
|
const [selectedModel, setSelectedModel] = useState(
|
|
25899
25942
|
models[0]
|
|
@@ -25913,9 +25956,24 @@ function AgentTriggerPrompt({
|
|
|
25913
25956
|
const settingsRef = useRef(null);
|
|
25914
25957
|
const modelRef = useRef(null);
|
|
25915
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";
|
|
25916
25969
|
useClickOutside(settingsRef, settingsOpen, () => setSettingsOpen(false));
|
|
25917
25970
|
useClickOutside(modelRef, modelDropdownOpen, () => setModelDropdownOpen(false));
|
|
25918
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]);
|
|
25919
25977
|
const hasThinking = capabilities?.supportThinking || selectedModel?.supportThinking;
|
|
25920
25978
|
const reasoningLevels = useMemo(
|
|
25921
25979
|
() => hasThinking ? selectedModel?.reasoningLevels ?? [] : [],
|
|
@@ -25932,16 +25990,130 @@ function AgentTriggerPrompt({
|
|
|
25932
25990
|
const toggleFeature = useCallback((key) => {
|
|
25933
25991
|
setFeatures((prev) => ({ ...prev, [key]: !prev[key] }));
|
|
25934
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
|
+
]);
|
|
25935
26105
|
const handleSubmit = useCallback(() => {
|
|
25936
26106
|
const trimmed = prompt.trim();
|
|
25937
26107
|
if (!trimmed) return;
|
|
25938
|
-
onSubmit(trimmed, features, selectedModel?.id);
|
|
26108
|
+
onSubmit(trimmed, features, selectedModel?.id, attachedFiles.length > 0 ? attachedFiles : void 0);
|
|
25939
26109
|
setPrompt("");
|
|
26110
|
+
setAttachedFiles([]);
|
|
25940
26111
|
}, [
|
|
25941
26112
|
prompt,
|
|
25942
26113
|
features,
|
|
25943
26114
|
selectedModel,
|
|
25944
|
-
onSubmit
|
|
26115
|
+
onSubmit,
|
|
26116
|
+
attachedFiles
|
|
25945
26117
|
]);
|
|
25946
26118
|
const handleKeyDown = useCallback(
|
|
25947
26119
|
(e) => {
|
|
@@ -25964,17 +26136,32 @@ function AgentTriggerPrompt({
|
|
|
25964
26136
|
return true;
|
|
25965
26137
|
}) : [];
|
|
25966
26138
|
return /* @__PURE__ */ jsxs("div", { className: "mt-4 mb-1 w-full max-w-[54rem]", children: [
|
|
25967
|
-
|
|
25968
|
-
|
|
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(
|
|
25969
26155
|
"button",
|
|
25970
26156
|
{
|
|
25971
26157
|
type: "button",
|
|
25972
|
-
title:
|
|
26158
|
+
title: "Generate Suggestions",
|
|
26159
|
+
onClick: generateSuggestions,
|
|
25973
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",
|
|
25974
26161
|
children: /* @__PURE__ */ jsx(Plus, { className: "size-4" })
|
|
25975
26162
|
}
|
|
25976
26163
|
),
|
|
25977
|
-
/* @__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(
|
|
25978
26165
|
"button",
|
|
25979
26166
|
{
|
|
25980
26167
|
type: "button",
|
|
@@ -25998,6 +26185,26 @@ function AgentTriggerPrompt({
|
|
|
25998
26185
|
rows: 2
|
|
25999
26186
|
}
|
|
26000
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
|
+
)) }),
|
|
26001
26208
|
/* @__PURE__ */ jsxs("div", { className: "flex h-10 items-center justify-between px-2", children: [
|
|
26002
26209
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
26003
26210
|
capabilities?.supportFiles && /* @__PURE__ */ jsx(
|
|
@@ -26005,6 +26212,7 @@ function AgentTriggerPrompt({
|
|
|
26005
26212
|
{
|
|
26006
26213
|
type: "button",
|
|
26007
26214
|
title: t("tools.file_upload"),
|
|
26215
|
+
onClick: handleFileSelect,
|
|
26008
26216
|
className: "flex size-7 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground",
|
|
26009
26217
|
children: /* @__PURE__ */ jsx(Plus, { className: "size-5" })
|
|
26010
26218
|
}
|
|
@@ -26118,14 +26326,34 @@ function AgentTriggerPrompt({
|
|
|
26118
26326
|
)) })
|
|
26119
26327
|
] })
|
|
26120
26328
|
] }),
|
|
26121
|
-
/* @__PURE__ */
|
|
26122
|
-
|
|
26123
|
-
|
|
26124
|
-
|
|
26125
|
-
|
|
26126
|
-
|
|
26127
|
-
|
|
26128
|
-
|
|
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
|
+
] })
|
|
26129
26357
|
] })
|
|
26130
26358
|
] })
|
|
26131
26359
|
] });
|
|
@@ -26156,9 +26384,9 @@ function AgentTriggerWidget({
|
|
|
26156
26384
|
[agents.length]
|
|
26157
26385
|
);
|
|
26158
26386
|
const handlePromptSubmit = useCallback(
|
|
26159
|
-
(prompt, features, modelId) => {
|
|
26387
|
+
(prompt, features, modelId, files) => {
|
|
26160
26388
|
if (!currentAgent) return;
|
|
26161
|
-
onSubmit?.(currentAgent.id, prompt, features, modelId);
|
|
26389
|
+
onSubmit?.(currentAgent.id, prompt, features, modelId, files);
|
|
26162
26390
|
},
|
|
26163
26391
|
[currentAgent, onSubmit]
|
|
26164
26392
|
);
|
|
@@ -26242,9 +26470,11 @@ function AgentTriggerWidget({
|
|
|
26242
26470
|
/* @__PURE__ */ jsx("div", { className: "flex h-fit w-full grow items-end justify-center px-6 pb-6", children: /* @__PURE__ */ jsx(
|
|
26243
26471
|
AgentTriggerPrompt,
|
|
26244
26472
|
{
|
|
26473
|
+
agentId: currentAgent?.id ?? null,
|
|
26245
26474
|
capabilities: currentAgent?.capabilities ?? null,
|
|
26246
26475
|
models: currentAgent?.models ?? [],
|
|
26247
26476
|
suggestions: currentAgent?.standardSuggestions ?? [],
|
|
26477
|
+
promptOptimizationChoice: currentAgent?.promptOptimizationChoice,
|
|
26248
26478
|
placeholder,
|
|
26249
26479
|
onSubmit: handlePromptSubmit
|
|
26250
26480
|
}
|