refactor(frontend): remove feature flag (planning agent) (#12880)

This commit is contained in:
Hiep Le
2026-02-26 18:44:26 +07:00
committed by GitHub
parent 0476d57451
commit f93e3254d3
10 changed files with 21 additions and 79 deletions

View File

@@ -5,11 +5,6 @@ import { ChangeAgentButton } from "#/components/features/chat/change-agent-butto
import { renderWithProviders } from "../../../../test-utils";
import { useConversationStore } from "#/stores/conversation-store";
// Mock feature flag to enable planning agent
vi.mock("#/utils/feature-flags", () => ({
USE_PLANNING_AGENT: () => true,
}));
// Mock WebSocket status
vi.mock("#/hooks/use-unified-websocket-status", () => ({
useUnifiedWebSocketStatus: () => "CONNECTED",

View File

@@ -27,11 +27,6 @@ function renderPlanPreview(ui: React.ReactElement) {
);
}
// Mock the feature flag to always return true (not testing feature flag behavior)
vi.mock("#/utils/feature-flags", () => ({
USE_PLANNING_AGENT: vi.fn(() => true),
}));
// Mock i18n - need to preserve initReactI18next and I18nextProvider for test-utils
vi.mock("react-i18next", async (importOriginal) => {
const actual = await importOriginal<typeof import("react-i18next")>();

View File

@@ -10,10 +10,6 @@ import { useConversationStore } from "#/stores/conversation-store";
const TASK_CONVERSATION_ID = "task-ec03fb2ab8604517b24af632b058c2fd";
const REAL_CONVERSATION_ID = "conv-abc123";
vi.mock("#/utils/feature-flags", () => ({
USE_PLANNING_AGENT: () => false,
}));
let mockConversationId = TASK_CONVERSATION_ID;
vi.mock("#/hooks/use-conversation-id", () => ({
@@ -120,9 +116,7 @@ describe("ConversationTabs localStorage behavior", () => {
// Verify localStorage was updated
const storedState = JSON.parse(
localStorage.getItem(
`conversation-state-${REAL_CONVERSATION_ID}`,
)!,
localStorage.getItem(`conversation-state-${REAL_CONVERSATION_ID}`)!,
);
expect(storedState.selectedTab).toBe("terminal");
expect(storedState.rightPanelShown).toBe(true);
@@ -152,9 +146,7 @@ describe("ConversationTabs localStorage behavior", () => {
// Verify localStorage was updated
const storedState = JSON.parse(
localStorage.getItem(
`conversation-state-${REAL_CONVERSATION_ID}`,
)!,
localStorage.getItem(`conversation-state-${REAL_CONVERSATION_ID}`)!,
);
expect(storedState.rightPanelShown).toBe(false);
});
@@ -184,9 +176,7 @@ describe("ConversationTabs localStorage behavior", () => {
// Verify localStorage was updated
const storedState = JSON.parse(
localStorage.getItem(
`conversation-state-${REAL_CONVERSATION_ID}`,
)!,
localStorage.getItem(`conversation-state-${REAL_CONVERSATION_ID}`)!,
);
expect(storedState.selectedTab).toBe("browser");
});

View File

@@ -9,11 +9,6 @@ import {
createPlanningObservationEvent,
} from "test-utils";
// Mock the feature flag
vi.mock("#/utils/feature-flags", () => ({
USE_PLANNING_AGENT: vi.fn(() => true),
}));
// Mock useConfig
vi.mock("#/hooks/query/use-config", () => ({
useConfig: () => ({

View File

@@ -9,7 +9,6 @@ import LessonPlanIcon from "#/icons/lesson-plan.svg?react";
import { useConversationStore } from "#/stores/conversation-store";
import { ChangeAgentContextMenu } from "./change-agent-context-menu";
import { cn } from "#/utils/utils";
import { USE_PLANNING_AGENT } from "#/utils/feature-flags";
import { useAgentState } from "#/hooks/use-agent-state";
import { AgentState } from "#/types/agent-state";
import { useActiveConversation } from "#/hooks/query/use-active-conversation";
@@ -27,8 +26,6 @@ export function ChangeAgentButton() {
const isWebSocketConnected = webSocketStatus === "CONNECTED";
const shouldUsePlanningAgent = USE_PLANNING_AGENT();
const { curAgentState } = useAgentState();
const { t } = useTranslation();
@@ -83,10 +80,7 @@ export function ChangeAgentButton() {
}, [isAgentRunning, contextMenuOpen, isWebSocketConnected]);
const isButtonDisabled =
isAgentRunning ||
isCreatingConversation ||
!isWebSocketConnected ||
!shouldUsePlanningAgent;
isAgentRunning || isCreatingConversation || !isWebSocketConnected;
// Handle Shift + Tab keyboard shortcut to cycle through modes
useEffect(() => {
@@ -151,10 +145,6 @@ export function ChangeAgentButton() {
return <LessonPlanIcon width={18} height={18} color="#ffffff" />;
}, [isExecutionAgent]);
if (!shouldUsePlanningAgent) {
return null;
}
return (
<div className="relative">
<button

View File

@@ -19,7 +19,6 @@ import { useInitialQueryStore } from "#/stores/initial-query-store";
import { useSendMessage } from "#/hooks/use-send-message";
import { useAgentState } from "#/hooks/use-agent-state";
import { useHandleBuildPlanClick } from "#/hooks/use-handle-build-plan-click";
import { USE_PLANNING_AGENT } from "#/utils/feature-flags";
import { ScrollToBottomButton } from "#/components/shared/buttons/scroll-to-bottom-button";
import { LoadingSpinner } from "#/components/shared/loading-spinner";
@@ -84,7 +83,6 @@ export function ChatInterface() {
const { curAgentState } = useAgentState();
const { handleBuildPlanClick } = useHandleBuildPlanClick();
const shouldUsePlanningAgent = USE_PLANNING_AGENT();
// Disable Build button while agent is running (streaming)
const isAgentRunning =
@@ -95,7 +93,7 @@ export function ChatInterface() {
// This is placed here instead of PlanPreview to avoid duplicate listeners
// when multiple PlanPreview components exist in the chat
React.useEffect(() => {
if (!shouldUsePlanningAgent || isAgentRunning) {
if (isAgentRunning) {
return undefined;
}
@@ -114,12 +112,7 @@ export function ChatInterface() {
return () => {
document.removeEventListener("keydown", handleKeyDown);
};
}, [
shouldUsePlanningAgent,
isAgentRunning,
handleBuildPlanClick,
scrollDomToBottom,
]);
}, [isAgentRunning, handleBuildPlanClick, scrollDomToBottom]);
const [feedbackPolarity, setFeedbackPolarity] = React.useState<
"positive" | "negative"

View File

@@ -2,7 +2,6 @@ import { useMemo, useCallback } from "react";
import { useTranslation } from "react-i18next";
import { ArrowUpRight } from "lucide-react";
import LessonPlanIcon from "#/icons/lesson-plan.svg?react";
import { USE_PLANNING_AGENT } from "#/utils/feature-flags";
import { Typography } from "#/ui/typography";
import { I18nKey } from "#/i18n/declaration";
import { MarkdownRenderer } from "#/components/features/markdown/markdown-renderer";
@@ -43,8 +42,6 @@ export function PlanPreview({
const { handleBuildPlanClick } = useHandleBuildPlanClick();
const { scrollDomToBottom } = useScrollContext();
const shouldUsePlanningAgent = USE_PLANNING_AGENT();
const handleViewClick = () => {
navigateToTab("planner");
};
@@ -65,7 +62,7 @@ export function PlanPreview({
return `${planContent.slice(0, MAX_CONTENT_LENGTH)}...`;
}, [planContent]);
if (!shouldUsePlanningAgent || !planContent) {
if (!planContent) {
return null;
}

View File

@@ -12,7 +12,6 @@ import GitChanges from "#/icons/git_changes.svg?react";
import VSCodeIcon from "#/icons/vscode.svg?react";
import PillIcon from "#/icons/pill.svg?react";
import PillFillIcon from "#/icons/pill-fill.svg?react";
import { USE_PLANNING_AGENT } from "#/utils/feature-flags";
import LessonPlanIcon from "#/icons/lesson-plan.svg?react";
interface ConversationTabsContextMenuProps {
@@ -30,9 +29,12 @@ export function ConversationTabsContextMenu({
const { state, setUnpinnedTabs } =
useConversationLocalStorageState(conversationId);
const shouldUsePlanningAgent = USE_PLANNING_AGENT();
const tabConfig = [
{
tab: "planner",
icon: LessonPlanIcon,
i18nKey: I18nKey.COMMON$PLANNER,
},
{ tab: "editor", icon: GitChanges, i18nKey: I18nKey.COMMON$CHANGES },
{ tab: "vscode", icon: VSCodeIcon, i18nKey: I18nKey.COMMON$CODE },
{ tab: "terminal", icon: TerminalIcon, i18nKey: I18nKey.COMMON$TERMINAL },
@@ -40,14 +42,6 @@ export function ConversationTabsContextMenu({
{ tab: "browser", icon: GlobeIcon, i18nKey: I18nKey.COMMON$BROWSER },
];
if (shouldUsePlanningAgent) {
tabConfig.unshift({
tab: "planner",
icon: LessonPlanIcon,
i18nKey: I18nKey.COMMON$PLANNER,
});
}
if (!isOpen) return null;
const handleTabClick = (tab: string) => {

View File

@@ -15,7 +15,6 @@ import { I18nKey } from "#/i18n/declaration";
import { VSCodeTooltipContent } from "./vscode-tooltip-content";
import { useConversationStore } from "#/stores/conversation-store";
import { ConversationTabsContextMenu } from "./conversation-tabs-context-menu";
import { USE_PLANNING_AGENT } from "#/utils/feature-flags";
import { useConversationId } from "#/hooks/use-conversation-id";
import { useSelectConversationTab } from "#/hooks/use-select-conversation-tab";
@@ -28,8 +27,6 @@ export function ConversationTabs() {
const { state: persistedState } =
useConversationLocalStorageState(conversationId);
const shouldUsePlanningAgent = USE_PLANNING_AGENT();
const {
selectTab,
isTabActive,
@@ -66,6 +63,15 @@ export function ConversationTabs() {
const { t } = useTranslation();
const tabs = [
{
tabValue: "planner",
isActive: isTabActive("planner"),
icon: LessonPlanIcon,
onClick: () => selectTab("planner"),
tooltipContent: t(I18nKey.COMMON$PLANNER),
tooltipAriaLabel: t(I18nKey.COMMON$PLANNER),
label: t(I18nKey.COMMON$PLANNER),
},
{
tabValue: "editor",
isActive: isTabActive("editor"),
@@ -114,18 +120,6 @@ export function ConversationTabs() {
},
];
if (shouldUsePlanningAgent) {
tabs.unshift({
tabValue: "planner",
isActive: isTabActive("planner"),
icon: LessonPlanIcon,
onClick: () => selectTab("planner"),
tooltipContent: t(I18nKey.COMMON$PLANNER),
tooltipAriaLabel: t(I18nKey.COMMON$PLANNER),
label: t(I18nKey.COMMON$PLANNER),
});
}
// Filter out unpinned tabs
const visibleTabs = tabs.filter(
(tab) => !persistedState.unpinnedTabs.includes(tab.tabValue),

View File

@@ -17,4 +17,3 @@ export const HIDE_LLM_SETTINGS = () => loadFeatureFlag("HIDE_LLM_SETTINGS");
export const VSCODE_IN_NEW_TAB = () => loadFeatureFlag("VSCODE_IN_NEW_TAB");
export const ENABLE_TRAJECTORY_REPLAY = () =>
loadFeatureFlag("TRAJECTORY_REPLAY");
export const USE_PLANNING_AGENT = () => loadFeatureFlag("USE_PLANNING_AGENT");