From 6b7c15e23cb77b9482964520fa758da90fdc0a84 Mon Sep 17 00:00:00 2001 From: openhands Date: Thu, 26 Dec 2024 00:37:20 +0000 Subject: [PATCH] Add runtime size configuration feature --- frontend/__tests__/services/settings.test.ts | 13 +++++++-- .../modals/settings/runtime-size-selector.tsx | 29 +++++++++++++++++++ .../shared/modals/settings/settings-form.tsx | 7 +++++ frontend/src/services/settings.ts | 10 ++++++- 4 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 frontend/src/components/shared/modals/settings/runtime-size-selector.tsx diff --git a/frontend/__tests__/services/settings.test.ts b/frontend/__tests__/services/settings.test.ts index 2dc57133a1f8..aa9845bc2660 100644 --- a/frontend/__tests__/services/settings.test.ts +++ b/frontend/__tests__/services/settings.test.ts @@ -22,7 +22,8 @@ describe("getSettings", () => { .mockReturnValueOnce("language_value") .mockReturnValueOnce("api_key") .mockReturnValueOnce("true") - .mockReturnValueOnce("invariant"); + .mockReturnValueOnce("invariant") + .mockReturnValueOnce("2"); const settings = getSettings(); @@ -34,6 +35,7 @@ describe("getSettings", () => { LLM_API_KEY: "api_key", CONFIRMATION_MODE: true, SECURITY_ANALYZER: "invariant", + REMOTE_RUNTIME_RESOURCE_FACTOR: 2, }); }); @@ -46,6 +48,7 @@ describe("getSettings", () => { .mockReturnValueOnce(null) .mockReturnValueOnce(null) .mockReturnValueOnce(null) + .mockReturnValueOnce(null) .mockReturnValueOnce(null); const settings = getSettings(); @@ -58,6 +61,7 @@ describe("getSettings", () => { LLM_BASE_URL: DEFAULT_SETTINGS.LLM_BASE_URL, CONFIRMATION_MODE: DEFAULT_SETTINGS.CONFIRMATION_MODE, SECURITY_ANALYZER: DEFAULT_SETTINGS.SECURITY_ANALYZER, + REMOTE_RUNTIME_RESOURCE_FACTOR: DEFAULT_SETTINGS.REMOTE_RUNTIME_RESOURCE_FACTOR, }); }); }); @@ -72,6 +76,7 @@ describe("saveSettings", () => { LLM_API_KEY: "some_key", CONFIRMATION_MODE: true, SECURITY_ANALYZER: "invariant", + REMOTE_RUNTIME_RESOURCE_FACTOR: 2, }; saveSettings(settings); @@ -86,6 +91,10 @@ describe("saveSettings", () => { "LLM_API_KEY", "some_key", ); + expect(localStorage.setItem).toHaveBeenCalledWith( + "REMOTE_RUNTIME_RESOURCE_FACTOR", + "2", + ); }); it.skip("should save partial settings", () => { @@ -97,7 +106,7 @@ describe("saveSettings", () => { expect(localStorage.setItem).toHaveBeenCalledTimes(2); expect(localStorage.setItem).toHaveBeenCalledWith("LLM_MODEL", "llm_value"); - expect(localStorage.setItem).toHaveBeenCalledWith("SETTINGS_VERSION", "2"); + expect(localStorage.setItem).toHaveBeenCalledWith("SETTINGS_VERSION", "5"); }); it("should not save invalid settings", () => { diff --git a/frontend/src/components/shared/modals/settings/runtime-size-selector.tsx b/frontend/src/components/shared/modals/settings/runtime-size-selector.tsx new file mode 100644 index 000000000000..e936b55f6e00 --- /dev/null +++ b/frontend/src/components/shared/modals/settings/runtime-size-selector.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +interface RuntimeSizeSelectorProps { + isDisabled: boolean; + defaultValue?: number; +} + +export function RuntimeSizeSelector({ isDisabled, defaultValue }: RuntimeSizeSelectorProps) { + const { t } = useTranslation(); + + return ( +
+ + +
+ ); +} diff --git a/frontend/src/components/shared/modals/settings/settings-form.tsx b/frontend/src/components/shared/modals/settings/settings-form.tsx index 0734d25db6b4..93448a68a2ec 100644 --- a/frontend/src/components/shared/modals/settings/settings-form.tsx +++ b/frontend/src/components/shared/modals/settings/settings-form.tsx @@ -25,6 +25,7 @@ import { SecurityAnalyzerInput } from "../../inputs/security-analyzers-input"; import { ModalBackdrop } from "../modal-backdrop"; import { ModelSelector } from "./model-selector"; import { useAuth } from "#/context/auth-context"; +import { RuntimeSizeSelector } from "./runtime-size-selector"; interface SettingsFormProps { disabled?: boolean; @@ -106,6 +107,7 @@ export function SettingsForm({ posthog.capture("settings_saved", { LLM_MODEL: newSettings.LLM_MODEL, LLM_API_KEY: newSettings.LLM_API_KEY ? "SET" : "UNSET", + REMOTE_RUNTIME_RESOURCE_FACTOR: newSettings.REMOTE_RUNTIME_RESOURCE_FACTOR, }); }; @@ -199,6 +201,11 @@ export function SettingsForm({ defaultValue={settings.LLM_API_KEY} /> + + {showAdvancedOptions && ( void) => { if (currentVersion < 4) { logout(); } + + if (currentVersion < 5) { + localStorage.setItem("REMOTE_RUNTIME_RESOURCE_FACTOR", DEFAULT_SETTINGS.REMOTE_RUNTIME_RESOURCE_FACTOR.toString()); + } }; /** @@ -76,6 +82,7 @@ export const getSettings = (): Settings => { const apiKey = localStorage.getItem("LLM_API_KEY"); const confirmationMode = localStorage.getItem("CONFIRMATION_MODE") === "true"; const securityAnalyzer = localStorage.getItem("SECURITY_ANALYZER"); + const remoteRuntimeResourceFactor = localStorage.getItem("REMOTE_RUNTIME_RESOURCE_FACTOR"); return { LLM_MODEL: model || DEFAULT_SETTINGS.LLM_MODEL, @@ -85,6 +92,7 @@ export const getSettings = (): Settings => { LLM_API_KEY: apiKey || DEFAULT_SETTINGS.LLM_API_KEY, CONFIRMATION_MODE: confirmationMode || DEFAULT_SETTINGS.CONFIRMATION_MODE, SECURITY_ANALYZER: securityAnalyzer || DEFAULT_SETTINGS.SECURITY_ANALYZER, + REMOTE_RUNTIME_RESOURCE_FACTOR: remoteRuntimeResourceFactor ? parseInt(remoteRuntimeResourceFactor, 10) : DEFAULT_SETTINGS.REMOTE_RUNTIME_RESOURCE_FACTOR, }; };