diff --git a/README.md b/README.md index 63ae90a80c5d..0a3470267205 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ docker run -it --rm --pull=always \ -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.17-nikolaik \ -e LOG_ALL_EVENTS=true \ -v /var/run/docker.sock:/var/run/docker.sock \ - -v ~/.openhands-state:/home/openhands/.openhands-state \ + -v ~/.openhands-state:/.openhands-state \ -p 3000:3000 \ --add-host host.docker.internal:host-gateway \ --name openhands-app \ diff --git a/containers/app/Dockerfile b/containers/app/Dockerfile index 59bd6968e917..127eb306f9ed 100644 --- a/containers/app/Dockerfile +++ b/containers/app/Dockerfile @@ -43,7 +43,8 @@ ENV WORKSPACE_BASE=/opt/workspace_base ENV OPENHANDS_BUILD_VERSION=$OPENHANDS_BUILD_VERSION ENV SANDBOX_USER_ID=0 ENV FILE_STORE=local -ENV FILE_STORE_PATH=~/.openhands-state +ENV FILE_STORE_PATH=/.openhands-state +RUN mkdir -p $FILE_STORE_PATH RUN mkdir -p $WORKSPACE_BASE RUN apt-get update -y \ diff --git a/frontend/src/components/shared/inputs/security-analyzers-input.tsx b/frontend/src/components/shared/inputs/security-analyzers-input.tsx index e5e6d159cf9c..8eb04c3ae081 100644 --- a/frontend/src/components/shared/inputs/security-analyzers-input.tsx +++ b/frontend/src/components/shared/inputs/security-analyzers-input.tsx @@ -25,7 +25,6 @@ export function SecurityAnalyzerInput({ { + updateSettingsVersion(logout); + }, []); + const isInWaitlist = !isFetchingAuth && !isAuthed && config.data?.APP_MODE === "saas"; diff --git a/frontend/src/services/settings.ts b/frontend/src/services/settings.ts index ceed34b4a17f..6b72750a27e8 100644 --- a/frontend/src/services/settings.ts +++ b/frontend/src/services/settings.ts @@ -1,6 +1,6 @@ import { openHands } from "#/api/open-hands-axios"; -export const LATEST_SETTINGS_VERSION = 4; +export const LATEST_SETTINGS_VERSION = 5; export type Settings = { LLM_MODEL: string; @@ -45,7 +45,53 @@ export const getCurrentSettingsVersion = () => { export const settingsAreUpToDate = () => getCurrentSettingsVersion() === LATEST_SETTINGS_VERSION; -export const maybeMigrateSettings = (logout: () => void) => { +// TODO: localStorage settings are deprecated. Remove this after 1/31/2025 +export const getLocalStorageSettings = (): Settings => { + const llmModel = localStorage.getItem("LLM_MODEL"); + const baseUrl = localStorage.getItem("LLM_BASE_URL"); + const agent = localStorage.getItem("AGENT"); + const language = localStorage.getItem("LANGUAGE"); + const llmApiKey = localStorage.getItem("LLM_API_KEY"); + const confirmationMode = localStorage.getItem("CONFIRMATION_MODE") === "true"; + const securityAnalyzer = localStorage.getItem("SECURITY_ANALYZER"); + + return { + LLM_MODEL: llmModel || DEFAULT_SETTINGS.LLM_MODEL, + LLM_BASE_URL: baseUrl || DEFAULT_SETTINGS.LLM_BASE_URL, + AGENT: agent || DEFAULT_SETTINGS.AGENT, + LANGUAGE: language || DEFAULT_SETTINGS.LANGUAGE, + LLM_API_KEY: llmApiKey || DEFAULT_SETTINGS.LLM_API_KEY, + CONFIRMATION_MODE: confirmationMode || DEFAULT_SETTINGS.CONFIRMATION_MODE, + SECURITY_ANALYZER: securityAnalyzer || DEFAULT_SETTINGS.SECURITY_ANALYZER, + }; +}; + +/** + * Save the settings to the server. Only valid settings are saved. + * @param settings - the settings to save + */ +export const saveSettings = async ( + settings: Partial, +): Promise => { + try { + const apiSettings = { + llm_model: settings.LLM_MODEL || null, + llm_base_url: settings.LLM_BASE_URL || null, + agent: settings.AGENT || null, + language: settings.LANGUAGE || null, + confirmation_mode: settings.CONFIRMATION_MODE || null, + security_analyzer: settings.SECURITY_ANALYZER || null, + llm_api_key: settings.LLM_API_KEY || null, + }; + + const { data } = await openHands.post("/api/settings", apiSettings); + return data; + } catch (error) { + return false; + } +}; + +export const maybeMigrateSettings = async (logout: () => void) => { // Sometimes we ship major changes, like a new default agent. // In this case, we may want to override a previous choice made by the user. const currentVersion = getCurrentSettingsVersion(); @@ -68,6 +114,11 @@ export const maybeMigrateSettings = (logout: () => void) => { if (currentVersion < 4) { logout(); } + + if (currentVersion < 5) { + const localSettings = getLocalStorageSettings(); + await saveSettings(localSettings); + } }; /** @@ -92,48 +143,5 @@ export const getSettings = async (): Promise => { LLM_API_KEY: "", }; } - - const llmModel = localStorage.getItem("LLM_MODEL"); - const baseUrl = localStorage.getItem("LLM_BASE_URL"); - const agent = localStorage.getItem("AGENT"); - const language = localStorage.getItem("LANGUAGE"); - const llmApiKey = localStorage.getItem("LLM_API_KEY"); - const confirmationMode = localStorage.getItem("CONFIRMATION_MODE") === "true"; - const securityAnalyzer = localStorage.getItem("SECURITY_ANALYZER"); - - return { - LLM_MODEL: llmModel || DEFAULT_SETTINGS.LLM_MODEL, - LLM_BASE_URL: baseUrl || DEFAULT_SETTINGS.LLM_BASE_URL, - AGENT: agent || DEFAULT_SETTINGS.AGENT, - LANGUAGE: language || DEFAULT_SETTINGS.LANGUAGE, - LLM_API_KEY: llmApiKey || DEFAULT_SETTINGS.LLM_API_KEY, - CONFIRMATION_MODE: confirmationMode || DEFAULT_SETTINGS.CONFIRMATION_MODE, - SECURITY_ANALYZER: securityAnalyzer || DEFAULT_SETTINGS.SECURITY_ANALYZER, - }; -}; - -/** - * Save the settings to the server. Only valid settings are saved. - * @param settings - the settings to save - */ -export const saveSettings = async ( - settings: Partial, -): Promise => { - try { - const apiSettings = { - llm_model: settings.LLM_MODEL || null, - llm_base_url: settings.LLM_BASE_URL || null, - agent: settings.AGENT || null, - language: settings.LANGUAGE || null, - confirmation_mode: settings.CONFIRMATION_MODE || null, - security_analyzer: settings.SECURITY_ANALYZER || null, - llm_api_key: settings.LLM_API_KEY || null, - }; - - const { data } = await openHands.post("/api/settings", apiSettings); - return data; - } catch (error) { - console.error("Error saving settings:", error); - return false; - } + return getLocalStorageSettings(); }; diff --git a/frontend/src/utils/settings-utils.ts b/frontend/src/utils/settings-utils.ts index 9f0dfa24c9fd..bb4780d3019a 100644 --- a/frontend/src/utils/settings-utils.ts +++ b/frontend/src/utils/settings-utils.ts @@ -82,9 +82,9 @@ const saveSettingsView = (view: "basic" | "advanced") => { * Updates the settings version in local storage if the current settings are not up to date. * If the settings are outdated, it attempts to migrate them before updating the version. */ -const updateSettingsVersion = (logout: () => void) => { +const updateSettingsVersion = async (logout: () => void) => { if (!settingsAreUpToDate()) { - maybeMigrateSettings(logout); + await maybeMigrateSettings(logout); localStorage.setItem( "SETTINGS_VERSION", LATEST_SETTINGS_VERSION.toString(),