From 1322f944be5b6a3585ae86a423f5aaef3abe8668 Mon Sep 17 00:00:00 2001 From: openhands Date: Tue, 17 Mar 2026 12:06:58 +0000 Subject: [PATCH] =?UTF-8?q?refactor:=20settings=20are=20transparent=20?= =?UTF-8?q?=E2=80=94=20no=20backend=20auto-fill?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit critic_server_url and critic_model_name are now user-facing settings exposed in the GUI. The backend no longer mutates them based on proxy detection. _get_agent_settings is now a pure pass-through with model override only. SDK pin: b69f7cee Co-authored-by: openhands --- .../live_status_app_conversation_service.py | 31 +------------------ ...st_live_status_app_conversation_service.py | 26 ++++------------ uv.lock | 6 ++-- 3 files changed, 10 insertions(+), 53 deletions(-) diff --git a/openhands/app_server/app_conversation/live_status_app_conversation_service.py b/openhands/app_server/app_conversation/live_status_app_conversation_service.py index a60e323e9c..78084fdc43 100644 --- a/openhands/app_server/app_conversation/live_status_app_conversation_service.py +++ b/openhands/app_server/app_conversation/live_status_app_conversation_service.py @@ -879,12 +879,7 @@ class LiveStatusAppConversationService(AppConversationServiceBase): def _get_agent_settings( self, user: UserInfo, llm_model: str | None ) -> AgentSettings: - """Resolve SDK ``AgentSettings`` for this request. - - Applies model override and, for users going through the - OpenHands LLM proxy, fills in the critic endpoint so that - ``create_agent()`` builds a correctly-routed critic. - """ + """Resolve SDK ``AgentSettings`` for this request.""" settings = user.to_agent_settings() if llm_model is not None: settings = settings.model_copy( @@ -894,30 +889,6 @@ class LiveStatusAppConversationService(AppConversationServiceBase): ), } ) - - # Resolve critic endpoint for proxy users - if ( - settings.verification.critic_enabled - and not settings.verification.critic_server_url - and settings.llm.model.startswith('openhands/') - ): - proxy_url = ( - settings.llm.base_url or self.openhands_provider_base_url - ) - if proxy_url: - settings = settings.model_copy( - update={ - 'verification': settings.verification.model_copy( - update={ - 'critic_server_url': ( - f'{proxy_url.rstrip("/")}/vllm' - ), - 'critic_model_name': 'critic', - } - ), - } - ) - return settings def _configure_llm(self, user: UserInfo, llm_model: str | None) -> LLM: diff --git a/tests/unit/app_server/test_live_status_app_conversation_service.py b/tests/unit/app_server/test_live_status_app_conversation_service.py index 5487969dd2..2a407f02f9 100644 --- a/tests/unit/app_server/test_live_status_app_conversation_service.py +++ b/tests/unit/app_server/test_live_status_app_conversation_service.py @@ -841,37 +841,23 @@ class TestLiveStatusAppConversationService: # Assert assert path == '/workspace/project/agents-tmp-config/PLAN.md' - def test_get_agent_settings_resolves_critic_proxy(self): - """_get_agent_settings sets critic endpoint for openhands/ models.""" + def test_get_agent_settings_passes_through_critic_settings(self): + """_get_agent_settings passes critic settings through unchanged.""" self.mock_user.sdk_settings_values = { 'llm.model': 'openhands/default', 'verification.critic_enabled': True, + 'verification.critic_server_url': 'https://my-critic.example.com', + 'verification.critic_model_name': 'my-critic', } - self.service.openhands_provider_base_url = ( - 'https://llm-proxy.app.all-hands.dev' - ) settings = self.service._get_agent_settings(self.mock_user, None) assert settings.verification.critic_enabled is True assert ( settings.verification.critic_server_url - == 'https://llm-proxy.app.all-hands.dev/vllm' + == 'https://my-critic.example.com' ) - assert settings.verification.critic_model_name == 'critic' - - def test_get_agent_settings_no_critic_proxy_for_external_models(self): - """_get_agent_settings leaves critic settings alone for non-proxy models.""" - self.mock_user.sdk_settings_values = { - 'llm.model': 'anthropic/claude-3', - 'verification.critic_enabled': True, - } - - settings = self.service._get_agent_settings(self.mock_user, None) - - # critic_enabled honored, but no proxy routing applied - assert settings.verification.critic_enabled is True - assert settings.verification.critic_server_url is None + assert settings.verification.critic_model_name == 'my-critic' @patch( 'openhands.app_server.app_conversation.live_status_app_conversation_service.get_planning_tools', diff --git a/uv.lock b/uv.lock index b698c2c86a..2d0297aedb 100644 --- a/uv.lock +++ b/uv.lock @@ -3643,7 +3643,7 @@ wheels = [ [[package]] name = "openhands-agent-server" version = "1.14.0" -source = { git = "https://github.com/OpenHands/software-agent-sdk.git?subdirectory=openhands-agent-server&rev=openhands%2Fissue-2228-sdk-settings-schema#0030eed1721b2bcb4dfcdb5be0e4742c58645223" } +source = { git = "https://github.com/OpenHands/software-agent-sdk.git?subdirectory=openhands-agent-server&rev=openhands%2Fissue-2228-sdk-settings-schema#b69f7ceec56f4cc37c3ec3a6c2969df345ed3d50" } dependencies = [ { name = "aiosqlite" }, { name = "alembic" }, @@ -3905,7 +3905,7 @@ test = [ [[package]] name = "openhands-sdk" version = "1.14.0" -source = { git = "https://github.com/OpenHands/software-agent-sdk.git?subdirectory=openhands-sdk&rev=openhands%2Fissue-2228-sdk-settings-schema#0030eed1721b2bcb4dfcdb5be0e4742c58645223" } +source = { git = "https://github.com/OpenHands/software-agent-sdk.git?subdirectory=openhands-sdk&rev=openhands%2Fissue-2228-sdk-settings-schema#b69f7ceec56f4cc37c3ec3a6c2969df345ed3d50" } dependencies = [ { name = "agent-client-protocol" }, { name = "deprecation" }, @@ -3925,7 +3925,7 @@ dependencies = [ [[package]] name = "openhands-tools" version = "1.14.0" -source = { git = "https://github.com/OpenHands/software-agent-sdk.git?subdirectory=openhands-tools&rev=openhands%2Fissue-2228-sdk-settings-schema#0030eed1721b2bcb4dfcdb5be0e4742c58645223" } +source = { git = "https://github.com/OpenHands/software-agent-sdk.git?subdirectory=openhands-tools&rev=openhands%2Fissue-2228-sdk-settings-schema#b69f7ceec56f4cc37c3ec3a6c2969df345ed3d50" } dependencies = [ { name = "bashlex" }, { name = "binaryornot" },