From 17e9b0fd6a7f54be21cf7179acedfe9e9a15ad18 Mon Sep 17 00:00:00 2001 From: Hiep Le <69354317+hieptl@users.noreply.github.com> Date: Tue, 15 Jul 2025 22:49:35 +0700 Subject: [PATCH] chore(Microagent Management UI): Set up the feature flag for the Microagent Management page. (#9704) --- frontend/src/api/open-hands.types.ts | 1 + .../microagent-management-sidebar-header.tsx | 19 ++++++++ .../microagent-management-sidebar.tsx | 9 ++++ .../components/features/sidebar/sidebar.tsx | 9 ++++ .../buttons/microagent-management-button.tsx | 28 +++++++++++ frontend/src/i18n/declaration.ts | 3 ++ frontend/src/i18n/translation.json | 48 +++++++++++++++++++ frontend/src/icons/question-circle.svg | 4 ++ frontend/src/icons/union.svg | 6 +++ frontend/src/routes.ts | 1 + frontend/src/routes/microagent-management.tsx | 37 ++++++++++++++ openhands/server/config/server_config.py | 3 ++ 12 files changed, 168 insertions(+) create mode 100644 frontend/src/components/features/microagent-management/microagent-management-sidebar-header.tsx create mode 100644 frontend/src/components/features/microagent-management/microagent-management-sidebar.tsx create mode 100644 frontend/src/components/shared/buttons/microagent-management-button.tsx create mode 100644 frontend/src/icons/question-circle.svg create mode 100644 frontend/src/icons/union.svg create mode 100644 frontend/src/routes/microagent-management.tsx diff --git a/frontend/src/api/open-hands.types.ts b/frontend/src/api/open-hands.types.ts index 4acdd16797..6074c5ef69 100644 --- a/frontend/src/api/open-hands.types.ts +++ b/frontend/src/api/open-hands.types.ts @@ -53,6 +53,7 @@ export interface GetConfigResponse { FEATURE_FLAGS: { ENABLE_BILLING: boolean; HIDE_LLM_SETTINGS: boolean; + HIDE_MICROAGENT_MANAGEMENT?: boolean; }; } diff --git a/frontend/src/components/features/microagent-management/microagent-management-sidebar-header.tsx b/frontend/src/components/features/microagent-management/microagent-management-sidebar-header.tsx new file mode 100644 index 0000000000..78322160de --- /dev/null +++ b/frontend/src/components/features/microagent-management/microagent-management-sidebar-header.tsx @@ -0,0 +1,19 @@ +import { useTranslation } from "react-i18next"; +import { I18nKey } from "#/i18n/declaration"; +import QuestionCircleIcon from "#/icons/question-circle.svg?react"; + +export function MicroagentManagementSidebarHeader() { + const { t } = useTranslation(); + + return ( +
+

+ {t(I18nKey.MICROAGENT_MANAGEMENT$DESCRIPTION)} +

+

+ {t(I18nKey.MICROAGENT_MANAGEMENT$USE_MICROAGENTS)} + +

+
+ ); +} diff --git a/frontend/src/components/features/microagent-management/microagent-management-sidebar.tsx b/frontend/src/components/features/microagent-management/microagent-management-sidebar.tsx new file mode 100644 index 0000000000..8c661e63b7 --- /dev/null +++ b/frontend/src/components/features/microagent-management/microagent-management-sidebar.tsx @@ -0,0 +1,9 @@ +import { MicroagentManagementSidebarHeader } from "./microagent-management-sidebar-header"; + +export function MicroagentManagementSidebar() { + return ( +
+ +
+ ); +} diff --git a/frontend/src/components/features/sidebar/sidebar.tsx b/frontend/src/components/features/sidebar/sidebar.tsx index a78facb3cf..989bb2f2d7 100644 --- a/frontend/src/components/features/sidebar/sidebar.tsx +++ b/frontend/src/components/features/sidebar/sidebar.tsx @@ -14,6 +14,7 @@ import { ConversationPanelWrapper } from "../conversation-panel/conversation-pan import { useLogout } from "#/hooks/mutation/use-logout"; import { useConfig } from "#/hooks/query/use-config"; import { displayErrorToast } from "#/utils/custom-toast-handlers"; +import { MicroagentManagementButton } from "#/components/shared/buttons/microagent-management-button"; export function Sidebar() { const location = useLocation(); @@ -36,6 +37,9 @@ export function Sidebar() { const shouldHideLlmSettings = config?.FEATURE_FLAGS.HIDE_LLM_SETTINGS && config?.APP_MODE === "saas"; + const shouldHideMicroagentManagement = + config?.FEATURE_FLAGS.HIDE_MICROAGENT_MANAGEMENT; + React.useEffect(() => { if (shouldHideLlmSettings) return; @@ -79,6 +83,11 @@ export function Sidebar() { } disabled={settings?.EMAIL_VERIFIED === false} /> + {!shouldHideMicroagentManagement && ( + + )}
diff --git a/frontend/src/components/shared/buttons/microagent-management-button.tsx b/frontend/src/components/shared/buttons/microagent-management-button.tsx new file mode 100644 index 0000000000..18a74d0b4e --- /dev/null +++ b/frontend/src/components/shared/buttons/microagent-management-button.tsx @@ -0,0 +1,28 @@ +import { useTranslation } from "react-i18next"; +import { I18nKey } from "#/i18n/declaration"; +import { TooltipButton } from "./tooltip-button"; +import UnionIcon from "#/icons/union.svg?react"; + +interface MicroagentManagementButtonProps { + disabled?: boolean; +} + +export function MicroagentManagementButton({ + disabled = false, +}: MicroagentManagementButtonProps) { + const { t } = useTranslation(); + + const microagentManagement = t(I18nKey.MICROAGENT_MANAGEMENT$TITLE); + + return ( + + + + ); +} diff --git a/frontend/src/i18n/declaration.ts b/frontend/src/i18n/declaration.ts index c466a11b9f..26ca6c9c1c 100644 --- a/frontend/src/i18n/declaration.ts +++ b/frontend/src/i18n/declaration.ts @@ -682,6 +682,9 @@ export enum I18nKey { COMMON$OPTIONAL = "COMMON$OPTIONAL", BROWSER$SERVER_MESSAGE = "BROWSER$SERVER_MESSAGE", API$NO_KEY_AVAILABLE = "API$NO_KEY_AVAILABLE", + MICROAGENT_MANAGEMENT$TITLE = "MICROAGENT_MANAGEMENT$TITLE", + MICROAGENT_MANAGEMENT$DESCRIPTION = "MICROAGENT_MANAGEMENT$DESCRIPTION", + MICROAGENT_MANAGEMENT$USE_MICROAGENTS = "MICROAGENT_MANAGEMENT$USE_MICROAGENTS", AUTH$BY_SIGNING_UP_YOU_AGREE_TO_OUR = "AUTH$BY_SIGNING_UP_YOU_AGREE_TO_OUR", COMMON$TERMS_OF_SERVICE = "COMMON$TERMS_OF_SERVICE", COMMON$AND = "COMMON$AND", diff --git a/frontend/src/i18n/translation.json b/frontend/src/i18n/translation.json index c1ed70e384..3703675d92 100644 --- a/frontend/src/i18n/translation.json +++ b/frontend/src/i18n/translation.json @@ -10911,6 +10911,54 @@ "de": "Kein API-Schlüssel verfügbar", "uk": "Немає доступного API-ключа" }, + "MICROAGENT_MANAGEMENT$TITLE": { + "en": "Microagent Management", + "ja": "マイクロエージェント管理", + "zh-CN": "微代理管理", + "zh-TW": "微代理管理", + "ko-KR": "마이크로에이전트 관리", + "no": "Microagent-administrasjon", + "it": "Gestione Microagent", + "pt": "Gerenciamento de Microagente", + "es": "Gestión de microagentes", + "ar": "إدارة الميكرووكيل", + "fr": "Gestion des microagents", + "tr": "Mikroajan Yönetimi", + "de": "Microagent-Verwaltung", + "uk": "Управління мікроагентами" + }, + "MICROAGENT_MANAGEMENT$DESCRIPTION": { + "en": "Manage Microagents", + "ja": "マイクロエージェントを管理する", + "zh-CN": "管理微代理", + "zh-TW": "管理微代理", + "ko-KR": "마이크로에이전트 관리", + "no": "Administrer mikroagenter", + "it": "Gestisci i Microagent", + "pt": "Gerenciar Microagentes", + "es": "Gestionar microagentes", + "ar": "إدارة الميكرووكلاء", + "fr": "Gérer les microagents", + "tr": "Mikro ajanları yönet", + "de": "Microagents verwalten", + "uk": "Керування мікроагентами" + }, + "MICROAGENT_MANAGEMENT$USE_MICROAGENTS": { + "en": "Use microagents to customize the behavior of OpenHands, teach it about your repositories, and help it work faster.", + "ja": "マイクロエージェントを使ってOpenHandsの動作をカスタマイズし、リポジトリについて教え、より速く作業できるようにしましょう。", + "zh-CN": "使用微代理自定义OpenHands的行为,让其了解您的仓库,并帮助其更快地工作。", + "zh-TW": "使用微代理自訂 OpenHands 的行為,讓其了解您的倉庫,並幫助其更快地工作。", + "ko-KR": "마이크로에이전트를 사용하여 OpenHands의 동작을 사용자 정의하고, 저장소에 대해 학습시키며, 더 빠르게 작업할 수 있도록 도와주세요.", + "no": "Bruk mikroagenter for å tilpasse oppførselen til OpenHands, lære den om dine repositories, og hjelpe den å jobbe raskere.", + "it": "Usa i microagent per personalizzare il comportamento di OpenHands, insegnargli i tuoi repository e aiutarlo a lavorare più velocemente.", + "pt": "Use microagentes para personalizar o comportamento do OpenHands, ensiná-lo sobre seus repositórios e ajudá-lo a trabalhar mais rápido.", + "es": "Utiliza microagentes para personalizar el comportamiento de OpenHands, enseñarle sobre tus repositorios y ayudarle a trabajar más rápido.", + "ar": "استخدم الوكلاء المصغرين لتخصيص سلوك OpenHands، وتعليمه حول مستودعاتك، ومساعدته على العمل بشكل أسرع.", + "fr": "Utilisez des microagents pour personnaliser le comportement d'OpenHands, lui apprendre vos dépôts et l'aider à travailler plus rapidement.", + "tr": "OpenHands'in davranışını özelleştirmek, depolarınızı ona öğretmek ve daha hızlı çalışmasına yardımcı olmak için mikro ajanları kullanın.", + "de": "Verwenden Sie Microagents, um das Verhalten von OpenHands anzupassen, ihm Ihre Repositories beizubringen und ihm zu helfen, schneller zu arbeiten.", + "uk": "Використовуйте мікроагенти, щоб налаштувати поведінку OpenHands, навчити його про ваші репозиторії та допомогти йому працювати швидше." + }, "AUTH$BY_SIGNING_UP_YOU_AGREE_TO_OUR": { "en": "By signing up, you agree to our", "ja": "サインアップすることで、あなたは当社の", diff --git a/frontend/src/icons/question-circle.svg b/frontend/src/icons/question-circle.svg new file mode 100644 index 0000000000..dc4169dc4b --- /dev/null +++ b/frontend/src/icons/question-circle.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/icons/union.svg b/frontend/src/icons/union.svg new file mode 100644 index 0000000000..6a7d70dfe4 --- /dev/null +++ b/frontend/src/icons/union.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/src/routes.ts b/frontend/src/routes.ts index c2b20234e9..70cd692f15 100644 --- a/frontend/src/routes.ts +++ b/frontend/src/routes.ts @@ -27,5 +27,6 @@ export default [ route("terminal", "routes/terminal-tab.tsx"), route("vscode", "routes/vscode-tab.tsx"), ]), + route("microagent-management", "routes/microagent-management.tsx"), ]), ] satisfies RouteConfig; diff --git a/frontend/src/routes/microagent-management.tsx b/frontend/src/routes/microagent-management.tsx new file mode 100644 index 0000000000..19ed169db8 --- /dev/null +++ b/frontend/src/routes/microagent-management.tsx @@ -0,0 +1,37 @@ +import { redirect } from "react-router"; +import { MicroagentManagementSidebar } from "#/components/features/microagent-management/microagent-management-sidebar"; +import { Route } from "./+types/settings"; +import { queryClient } from "#/query-client-config"; +import { GetConfigResponse } from "#/api/open-hands.types"; +import OpenHands from "#/api/open-hands"; + +export const clientLoader = async ({ request }: Route.ClientLoaderArgs) => { + const url = new URL(request.url); + const { pathname } = url; + + let config = queryClient.getQueryData(["config"]); + if (!config) { + config = await OpenHands.getConfig(); + queryClient.setQueryData(["config"], config); + } + + const shouldHideMicroagentManagement = + config?.FEATURE_FLAGS.HIDE_MICROAGENT_MANAGEMENT; + + if (shouldHideMicroagentManagement && pathname === "/microagent-management") { + return redirect("/"); + } + + return null; +}; + +function MicroagentManagement() { + return ( +
+ +
+
+ ); +} + +export default MicroagentManagement; diff --git a/openhands/server/config/server_config.py b/openhands/server/config/server_config.py index ba5e24cb3f..0e566d8c98 100644 --- a/openhands/server/config/server_config.py +++ b/openhands/server/config/server_config.py @@ -12,6 +12,8 @@ class ServerConfig(ServerConfigInterface): github_client_id = os.environ.get('GITHUB_APP_CLIENT_ID', '') enable_billing = os.environ.get('ENABLE_BILLING', 'false') == 'true' hide_llm_settings = os.environ.get('HIDE_LLM_SETTINGS', 'false') == 'true' + # This config is used to hide the microagent management page from the users for now. We will remove this once we release the new microagent management page. + hide_microagent_management = True settings_store_class: str = ( 'openhands.storage.settings.file_settings_store.FileSettingsStore' ) @@ -42,6 +44,7 @@ class ServerConfig(ServerConfigInterface): 'FEATURE_FLAGS': { 'ENABLE_BILLING': self.enable_billing, 'HIDE_LLM_SETTINGS': self.hide_llm_settings, + 'HIDE_MICROAGENT_MANAGEMENT': self.hide_microagent_management, }, }