refactor: add General/Security pages, remove SDK_LEGACY_FIELD_MAP, fix inferInitialView

- Add /settings/general and /settings/security sidebar pages rendering
  their respective SDK schema sections
- Reorder nav: General above LLM, Security below LLM (both SAAS + OSS)
- Remove SDK_LEGACY_FIELD_MAP and all legacy field bridging — the only
  canonical store for SDK settings is now sdk_settings_values
- Simplify to_agent_settings(), _extract_sdk_settings_values(), and
  _apply_settings_payload() to read/write sdk_settings_values only
- Fix inferInitialView to accept an optional schemaOverride so
  SdkSectionPage passes filteredSchema (prevents cross-section
  minor-value overrides from elevating the view tier on unrelated pages)
- Add SETTINGS$NAV_GENERAL and SETTINGS$NAV_SECURITY i18n keys with
  translations for all 14 languages
- Use lock.svg for Security icon and settings.svg for General icon

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
openhands
2026-03-17 01:46:11 +00:00
parent cfa7def554
commit 3a12924bc8
12 changed files with 112 additions and 72 deletions

View File

@@ -134,14 +134,13 @@ class TestLiveStatusAppConversationService:
self.service._load_hooks_from_workspace = AsyncMock(return_value=None)
def _mock_user_to_agent_settings(self) -> AgentSettings:
return Settings(
llm_model=self.mock_user.llm_model,
llm_api_key=self.mock_user.llm_api_key,
llm_base_url=self.mock_user.llm_base_url,
enable_default_condenser=True,
condenser_max_size=self.mock_user.condenser_max_size,
sdk_settings_values=dict(self.mock_user.sdk_settings_values),
).to_agent_settings()
sdk_values = dict(self.mock_user.sdk_settings_values)
sdk_values.setdefault('llm.model', self.mock_user.llm_model or '')
if self.mock_user.llm_api_key:
sdk_values.setdefault('llm.api_key', self.mock_user.llm_api_key)
if self.mock_user.llm_base_url:
sdk_values.setdefault('llm.base_url', self.mock_user.llm_base_url)
return Settings(sdk_settings_values=sdk_values).to_agent_settings()
def test_apply_suggested_task_sets_prompt_and_trigger(self):
"""Test suggested task prompts populate initial message and trigger."""
@@ -2472,14 +2471,13 @@ class TestPluginHandling:
self.mock_sandbox.status = SandboxStatus.RUNNING
def _mock_user_to_agent_settings(self) -> AgentSettings:
return Settings(
llm_model=self.mock_user.llm_model,
llm_api_key=self.mock_user.llm_api_key,
llm_base_url=self.mock_user.llm_base_url,
enable_default_condenser=True,
condenser_max_size=self.mock_user.condenser_max_size,
sdk_settings_values=dict(self.mock_user.sdk_settings_values),
).to_agent_settings()
sdk_values = dict(self.mock_user.sdk_settings_values)
sdk_values.setdefault('llm.model', self.mock_user.llm_model or '')
if self.mock_user.llm_api_key:
sdk_values.setdefault('llm.api_key', self.mock_user.llm_api_key)
if self.mock_user.llm_base_url:
sdk_values.setdefault('llm.base_url', self.mock_user.llm_base_url)
return Settings(sdk_settings_values=sdk_values).to_agent_settings()
def test_construct_initial_message_with_plugin_params_no_plugins(self):
"""Test _construct_initial_message_with_plugin_params with no plugins returns original message."""

View File

@@ -108,17 +108,14 @@ def test_settings_preserve_sdk_settings_values():
}
def test_settings_to_agent_settings_prefers_sdk_values_and_legacy_fallbacks():
def test_settings_to_agent_settings_uses_sdk_values():
settings = Settings(
llm_model='legacy-model',
llm_api_key='legacy-key',
llm_base_url='https://legacy.example.com',
enable_default_condenser=True,
condenser_max_size=88,
sdk_settings_values={
'llm.model': 'sdk-model',
'llm.base_url': 'https://sdk.example.com',
'llm.litellm_extra_body': {'metadata': {'tier': 'enterprise'}},
'condenser.enabled': False,
'condenser.max_size': 88,
'critic.enabled': True,
'critic.mode': 'all_actions',
},
@@ -127,8 +124,7 @@ def test_settings_to_agent_settings_prefers_sdk_values_and_legacy_fallbacks():
agent_settings = settings.to_agent_settings()
assert agent_settings.llm.model == 'sdk-model'
assert agent_settings.llm.api_key.get_secret_value() == 'legacy-key'
assert agent_settings.llm.base_url == 'https://legacy.example.com'
assert agent_settings.llm.base_url == 'https://sdk.example.com'
assert agent_settings.llm.litellm_extra_body == {'metadata': {'tier': 'enterprise'}}
assert agent_settings.condenser.enabled is False
assert agent_settings.condenser.max_size == 88