@docyrus/ui-pro-ai-assistant 0.2.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/agent-trigger-widget/agent-trigger-prompt.d.ts +4 -2
- package/dist/components/agent-trigger-widget/index.d.ts +1 -1
- package/dist/components/input-area.d.ts +8 -0
- package/dist/docy-assistant.d.ts +1 -1
- package/dist/hooks/use-agents-data.d.ts +1 -0
- package/dist/index.js +279 -27
- package/dist/index.js.map +1 -1
- package/dist/styles.css +13 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/views/assistant-view.d.ts +8 -0
- package/dist/views/chat-panel.d.ts +9 -1
- 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;
|
|
@@ -44,6 +44,14 @@ interface AIInputAreaProps {
|
|
|
44
44
|
threadId?: string;
|
|
45
45
|
hasMessages?: boolean;
|
|
46
46
|
tenantAiProjectId?: string;
|
|
47
|
+
initialModelId?: string;
|
|
48
|
+
initialFeatures?: {
|
|
49
|
+
webSearch?: boolean;
|
|
50
|
+
thinking?: boolean;
|
|
51
|
+
deepResearch?: boolean;
|
|
52
|
+
documentSearch?: boolean;
|
|
53
|
+
workCanvas?: boolean;
|
|
54
|
+
};
|
|
47
55
|
}
|
|
48
56
|
export declare const AIInputArea: FC<AIInputAreaProps>;
|
|
49
57
|
export {};
|
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) {
|
|
@@ -3978,7 +3979,9 @@ var AIInputArea = ({
|
|
|
3978
3979
|
compactToolbar = false,
|
|
3979
3980
|
threadId,
|
|
3980
3981
|
hasMessages = false,
|
|
3981
|
-
tenantAiProjectId
|
|
3982
|
+
tenantAiProjectId,
|
|
3983
|
+
initialModelId,
|
|
3984
|
+
initialFeatures
|
|
3982
3985
|
}) => {
|
|
3983
3986
|
const { t } = useAssistantTranslation();
|
|
3984
3987
|
const isBaseAgent = !deploymentId && !!tenantAiAgentId;
|
|
@@ -4003,11 +4006,21 @@ var AIInputArea = ({
|
|
|
4003
4006
|
const effectiveSupportThinking = capabilities ? capabilities.supportThinking : supportThinking;
|
|
4004
4007
|
const effectiveSupportDeepResearch = capabilities ? capabilities.supportDeepResearch : supportDeepResearch;
|
|
4005
4008
|
const effectiveSupportWorkCanvas = capabilities ? capabilities.supportWorkCanvas : supportWorkCanvas;
|
|
4006
|
-
const [webSearchActive, setWebSearchActive] = useState(false);
|
|
4007
|
-
const [documentSearchActive, setDocumentSearchActive] = useState(false);
|
|
4008
|
-
const [thinkingActive, setThinkingActive] = useState(false);
|
|
4009
|
-
const [deepResearchActive, setDeepResearchActive] = useState(false);
|
|
4010
|
-
const [workCanvasActive, setWorkCanvasActive] = useState(false);
|
|
4009
|
+
const [webSearchActive, setWebSearchActive] = useState(initialFeatures?.webSearch ?? false);
|
|
4010
|
+
const [documentSearchActive, setDocumentSearchActive] = useState(initialFeatures?.documentSearch ?? false);
|
|
4011
|
+
const [thinkingActive, setThinkingActive] = useState(initialFeatures?.thinking ?? false);
|
|
4012
|
+
const [deepResearchActive, setDeepResearchActive] = useState(initialFeatures?.deepResearch ?? false);
|
|
4013
|
+
const [workCanvasActive, setWorkCanvasActive] = useState(initialFeatures?.workCanvas ?? false);
|
|
4014
|
+
const initialModelAppliedRef = useRef(false);
|
|
4015
|
+
useEffect(() => {
|
|
4016
|
+
if (initialModelId && models.length > 0 && !initialModelAppliedRef.current) {
|
|
4017
|
+
const match = models.find((m) => m.id === initialModelId);
|
|
4018
|
+
if (match) {
|
|
4019
|
+
setSelectedModel(match);
|
|
4020
|
+
initialModelAppliedRef.current = true;
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
}, [initialModelId, models, setSelectedModel]);
|
|
4011
4024
|
const toggleActiveClass = "bg-primary/10 text-primary hover:bg-primary/20 ring-1 ring-primary/30";
|
|
4012
4025
|
const [memoryExtractionOpen, setMemoryExtractionOpen] = useState(false);
|
|
4013
4026
|
const [memoryExtractionLoading, setMemoryExtractionLoading] = useState(false);
|
|
@@ -7370,7 +7383,9 @@ function ChatPanel({
|
|
|
7370
7383
|
renderThreadHeader,
|
|
7371
7384
|
messagesClassName,
|
|
7372
7385
|
compactToolbar,
|
|
7373
|
-
threadId
|
|
7386
|
+
threadId,
|
|
7387
|
+
initialModelId,
|
|
7388
|
+
initialFeatures
|
|
7374
7389
|
}) {
|
|
7375
7390
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7376
7391
|
renderThreadHeader?.(),
|
|
@@ -7418,7 +7433,9 @@ function ChatPanel({
|
|
|
7418
7433
|
showToolbar: !compactToolbar,
|
|
7419
7434
|
compactToolbar,
|
|
7420
7435
|
threadId,
|
|
7421
|
-
hasMessages: messages.length > 0
|
|
7436
|
+
hasMessages: messages.length > 0,
|
|
7437
|
+
initialModelId,
|
|
7438
|
+
initialFeatures
|
|
7422
7439
|
}
|
|
7423
7440
|
) })
|
|
7424
7441
|
] });
|
|
@@ -22504,6 +22521,8 @@ var AssistantView = ({ ref, ...props }) => {
|
|
|
22504
22521
|
onToolAction: commonProps2.onToolAction,
|
|
22505
22522
|
openCanvasView: handleOpenCanvasView,
|
|
22506
22523
|
threadId: commonProps2.threadId,
|
|
22524
|
+
initialModelId: commonProps2.initialModelId,
|
|
22525
|
+
initialFeatures: commonProps2.initialFeatures,
|
|
22507
22526
|
messagesClassName: "p-4"
|
|
22508
22527
|
}
|
|
22509
22528
|
);
|
|
@@ -22953,6 +22972,8 @@ var AssistantView = ({ ref, ...props }) => {
|
|
|
22953
22972
|
openCanvasView: handleOpenCanvasViewInline,
|
|
22954
22973
|
renderThreadHeader,
|
|
22955
22974
|
threadId: commonProps.threadId,
|
|
22975
|
+
initialModelId: commonProps.initialModelId,
|
|
22976
|
+
initialFeatures: commonProps.initialFeatures,
|
|
22956
22977
|
compactToolbar: !isFullscreen
|
|
22957
22978
|
}
|
|
22958
22979
|
)
|
|
@@ -24677,6 +24698,9 @@ var DocyAssistant = ({
|
|
|
24677
24698
|
baseAgentSelectorUrl = "/ai/agent-deployments/base",
|
|
24678
24699
|
onAgentChange,
|
|
24679
24700
|
initialPrompt,
|
|
24701
|
+
initialModelId,
|
|
24702
|
+
initialFeatures,
|
|
24703
|
+
initialFiles,
|
|
24680
24704
|
...props
|
|
24681
24705
|
}) => {
|
|
24682
24706
|
const config3 = useAssistantConfig();
|
|
@@ -25024,7 +25048,42 @@ var DocyAssistant = ({
|
|
|
25024
25048
|
if (!initialPrompt || initialPromptSentRef.current) return;
|
|
25025
25049
|
initialPromptSentRef.current = true;
|
|
25026
25050
|
setInput(initialPrompt);
|
|
25027
|
-
|
|
25051
|
+
const buildOptionsAndSend = async () => {
|
|
25052
|
+
const initialOptions = {};
|
|
25053
|
+
if (initialModelId) initialOptions.modelId = initialModelId;
|
|
25054
|
+
if (initialFeatures) {
|
|
25055
|
+
initialOptions.supportWebSearch = initialFeatures.webSearch;
|
|
25056
|
+
initialOptions.supportThinking = initialFeatures.thinking;
|
|
25057
|
+
initialOptions.supportDeepResearch = initialFeatures.deepResearch;
|
|
25058
|
+
initialOptions.supportDocumentSearch = initialFeatures.documentSearch;
|
|
25059
|
+
initialOptions.supportWorkCanvas = initialFeatures.workCanvas;
|
|
25060
|
+
initialOptions.supportFiles = initialFeatures.files;
|
|
25061
|
+
}
|
|
25062
|
+
if (initialFiles && initialFiles.length > 0) {
|
|
25063
|
+
const fileData = [];
|
|
25064
|
+
for (const file of initialFiles) {
|
|
25065
|
+
try {
|
|
25066
|
+
const url = await new Promise((resolve, reject) => {
|
|
25067
|
+
const reader = new FileReader();
|
|
25068
|
+
reader.onload = () => resolve(reader.result);
|
|
25069
|
+
reader.onerror = reject;
|
|
25070
|
+
reader.readAsDataURL(file);
|
|
25071
|
+
});
|
|
25072
|
+
fileData.push({ url, mediaType: file.type, filename: file.name });
|
|
25073
|
+
} catch {
|
|
25074
|
+
}
|
|
25075
|
+
}
|
|
25076
|
+
if (fileData.length > 0) {
|
|
25077
|
+
initialOptions.files = fileData;
|
|
25078
|
+
}
|
|
25079
|
+
}
|
|
25080
|
+
void handleSendMessage(
|
|
25081
|
+
void 0,
|
|
25082
|
+
Object.keys(initialOptions).length > 0 ? initialOptions : void 0,
|
|
25083
|
+
initialPrompt
|
|
25084
|
+
);
|
|
25085
|
+
};
|
|
25086
|
+
void buildOptionsAndSend();
|
|
25028
25087
|
}, [initialPrompt]);
|
|
25029
25088
|
const handleInputChange = useCallback((e) => {
|
|
25030
25089
|
setInput(e.target.value);
|
|
@@ -25193,6 +25252,8 @@ var DocyAssistant = ({
|
|
|
25193
25252
|
supportMultiModels,
|
|
25194
25253
|
deploymentId,
|
|
25195
25254
|
tenantAiAgentId: activeAgentId,
|
|
25255
|
+
initialModelId,
|
|
25256
|
+
initialFeatures,
|
|
25196
25257
|
enableMicrophone,
|
|
25197
25258
|
enableVoice,
|
|
25198
25259
|
isRecording,
|
|
@@ -25845,6 +25906,7 @@ var CAPABILITY_TOGGLES = [
|
|
|
25845
25906
|
labelKey: "tools.file_upload"
|
|
25846
25907
|
}
|
|
25847
25908
|
];
|
|
25909
|
+
var ACCEPTED_FILE_TYPES = ".pdf,.doc,.docx,.txt,.csv,.xlsx,.xls,.json,.xml,.png,.jpg,.jpeg,.gif,.webp";
|
|
25848
25910
|
function ToggleSwitch({
|
|
25849
25911
|
checked,
|
|
25850
25912
|
onChange,
|
|
@@ -25887,13 +25949,16 @@ function useClickOutside(ref, open, onClose) {
|
|
|
25887
25949
|
}, [ref, open, onClose]);
|
|
25888
25950
|
}
|
|
25889
25951
|
function AgentTriggerPrompt({
|
|
25952
|
+
agentId,
|
|
25890
25953
|
capabilities,
|
|
25891
25954
|
models,
|
|
25892
25955
|
suggestions,
|
|
25893
25956
|
placeholder,
|
|
25957
|
+
promptOptimizationChoice,
|
|
25894
25958
|
onSubmit
|
|
25895
25959
|
}) {
|
|
25896
25960
|
const { t } = useAssistantTranslation();
|
|
25961
|
+
const apiClient = useApiClient();
|
|
25897
25962
|
const [prompt, setPrompt] = useState("");
|
|
25898
25963
|
const [selectedModel, setSelectedModel] = useState(
|
|
25899
25964
|
models[0]
|
|
@@ -25913,9 +25978,24 @@ function AgentTriggerPrompt({
|
|
|
25913
25978
|
const settingsRef = useRef(null);
|
|
25914
25979
|
const modelRef = useRef(null);
|
|
25915
25980
|
const reasoningRef = useRef(null);
|
|
25981
|
+
const [attachedFiles, setAttachedFiles] = useState([]);
|
|
25982
|
+
const fileInputRef = useRef(null);
|
|
25983
|
+
const [generatedSuggestions, setGeneratedSuggestions] = useState([]);
|
|
25984
|
+
const [isGeneratingSuggestions, setIsGeneratingSuggestions] = useState(false);
|
|
25985
|
+
const [isRecording, setIsRecording] = useState(false);
|
|
25986
|
+
const [isTranscribing, setIsTranscribing] = useState(false);
|
|
25987
|
+
const mediaRecorderRef = useRef(null);
|
|
25988
|
+
const audioChunksRef = useRef([]);
|
|
25989
|
+
const [isOptimizing, setIsOptimizing] = useState(false);
|
|
25990
|
+
const showOptimize = promptOptimizationChoice === "manual";
|
|
25916
25991
|
useClickOutside(settingsRef, settingsOpen, () => setSettingsOpen(false));
|
|
25917
25992
|
useClickOutside(modelRef, modelDropdownOpen, () => setModelDropdownOpen(false));
|
|
25918
25993
|
useClickOutside(reasoningRef, reasoningDropdownOpen, () => setReasoningDropdownOpen(false));
|
|
25994
|
+
useEffect(() => {
|
|
25995
|
+
if (models.length > 0 && !models.find((m) => m.id === selectedModel?.id)) {
|
|
25996
|
+
setSelectedModel(models[0]);
|
|
25997
|
+
}
|
|
25998
|
+
}, [models, selectedModel?.id]);
|
|
25919
25999
|
const hasThinking = capabilities?.supportThinking || selectedModel?.supportThinking;
|
|
25920
26000
|
const reasoningLevels = useMemo(
|
|
25921
26001
|
() => hasThinking ? selectedModel?.reasoningLevels ?? [] : [],
|
|
@@ -25932,16 +26012,130 @@ function AgentTriggerPrompt({
|
|
|
25932
26012
|
const toggleFeature = useCallback((key) => {
|
|
25933
26013
|
setFeatures((prev) => ({ ...prev, [key]: !prev[key] }));
|
|
25934
26014
|
}, []);
|
|
26015
|
+
const allSuggestions = useMemo(() => {
|
|
26016
|
+
const set = /* @__PURE__ */ new Set([...suggestions, ...generatedSuggestions]);
|
|
26017
|
+
return [...set];
|
|
26018
|
+
}, [suggestions, generatedSuggestions]);
|
|
26019
|
+
const generateSuggestions = useCallback(async () => {
|
|
26020
|
+
if (!agentId || isGeneratingSuggestions) return;
|
|
26021
|
+
setIsGeneratingSuggestions(true);
|
|
26022
|
+
try {
|
|
26023
|
+
const res = await apiClient.post(`/ai/agents/${agentId}/suggestions`, {
|
|
26024
|
+
prompt: prompt || void 0
|
|
26025
|
+
});
|
|
26026
|
+
if (res.success && res.data) {
|
|
26027
|
+
const data = res.data;
|
|
26028
|
+
if (data.promptSuggestions?.length) {
|
|
26029
|
+
setGeneratedSuggestions(data.promptSuggestions);
|
|
26030
|
+
}
|
|
26031
|
+
}
|
|
26032
|
+
} catch {
|
|
26033
|
+
} finally {
|
|
26034
|
+
setIsGeneratingSuggestions(false);
|
|
26035
|
+
}
|
|
26036
|
+
}, [
|
|
26037
|
+
agentId,
|
|
26038
|
+
apiClient,
|
|
26039
|
+
isGeneratingSuggestions,
|
|
26040
|
+
prompt
|
|
26041
|
+
]);
|
|
26042
|
+
const handleFileSelect = useCallback(() => {
|
|
26043
|
+
fileInputRef.current?.click();
|
|
26044
|
+
}, []);
|
|
26045
|
+
const handleFileChange = useCallback((e) => {
|
|
26046
|
+
const { files } = e.target;
|
|
26047
|
+
if (!files) return;
|
|
26048
|
+
setAttachedFiles((prev) => [...prev, ...Array.from(files)]);
|
|
26049
|
+
e.target.value = "";
|
|
26050
|
+
}, []);
|
|
26051
|
+
const removeFile = useCallback((index) => {
|
|
26052
|
+
setAttachedFiles((prev) => prev.filter((_, i) => i !== index));
|
|
26053
|
+
}, []);
|
|
26054
|
+
const startRecording = useCallback(async () => {
|
|
26055
|
+
try {
|
|
26056
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
26057
|
+
const mediaRecorder = new MediaRecorder(stream);
|
|
26058
|
+
audioChunksRef.current = [];
|
|
26059
|
+
mediaRecorder.ondataavailable = (e) => {
|
|
26060
|
+
if (e.data.size > 0) {
|
|
26061
|
+
audioChunksRef.current.push(e.data);
|
|
26062
|
+
}
|
|
26063
|
+
};
|
|
26064
|
+
mediaRecorder.onstop = async () => {
|
|
26065
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
26066
|
+
const audioBlob = new Blob(audioChunksRef.current, { type: "audio/webm" });
|
|
26067
|
+
if (audioBlob.size === 0) return;
|
|
26068
|
+
setIsTranscribing(true);
|
|
26069
|
+
try {
|
|
26070
|
+
const formData = new FormData();
|
|
26071
|
+
formData.append("file", audioBlob, "recording.webm");
|
|
26072
|
+
const res = await apiClient.post("/ai/transcribe", formData);
|
|
26073
|
+
if (res.success && res.data) {
|
|
26074
|
+
const data = res.data;
|
|
26075
|
+
const transcript = data.transcription?.text || "";
|
|
26076
|
+
if (transcript) {
|
|
26077
|
+
setPrompt((prev) => prev ? `${prev} ${transcript}` : transcript);
|
|
26078
|
+
}
|
|
26079
|
+
}
|
|
26080
|
+
} catch {
|
|
26081
|
+
} finally {
|
|
26082
|
+
setIsTranscribing(false);
|
|
26083
|
+
}
|
|
26084
|
+
};
|
|
26085
|
+
mediaRecorderRef.current = mediaRecorder;
|
|
26086
|
+
mediaRecorder.start();
|
|
26087
|
+
setIsRecording(true);
|
|
26088
|
+
} catch {
|
|
26089
|
+
}
|
|
26090
|
+
}, [apiClient]);
|
|
26091
|
+
const stopRecording = useCallback(() => {
|
|
26092
|
+
if (mediaRecorderRef.current && mediaRecorderRef.current.state === "recording") {
|
|
26093
|
+
mediaRecorderRef.current.stop();
|
|
26094
|
+
setIsRecording(false);
|
|
26095
|
+
}
|
|
26096
|
+
}, []);
|
|
26097
|
+
const handleMicClick = useCallback(() => {
|
|
26098
|
+
if (isRecording) {
|
|
26099
|
+
stopRecording();
|
|
26100
|
+
} else {
|
|
26101
|
+
void startRecording();
|
|
26102
|
+
}
|
|
26103
|
+
}, [isRecording, startRecording, stopRecording]);
|
|
26104
|
+
const optimizePrompt = useCallback(async () => {
|
|
26105
|
+
if (!agentId || !prompt.trim() || isOptimizing) return;
|
|
26106
|
+
setIsOptimizing(true);
|
|
26107
|
+
try {
|
|
26108
|
+
const res = await apiClient.post(`/ai/agents/${agentId}/optimize`, {
|
|
26109
|
+
prompt: prompt.trim()
|
|
26110
|
+
});
|
|
26111
|
+
if (res.success && res.data) {
|
|
26112
|
+
const data = res.data;
|
|
26113
|
+
if (data.optimizedPrompt) {
|
|
26114
|
+
setPrompt(data.optimizedPrompt);
|
|
26115
|
+
}
|
|
26116
|
+
}
|
|
26117
|
+
} catch {
|
|
26118
|
+
} finally {
|
|
26119
|
+
setIsOptimizing(false);
|
|
26120
|
+
}
|
|
26121
|
+
}, [
|
|
26122
|
+
agentId,
|
|
26123
|
+
apiClient,
|
|
26124
|
+
isOptimizing,
|
|
26125
|
+
prompt
|
|
26126
|
+
]);
|
|
25935
26127
|
const handleSubmit = useCallback(() => {
|
|
25936
26128
|
const trimmed = prompt.trim();
|
|
25937
26129
|
if (!trimmed) return;
|
|
25938
|
-
onSubmit(trimmed, features, selectedModel?.id);
|
|
26130
|
+
onSubmit(trimmed, features, selectedModel?.id, attachedFiles.length > 0 ? attachedFiles : void 0);
|
|
25939
26131
|
setPrompt("");
|
|
26132
|
+
setAttachedFiles([]);
|
|
25940
26133
|
}, [
|
|
25941
26134
|
prompt,
|
|
25942
26135
|
features,
|
|
25943
26136
|
selectedModel,
|
|
25944
|
-
onSubmit
|
|
26137
|
+
onSubmit,
|
|
26138
|
+
attachedFiles
|
|
25945
26139
|
]);
|
|
25946
26140
|
const handleKeyDown = useCallback(
|
|
25947
26141
|
(e) => {
|
|
@@ -25964,17 +26158,32 @@ function AgentTriggerPrompt({
|
|
|
25964
26158
|
return true;
|
|
25965
26159
|
}) : [];
|
|
25966
26160
|
return /* @__PURE__ */ jsxs("div", { className: "mt-4 mb-1 w-full max-w-[54rem]", children: [
|
|
25967
|
-
|
|
25968
|
-
|
|
26161
|
+
/* @__PURE__ */ jsx(
|
|
26162
|
+
"input",
|
|
26163
|
+
{
|
|
26164
|
+
ref: fileInputRef,
|
|
26165
|
+
type: "file",
|
|
26166
|
+
multiple: true,
|
|
26167
|
+
accept: ACCEPTED_FILE_TYPES,
|
|
26168
|
+
className: "hidden",
|
|
26169
|
+
onChange: handleFileChange
|
|
26170
|
+
}
|
|
26171
|
+
),
|
|
26172
|
+
agentId && /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2", children: [
|
|
26173
|
+
isGeneratingSuggestions ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs font-medium text-muted-foreground", children: [
|
|
26174
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }),
|
|
26175
|
+
/* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children: "Generating suggestions..." })
|
|
26176
|
+
] }) : /* @__PURE__ */ jsx(
|
|
25969
26177
|
"button",
|
|
25970
26178
|
{
|
|
25971
26179
|
type: "button",
|
|
25972
|
-
title:
|
|
26180
|
+
title: "Generate Suggestions",
|
|
26181
|
+
onClick: generateSuggestions,
|
|
25973
26182
|
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
26183
|
children: /* @__PURE__ */ jsx(Plus, { className: "size-4" })
|
|
25975
26184
|
}
|
|
25976
26185
|
),
|
|
25977
|
-
/* @__PURE__ */ jsx("div", { className: "suggestions-container flex items-center gap-2 overflow-x-auto", children:
|
|
26186
|
+
allSuggestions.length > 0 && /* @__PURE__ */ jsx("div", { className: "suggestions-container flex items-center gap-2 overflow-x-auto", children: allSuggestions.map((s) => /* @__PURE__ */ jsx(
|
|
25978
26187
|
"button",
|
|
25979
26188
|
{
|
|
25980
26189
|
type: "button",
|
|
@@ -25998,6 +26207,26 @@ function AgentTriggerPrompt({
|
|
|
25998
26207
|
rows: 2
|
|
25999
26208
|
}
|
|
26000
26209
|
),
|
|
26210
|
+
attachedFiles.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 px-3 pb-2", children: attachedFiles.map((file, index) => /* @__PURE__ */ jsxs(
|
|
26211
|
+
"div",
|
|
26212
|
+
{
|
|
26213
|
+
className: "flex items-center gap-1.5 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground",
|
|
26214
|
+
children: [
|
|
26215
|
+
/* @__PURE__ */ jsx(FileUp, { className: "size-3.5 text-muted-foreground" }),
|
|
26216
|
+
/* @__PURE__ */ jsx("span", { className: "max-w-32 truncate", children: file.name }),
|
|
26217
|
+
/* @__PURE__ */ jsx(
|
|
26218
|
+
"button",
|
|
26219
|
+
{
|
|
26220
|
+
type: "button",
|
|
26221
|
+
onClick: () => removeFile(index),
|
|
26222
|
+
className: "ml-0.5 text-muted-foreground transition-colors hover:text-foreground",
|
|
26223
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-3" })
|
|
26224
|
+
}
|
|
26225
|
+
)
|
|
26226
|
+
]
|
|
26227
|
+
},
|
|
26228
|
+
`${file.name}-${index}`
|
|
26229
|
+
)) }),
|
|
26001
26230
|
/* @__PURE__ */ jsxs("div", { className: "flex h-10 items-center justify-between px-2", children: [
|
|
26002
26231
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
26003
26232
|
capabilities?.supportFiles && /* @__PURE__ */ jsx(
|
|
@@ -26005,6 +26234,7 @@ function AgentTriggerPrompt({
|
|
|
26005
26234
|
{
|
|
26006
26235
|
type: "button",
|
|
26007
26236
|
title: t("tools.file_upload"),
|
|
26237
|
+
onClick: handleFileSelect,
|
|
26008
26238
|
className: "flex size-7 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground",
|
|
26009
26239
|
children: /* @__PURE__ */ jsx(Plus, { className: "size-5" })
|
|
26010
26240
|
}
|
|
@@ -26118,14 +26348,34 @@ function AgentTriggerPrompt({
|
|
|
26118
26348
|
)) })
|
|
26119
26349
|
] })
|
|
26120
26350
|
] }),
|
|
26121
|
-
/* @__PURE__ */
|
|
26122
|
-
|
|
26123
|
-
|
|
26124
|
-
|
|
26125
|
-
|
|
26126
|
-
|
|
26127
|
-
|
|
26128
|
-
|
|
26351
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
26352
|
+
showOptimize && /* @__PURE__ */ jsx(
|
|
26353
|
+
"button",
|
|
26354
|
+
{
|
|
26355
|
+
type: "button",
|
|
26356
|
+
title: t("common.optimize_prompt") || "Optimize Prompt",
|
|
26357
|
+
disabled: isOptimizing || !prompt.trim(),
|
|
26358
|
+
onClick: () => void optimizePrompt(),
|
|
26359
|
+
className: "flex size-7 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground disabled:opacity-50",
|
|
26360
|
+
children: isOptimizing ? /* @__PURE__ */ jsx(Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ jsx(Wand2, { className: "size-5" })
|
|
26361
|
+
}
|
|
26362
|
+
),
|
|
26363
|
+
/* @__PURE__ */ jsx(
|
|
26364
|
+
"button",
|
|
26365
|
+
{
|
|
26366
|
+
type: "button",
|
|
26367
|
+
title: isRecording ? t("common.stop_recording") || "Stop Recording" : t("common.start_recording") || "Start Recording",
|
|
26368
|
+
disabled: isTranscribing,
|
|
26369
|
+
onClick: handleMicClick,
|
|
26370
|
+
className: cn(
|
|
26371
|
+
"flex size-7 items-center justify-center rounded transition-colors",
|
|
26372
|
+
isRecording ? "text-red-500 animate-pulse hover:text-red-600" : "text-muted-foreground hover:text-foreground",
|
|
26373
|
+
isTranscribing && "opacity-50"
|
|
26374
|
+
),
|
|
26375
|
+
children: isTranscribing ? /* @__PURE__ */ jsx(Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ jsx(Mic, { className: "size-5" })
|
|
26376
|
+
}
|
|
26377
|
+
)
|
|
26378
|
+
] })
|
|
26129
26379
|
] })
|
|
26130
26380
|
] })
|
|
26131
26381
|
] });
|
|
@@ -26156,9 +26406,9 @@ function AgentTriggerWidget({
|
|
|
26156
26406
|
[agents.length]
|
|
26157
26407
|
);
|
|
26158
26408
|
const handlePromptSubmit = useCallback(
|
|
26159
|
-
(prompt, features, modelId) => {
|
|
26409
|
+
(prompt, features, modelId, files) => {
|
|
26160
26410
|
if (!currentAgent) return;
|
|
26161
|
-
onSubmit?.(currentAgent.id, prompt, features, modelId);
|
|
26411
|
+
onSubmit?.(currentAgent.id, prompt, features, modelId, files);
|
|
26162
26412
|
},
|
|
26163
26413
|
[currentAgent, onSubmit]
|
|
26164
26414
|
);
|
|
@@ -26242,9 +26492,11 @@ function AgentTriggerWidget({
|
|
|
26242
26492
|
/* @__PURE__ */ jsx("div", { className: "flex h-fit w-full grow items-end justify-center px-6 pb-6", children: /* @__PURE__ */ jsx(
|
|
26243
26493
|
AgentTriggerPrompt,
|
|
26244
26494
|
{
|
|
26495
|
+
agentId: currentAgent?.id ?? null,
|
|
26245
26496
|
capabilities: currentAgent?.capabilities ?? null,
|
|
26246
26497
|
models: currentAgent?.models ?? [],
|
|
26247
26498
|
suggestions: currentAgent?.standardSuggestions ?? [],
|
|
26499
|
+
promptOptimizationChoice: currentAgent?.promptOptimizationChoice,
|
|
26248
26500
|
placeholder,
|
|
26249
26501
|
onSubmit: handlePromptSubmit
|
|
26250
26502
|
}
|