import React from "react"; import { Paperclip, Plus } from "lucide-react"; import { useTranslation } from "react-i18next"; import { I18nKey } from "#/i18n/declaration"; import { cn } from "#/utils/utils"; import { chatInputIconButtonClassName } from "#/utils/form-control-classes"; import { useOptionalConversationId } from "#/hooks/use-conversation-id"; import { useActiveConversation } from "#/hooks/query/use-active-conversation"; import { useConversationNameContextMenu } from "#/hooks/use-conversation-name-context-menu"; import { ToolsContextMenu } from "#/components/features/controls/tools-context-menu"; import { SystemMessageModal } from "#/components/features/conversation-panel/system-message-modal"; import { SkillsModal } from "#/components/features/conversation-panel/skills-modal"; import { PluginsModal } from "#/components/features/conversation-panel/plugins-modal"; import { HooksModal } from "#/components/features/conversation-panel/hooks-modal"; export interface ChatAddFileButtonProps { handleFileIconClick: () => void; disabled?: boolean; /** * Offer the "Switch agent profile" submenu. Computed by ChatInputActions: * only while starting a new conversation (home or a blank conversation) and * only when the backend has agent profiles (OSS-5735 — once a conversation * starts, the agent profile is locked). */ showAgentProfileSwitch?: boolean; } export function ChatAddFileButton({ handleFileIconClick, disabled = false, showAgentProfileSwitch = false, }: ChatAddFileButtonProps) { const { t } = useTranslation("openhands"); const { conversationId } = useOptionalConversationId(); const { data: conversation } = useActiveConversation(); const [menuOpen, setMenuOpen] = React.useState(false); const { handleShowAgentTools, handleShowSkills, handleShowPlugins, handleShowHooks, systemModalVisible, setSystemModalVisible, skillsModalVisible, setSkillsModalVisible, pluginsModalVisible, setPluginsModalVisible, hooksModalVisible, setHooksModalVisible, systemMessage, shouldShowAgentTools, shouldShowHooks, shouldShowPlugins, } = useConversationNameContextMenu({ conversationId: conversationId ?? undefined, executionStatus: conversation?.execution_status, showOptions: true, onContextMenuToggle: setMenuOpen, }); const handleClick = (event: React.MouseEvent) => { event.preventDefault(); event.stopPropagation(); if (disabled) return; setMenuOpen((open) => !open); }; return (
{menuOpen && ( setMenuOpen(false)} showAgentProfileSwitch={showAgentProfileSwitch} onShowSkills={handleShowSkills} onShowPlugins={handleShowPlugins} onShowHooks={handleShowHooks} onShowAgentTools={handleShowAgentTools} shouldShowAgentTools={shouldShowAgentTools} shouldShowHooks={shouldShowHooks} shouldShowPlugins={shouldShowPlugins} footerAction={{ testId: "add-files-and-images-button", icon: ( ), label: t(I18nKey.CHAT_INTERFACE$ADD_FILES_AND_IMAGES), onClick: handleFileIconClick, }} /> )} setSystemModalVisible(false)} systemMessage={systemMessage || null} /> {skillsModalVisible && ( setSkillsModalVisible(false)} /> )} {pluginsModalVisible && ( setPluginsModalVisible(false)} /> )} {hooksModalVisible && ( setHooksModalVisible(false)} /> )}
); }