diff --git a/frontend/src/components/features/chat/chat-interface.tsx b/frontend/src/components/features/chat/chat-interface.tsx index aac8e7b42d..350b2e6e71 100644 --- a/frontend/src/components/features/chat/chat-interface.tsx +++ b/frontend/src/components/features/chat/chat-interface.tsx @@ -249,7 +249,7 @@ export function ChatInterface() {
- {totalEvents > 0 && ( + {totalEvents > 0 && !isV1Conversation && ( onClickShareFeedbackActionButton("positive") @@ -274,7 +274,7 @@ export function ChatInterface() {
- {config?.APP_MODE !== "saas" && ( + {config?.APP_MODE !== "saas" && !isV1Conversation && ( setFeedbackModalIsOpen(false)} diff --git a/frontend/src/components/features/chat/messages.tsx b/frontend/src/components/features/chat/messages.tsx index 289a6bdb58..0d9032164d 100644 --- a/frontend/src/components/features/chat/messages.tsx +++ b/frontend/src/components/features/chat/messages.tsx @@ -24,6 +24,7 @@ import { import { AgentState } from "#/types/agent-state"; import { getFirstPRUrl } from "#/utils/parse-pr-url"; import MemoryIcon from "#/icons/memory_icon.svg?react"; +import { useActiveConversation } from "#/hooks/query/use-active-conversation"; const isErrorEvent = (evt: unknown): evt is { error: true; message: string } => typeof evt === "object" && @@ -51,6 +52,11 @@ export const Messages: React.FC = React.memo( const { getOptimisticUserMessage } = useOptimisticUserMessageStore(); const { conversationId } = useConversationId(); const { data: conversation } = useUserConversation(conversationId); + const { data: activeConversation } = useActiveConversation(); + + // TODO: Hide microagent actions for V1 conversations + // This is a temporary measure and may be re-enabled in the future + const isV1Conversation = activeConversation?.conversation_version === "V1"; const optimisticUserMessage = getOptimisticUserMessage(); @@ -236,7 +242,7 @@ export const Messages: React.FC = React.memo( )} microagentPRUrl={getMicroagentPRUrlForEvent(message.id)} actions={ - conversation?.selected_repository + conversation?.selected_repository && !isV1Conversation ? [ { icon: ( @@ -259,6 +265,7 @@ export const Messages: React.FC = React.memo( )} {conversation?.selected_repository && + !isV1Conversation && showLaunchMicroagentModal && selectedEventId && createPortal( diff --git a/frontend/src/components/features/chat/microagent/launch-microagent-modal.tsx b/frontend/src/components/features/chat/microagent/launch-microagent-modal.tsx index 4a09f6bf34..40d67dbb1b 100644 --- a/frontend/src/components/features/chat/microagent/launch-microagent-modal.tsx +++ b/frontend/src/components/features/chat/microagent/launch-microagent-modal.tsx @@ -14,6 +14,7 @@ import { LoadingMicroagentBody } from "./loading-microagent-body"; import { LoadingMicroagentTextarea } from "./loading-microagent-textarea"; import { useGetMicroagents } from "#/hooks/query/use-get-microagents"; import { Typography } from "#/ui/typography"; +import { useActiveConversation } from "#/hooks/query/use-active-conversation"; interface LaunchMicroagentModalProps { onClose: () => void; @@ -32,6 +33,7 @@ export function LaunchMicroagentModal({ }: LaunchMicroagentModalProps) { const { t } = useTranslation(); const { runtimeActive } = useHandleRuntimeActive(); + const { data: conversation } = useActiveConversation(); const { data: prompt, isLoading: promptIsLoading } = useMicroagentPrompt(eventId); @@ -40,6 +42,15 @@ export function LaunchMicroagentModal({ const [triggers, setTriggers] = React.useState([]); + // TODO: Hide LaunchMicroagentModal for V1 conversations + // This is a temporary measure and may be re-enabled in the future + const isV1Conversation = conversation?.conversation_version === "V1"; + + // Don't render anything for V1 conversations + if (isV1Conversation) { + return null; + } + const formAction = (formData: FormData) => { const query = formData.get("query-input")?.toString(); const target = formData.get("target-input")?.toString(); diff --git a/frontend/src/components/features/controls/tools-context-menu.tsx b/frontend/src/components/features/controls/tools-context-menu.tsx index a1e89df33e..39330e25e4 100644 --- a/frontend/src/components/features/controls/tools-context-menu.tsx +++ b/frontend/src/components/features/controls/tools-context-menu.tsx @@ -28,17 +28,23 @@ interface ToolsContextMenuProps { onClose: () => void; onShowMicroagents: (event: React.MouseEvent) => void; onShowAgentTools: (event: React.MouseEvent) => void; + shouldShowAgentTools?: boolean; } export function ToolsContextMenu({ onClose, onShowMicroagents, onShowAgentTools, + shouldShowAgentTools = true, }: ToolsContextMenuProps) { const { t } = useTranslation(); const { data: conversation } = useActiveConversation(); const { providers } = useUserProviders(); + // TODO: Hide microagent menu items for V1 conversations + // This is a temporary measure and may be re-enabled in the future + const isV1Conversation = conversation?.conversation_version === "V1"; + const [activeSubmenu, setActiveSubmenu] = useState<"git" | "macros" | null>( null, ); @@ -64,7 +70,7 @@ export function ToolsContextMenu({ testId="tools-context-menu" position="top" alignment="left" - className="left-[-16px] mb-2 bottom-full overflow-visible" + className="left-[-16px] mb-2 bottom-full overflow-visible min-w-[200px]" > {/* Git Tools */} {showGitTools && ( @@ -122,33 +128,37 @@ export function ToolsContextMenu({
- + {(!isV1Conversation || shouldShowAgentTools) && } - {/* Show Available Microagents */} - - } - text={t(I18nKey.CONVERSATION$SHOW_MICROAGENTS)} - className={CONTEXT_MENU_ICON_TEXT_CLASSNAME} - /> - + {/* Show Available Microagents - Hidden for V1 conversations */} + {!isV1Conversation && ( + + } + text={t(I18nKey.CONVERSATION$SHOW_MICROAGENTS)} + className={CONTEXT_MENU_ICON_TEXT_CLASSNAME} + /> + + )} - {/* Show Agent Tools and Metadata */} - - } - text={t(I18nKey.BUTTON$SHOW_AGENT_TOOLS_AND_METADATA)} - className={CONTEXT_MENU_ICON_TEXT_CLASSNAME} - /> - + {/* Show Agent Tools and Metadata - Only show if system message is available */} + {shouldShowAgentTools && ( + + } + text={t(I18nKey.BUTTON$SHOW_AGENT_TOOLS_AND_METADATA)} + className={CONTEXT_MENU_ICON_TEXT_CLASSNAME} + /> + + )} ); } diff --git a/frontend/src/components/features/controls/tools.tsx b/frontend/src/components/features/controls/tools.tsx index f7fc4488bc..56ef58bc8e 100644 --- a/frontend/src/components/features/controls/tools.tsx +++ b/frontend/src/components/features/controls/tools.tsx @@ -23,6 +23,7 @@ export function Tools() { microagentsModalVisible, setMicroagentsModalVisible, systemMessage, + shouldShowAgentTools, } = useConversationNameContextMenu({ conversationId, conversationStatus: conversation?.status, @@ -52,6 +53,7 @@ export function Tools() { onClose={() => setContextMenuOpen(false)} onShowMicroagents={handleShowMicroagents} onShowAgentTools={handleShowAgentTools} + shouldShowAgentTools={shouldShowAgentTools} /> )} diff --git a/frontend/src/components/features/conversation-panel/conversation-card-context-menu.tsx b/frontend/src/components/features/conversation-panel/conversation-card-context-menu.tsx index a5b4888d94..63ea33152b 100644 --- a/frontend/src/components/features/conversation-panel/conversation-card-context-menu.tsx +++ b/frontend/src/components/features/conversation-panel/conversation-card-context-menu.tsx @@ -15,6 +15,7 @@ import { ContextMenuListItem } from "../context-menu/context-menu-list-item"; import { Divider } from "#/ui/divider"; import { I18nKey } from "#/i18n/declaration"; import { ContextMenuIconText } from "../context-menu/context-menu-icon-text"; +import { useActiveConversation } from "#/hooks/query/use-active-conversation"; interface ConversationCardContextMenuProps { onClose: () => void; @@ -41,6 +42,11 @@ export function ConversationCardContextMenu({ }: ConversationCardContextMenuProps) { const { t } = useTranslation(); const ref = useClickOutsideElement(onClose); + const { data: conversation } = useActiveConversation(); + + // TODO: Hide microagent menu items for V1 conversations + // This is a temporary measure and may be re-enabled in the future + const isV1Conversation = conversation?.conversation_version === "V1"; const hasEdit = Boolean(onEdit); const hasDownload = Boolean(onDownloadViaVSCode); @@ -97,7 +103,7 @@ export function ConversationCardContextMenu({ )} - {onShowMicroagents && ( + {onShowMicroagents && !isV1Conversation && ( void; @@ -19,6 +20,7 @@ interface MicroagentsModalProps { export function MicroagentsModal({ onClose }: MicroagentsModalProps) { const { t } = useTranslation(); const { curAgentState } = useAgentState(); + const { data: conversation } = useActiveConversation(); const [expandedAgents, setExpandedAgents] = useState>( {}, ); @@ -30,6 +32,15 @@ export function MicroagentsModal({ onClose }: MicroagentsModalProps) { isRefetching, } = useConversationMicroagents(); + // TODO: Hide MicroagentsModal for V1 conversations + // This is a temporary measure and may be re-enabled in the future + const isV1Conversation = conversation?.conversation_version === "V1"; + + // Don't render anything for V1 conversations + if (isV1Conversation) { + return null; + } + const toggleAgent = (agentName: string) => { setExpandedAgents((prev) => ({ ...prev, diff --git a/frontend/src/components/features/conversation/conversation-name-context-menu.tsx b/frontend/src/components/features/conversation/conversation-name-context-menu.tsx index c122ba363c..97ade1edb5 100644 --- a/frontend/src/components/features/conversation/conversation-name-context-menu.tsx +++ b/frontend/src/components/features/conversation/conversation-name-context-menu.tsx @@ -6,6 +6,7 @@ import { ContextMenu } from "#/ui/context-menu"; import { ContextMenuListItem } from "../context-menu/context-menu-list-item"; import { Divider } from "#/ui/divider"; import { I18nKey } from "#/i18n/declaration"; +import { useActiveConversation } from "#/hooks/query/use-active-conversation"; import EditIcon from "#/icons/u-edit.svg?react"; import RobotIcon from "#/icons/u-robot.svg?react"; @@ -52,6 +53,11 @@ export function ConversationNameContextMenu({ const { t } = useTranslation(); const ref = useClickOutsideElement(onClose); + const { data: conversation } = useActiveConversation(); + + // TODO: Hide microagent menu items for V1 conversations + // This is a temporary measure and may be re-enabled in the future + const isV1Conversation = conversation?.conversation_version === "V1"; const hasDownload = Boolean(onDownloadViaVSCode); const hasExport = Boolean(onExportConversation); @@ -85,7 +91,7 @@ export function ConversationNameContextMenu({ {hasTools && } - {onShowMicroagents && ( + {onShowMicroagents && !isV1Conversation && ( )} - {(hasExport || hasDownload) && } + {(hasExport || hasDownload) && !isV1Conversation && ( + + )} - {onExportConversation && ( + {onExportConversation && !isV1Conversation && ( )} - {onDownloadViaVSCode && ( + {onDownloadViaVSCode && !isV1Conversation && ( )} - {(hasInfo || hasControl) && } + {(hasInfo || hasControl) && !isV1Conversation && ( + + )} {onDisplayCost && ( { hotToast(t(I18nKey.FEEDBACK$PASSWORD_COPIED_MESSAGE), { @@ -60,6 +62,15 @@ export function FeedbackForm({ onClose, polarity }: FeedbackFormProps) { const { mutate: submitFeedback, isPending } = useSubmitFeedback(); + // TODO: Hide FeedbackForm for V1 conversations + // This is a temporary measure and may be re-enabled in the future + const isV1Conversation = conversation?.conversation_version === "V1"; + + // Don't render anything for V1 conversations + if (isV1Conversation) { + return null; + } + const handleSubmit = async (event: React.FormEvent) => { event?.preventDefault(); const formData = new FormData(event.currentTarget); diff --git a/frontend/src/components/features/feedback/likert-scale.tsx b/frontend/src/components/features/feedback/likert-scale.tsx index 3c867cc1ea..367406d25a 100644 --- a/frontend/src/components/features/feedback/likert-scale.tsx +++ b/frontend/src/components/features/feedback/likert-scale.tsx @@ -5,6 +5,7 @@ import { cn } from "#/utils/utils"; import { I18nKey } from "#/i18n/declaration"; import { useSubmitConversationFeedback } from "#/hooks/mutation/use-submit-conversation-feedback"; import { ScrollContext } from "#/context/scroll-context"; +import { useActiveConversation } from "#/hooks/query/use-active-conversation"; // Global timeout duration in milliseconds const AUTO_SUBMIT_TIMEOUT = 10000; @@ -23,6 +24,7 @@ export function LikertScale({ initialReason, }: LikertScaleProps) { const { t } = useTranslation(); + const { data: conversation } = useActiveConversation(); const [selectedRating, setSelectedRating] = useState( initialRating || null, @@ -77,6 +79,56 @@ export function LikertScale({ } }, [initialReason]); + // Countdown effect + useEffect(() => { + if (countdown > 0 && showReasons && !isSubmitted) { + const timer = setTimeout(() => { + setCountdown(countdown - 1); + }, 1000); + return () => clearTimeout(timer); + } + return () => {}; + }, [countdown, showReasons, isSubmitted]); + + // Clean up timeout on unmount + useEffect( + () => () => { + if (reasonTimeout) { + clearTimeout(reasonTimeout); + } + }, + [reasonTimeout], + ); + + // Scroll to bottom when component mounts, but only if user is already at the bottom + useEffect(() => { + if (scrollToBottom && autoScroll && !isSubmitted) { + // Small delay to ensure the component is fully rendered + setTimeout(() => { + scrollToBottom(); + }, 100); + } + }, [scrollToBottom, autoScroll, isSubmitted]); + + // Scroll to bottom when reasons are shown, but only if user is already at the bottom + useEffect(() => { + if (scrollToBottom && autoScroll && showReasons) { + // Small delay to ensure the reasons are fully rendered + setTimeout(() => { + scrollToBottom(); + }, 100); + } + }, [scrollToBottom, autoScroll, showReasons]); + + // TODO: Hide LikertScale for V1 conversations + // This is a temporary measure and may be re-enabled in the future + const isV1Conversation = conversation?.conversation_version === "V1"; + + // Don't render anything for V1 conversations + if (isV1Conversation) { + return null; + } + // Submit feedback and disable the component const submitFeedback = (rating: number, reason?: string) => { submitConversationFeedback( @@ -137,47 +189,6 @@ export function LikertScale({ } }; - // Countdown effect - useEffect(() => { - if (countdown > 0 && showReasons && !isSubmitted) { - const timer = setTimeout(() => { - setCountdown(countdown - 1); - }, 1000); - return () => clearTimeout(timer); - } - return () => {}; - }, [countdown, showReasons, isSubmitted]); - - // Clean up timeout on unmount - useEffect( - () => () => { - if (reasonTimeout) { - clearTimeout(reasonTimeout); - } - }, - [reasonTimeout], - ); - - // Scroll to bottom when component mounts, but only if user is already at the bottom - useEffect(() => { - if (scrollToBottom && autoScroll && !isSubmitted) { - // Small delay to ensure the component is fully rendered - setTimeout(() => { - scrollToBottom(); - }, 100); - } - }, [scrollToBottom, autoScroll, isSubmitted]); - - // Scroll to bottom when reasons are shown, but only if user is already at the bottom - useEffect(() => { - if (scrollToBottom && autoScroll && showReasons) { - // Small delay to ensure the reasons are fully rendered - setTimeout(() => { - scrollToBottom(); - }, 100); - } - }, [scrollToBottom, autoScroll, showReasons]); - // Helper function to get button class based on state const getButtonClass = (rating: number) => { if (isSubmitted) { diff --git a/frontend/src/hooks/mutation/use-submit-feedback.ts b/frontend/src/hooks/mutation/use-submit-feedback.ts index c04e4b964c..142d1c2b9a 100644 --- a/frontend/src/hooks/mutation/use-submit-feedback.ts +++ b/frontend/src/hooks/mutation/use-submit-feedback.ts @@ -10,6 +10,7 @@ type SubmitFeedbackArgs = { export const useSubmitFeedback = () => { const { conversationId } = useConversationId(); + return useMutation({ mutationFn: ({ feedback }: SubmitFeedbackArgs) => ConversationService.submitFeedback(conversationId, feedback), diff --git a/frontend/src/hooks/query/use-microagent-prompt.ts b/frontend/src/hooks/query/use-microagent-prompt.ts index c728e5f795..4661520d15 100644 --- a/frontend/src/hooks/query/use-microagent-prompt.ts +++ b/frontend/src/hooks/query/use-microagent-prompt.ts @@ -4,7 +4,6 @@ import { useConversationId } from "../use-conversation-id"; export const useMicroagentPrompt = (eventId: number) => { const { conversationId } = useConversationId(); - return useQuery({ queryKey: ["memory", "prompt", conversationId, eventId], queryFn: () =>