From ecbd3ae7490dec1ad9d99ca29bde3b19db21e4e2 Mon Sep 17 00:00:00 2001 From: chuckbutkus Date: Mon, 29 Dec 2025 16:18:02 -0500 Subject: [PATCH 01/15] Fix local dev deployments (#12198) --- enterprise/enterprise_local/README.md | 2 +- enterprise/enterprise_local/decrypt_env.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 enterprise/enterprise_local/decrypt_env.sh diff --git a/enterprise/enterprise_local/README.md b/enterprise/enterprise_local/README.md index 4d621f16a8..18dee5b144 100644 --- a/enterprise/enterprise_local/README.md +++ b/enterprise/enterprise_local/README.md @@ -50,7 +50,7 @@ First run this to retrieve Github App secrets ``` gcloud auth application-default login gcloud config set project global-432717 -local/decrypt_env.sh +enterprise_local/decrypt_env.sh /path/to/root/of/deploy/repo ``` Now run this to generate a `.env` file, which will used to run SAAS locally diff --git a/enterprise/enterprise_local/decrypt_env.sh b/enterprise/enterprise_local/decrypt_env.sh old mode 100644 new mode 100755 index e2988b4bd8..923ec0305e --- a/enterprise/enterprise_local/decrypt_env.sh +++ b/enterprise/enterprise_local/decrypt_env.sh @@ -4,12 +4,12 @@ set -euo pipefail # Check if DEPLOY_DIR argument was provided if [ $# -lt 1 ]; then echo "Usage: $0 " - echo "Example: $0 /path/to/deploy" + echo "Example: $0 /path/to/root/of/deploy/repo" exit 1 fi # Normalize path (remove trailing slash) -DEPLOY_DIR="${DEPLOY_DIR%/}" +DEPLOY_DIR="${1%/}" # Function to decrypt and rename decrypt_and_move() { From c3f51d9dbe44fb19347ef230d11046be7ad2b7e9 Mon Sep 17 00:00:00 2001 From: Graham Neubig Date: Mon, 29 Dec 2025 18:01:55 -0500 Subject: [PATCH 02/15] fix(billing): Add error handling for LiteLLM API failures in get_credits (#12201) Co-authored-by: openhands --- enterprise/server/routes/billing.py | 22 ++++++++++++++++++---- enterprise/tests/unit/test_billing.py | 13 ++++++------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/enterprise/server/routes/billing.py b/enterprise/server/routes/billing.py index 5a8b59e2d7..1e56c669ad 100644 --- a/enterprise/server/routes/billing.py +++ b/enterprise/server/routes/billing.py @@ -111,10 +111,24 @@ def calculate_credits(user_info: LiteLlmUserInfo) -> float: async def get_credits(user_id: str = Depends(get_user_id)) -> GetCreditsResponse: if not stripe_service.STRIPE_API_KEY: return GetCreditsResponse() - async with httpx.AsyncClient(verify=httpx_verify_option()) as client: - user_json = await _get_litellm_user(client, user_id) - credits = calculate_credits(user_json['user_info']) - return GetCreditsResponse(credits=Decimal('{:.2f}'.format(credits))) + try: + async with httpx.AsyncClient(verify=httpx_verify_option()) as client: + user_json = await _get_litellm_user(client, user_id) + credits = calculate_credits(user_json['user_info']) + return GetCreditsResponse(credits=Decimal('{:.2f}'.format(credits))) + except httpx.HTTPStatusError as e: + logger.error( + f'litellm_get_user_failed: {type(e).__name__}: {e}', + extra={ + 'user_id': user_id, + 'status_code': e.response.status_code, + }, + exc_info=True, + ) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail='Failed to retrieve credit balance from billing service', + ) # Endpoint to retrieve user's current subscription access diff --git a/enterprise/tests/unit/test_billing.py b/enterprise/tests/unit/test_billing.py index cc05af60e2..2d7f0924f5 100644 --- a/enterprise/tests/unit/test_billing.py +++ b/enterprise/tests/unit/test_billing.py @@ -4,7 +4,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest import stripe from fastapi import HTTPException, Request, status -from httpx import HTTPStatusError, Response +from httpx import Response from integrations.stripe_service import has_payment_method from server.routes.billing import ( CreateBillingSessionResponse, @@ -78,8 +78,6 @@ def mock_subscription_request(): @pytest.mark.asyncio async def test_get_credits_lite_llm_error(): - mock_request = Request(scope={'type': 'http', 'state': {'user_id': 'mock_user'}}) - mock_response = Response( status_code=500, json={'error': 'Internal Server Error'}, request=MagicMock() ) @@ -88,11 +86,12 @@ async def test_get_credits_lite_llm_error(): with patch('integrations.stripe_service.STRIPE_API_KEY', 'mock_key'): with patch('httpx.AsyncClient', return_value=mock_client): - with pytest.raises(HTTPStatusError) as exc_info: - await get_credits(mock_request) + with pytest.raises(HTTPException) as exc_info: + await get_credits('mock_user') + assert exc_info.value.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR assert ( - exc_info.value.response.status_code - == status.HTTP_500_INTERNAL_SERVER_ERROR + exc_info.value.detail + == 'Failed to retrieve credit balance from billing service' ) From 4dec38c7ce2f1a9ee502bedc972f29c6832079b1 Mon Sep 17 00:00:00 2001 From: Graham Neubig Date: Mon, 29 Dec 2025 18:09:20 -0500 Subject: [PATCH 03/15] fix(event-webhook): Improve error logging with exception type and stack trace (#12202) Co-authored-by: openhands --- enterprise/server/routes/event_webhook.py | 4 ++-- .../tests/unit/server/test_event_webhook.py | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/enterprise/server/routes/event_webhook.py b/enterprise/server/routes/event_webhook.py index b4f8b71f68..e174f71660 100644 --- a/enterprise/server/routes/event_webhook.py +++ b/enterprise/server/routes/event_webhook.py @@ -134,12 +134,12 @@ async def _process_batch_operations_background( ) except Exception as e: logger.error( - 'error_processing_batch_operation', + f'error_processing_batch_operation: {type(e).__name__}: {e}', extra={ 'path': batch_op.path, 'method': str(batch_op.method), - 'error': str(e), }, + exc_info=True, ) diff --git a/enterprise/tests/unit/server/test_event_webhook.py b/enterprise/tests/unit/server/test_event_webhook.py index 71ba143ae4..64bf491c96 100644 --- a/enterprise/tests/unit/server/test_event_webhook.py +++ b/enterprise/tests/unit/server/test_event_webhook.py @@ -699,12 +699,11 @@ class TestProcessBatchOperationsBackground: # Should not raise exceptions await _process_batch_operations_background(batch_ops, 'test-api-key') - # Should log the error - mock_logger.error.assert_called_once_with( - 'error_processing_batch_operation', - extra={ - 'path': 'invalid-path', - 'method': 'BatchMethod.POST', - 'error': mock_logger.error.call_args[1]['extra']['error'], - }, - ) + # Should log the error with exception type and message in the log message + mock_logger.error.assert_called_once() + call_args = mock_logger.error.call_args + log_message = call_args[0][0] + assert log_message.startswith('error_processing_batch_operation:') + assert call_args[1]['extra']['path'] == 'invalid-path' + assert call_args[1]['extra']['method'] == 'BatchMethod.POST' + assert call_args[1]['exc_info'] is True From d9d19043f19bdf0421c7cfe14cd563d93a695eb1 Mon Sep 17 00:00:00 2001 From: Engel Nyst Date: Tue, 30 Dec 2025 00:21:29 +0100 Subject: [PATCH 04/15] chore: Mark V0 legacy files with clear headers and V1 pointers (#12165) Co-authored-by: openhands Co-authored-by: Rohit Malhotra --- openhands/agenthub/browsing_agent/browsing_agent.py | 7 +++++++ openhands/agenthub/browsing_agent/response_parser.py | 7 +++++++ openhands/agenthub/browsing_agent/utils.py | 7 +++++++ openhands/agenthub/codeact_agent/codeact_agent.py | 8 ++++++++ openhands/agenthub/codeact_agent/function_calling.py | 7 +++++++ openhands/agenthub/codeact_agent/tools/bash.py | 7 +++++++ openhands/agenthub/codeact_agent/tools/browser.py | 7 +++++++ .../agenthub/codeact_agent/tools/condensation_request.py | 7 +++++++ openhands/agenthub/codeact_agent/tools/finish.py | 7 +++++++ openhands/agenthub/codeact_agent/tools/ipython.py | 7 +++++++ openhands/agenthub/codeact_agent/tools/llm_based_edit.py | 7 +++++++ openhands/agenthub/codeact_agent/tools/prompt.py | 7 +++++++ openhands/agenthub/codeact_agent/tools/security_utils.py | 7 +++++++ .../agenthub/codeact_agent/tools/str_replace_editor.py | 7 +++++++ openhands/agenthub/codeact_agent/tools/task_tracker.py | 7 +++++++ openhands/agenthub/codeact_agent/tools/think.py | 7 +++++++ openhands/agenthub/dummy_agent/agent.py | 7 +++++++ openhands/agenthub/loc_agent/function_calling.py | 7 +++++++ openhands/agenthub/loc_agent/loc_agent.py | 7 +++++++ openhands/agenthub/loc_agent/tools/explore_structure.py | 7 +++++++ openhands/agenthub/loc_agent/tools/search_content.py | 7 +++++++ openhands/agenthub/readonly_agent/function_calling.py | 7 +++++++ openhands/agenthub/readonly_agent/readonly_agent.py | 7 +++++++ openhands/agenthub/readonly_agent/tools/glob.py | 7 +++++++ openhands/agenthub/readonly_agent/tools/grep.py | 7 +++++++ openhands/agenthub/readonly_agent/tools/view.py | 7 +++++++ .../visualbrowsing_agent/visualbrowsing_agent.py | 7 +++++++ openhands/controller/action_parser.py | 7 +++++++ openhands/controller/agent.py | 8 ++++++++ openhands/controller/agent_controller.py | 8 ++++++++ openhands/controller/replay.py | 7 +++++++ openhands/controller/state/control_flags.py | 7 +++++++ openhands/controller/state/state.py | 7 +++++++ openhands/controller/state/state_tracker.py | 7 +++++++ openhands/controller/stuck.py | 7 +++++++ openhands/core/config/__init__.py | 4 ---- openhands/core/config/agent_config.py | 7 +++++++ openhands/core/config/arg_utils.py | 7 +++++++ openhands/core/config/cli_config.py | 9 --------- openhands/core/config/condenser_config.py | 7 +++++++ openhands/core/config/config_utils.py | 7 +++++++ openhands/core/config/extended_config.py | 7 +++++++ openhands/core/config/kubernetes_config.py | 7 +++++++ openhands/core/config/llm_config.py | 7 +++++++ openhands/core/config/mcp_config.py | 7 +++++++ openhands/core/config/model_routing_config.py | 7 +++++++ openhands/core/config/openhands_config.py | 9 +++++++-- openhands/core/config/sandbox_config.py | 7 +++++++ openhands/core/config/security_config.py | 7 +++++++ openhands/core/config/utils.py | 7 +++++++ openhands/core/const/guide_url.py | 7 +++++++ openhands/core/download.py | 7 +++++++ openhands/core/exceptions.py | 7 +++++++ openhands/core/logger.py | 7 +++++++ openhands/core/loop.py | 7 +++++++ openhands/core/main.py | 7 +++++++ openhands/core/message.py | 7 +++++++ openhands/core/message_utils.py | 7 +++++++ openhands/core/schema/action.py | 7 +++++++ openhands/core/schema/agent.py | 7 +++++++ openhands/core/schema/exit_reason.py | 7 +++++++ openhands/core/schema/observation.py | 7 +++++++ openhands/core/setup.py | 7 +++++++ openhands/llm/async_llm.py | 7 +++++++ openhands/llm/bedrock.py | 7 +++++++ openhands/llm/debug_mixin.py | 7 +++++++ openhands/llm/fn_call_converter.py | 7 +++++++ openhands/llm/llm.py | 8 ++++++++ openhands/llm/llm_registry.py | 7 +++++++ openhands/llm/llm_utils.py | 7 +++++++ openhands/llm/metrics.py | 7 +++++++ openhands/llm/model_features.py | 7 +++++++ openhands/llm/retry_mixin.py | 7 +++++++ openhands/llm/router/base.py | 7 +++++++ openhands/llm/router/rule_based/impl.py | 7 +++++++ openhands/llm/streaming_llm.py | 7 +++++++ openhands/llm/tool_names.py | 7 +++++++ openhands/server/__main__.py | 8 ++++++++ openhands/server/app.py | 8 ++++++++ openhands/server/config/server_config.py | 8 ++++++++ openhands/server/constants.py | 8 ++++++++ .../server/conversation_manager/conversation_manager.py | 8 ++++++++ .../docker_nested_conversation_manager.py | 8 ++++++++ .../standalone_conversation_manager.py | 8 ++++++++ openhands/server/conversation_manager/utils.py | 8 ++++++++ openhands/server/data_models/agent_loop_info.py | 8 ++++++++ openhands/server/data_models/conversation_info.py | 8 ++++++++ .../server/data_models/conversation_info_result_set.py | 8 ++++++++ openhands/server/data_models/feedback.py | 8 ++++++++ openhands/server/dependencies.py | 8 ++++++++ openhands/server/file_config.py | 8 ++++++++ openhands/server/files.py | 8 ++++++++ openhands/server/listen.py | 8 ++++++++ openhands/server/listen_socket.py | 8 ++++++++ openhands/server/middleware.py | 8 ++++++++ openhands/server/mock/listen.py | 8 ++++++++ openhands/server/monitoring.py | 8 ++++++++ openhands/server/routes/conversation.py | 8 ++++++++ openhands/server/routes/feedback.py | 8 ++++++++ openhands/server/routes/files.py | 8 ++++++++ openhands/server/routes/git.py | 8 ++++++++ openhands/server/routes/health.py | 8 ++++++++ openhands/server/routes/manage_conversations.py | 8 ++++++++ openhands/server/routes/public.py | 8 ++++++++ openhands/server/routes/secrets.py | 8 ++++++++ openhands/server/routes/security.py | 8 ++++++++ openhands/server/routes/settings.py | 8 ++++++++ openhands/server/routes/trajectory.py | 8 ++++++++ openhands/server/services/conversation_service.py | 8 ++++++++ openhands/server/services/conversation_stats.py | 8 ++++++++ openhands/server/session/agent_session.py | 8 ++++++++ openhands/server/session/conversation.py | 8 ++++++++ openhands/server/session/conversation_init_data.py | 8 ++++++++ openhands/server/session/session.py | 8 ++++++++ openhands/server/settings.py | 8 ++++++++ openhands/server/shared.py | 8 ++++++++ openhands/server/static.py | 8 ++++++++ openhands/server/types.py | 8 ++++++++ openhands/server/user_auth/default_user_auth.py | 8 ++++++++ openhands/server/user_auth/user_auth.py | 8 ++++++++ openhands/server/utils.py | 8 ++++++++ 121 files changed, 881 insertions(+), 15 deletions(-) delete mode 100644 openhands/core/config/cli_config.py diff --git a/openhands/agenthub/browsing_agent/browsing_agent.py b/openhands/agenthub/browsing_agent/browsing_agent.py index cd1decd261..65071a2f11 100644 --- a/openhands/agenthub/browsing_agent/browsing_agent.py +++ b/openhands/agenthub/browsing_agent/browsing_agent.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import os from browsergym.core.action.highlevel import HighLevelActionSet diff --git a/openhands/agenthub/browsing_agent/response_parser.py b/openhands/agenthub/browsing_agent/response_parser.py index 1caacc0e4e..b7f7ee19ce 100644 --- a/openhands/agenthub/browsing_agent/response_parser.py +++ b/openhands/agenthub/browsing_agent/response_parser.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import ast import re diff --git a/openhands/agenthub/browsing_agent/utils.py b/openhands/agenthub/browsing_agent/utils.py index ff08735aff..d5dc119933 100644 --- a/openhands/agenthub/browsing_agent/utils.py +++ b/openhands/agenthub/browsing_agent/utils.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import collections import re from warnings import warn diff --git a/openhands/agenthub/codeact_agent/codeact_agent.py b/openhands/agenthub/codeact_agent/codeact_agent.py index 9dd814e9cf..d03f0f83a7 100644 --- a/openhands/agenthub/codeact_agent/codeact_agent.py +++ b/openhands/agenthub/codeact_agent/codeact_agent.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# V1 replacement for this module lives in the Software Agent SDK. import os import sys from collections import deque diff --git a/openhands/agenthub/codeact_agent/function_calling.py b/openhands/agenthub/codeact_agent/function_calling.py index 763b75ee53..dc17aac6c7 100644 --- a/openhands/agenthub/codeact_agent/function_calling.py +++ b/openhands/agenthub/codeact_agent/function_calling.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 """This file contains the function calling implementation for different actions. This is similar to the functionality of `CodeActResponseParser`. diff --git a/openhands/agenthub/codeact_agent/tools/bash.py b/openhands/agenthub/codeact_agent/tools/bash.py index b1113cb8c8..00a98f4e4d 100644 --- a/openhands/agenthub/codeact_agent/tools/bash.py +++ b/openhands/agenthub/codeact_agent/tools/bash.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk from openhands.agenthub.codeact_agent.tools.prompt import refine_prompt diff --git a/openhands/agenthub/codeact_agent/tools/browser.py b/openhands/agenthub/codeact_agent/tools/browser.py index 78a7e503db..df1451ffd4 100644 --- a/openhands/agenthub/codeact_agent/tools/browser.py +++ b/openhands/agenthub/codeact_agent/tools/browser.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from browsergym.core.action.highlevel import HighLevelActionSet from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk diff --git a/openhands/agenthub/codeact_agent/tools/condensation_request.py b/openhands/agenthub/codeact_agent/tools/condensation_request.py index e1a5754ffc..7862aab015 100644 --- a/openhands/agenthub/codeact_agent/tools/condensation_request.py +++ b/openhands/agenthub/codeact_agent/tools/condensation_request.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk _CONDENSATION_REQUEST_DESCRIPTION = 'Request a condensation of the conversation history when the context becomes too long or when you need to focus on the most relevant information.' diff --git a/openhands/agenthub/codeact_agent/tools/finish.py b/openhands/agenthub/codeact_agent/tools/finish.py index 033d0f3df0..f5b9b70d71 100644 --- a/openhands/agenthub/codeact_agent/tools/finish.py +++ b/openhands/agenthub/codeact_agent/tools/finish.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk from openhands.llm.tool_names import FINISH_TOOL_NAME diff --git a/openhands/agenthub/codeact_agent/tools/ipython.py b/openhands/agenthub/codeact_agent/tools/ipython.py index 07f6c006c3..28ee55d29a 100644 --- a/openhands/agenthub/codeact_agent/tools/ipython.py +++ b/openhands/agenthub/codeact_agent/tools/ipython.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk from openhands.agenthub.codeact_agent.tools.security_utils import ( diff --git a/openhands/agenthub/codeact_agent/tools/llm_based_edit.py b/openhands/agenthub/codeact_agent/tools/llm_based_edit.py index 18a2abaa3b..97e223aeeb 100644 --- a/openhands/agenthub/codeact_agent/tools/llm_based_edit.py +++ b/openhands/agenthub/codeact_agent/tools/llm_based_edit.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk from openhands.agenthub.codeact_agent.tools.security_utils import ( diff --git a/openhands/agenthub/codeact_agent/tools/prompt.py b/openhands/agenthub/codeact_agent/tools/prompt.py index 9a9ee8ab8a..9bd8cf941b 100644 --- a/openhands/agenthub/codeact_agent/tools/prompt.py +++ b/openhands/agenthub/codeact_agent/tools/prompt.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import re import sys diff --git a/openhands/agenthub/codeact_agent/tools/security_utils.py b/openhands/agenthub/codeact_agent/tools/security_utils.py index 2829712e23..b7a45b03ad 100644 --- a/openhands/agenthub/codeact_agent/tools/security_utils.py +++ b/openhands/agenthub/codeact_agent/tools/security_utils.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 """Security utility constants for tool risk descriptions. This file contains standardized risk description text for various tools. diff --git a/openhands/agenthub/codeact_agent/tools/str_replace_editor.py b/openhands/agenthub/codeact_agent/tools/str_replace_editor.py index b5c67c1025..2adcef4987 100644 --- a/openhands/agenthub/codeact_agent/tools/str_replace_editor.py +++ b/openhands/agenthub/codeact_agent/tools/str_replace_editor.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import os from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk diff --git a/openhands/agenthub/codeact_agent/tools/task_tracker.py b/openhands/agenthub/codeact_agent/tools/task_tracker.py index 3bac10f4c6..ae556545b0 100644 --- a/openhands/agenthub/codeact_agent/tools/task_tracker.py +++ b/openhands/agenthub/codeact_agent/tools/task_tracker.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk from openhands.llm.tool_names import TASK_TRACKER_TOOL_NAME diff --git a/openhands/agenthub/codeact_agent/tools/think.py b/openhands/agenthub/codeact_agent/tools/think.py index 1986758012..f25d682c26 100644 --- a/openhands/agenthub/codeact_agent/tools/think.py +++ b/openhands/agenthub/codeact_agent/tools/think.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk _THINK_DESCRIPTION = """Use the tool to think about something. It will not obtain new information or make any changes to the repository, but just log the thought. Use it when complex reasoning or brainstorming is needed. diff --git a/openhands/agenthub/dummy_agent/agent.py b/openhands/agenthub/dummy_agent/agent.py index 4d2531e03a..74d818d2ea 100644 --- a/openhands/agenthub/dummy_agent/agent.py +++ b/openhands/agenthub/dummy_agent/agent.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from typing import TypedDict from openhands.controller.agent import Agent diff --git a/openhands/agenthub/loc_agent/function_calling.py b/openhands/agenthub/loc_agent/function_calling.py index 06cb01fe49..b88cca5b57 100644 --- a/openhands/agenthub/loc_agent/function_calling.py +++ b/openhands/agenthub/loc_agent/function_calling.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 """This file contains the function calling implementation for different actions. This is similar to the functionality of `CodeActResponseParser`. diff --git a/openhands/agenthub/loc_agent/loc_agent.py b/openhands/agenthub/loc_agent/loc_agent.py index 516323d106..8dfe65226f 100644 --- a/openhands/agenthub/loc_agent/loc_agent.py +++ b/openhands/agenthub/loc_agent/loc_agent.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from typing import TYPE_CHECKING import openhands.agenthub.loc_agent.function_calling as locagent_function_calling diff --git a/openhands/agenthub/loc_agent/tools/explore_structure.py b/openhands/agenthub/loc_agent/tools/explore_structure.py index 47c0a91ed6..221aef0299 100644 --- a/openhands/agenthub/loc_agent/tools/explore_structure.py +++ b/openhands/agenthub/loc_agent/tools/explore_structure.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ( ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk, diff --git a/openhands/agenthub/loc_agent/tools/search_content.py b/openhands/agenthub/loc_agent/tools/search_content.py index 586b0ccf72..233cda3900 100644 --- a/openhands/agenthub/loc_agent/tools/search_content.py +++ b/openhands/agenthub/loc_agent/tools/search_content.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ( ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk, diff --git a/openhands/agenthub/readonly_agent/function_calling.py b/openhands/agenthub/readonly_agent/function_calling.py index fded8d324b..b047ee9ec9 100644 --- a/openhands/agenthub/readonly_agent/function_calling.py +++ b/openhands/agenthub/readonly_agent/function_calling.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 """This file contains the function calling implementation for different actions. This is similar to the functionality of `CodeActResponseParser`. diff --git a/openhands/agenthub/readonly_agent/readonly_agent.py b/openhands/agenthub/readonly_agent/readonly_agent.py index 2e9a54b416..af5965395a 100644 --- a/openhands/agenthub/readonly_agent/readonly_agent.py +++ b/openhands/agenthub/readonly_agent/readonly_agent.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 """ReadOnlyAgent - A specialized version of CodeActAgent that only uses read-only tools.""" import os diff --git a/openhands/agenthub/readonly_agent/tools/glob.py b/openhands/agenthub/readonly_agent/tools/glob.py index 202bed4f3b..85c5c5bd92 100644 --- a/openhands/agenthub/readonly_agent/tools/glob.py +++ b/openhands/agenthub/readonly_agent/tools/glob.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk _GLOB_DESCRIPTION = """Fast file pattern matching tool. diff --git a/openhands/agenthub/readonly_agent/tools/grep.py b/openhands/agenthub/readonly_agent/tools/grep.py index 976e288c8c..d0695ac36a 100644 --- a/openhands/agenthub/readonly_agent/tools/grep.py +++ b/openhands/agenthub/readonly_agent/tools/grep.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk _GREP_DESCRIPTION = """Fast content search tool. diff --git a/openhands/agenthub/readonly_agent/tools/view.py b/openhands/agenthub/readonly_agent/tools/view.py index 4ac3196702..ef8e5159a2 100644 --- a/openhands/agenthub/readonly_agent/tools/view.py +++ b/openhands/agenthub/readonly_agent/tools/view.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from litellm import ChatCompletionToolParam, ChatCompletionToolParamFunctionChunk _VIEW_DESCRIPTION = """Reads a file or list directories from the local filesystem. diff --git a/openhands/agenthub/visualbrowsing_agent/visualbrowsing_agent.py b/openhands/agenthub/visualbrowsing_agent/visualbrowsing_agent.py index 0603da38f9..3f858b9c10 100644 --- a/openhands/agenthub/visualbrowsing_agent/visualbrowsing_agent.py +++ b/openhands/agenthub/visualbrowsing_agent/visualbrowsing_agent.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from browsergym.core.action.highlevel import HighLevelActionSet from browsergym.utils.obs import flatten_axtree_to_str diff --git a/openhands/controller/action_parser.py b/openhands/controller/action_parser.py index 4250f46f38..cb7d1e472f 100644 --- a/openhands/controller/action_parser.py +++ b/openhands/controller/action_parser.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from abc import ABC, abstractmethod from typing import Any diff --git a/openhands/controller/agent.py b/openhands/controller/agent.py index 71c18f8c25..cff5cda918 100644 --- a/openhands/controller/agent.py +++ b/openhands/controller/agent.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# V1 replacement for this module lives in the Software Agent SDK. from __future__ import annotations from abc import ABC, abstractmethod diff --git a/openhands/controller/agent_controller.py b/openhands/controller/agent_controller.py index 0753f0a0a1..9948007208 100644 --- a/openhands/controller/agent_controller.py +++ b/openhands/controller/agent_controller.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# V1 replacement for this module lives in the Software Agent SDK. from __future__ import annotations import asyncio diff --git a/openhands/controller/replay.py b/openhands/controller/replay.py index 4cfec767f4..98cfa477cc 100644 --- a/openhands/controller/replay.py +++ b/openhands/controller/replay.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from __future__ import annotations from openhands.core.logger import openhands_logger as logger diff --git a/openhands/controller/state/control_flags.py b/openhands/controller/state/control_flags.py index c41cbb927a..bafeeff6b2 100644 --- a/openhands/controller/state/control_flags.py +++ b/openhands/controller/state/control_flags.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from __future__ import annotations from dataclasses import dataclass diff --git a/openhands/controller/state/state.py b/openhands/controller/state/state.py index e3690a2e53..94e6742b7c 100644 --- a/openhands/controller/state/state.py +++ b/openhands/controller/state/state.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from __future__ import annotations import base64 diff --git a/openhands/controller/state/state_tracker.py b/openhands/controller/state/state_tracker.py index 4813ec798e..a7c6c915d3 100644 --- a/openhands/controller/state/state_tracker.py +++ b/openhands/controller/state/state_tracker.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from openhands.controller.state.control_flags import ( BudgetControlFlag, IterationControlFlag, diff --git a/openhands/controller/stuck.py b/openhands/controller/stuck.py index 092be02efe..27fde6c169 100644 --- a/openhands/controller/stuck.py +++ b/openhands/controller/stuck.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from dataclasses import dataclass from typing import Optional diff --git a/openhands/core/config/__init__.py b/openhands/core/config/__init__.py index df7f745bef..af27a65ae2 100644 --- a/openhands/core/config/__init__.py +++ b/openhands/core/config/__init__.py @@ -1,10 +1,8 @@ from openhands.core.config.agent_config import AgentConfig from openhands.core.config.arg_utils import ( - get_cli_parser, get_evaluation_parser, get_headless_parser, ) -from openhands.core.config.cli_config import CLIConfig from openhands.core.config.config_utils import ( OH_DEFAULT_AGENT, OH_MAX_ITERATIONS, @@ -34,7 +32,6 @@ __all__ = [ 'OH_DEFAULT_AGENT', 'OH_MAX_ITERATIONS', 'AgentConfig', - 'CLIConfig', 'OpenHandsConfig', 'MCPConfig', 'LLMConfig', @@ -49,7 +46,6 @@ __all__ = [ 'get_agent_config_arg', 'get_llm_config_arg', 'get_field_info', - 'get_cli_parser', 'get_headless_parser', 'get_evaluation_parser', 'parse_arguments', diff --git a/openhands/core/config/agent_config.py b/openhands/core/config/agent_config.py index b9b5873e9e..60315ed6fa 100644 --- a/openhands/core/config/agent_config.py +++ b/openhands/core/config/agent_config.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from __future__ import annotations from pydantic import BaseModel, ConfigDict, Field, ValidationError diff --git a/openhands/core/config/arg_utils.py b/openhands/core/config/arg_utils.py index d39a4856e0..4b90aa16ad 100644 --- a/openhands/core/config/arg_utils.py +++ b/openhands/core/config/arg_utils.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 """Centralized command line argument configuration for OpenHands CLI and headless modes.""" import argparse diff --git a/openhands/core/config/cli_config.py b/openhands/core/config/cli_config.py deleted file mode 100644 index 89b6829d3d..0000000000 --- a/openhands/core/config/cli_config.py +++ /dev/null @@ -1,9 +0,0 @@ -from pydantic import BaseModel, Field - - -class CLIConfig(BaseModel): - """Configuration for CLI-specific settings.""" - - vi_mode: bool = Field(default=False) - - model_config = {'extra': 'forbid'} diff --git a/openhands/core/config/condenser_config.py b/openhands/core/config/condenser_config.py index 2045e9c9ee..afb2ee00bb 100644 --- a/openhands/core/config/condenser_config.py +++ b/openhands/core/config/condenser_config.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from __future__ import annotations from typing import Literal, cast diff --git a/openhands/core/config/config_utils.py b/openhands/core/config/config_utils.py index 5dd5c5a98c..88c9853cf3 100644 --- a/openhands/core/config/config_utils.py +++ b/openhands/core/config/config_utils.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from types import UnionType from typing import Any, get_args, get_origin diff --git a/openhands/core/config/extended_config.py b/openhands/core/config/extended_config.py index b9616fec7e..ab5decc8a5 100644 --- a/openhands/core/config/extended_config.py +++ b/openhands/core/config/extended_config.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from typing import Any from pydantic import RootModel diff --git a/openhands/core/config/kubernetes_config.py b/openhands/core/config/kubernetes_config.py index 706a51a29f..07d4a19746 100644 --- a/openhands/core/config/kubernetes_config.py +++ b/openhands/core/config/kubernetes_config.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from pydantic import BaseModel, ConfigDict, Field, ValidationError diff --git a/openhands/core/config/llm_config.py b/openhands/core/config/llm_config.py index 8a5f704b36..0bb993b8ef 100644 --- a/openhands/core/config/llm_config.py +++ b/openhands/core/config/llm_config.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from __future__ import annotations import os diff --git a/openhands/core/config/mcp_config.py b/openhands/core/config/mcp_config.py index dd25318d37..9f97624e82 100644 --- a/openhands/core/config/mcp_config.py +++ b/openhands/core/config/mcp_config.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from __future__ import annotations import os diff --git a/openhands/core/config/model_routing_config.py b/openhands/core/config/model_routing_config.py index 9377a5b097..8f20abc0fa 100644 --- a/openhands/core/config/model_routing_config.py +++ b/openhands/core/config/model_routing_config.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from pydantic import BaseModel, ConfigDict, Field, ValidationError from openhands.core.config.llm_config import LLMConfig diff --git a/openhands/core/config/openhands_config.py b/openhands/core/config/openhands_config.py index 037cc7f3d3..82834aac35 100644 --- a/openhands/core/config/openhands_config.py +++ b/openhands/core/config/openhands_config.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import os from typing import Any, ClassVar @@ -5,7 +12,6 @@ from pydantic import BaseModel, ConfigDict, Field, SecretStr from openhands.core import logger from openhands.core.config.agent_config import AgentConfig -from openhands.core.config.cli_config import CLIConfig from openhands.core.config.config_utils import ( DEFAULT_WORKSPACE_MOUNT_PATH_IN_SANDBOX, OH_DEFAULT_AGENT, @@ -119,7 +125,6 @@ class OpenHandsConfig(BaseModel): mcp_host: str = Field(default=f'localhost:{os.getenv("port", 3000)}') mcp: MCPConfig = Field(default_factory=MCPConfig) kubernetes: KubernetesConfig = Field(default_factory=KubernetesConfig) - cli: CLIConfig = Field(default_factory=CLIConfig) git_user_name: str = Field( default='openhands', description='Git user name for commits made by the agent' ) diff --git a/openhands/core/config/sandbox_config.py b/openhands/core/config/sandbox_config.py index 0576e6a397..4b9aa864ed 100644 --- a/openhands/core/config/sandbox_config.py +++ b/openhands/core/config/sandbox_config.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import os from pydantic import BaseModel, ConfigDict, Field, ValidationError, model_validator diff --git a/openhands/core/config/security_config.py b/openhands/core/config/security_config.py index 63067cf912..2200448082 100644 --- a/openhands/core/config/security_config.py +++ b/openhands/core/config/security_config.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from pydantic import BaseModel, ConfigDict, Field, ValidationError diff --git a/openhands/core/config/utils.py b/openhands/core/config/utils.py index e1752838ba..3953f2a513 100644 --- a/openhands/core/config/utils.py +++ b/openhands/core/config/utils.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import argparse import os import pathlib diff --git a/openhands/core/const/guide_url.py b/openhands/core/const/guide_url.py index 62af6e5475..dce7264aff 100644 --- a/openhands/core/const/guide_url.py +++ b/openhands/core/const/guide_url.py @@ -1 +1,8 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 TROUBLESHOOTING_URL = 'https://docs.all-hands.dev/usage/troubleshooting' diff --git a/openhands/core/download.py b/openhands/core/download.py index 7d2392a63a..6e481054c5 100644 --- a/openhands/core/download.py +++ b/openhands/core/download.py @@ -1,2 +1,9 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 # Run this file to trigger a model download import openhands.agenthub # noqa F401 (we import this to get the agents registered) diff --git a/openhands/core/exceptions.py b/openhands/core/exceptions.py index 4d706e6aa5..21f25d45eb 100644 --- a/openhands/core/exceptions.py +++ b/openhands/core/exceptions.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 # ============================================ # Agent Exceptions # ============================================ diff --git a/openhands/core/logger.py b/openhands/core/logger.py index b48759b352..2fabb6f350 100644 --- a/openhands/core/logger.py +++ b/openhands/core/logger.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import copy import logging import os diff --git a/openhands/core/loop.py b/openhands/core/loop.py index ff7680488e..e89136dc97 100644 --- a/openhands/core/loop.py +++ b/openhands/core/loop.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import asyncio from openhands.controller import AgentController diff --git a/openhands/core/main.py b/openhands/core/main.py index 633fed3a17..6f785b09ab 100644 --- a/openhands/core/main.py +++ b/openhands/core/main.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import asyncio import json import os diff --git a/openhands/core/message.py b/openhands/core/message.py index c5c026361d..cd3298b04a 100644 --- a/openhands/core/message.py +++ b/openhands/core/message.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from enum import Enum from typing import Any, Literal diff --git a/openhands/core/message_utils.py b/openhands/core/message_utils.py index 1235a58ae3..0d75ff9a4d 100644 --- a/openhands/core/message_utils.py +++ b/openhands/core/message_utils.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from openhands.events.event import Event from openhands.llm.metrics import Metrics, TokenUsage diff --git a/openhands/core/schema/action.py b/openhands/core/schema/action.py index 168689b0f9..c3d63b80df 100644 --- a/openhands/core/schema/action.py +++ b/openhands/core/schema/action.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from enum import Enum diff --git a/openhands/core/schema/agent.py b/openhands/core/schema/agent.py index 05fcae5288..8e46e181b2 100644 --- a/openhands/core/schema/agent.py +++ b/openhands/core/schema/agent.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from enum import Enum diff --git a/openhands/core/schema/exit_reason.py b/openhands/core/schema/exit_reason.py index ffae2505c7..8ba159bfbf 100644 --- a/openhands/core/schema/exit_reason.py +++ b/openhands/core/schema/exit_reason.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from enum import Enum diff --git a/openhands/core/schema/observation.py b/openhands/core/schema/observation.py index 3f0c71052c..dac675b929 100644 --- a/openhands/core/schema/observation.py +++ b/openhands/core/schema/observation.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from enum import Enum diff --git a/openhands/core/setup.py b/openhands/core/setup.py index 5cac8c3f72..28664dcf8d 100644 --- a/openhands/core/setup.py +++ b/openhands/core/setup.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import hashlib import os import uuid diff --git a/openhands/llm/async_llm.py b/openhands/llm/async_llm.py index a08958b957..8aa1be321a 100644 --- a/openhands/llm/async_llm.py +++ b/openhands/llm/async_llm.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import asyncio from functools import partial from typing import Any, Callable diff --git a/openhands/llm/bedrock.py b/openhands/llm/bedrock.py index 62cfe1780a..fa284983f8 100644 --- a/openhands/llm/bedrock.py +++ b/openhands/llm/bedrock.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import boto3 from openhands.core.logger import openhands_logger as logger diff --git a/openhands/llm/debug_mixin.py b/openhands/llm/debug_mixin.py index 7438f455c4..3c0718b327 100644 --- a/openhands/llm/debug_mixin.py +++ b/openhands/llm/debug_mixin.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from logging import DEBUG from typing import Any diff --git a/openhands/llm/fn_call_converter.py b/openhands/llm/fn_call_converter.py index 826b278dc4..bea9eb81a9 100644 --- a/openhands/llm/fn_call_converter.py +++ b/openhands/llm/fn_call_converter.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 """Convert function calling messages to non-function calling messages and vice versa. This will inject prompts so that models that doesn't support function calling diff --git a/openhands/llm/llm.py b/openhands/llm/llm.py index c786cfd6a3..1e53df4dc1 100644 --- a/openhands/llm/llm.py +++ b/openhands/llm/llm.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# V1 replacement for this module lives in the Software Agent SDK. import copy import os import time diff --git a/openhands/llm/llm_registry.py b/openhands/llm/llm_registry.py index 941f80b9b3..38064bc070 100644 --- a/openhands/llm/llm_registry.py +++ b/openhands/llm/llm_registry.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import copy from typing import Any, Callable from uuid import uuid4 diff --git a/openhands/llm/llm_utils.py b/openhands/llm/llm_utils.py index c59c24d0bf..e1c7b17d67 100644 --- a/openhands/llm/llm_utils.py +++ b/openhands/llm/llm_utils.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import copy from typing import TYPE_CHECKING diff --git a/openhands/llm/metrics.py b/openhands/llm/metrics.py index bacad0d0e5..0d1ba81499 100644 --- a/openhands/llm/metrics.py +++ b/openhands/llm/metrics.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import copy import time diff --git a/openhands/llm/model_features.py b/openhands/llm/model_features.py index f592f0bb98..15e84598c2 100644 --- a/openhands/llm/model_features.py +++ b/openhands/llm/model_features.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from __future__ import annotations from dataclasses import dataclass diff --git a/openhands/llm/retry_mixin.py b/openhands/llm/retry_mixin.py index 3169d1313d..cf6dd037c5 100644 --- a/openhands/llm/retry_mixin.py +++ b/openhands/llm/retry_mixin.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from typing import Any, Callable from tenacity import ( diff --git a/openhands/llm/router/base.py b/openhands/llm/router/base.py index 84143b3785..8b8ef169a2 100644 --- a/openhands/llm/router/base.py +++ b/openhands/llm/router/base.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import copy from abc import abstractmethod from typing import TYPE_CHECKING, Any, Callable diff --git a/openhands/llm/router/rule_based/impl.py b/openhands/llm/router/rule_based/impl.py index 81cb5bb3a4..a9672fa87e 100644 --- a/openhands/llm/router/rule_based/impl.py +++ b/openhands/llm/router/rule_based/impl.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 from openhands.core.config import AgentConfig from openhands.core.logger import openhands_logger as logger from openhands.core.message import Message diff --git a/openhands/llm/streaming_llm.py b/openhands/llm/streaming_llm.py index e7fa2ded80..bc1ede4b67 100644 --- a/openhands/llm/streaming_llm.py +++ b/openhands/llm/streaming_llm.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 import asyncio from functools import partial from typing import Any, Callable diff --git a/openhands/llm/tool_names.py b/openhands/llm/tool_names.py index 7b037847f2..62ec7637fb 100644 --- a/openhands/llm/tool_names.py +++ b/openhands/llm/tool_names.py @@ -1,3 +1,10 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 """Constants for tool names used in function calling.""" EXECUTE_BASH_TOOL_NAME = 'execute_bash' diff --git a/openhands/server/__main__.py b/openhands/server/__main__.py index adf4ad0dbc..510a881fa5 100644 --- a/openhands/server/__main__.py +++ b/openhands/server/__main__.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import os import warnings diff --git a/openhands/server/app.py b/openhands/server/app.py index 5cee75b163..910d6961c7 100644 --- a/openhands/server/app.py +++ b/openhands/server/app.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import contextlib import warnings from contextlib import asynccontextmanager diff --git a/openhands/server/config/server_config.py b/openhands/server/config/server_config.py index 4175227267..abcbfce91e 100644 --- a/openhands/server/config/server_config.py +++ b/openhands/server/config/server_config.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import os from openhands.core.logger import openhands_logger as logger diff --git a/openhands/server/constants.py b/openhands/server/constants.py index 2f09bab748..8722e77fb3 100644 --- a/openhands/server/constants.py +++ b/openhands/server/constants.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. """Server constants.""" ROOM_KEY = 'room:{sid}' diff --git a/openhands/server/conversation_manager/conversation_manager.py b/openhands/server/conversation_manager/conversation_manager.py index 8a120d8d22..90da2c5857 100644 --- a/openhands/server/conversation_manager/conversation_manager.py +++ b/openhands/server/conversation_manager/conversation_manager.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from __future__ import annotations from abc import ABC, abstractmethod diff --git a/openhands/server/conversation_manager/docker_nested_conversation_manager.py b/openhands/server/conversation_manager/docker_nested_conversation_manager.py index 81aa4b4bea..a97907964e 100644 --- a/openhands/server/conversation_manager/docker_nested_conversation_manager.py +++ b/openhands/server/conversation_manager/docker_nested_conversation_manager.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from __future__ import annotations import asyncio diff --git a/openhands/server/conversation_manager/standalone_conversation_manager.py b/openhands/server/conversation_manager/standalone_conversation_manager.py index 5da4e323cd..35913b16bf 100644 --- a/openhands/server/conversation_manager/standalone_conversation_manager.py +++ b/openhands/server/conversation_manager/standalone_conversation_manager.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import asyncio import time from dataclasses import dataclass, field diff --git a/openhands/server/conversation_manager/utils.py b/openhands/server/conversation_manager/utils.py index e69de29bb2..e63b4adbe8 100644 --- a/openhands/server/conversation_manager/utils.py +++ b/openhands/server/conversation_manager/utils.py @@ -0,0 +1,8 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. diff --git a/openhands/server/data_models/agent_loop_info.py b/openhands/server/data_models/agent_loop_info.py index c094c9dcfc..5f321151a5 100644 --- a/openhands/server/data_models/agent_loop_info.py +++ b/openhands/server/data_models/agent_loop_info.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from dataclasses import dataclass, field from openhands.events.event_store_abc import EventStoreABC diff --git a/openhands/server/data_models/conversation_info.py b/openhands/server/data_models/conversation_info.py index 5ca7b80b08..2c93cd1757 100644 --- a/openhands/server/data_models/conversation_info.py +++ b/openhands/server/data_models/conversation_info.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from dataclasses import dataclass, field from datetime import datetime, timezone diff --git a/openhands/server/data_models/conversation_info_result_set.py b/openhands/server/data_models/conversation_info_result_set.py index 5f91f5f531..773d521acc 100644 --- a/openhands/server/data_models/conversation_info_result_set.py +++ b/openhands/server/data_models/conversation_info_result_set.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from dataclasses import dataclass, field from openhands.server.data_models.conversation_info import ConversationInfo diff --git a/openhands/server/data_models/feedback.py b/openhands/server/data_models/feedback.py index 59f8a1dcc3..d6dcd125ff 100644 --- a/openhands/server/data_models/feedback.py +++ b/openhands/server/data_models/feedback.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import json from typing import Any, Literal diff --git a/openhands/server/dependencies.py b/openhands/server/dependencies.py index 0c1f6b1ec7..8e3ec3fcd3 100644 --- a/openhands/server/dependencies.py +++ b/openhands/server/dependencies.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import os from fastapi import Depends, HTTPException, status diff --git a/openhands/server/file_config.py b/openhands/server/file_config.py index 799bc21fe8..9e98575bb7 100644 --- a/openhands/server/file_config.py +++ b/openhands/server/file_config.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import os import re diff --git a/openhands/server/files.py b/openhands/server/files.py index b0f6069f03..08e69177c7 100644 --- a/openhands/server/files.py +++ b/openhands/server/files.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from pydantic import ( BaseModel, ) diff --git a/openhands/server/listen.py b/openhands/server/listen.py index e8ef7ce2ba..b77508b5a6 100644 --- a/openhands/server/listen.py +++ b/openhands/server/listen.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import os import socketio diff --git a/openhands/server/listen_socket.py b/openhands/server/listen_socket.py index 0fec3bd575..a1a9703975 100644 --- a/openhands/server/listen_socket.py +++ b/openhands/server/listen_socket.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import asyncio import os from typing import Any diff --git a/openhands/server/middleware.py b/openhands/server/middleware.py index e2bae700a7..dfc73e5b97 100644 --- a/openhands/server/middleware.py +++ b/openhands/server/middleware.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import asyncio import os from collections import defaultdict diff --git a/openhands/server/mock/listen.py b/openhands/server/mock/listen.py index 31b5fdb6b1..65c85733ef 100644 --- a/openhands/server/mock/listen.py +++ b/openhands/server/mock/listen.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import uvicorn from fastapi import FastAPI, WebSocket diff --git a/openhands/server/monitoring.py b/openhands/server/monitoring.py index 2ff30744a8..1e450f6519 100644 --- a/openhands/server/monitoring.py +++ b/openhands/server/monitoring.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from openhands.core.config.openhands_config import OpenHandsConfig from openhands.events.event import Event diff --git a/openhands/server/routes/conversation.py b/openhands/server/routes/conversation.py index 5892843d05..567d5fcda9 100644 --- a/openhands/server/routes/conversation.py +++ b/openhands/server/routes/conversation.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import uuid from fastapi import APIRouter, Depends, HTTPException, Request, status diff --git a/openhands/server/routes/feedback.py b/openhands/server/routes/feedback.py index 2adc1855e2..d6444a907b 100644 --- a/openhands/server/routes/feedback.py +++ b/openhands/server/routes/feedback.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from fastapi import APIRouter, Depends, Request, status from fastapi.responses import JSONResponse diff --git a/openhands/server/routes/files.py b/openhands/server/routes/files.py index 5a012e5be6..7e3f114169 100644 --- a/openhands/server/routes/files.py +++ b/openhands/server/routes/files.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import os from typing import Any diff --git a/openhands/server/routes/git.py b/openhands/server/routes/git.py index 7223c6fab6..3878561a0b 100644 --- a/openhands/server/routes/git.py +++ b/openhands/server/routes/git.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from types import MappingProxyType from typing import Annotated, cast diff --git a/openhands/server/routes/health.py b/openhands/server/routes/health.py index 2a1c6e5c0b..e0bb0501d2 100644 --- a/openhands/server/routes/health.py +++ b/openhands/server/routes/health.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from fastapi import FastAPI from openhands.runtime.utils.system_stats import get_system_info diff --git a/openhands/server/routes/manage_conversations.py b/openhands/server/routes/manage_conversations.py index b88c2851e2..69f7c747b0 100644 --- a/openhands/server/routes/manage_conversations.py +++ b/openhands/server/routes/manage_conversations.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import asyncio import base64 import itertools diff --git a/openhands/server/routes/public.py b/openhands/server/routes/public.py index f345a1041b..5e8669dfa8 100644 --- a/openhands/server/routes/public.py +++ b/openhands/server/routes/public.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from typing import Any from fastapi import APIRouter diff --git a/openhands/server/routes/secrets.py b/openhands/server/routes/secrets.py index 175d8863db..2f3910c998 100644 --- a/openhands/server/routes/secrets.py +++ b/openhands/server/routes/secrets.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from fastapi import APIRouter, Depends, status from fastapi.responses import JSONResponse diff --git a/openhands/server/routes/security.py b/openhands/server/routes/security.py index aebf976d57..4415253308 100644 --- a/openhands/server/routes/security.py +++ b/openhands/server/routes/security.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from fastapi import ( APIRouter, Depends, diff --git a/openhands/server/routes/settings.py b/openhands/server/routes/settings.py index 7a78ca7720..5707110d84 100644 --- a/openhands/server/routes/settings.py +++ b/openhands/server/routes/settings.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from fastapi import APIRouter, Depends, status from fastapi.responses import JSONResponse diff --git a/openhands/server/routes/trajectory.py b/openhands/server/routes/trajectory.py index 5f33e4c064..0b3d2c0f7e 100644 --- a/openhands/server/routes/trajectory.py +++ b/openhands/server/routes/trajectory.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from fastapi import APIRouter, Depends, status from fastapi.responses import JSONResponse diff --git a/openhands/server/services/conversation_service.py b/openhands/server/services/conversation_service.py index ac2e06b8cd..242ea56294 100644 --- a/openhands/server/services/conversation_service.py +++ b/openhands/server/services/conversation_service.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import uuid from types import MappingProxyType from typing import Any diff --git a/openhands/server/services/conversation_stats.py b/openhands/server/services/conversation_stats.py index 178fb7b0f9..b2cf045ad3 100644 --- a/openhands/server/services/conversation_stats.py +++ b/openhands/server/services/conversation_stats.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import base64 import pickle from threading import Lock diff --git a/openhands/server/session/agent_session.py b/openhands/server/session/agent_session.py index 41c80ffbd1..1a42e3e817 100644 --- a/openhands/server/session/agent_session.py +++ b/openhands/server/session/agent_session.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import asyncio import json import time diff --git a/openhands/server/session/conversation.py b/openhands/server/session/conversation.py index 2301a33bf0..727566690c 100644 --- a/openhands/server/session/conversation.py +++ b/openhands/server/session/conversation.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import asyncio from openhands.core.config import OpenHandsConfig diff --git a/openhands/server/session/conversation_init_data.py b/openhands/server/session/conversation_init_data.py index c1bf660c28..2e10813157 100644 --- a/openhands/server/session/conversation_init_data.py +++ b/openhands/server/session/conversation_init_data.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from collections.abc import Mapping from types import MappingProxyType diff --git a/openhands/server/session/session.py b/openhands/server/session/session.py index 9c92838201..2e6e33d32c 100644 --- a/openhands/server/session/session.py +++ b/openhands/server/session/session.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import asyncio import time from logging import LoggerAdapter diff --git a/openhands/server/settings.py b/openhands/server/settings.py index ebcadec932..01c6f2dbed 100644 --- a/openhands/server/settings.py +++ b/openhands/server/settings.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from __future__ import annotations from pydantic import ( diff --git a/openhands/server/shared.py b/openhands/server/shared.py index 1f0d3a4c26..9800f3712b 100644 --- a/openhands/server/shared.py +++ b/openhands/server/shared.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import os import socketio diff --git a/openhands/server/static.py b/openhands/server/static.py index 15557f9d76..82893a84cf 100644 --- a/openhands/server/static.py +++ b/openhands/server/static.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from fastapi.staticfiles import StaticFiles from starlette.responses import Response from starlette.types import Scope diff --git a/openhands/server/types.py b/openhands/server/types.py index 717a0a41ac..6809f8256a 100644 --- a/openhands/server/types.py +++ b/openhands/server/types.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from abc import ABC, abstractmethod from enum import Enum from typing import Any, ClassVar, Protocol diff --git a/openhands/server/user_auth/default_user_auth.py b/openhands/server/user_auth/default_user_auth.py index 8bc79af156..29d9f19531 100644 --- a/openhands/server/user_auth/default_user_auth.py +++ b/openhands/server/user_auth/default_user_auth.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from dataclasses import dataclass from fastapi import Request diff --git a/openhands/server/user_auth/user_auth.py b/openhands/server/user_auth/user_auth.py index c61c9ceb8b..98b30f9a7a 100644 --- a/openhands/server/user_auth/user_auth.py +++ b/openhands/server/user_auth/user_auth.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. from __future__ import annotations from abc import ABC, abstractmethod diff --git a/openhands/server/utils.py b/openhands/server/utils.py index 7910db00ce..efbf125c1b 100644 --- a/openhands/server/utils.py +++ b/openhands/server/utils.py @@ -1,3 +1,11 @@ +# IMPORTANT: LEGACY V0 CODE +# This file is part of the legacy (V0) implementation of OpenHands and will be removed soon as we complete the migration to V1. +# OpenHands V1 uses the Software Agent SDK for the agentic core and runs a new application server. Please refer to: +# - V1 agentic core (SDK): https://github.com/OpenHands/software-agent-sdk +# - V1 application server (in this repo): openhands/app_server/ +# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above. +# Tag: Legacy-V0 +# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import uuid from fastapi import Depends, HTTPException, Request, status From 910646d11ffc5bef788785fe4d2795d536fc8c74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Dec 2025 00:25:17 +0100 Subject: [PATCH 05/15] chore(deps): bump actions/cache from 4 to 5 (#12191) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/openhands-resolver.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/openhands-resolver.yml b/.github/workflows/openhands-resolver.yml index 6f4be5c398..b021c22a66 100644 --- a/.github/workflows/openhands-resolver.yml +++ b/.github/workflows/openhands-resolver.yml @@ -118,7 +118,7 @@ jobs: contains(github.event.review.body, '@openhands-agent-exp') ) ) - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ${{ env.pythonLocation }}/lib/python3.12/site-packages/* key: ${{ runner.os }}-pip-openhands-resolver-${{ hashFiles('/tmp/requirements.txt') }} From 443918af3c9b654aa96f08a46c321f17b271398f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Dec 2025 00:25:56 +0100 Subject: [PATCH 06/15] chore(deps): bump docker/setup-qemu-action from 3.6.0 to 3.7.0 (#12193) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ghcr-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ghcr-build.yml b/.github/workflows/ghcr-build.yml index 9bdcd073d5..b63e681fe3 100644 --- a/.github/workflows/ghcr-build.yml +++ b/.github/workflows/ghcr-build.yml @@ -64,7 +64,7 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha }} - name: Set up QEMU - uses: docker/setup-qemu-action@v3.6.0 + uses: docker/setup-qemu-action@v3.7.0 with: image: tonistiigi/binfmt:latest - name: Login to GHCR @@ -102,7 +102,7 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha }} - name: Set up QEMU - uses: docker/setup-qemu-action@v3.6.0 + uses: docker/setup-qemu-action@v3.7.0 with: image: tonistiigi/binfmt:latest - name: Login to GHCR From d5e83d0f06e5112e0c64866806348926582daeb4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Dec 2025 23:50:40 +0000 Subject: [PATCH 07/15] chore(deps): bump peter-evans/create-or-update-comment from 4 to 5 (#12192) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Engel Nyst --- .github/workflows/enterprise-check-migrations.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/enterprise-check-migrations.yml b/.github/workflows/enterprise-check-migrations.yml index 8daca0e1b1..354b25bd1e 100644 --- a/.github/workflows/enterprise-check-migrations.yml +++ b/.github/workflows/enterprise-check-migrations.yml @@ -43,7 +43,7 @@ jobs: ⚠️ This PR contains **migrations** - name: Comment warning on PR - uses: peter-evans/create-or-update-comment@v4 + uses: peter-evans/create-or-update-comment@v5 with: issue-number: ${{ github.event.pull_request.number }} comment-id: ${{ steps.find-comment.outputs.comment-id }} From 103e3ead0a8c2fc201e976bc359deaaf88edfb8a Mon Sep 17 00:00:00 2001 From: "sp.wack" <83104063+amanape@users.noreply.github.com> Date: Tue, 30 Dec 2025 16:33:09 +0400 Subject: [PATCH 08/15] hotfix(frontend): validate git changes response is array before mapping (#12208) --- frontend/__tests__/api/v1-git-service.test.ts | 18 ++++++++++++++++++ .../src/api/git-service/v1-git-service.api.ts | 7 +++++++ 2 files changed, 25 insertions(+) create mode 100644 frontend/__tests__/api/v1-git-service.test.ts diff --git a/frontend/__tests__/api/v1-git-service.test.ts b/frontend/__tests__/api/v1-git-service.test.ts new file mode 100644 index 0000000000..495a395c81 --- /dev/null +++ b/frontend/__tests__/api/v1-git-service.test.ts @@ -0,0 +1,18 @@ +import { test, expect, vi } from "vitest"; +import axios from "axios"; +import V1GitService from "../../src/api/git-service/v1-git-service.api"; + +vi.mock("axios"); + +test("getGitChanges throws when response is not an array (dead runtime returns HTML)", async () => { + const htmlResponse = "..."; + vi.mocked(axios.get).mockResolvedValue({ data: htmlResponse }); + + await expect( + V1GitService.getGitChanges( + "http://localhost:3000/api/conversations/123", + "test-api-key", + "/workspace", + ), + ).rejects.toThrow("Invalid response from runtime"); +}); diff --git a/frontend/src/api/git-service/v1-git-service.api.ts b/frontend/src/api/git-service/v1-git-service.api.ts index ce8f2030fd..0c874825aa 100644 --- a/frontend/src/api/git-service/v1-git-service.api.ts +++ b/frontend/src/api/git-service/v1-git-service.api.ts @@ -53,6 +53,13 @@ class V1GitService { // V1 API returns V1GitChangeStatus types, we need to map them to V0 format const { data } = await axios.get(url, { headers }); + // Validate response is an array (could be HTML error page if runtime is dead) + if (!Array.isArray(data)) { + throw new Error( + "Invalid response from runtime - runtime may be unavailable", + ); + } + // Map V1 statuses to V0 format for compatibility return data.map((change) => ({ status: mapV1ToV0Status(change.status), From 64d408561259ac3e8187e367ed482148f12afe4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Dec 2025 18:52:39 +0400 Subject: [PATCH 09/15] chore(deps): bump the version-all group in /frontend with 2 updates (#12211) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend/package-lock.json | 24 ++++++++++++------------ frontend/package.json | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index bc1a20c9f2..ada75eec74 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,7 +14,7 @@ "@react-router/node": "^7.11.0", "@react-router/serve": "^7.11.0", "@tailwindcss/vite": "^4.1.18", - "@tanstack/react-query": "^5.90.14", + "@tanstack/react-query": "^5.90.15", "@uidotdev/usehooks": "^2.4.1", "@xterm/addon-fit": "^0.11.0", "@xterm/xterm": "^6.0.0", @@ -30,7 +30,7 @@ "isbot": "^5.1.32", "lucide-react": "^0.562.0", "monaco-editor": "^0.55.1", - "posthog-js": "^1.310.1", + "posthog-js": "^1.311.0", "react": "^19.2.3", "react-dom": "^19.2.3", "react-hot-toast": "^2.6.0", @@ -5543,20 +5543,20 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.90.14", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.14.tgz", - "integrity": "sha512-/6di2yNI+YxpVrH9Ig74Q+puKnkCE+D0LGyagJEGndJHJc6ahkcc/UqirHKy8zCYE/N9KLggxcQvzYCsUBWgdw==", + "version": "5.90.15", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.15.tgz", + "integrity": "sha512-mInIZNUZftbERE+/Hbtswfse49uUQwch46p+27gP9DWJL927UjnaWEF2t3RMOqBcXbfMdcNkPe06VyUIAZTV1g==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/react-query": { - "version": "5.90.14", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.14.tgz", - "integrity": "sha512-JAMuULej09hrZ14W9+mxoRZ44rR2BuZfCd6oKTQVNfynQxCN3muH3jh3W46gqZNw5ZqY0ZVaS43Imb3dMr6tgw==", + "version": "5.90.15", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.15.tgz", + "integrity": "sha512-uQvnDDcTOgJouNtAyrgRej+Azf0U5WDov3PXmHFUBc+t1INnAYhIlpZtCGNBLwCN41b43yO7dPNZu8xWkUFBwQ==", "dependencies": { - "@tanstack/query-core": "5.90.14" + "@tanstack/query-core": "5.90.15" }, "funding": { "type": "github", @@ -13382,9 +13382,9 @@ } }, "node_modules/posthog-js": { - "version": "1.310.1", - "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.310.1.tgz", - "integrity": "sha512-UkR6zzlWNtqHDXHJl2Yk062DOmZyVKTPL5mX4j4V+u3RiYbMHJe47+PpMMUsvK1R2e1r/m9uSlHaJMJRzyUjGg==", + "version": "1.311.0", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.311.0.tgz", + "integrity": "sha512-P1dWYNFr1dlfa5sAOFj4uq2jJuGfNce3ctYl565t0Fm/i4ZJZq4D2hmKyTMjKu5f9wyZVlTeRdxdmTIGDjCegw==", "dependencies": { "@posthog/core": "1.9.0", "core-js": "^3.38.1", diff --git a/frontend/package.json b/frontend/package.json index 4d13caa0da..f993462524 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,7 +13,7 @@ "@react-router/node": "^7.11.0", "@react-router/serve": "^7.11.0", "@tailwindcss/vite": "^4.1.18", - "@tanstack/react-query": "^5.90.14", + "@tanstack/react-query": "^5.90.15", "@uidotdev/usehooks": "^2.4.1", "@xterm/addon-fit": "^0.11.0", "@xterm/xterm": "^6.0.0", @@ -29,7 +29,7 @@ "isbot": "^5.1.32", "lucide-react": "^0.562.0", "monaco-editor": "^0.55.1", - "posthog-js": "^1.310.1", + "posthog-js": "^1.311.0", "react": "^19.2.3", "react-dom": "^19.2.3", "react-hot-toast": "^2.6.0", From 0e5f4325be131027f05f975ac6eb8b7b194ec40f Mon Sep 17 00:00:00 2001 From: "sp.wack" <83104063+amanape@users.noreply.github.com> Date: Tue, 30 Dec 2025 18:58:58 +0400 Subject: [PATCH 10/15] hotfix(frontend): set terminal background color for `xterm.js` 6.0.0 compatibility (#12213) --- frontend/src/hooks/use-terminal.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/hooks/use-terminal.ts b/frontend/src/hooks/use-terminal.ts index 5791bc0fa0..676d7893c4 100644 --- a/frontend/src/hooks/use-terminal.ts +++ b/frontend/src/hooks/use-terminal.ts @@ -89,10 +89,9 @@ export const useTerminal = () => { scrollback: 10000, scrollSensitivity: 1, fastScrollSensitivity: 5, - allowTransparency: true, disableStdin: true, // Make terminal read-only theme: { - background: "transparent", + background: "#25272D", }, }); From 3ae09680d6606e68cdb41769f28ab98414f766e0 Mon Sep 17 00:00:00 2001 From: mamoodi Date: Tue, 30 Dec 2025 11:35:14 -0500 Subject: [PATCH 11/15] Release 1.1.0 (#12212) --- Development.md | 2 +- containers/dev/compose.yml | 2 +- docker-compose.yml | 2 +- frontend/package-lock.json | 4 ++-- frontend/package.json | 2 +- openhands/runtime/impl/kubernetes/README.md | 2 +- pyproject.toml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Development.md b/Development.md index 421959a5ec..028d71514c 100644 --- a/Development.md +++ b/Development.md @@ -161,7 +161,7 @@ poetry run pytest ./tests/unit/test_*.py To reduce build time (e.g., if no changes were made to the client-runtime component), you can use an existing Docker container image by setting the SANDBOX_RUNTIME_CONTAINER_IMAGE environment variable to the desired Docker image. -Example: `export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/openhands/runtime:1.0-nikolaik` +Example: `export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/openhands/runtime:1.1-nikolaik` ## Develop inside Docker container diff --git a/containers/dev/compose.yml b/containers/dev/compose.yml index 7ff5042081..78549feb68 100644 --- a/containers/dev/compose.yml +++ b/containers/dev/compose.yml @@ -12,7 +12,7 @@ services: - SANDBOX_API_HOSTNAME=host.docker.internal - DOCKER_HOST_ADDR=host.docker.internal # - - SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/openhands/runtime:1.0-nikolaik} + - SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/openhands/runtime:1.1-nikolaik} - SANDBOX_USER_ID=${SANDBOX_USER_ID:-1234} - WORKSPACE_MOUNT_PATH=${WORKSPACE_BASE:-$PWD/workspace} ports: diff --git a/docker-compose.yml b/docker-compose.yml index d4aef552c0..7e879f09b3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ services: image: openhands:latest container_name: openhands-app-${DATE:-} environment: - - SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-docker.openhands.dev/openhands/runtime:1.0-nikolaik} + - SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-docker.openhands.dev/openhands/runtime:1.1-nikolaik} #- SANDBOX_USER_ID=${SANDBOX_USER_ID:-1234} # enable this only if you want a specific non-root sandbox user but you will have to manually adjust permissions of ~/.openhands for this user - WORKSPACE_MOUNT_PATH=${WORKSPACE_BASE:-$PWD/workspace} ports: diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ada75eec74..2cc295d243 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "openhands-frontend", - "version": "1.0.0", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "openhands-frontend", - "version": "1.0.0", + "version": "1.1.0", "dependencies": { "@heroui/react": "2.8.7", "@microlink/react-json-view": "^1.26.2", diff --git a/frontend/package.json b/frontend/package.json index f993462524..9003680543 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "openhands-frontend", - "version": "1.0.0", + "version": "1.1.0", "private": true, "type": "module", "engines": { diff --git a/openhands/runtime/impl/kubernetes/README.md b/openhands/runtime/impl/kubernetes/README.md index 36b7452d1e..c9f5ccfdf2 100644 --- a/openhands/runtime/impl/kubernetes/README.md +++ b/openhands/runtime/impl/kubernetes/README.md @@ -40,7 +40,7 @@ Two configuration options are required to use the Kubernetes runtime: 2. **Runtime Container Image**: Specify the container image to use for the runtime environment ```toml [sandbox] - runtime_container_image = "docker.openhands.dev/openhands/runtime:1.0-nikolaik" + runtime_container_image = "docker.openhands.dev/openhands/runtime:1.1-nikolaik" ``` #### Additional Kubernetes Options diff --git a/pyproject.toml b/pyproject.toml index 94ecd393e4..fc5e8fab98 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ requires = [ [tool.poetry] name = "openhands-ai" -version = "1.0.0" +version = "1.1.0" description = "OpenHands: Code Less, Make More" authors = [ "OpenHands" ] license = "MIT" From b5758b160415455976de704e0ead4567b0c74c2d Mon Sep 17 00:00:00 2001 From: Graham Neubig Date: Tue, 30 Dec 2025 12:59:51 -0500 Subject: [PATCH 12/15] Update GithubIntegration to use auth=Auth.AppAuth() (#12204) Co-authored-by: openhands --- .../integrations/github/data_collector.py | 4 ++-- .../integrations/github/github_manager.py | 4 ++-- enterprise/integrations/github/github_view.py | 6 +++--- .../github_v1_callback_processor.py | 5 ++--- .../test_github_v1_callback_processor.py | 21 ++++++++++++++----- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/enterprise/integrations/github/data_collector.py b/enterprise/integrations/github/data_collector.py index f6b2477e7e..2d1f4b1b18 100644 --- a/enterprise/integrations/github/data_collector.py +++ b/enterprise/integrations/github/data_collector.py @@ -6,7 +6,7 @@ from datetime import datetime from enum import Enum from typing import Any -from github import Github, GithubIntegration +from github import Auth, Github, GithubIntegration from integrations.github.github_view import ( GithubIssue, ) @@ -84,7 +84,7 @@ class GitHubDataCollector: # self.full_saved_pr_path = 'github_data/prs/{}-{}/data.json' self.full_saved_pr_path = 'prs/github/{}-{}/data.json' self.github_integration = GithubIntegration( - GITHUB_APP_CLIENT_ID, GITHUB_APP_PRIVATE_KEY + auth=Auth.AppAuth(GITHUB_APP_CLIENT_ID, GITHUB_APP_PRIVATE_KEY) ) self.conversation_id = None diff --git a/enterprise/integrations/github/github_manager.py b/enterprise/integrations/github/github_manager.py index 00ad5124ce..8b5d9fc542 100644 --- a/enterprise/integrations/github/github_manager.py +++ b/enterprise/integrations/github/github_manager.py @@ -1,6 +1,6 @@ from types import MappingProxyType -from github import Github, GithubIntegration +from github import Auth, Github, GithubIntegration from integrations.github.data_collector import GitHubDataCollector from integrations.github.github_solvability import summarize_issue_solvability from integrations.github.github_view import ( @@ -43,7 +43,7 @@ class GithubManager(Manager): self.token_manager = token_manager self.data_collector = data_collector self.github_integration = GithubIntegration( - GITHUB_APP_CLIENT_ID, GITHUB_APP_PRIVATE_KEY + auth=Auth.AppAuth(GITHUB_APP_CLIENT_ID, GITHUB_APP_PRIVATE_KEY) ) self.jinja_env = Environment( diff --git a/enterprise/integrations/github/github_view.py b/enterprise/integrations/github/github_view.py index a01457f88c..a37ae04c33 100644 --- a/enterprise/integrations/github/github_view.py +++ b/enterprise/integrations/github/github_view.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from uuid import UUID, uuid4 -from github import Github, GithubIntegration +from github import Auth, Github, GithubIntegration from github.Issue import Issue from integrations.github.github_types import ( WorkflowRun, @@ -729,7 +729,7 @@ class GithubFactory: def _interact_with_github() -> Issue | None: with GithubIntegration( - GITHUB_APP_CLIENT_ID, GITHUB_APP_PRIVATE_KEY + auth=Auth.AppAuth(GITHUB_APP_CLIENT_ID, GITHUB_APP_PRIVATE_KEY) ) as integration: access_token = integration.get_access_token( payload['installation']['id'] @@ -867,7 +867,7 @@ class GithubFactory: access_token = '' with GithubIntegration( - GITHUB_APP_CLIENT_ID, GITHUB_APP_PRIVATE_KEY + auth=Auth.AppAuth(GITHUB_APP_CLIENT_ID, GITHUB_APP_PRIVATE_KEY) ) as integration: access_token = integration.get_access_token(installation_id).token diff --git a/openhands/app_server/event_callback/github_v1_callback_processor.py b/openhands/app_server/event_callback/github_v1_callback_processor.py index 1a83bed9c0..dc48ab5dcf 100644 --- a/openhands/app_server/event_callback/github_v1_callback_processor.py +++ b/openhands/app_server/event_callback/github_v1_callback_processor.py @@ -4,7 +4,7 @@ from typing import Any from uuid import UUID import httpx -from github import Github, GithubIntegration +from github import Auth, Github, GithubIntegration from pydantic import Field from openhands.agent_server.models import AskAgentRequest, AskAgentResponse @@ -124,8 +124,7 @@ class GithubV1CallbackProcessor(EventCallbackProcessor): raise ValueError('GitHub App credentials are not configured') github_integration = GithubIntegration( - github_app_client_id, - github_app_private_key, + auth=Auth.AppAuth(github_app_client_id, github_app_private_key), ) token_data = github_integration.get_access_token(installation_id) return token_data.token diff --git a/tests/unit/app_server/test_github_v1_callback_processor.py b/tests/unit/app_server/test_github_v1_callback_processor.py index acf958a8e3..037485e278 100644 --- a/tests/unit/app_server/test_github_v1_callback_processor.py +++ b/tests/unit/app_server/test_github_v1_callback_processor.py @@ -211,6 +211,7 @@ class TestGithubV1CallbackProcessor: @patch( 'openhands.app_server.event_callback.github_v1_callback_processor.get_prompt_template' ) + @patch('openhands.app_server.event_callback.github_v1_callback_processor.Auth') @patch( 'openhands.app_server.event_callback.github_v1_callback_processor.GithubIntegration' ) @@ -219,6 +220,7 @@ class TestGithubV1CallbackProcessor: self, mock_github, mock_github_integration, + mock_auth, mock_get_prompt_template, mock_get_httpx_client, mock_get_sandbox_service, @@ -242,6 +244,10 @@ class TestGithubV1CallbackProcessor: mock_get_prompt_template.return_value = 'Please provide a summary' + # Auth.AppAuth mock + mock_app_auth_instance = MagicMock() + mock_auth.AppAuth.return_value = mock_app_auth_instance + # GitHub integration mock_token_data = MagicMock() mock_token_data.token = 'test_access_token' @@ -271,9 +277,8 @@ class TestGithubV1CallbackProcessor: assert result.detail == 'Test summary from agent' assert github_callback_processor.should_request_summary is False - mock_github_integration.assert_called_once_with( - 'test_client_id', 'test_private_key' - ) + mock_auth.AppAuth.assert_called_once_with('test_client_id', 'test_private_key') + mock_github_integration.assert_called_once_with(auth=mock_app_auth_instance) mock_integration_instance.get_access_token.assert_called_once_with(12345) mock_github.assert_called_once_with('test_access_token') @@ -618,12 +623,17 @@ class TestGithubV1CallbackProcessor: 'GITHUB_APP_PRIVATE_KEY': 'test_private_key\\nwith_newlines', }, ) + @patch('openhands.app_server.event_callback.github_v1_callback_processor.Auth') @patch( 'openhands.app_server.event_callback.github_v1_callback_processor.GithubIntegration' ) def test_get_installation_access_token_success( - self, mock_github_integration, github_callback_processor + self, mock_github_integration, mock_auth, github_callback_processor ): + # Auth.AppAuth mock + mock_app_auth_instance = MagicMock() + mock_auth.AppAuth.return_value = mock_app_auth_instance + mock_token_data = MagicMock() mock_token_data.token = 'test_access_token' mock_integration_instance = MagicMock() @@ -633,9 +643,10 @@ class TestGithubV1CallbackProcessor: token = github_callback_processor._get_installation_access_token() assert token == 'test_access_token' - mock_github_integration.assert_called_once_with( + mock_auth.AppAuth.assert_called_once_with( 'test_client_id', 'test_private_key\nwith_newlines' ) + mock_github_integration.assert_called_once_with(auth=mock_app_auth_instance) mock_integration_instance.get_access_token.assert_called_once_with(12345) @patch('openhands.app_server.event_callback.github_v1_callback_processor.Github') From 06a97fc3826db73035db9e0147da9c7950c2a6ac Mon Sep 17 00:00:00 2001 From: OpenHands Bot Date: Wed, 31 Dec 2025 02:47:14 +0800 Subject: [PATCH 13/15] Bump SDK packages to v1.7.3 (#12218) Co-authored-by: Tim O'Farrell --- enterprise/poetry.lock | 26 +++++++++---------- .../sandbox/sandbox_spec_service.py | 2 +- poetry.lock | 20 +++++++------- pyproject.toml | 6 ++--- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/enterprise/poetry.lock b/enterprise/poetry.lock index ca4b190ec1..fbb1e8c5ea 100644 --- a/enterprise/poetry.lock +++ b/enterprise/poetry.lock @@ -5836,14 +5836,14 @@ llama = ["llama-index (>=0.12.29,<0.13.0)", "llama-index-core (>=0.12.29,<0.13.0 [[package]] name = "openhands-agent-server" -version = "1.7.1" +version = "1.7.3" description = "OpenHands Agent Server - REST/WebSocket interface for OpenHands AI Agent" optional = false python-versions = ">=3.12" groups = ["main"] files = [ - {file = "openhands_agent_server-1.7.1-py3-none-any.whl", hash = "sha256:e5c57f1b73293d00a68b77f9d290f59d9e2217d9df844fb01c7d2f929c3417f4"}, - {file = "openhands_agent_server-1.7.1.tar.gz", hash = "sha256:c82e1e6748ea3b4278ef2ee72f091dc37da6667c854b3aa3c0bc616086a82310"}, + {file = "openhands_agent_server-1.7.3-py3-none-any.whl", hash = "sha256:456e7162cefec8ed7fda61433180b3f867265e15c7151b3a2e3e02546c9d9b6d"}, + {file = "openhands_agent_server-1.7.3.tar.gz", hash = "sha256:2c06dc497c38050d445559da2825d4d69fe84af90289c82a95317e45359cc547"}, ] [package.dependencies] @@ -5860,7 +5860,7 @@ wsproto = ">=1.2.0" [[package]] name = "openhands-ai" -version = "0.0.0-post.5742+ee50f333b" +version = "0.0.0-post.5769+b5758b160" description = "OpenHands: Code Less, Make More" optional = false python-versions = "^3.12,<3.14" @@ -5902,9 +5902,9 @@ memory-profiler = "^0.61.0" numpy = "*" openai = "2.8.0" openhands-aci = "0.3.2" -openhands-agent-server = "1.7.1" -openhands-sdk = "1.7.1" -openhands-tools = "1.7.1" +openhands-agent-server = "1.7.3" +openhands-sdk = "1.7.3" +openhands-tools = "1.7.3" opentelemetry-api = "^1.33.1" opentelemetry-exporter-otlp-proto-grpc = "^1.33.1" pathspec = "^0.12.1" @@ -5960,14 +5960,14 @@ url = ".." [[package]] name = "openhands-sdk" -version = "1.7.1" +version = "1.7.3" description = "OpenHands SDK - Core functionality for building AI agents" optional = false python-versions = ">=3.12" groups = ["main"] files = [ - {file = "openhands_sdk-1.7.1-py3-none-any.whl", hash = "sha256:e097e34dfbd45f38225ae2ff4830702424bcf742bc197b5a811540a75265b135"}, - {file = "openhands_sdk-1.7.1.tar.gz", hash = "sha256:e13d1fe8bf14dffd91e9080608072a989132c981cf9bfcd124fa4f7a68a13691"}, + {file = "openhands_sdk-1.7.3-py3-none-any.whl", hash = "sha256:afbce9c9e7d1167d9b9610673657fbbcd454b04f0151d943418d897de790aeed"}, + {file = "openhands_sdk-1.7.3.tar.gz", hash = "sha256:7fa0cde9148ab905e24346b50f2d7267fb6dde32ec8dcbc1c7d35ced6e0233aa"}, ] [package.dependencies] @@ -5987,14 +5987,14 @@ boto3 = ["boto3 (>=1.35.0)"] [[package]] name = "openhands-tools" -version = "1.7.1" +version = "1.7.3" description = "OpenHands Tools - Runtime tools for AI agents" optional = false python-versions = ">=3.12" groups = ["main"] files = [ - {file = "openhands_tools-1.7.1-py3-none-any.whl", hash = "sha256:e25815f24925e94fbd4d8c3fd9b2147a0556fde595bf4f80a7dbba1014ea3c86"}, - {file = "openhands_tools-1.7.1.tar.gz", hash = "sha256:f3823f7bd302c78969c454730cf793eb63109ce2d986e78585989c53986cc966"}, + {file = "openhands_tools-1.7.3-py3-none-any.whl", hash = "sha256:e823f5a47936dd23221cb4eb846d62b59dce5be69210330095fc242772e71d27"}, + {file = "openhands_tools-1.7.3.tar.gz", hash = "sha256:f2779cc5ca3b78b9afebb7617006da8069c12b41e6d67cbf0cc8de5d819005f8"}, ] [package.dependencies] diff --git a/openhands/app_server/sandbox/sandbox_spec_service.py b/openhands/app_server/sandbox/sandbox_spec_service.py index a3f77db134..0338bc822d 100644 --- a/openhands/app_server/sandbox/sandbox_spec_service.py +++ b/openhands/app_server/sandbox/sandbox_spec_service.py @@ -13,7 +13,7 @@ from openhands.sdk.utils.models import DiscriminatedUnionMixin # The version of the agent server to use for deployments. # Typically this will be the same as the values from the pyproject.toml -AGENT_SERVER_IMAGE = 'ghcr.io/openhands/agent-server:0b7ccc9-python' +AGENT_SERVER_IMAGE = 'ghcr.io/openhands/agent-server:5cbfbf7-python' class SandboxSpecService(ABC): diff --git a/poetry.lock b/poetry.lock index 61097d2151..df339a9c03 100644 --- a/poetry.lock +++ b/poetry.lock @@ -7380,14 +7380,14 @@ llama = ["llama-index (>=0.12.29,<0.13.0)", "llama-index-core (>=0.12.29,<0.13.0 [[package]] name = "openhands-agent-server" -version = "1.7.1" +version = "1.7.3" description = "OpenHands Agent Server - REST/WebSocket interface for OpenHands AI Agent" optional = false python-versions = ">=3.12" groups = ["main"] files = [ - {file = "openhands_agent_server-1.7.1-py3-none-any.whl", hash = "sha256:e5c57f1b73293d00a68b77f9d290f59d9e2217d9df844fb01c7d2f929c3417f4"}, - {file = "openhands_agent_server-1.7.1.tar.gz", hash = "sha256:c82e1e6748ea3b4278ef2ee72f091dc37da6667c854b3aa3c0bc616086a82310"}, + {file = "openhands_agent_server-1.7.3-py3-none-any.whl", hash = "sha256:456e7162cefec8ed7fda61433180b3f867265e15c7151b3a2e3e02546c9d9b6d"}, + {file = "openhands_agent_server-1.7.3.tar.gz", hash = "sha256:2c06dc497c38050d445559da2825d4d69fe84af90289c82a95317e45359cc547"}, ] [package.dependencies] @@ -7404,14 +7404,14 @@ wsproto = ">=1.2.0" [[package]] name = "openhands-sdk" -version = "1.7.1" +version = "1.7.3" description = "OpenHands SDK - Core functionality for building AI agents" optional = false python-versions = ">=3.12" groups = ["main"] files = [ - {file = "openhands_sdk-1.7.1-py3-none-any.whl", hash = "sha256:e097e34dfbd45f38225ae2ff4830702424bcf742bc197b5a811540a75265b135"}, - {file = "openhands_sdk-1.7.1.tar.gz", hash = "sha256:e13d1fe8bf14dffd91e9080608072a989132c981cf9bfcd124fa4f7a68a13691"}, + {file = "openhands_sdk-1.7.3-py3-none-any.whl", hash = "sha256:afbce9c9e7d1167d9b9610673657fbbcd454b04f0151d943418d897de790aeed"}, + {file = "openhands_sdk-1.7.3.tar.gz", hash = "sha256:7fa0cde9148ab905e24346b50f2d7267fb6dde32ec8dcbc1c7d35ced6e0233aa"}, ] [package.dependencies] @@ -7431,14 +7431,14 @@ boto3 = ["boto3 (>=1.35.0)"] [[package]] name = "openhands-tools" -version = "1.7.1" +version = "1.7.3" description = "OpenHands Tools - Runtime tools for AI agents" optional = false python-versions = ">=3.12" groups = ["main"] files = [ - {file = "openhands_tools-1.7.1-py3-none-any.whl", hash = "sha256:e25815f24925e94fbd4d8c3fd9b2147a0556fde595bf4f80a7dbba1014ea3c86"}, - {file = "openhands_tools-1.7.1.tar.gz", hash = "sha256:f3823f7bd302c78969c454730cf793eb63109ce2d986e78585989c53986cc966"}, + {file = "openhands_tools-1.7.3-py3-none-any.whl", hash = "sha256:e823f5a47936dd23221cb4eb846d62b59dce5be69210330095fc242772e71d27"}, + {file = "openhands_tools-1.7.3.tar.gz", hash = "sha256:f2779cc5ca3b78b9afebb7617006da8069c12b41e6d67cbf0cc8de5d819005f8"}, ] [package.dependencies] @@ -16824,4 +16824,4 @@ third-party-runtimes = ["daytona", "e2b-code-interpreter", "modal", "runloop-api [metadata] lock-version = "2.1" python-versions = "^3.12,<3.14" -content-hash = "5673c5d0fd9cc39031661fa199bc50eb3add121eaeef139f418261838bdbb3c8" +content-hash = "dc1654633f511a20e9bfbb3d660e24869c587cbab2c14267692e9042de34f43d" diff --git a/pyproject.toml b/pyproject.toml index fc5e8fab98..c042bffe88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -116,9 +116,9 @@ pybase62 = "^1.0.0" #openhands-agent-server = { git = "https://github.com/OpenHands/agent-sdk.git", subdirectory = "openhands-agent-server", rev = "15f565b8ac38876e40dc05c08e2b04ccaae4a66d" } #openhands-sdk = { git = "https://github.com/OpenHands/agent-sdk.git", subdirectory = "openhands-sdk", rev = "15f565b8ac38876e40dc05c08e2b04ccaae4a66d" } #openhands-tools = { git = "https://github.com/OpenHands/agent-sdk.git", subdirectory = "openhands-tools", rev = "15f565b8ac38876e40dc05c08e2b04ccaae4a66d" } -openhands-sdk = "1.7.1" -openhands-agent-server = "1.7.1" -openhands-tools = "1.7.1" +openhands-sdk = "1.7.3" +openhands-agent-server = "1.7.3" +openhands-tools = "1.7.3" python-jose = { version = ">=3.3", extras = [ "cryptography" ] } sqlalchemy = { extras = [ "asyncio" ], version = "^2.0.40" } pg8000 = "^1.31.5" From bfe827596346fd09baab5ab3c65fcf43b3b7eb5e Mon Sep 17 00:00:00 2001 From: "sp.wack" <83104063+amanape@users.noreply.github.com> Date: Tue, 30 Dec 2025 23:04:29 +0400 Subject: [PATCH 14/15] hotfix(test): add top-level mock for custom-toast-handlers in conversation-panel tests (#12220) --- .../conversation-panel.test.tsx | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/frontend/__tests__/components/features/conversation-panel/conversation-panel.test.tsx b/frontend/__tests__/components/features/conversation-panel/conversation-panel.test.tsx index 95c4ca9521..7a7765f542 100644 --- a/frontend/__tests__/components/features/conversation-panel/conversation-panel.test.tsx +++ b/frontend/__tests__/components/features/conversation-panel/conversation-panel.test.tsx @@ -16,6 +16,13 @@ vi.mock("#/hooks/mutation/use-unified-stop-conversation", () => ({ }), })); +// Mock toast handlers to prevent unhandled rejection errors +vi.mock("#/utils/custom-toast-handlers", () => ({ + displaySuccessToast: vi.fn(), + displayErrorToast: vi.fn(), + TOAST_OPTIONS: {}, +})); + describe("ConversationPanel", () => { const onCloseMock = vi.fn(); const RouterStub = createRoutesStub([ @@ -634,12 +641,6 @@ describe("ConversationPanel", () => { ); updateConversationSpy.mockResolvedValue(true); - // Mock the toast function - const mockToast = vi.fn(); - vi.mock("#/utils/custom-toast-handlers", () => ({ - displaySuccessToast: mockToast, - })); - renderConversationPanel(); const cards = await screen.findAllByTestId("conversation-card"); @@ -767,10 +768,6 @@ describe("ConversationPanel", () => { ); updateConversationSpy.mockRejectedValue(new Error("API Error")); - vi.mock("#/utils/custom-toast-handlers", () => ({ - displayErrorToast: vi.fn(), - })); - renderConversationPanel(); const cards = await screen.findAllByTestId("conversation-card"); From ffdd95305f066708cecbda17585b858e78e74da4 Mon Sep 17 00:00:00 2001 From: Hiep Le <69354317+hieptl@users.noreply.github.com> Date: Wed, 31 Dec 2025 02:05:43 +0700 Subject: [PATCH 15/15] fix(backend): invalid api key (#12217) --- enterprise/server/constants.py | 2 + enterprise/server/routes/api_keys.py | 105 +++++- .../tests/unit/server/routes/test_api_keys.py | 330 ++++++++++++++++++ 3 files changed, 433 insertions(+), 4 deletions(-) create mode 100644 enterprise/tests/unit/server/routes/test_api_keys.py diff --git a/enterprise/server/constants.py b/enterprise/server/constants.py index e2020ba2b9..1dbe3384f2 100644 --- a/enterprise/server/constants.py +++ b/enterprise/server/constants.py @@ -38,6 +38,8 @@ LITE_LLM_API_URL = os.environ.get( ) LITE_LLM_TEAM_ID = os.environ.get('LITE_LLM_TEAM_ID', None) LITE_LLM_API_KEY = os.environ.get('LITE_LLM_API_KEY', None) +# Timeout in seconds for BYOR key verification requests to LiteLLM +BYOR_KEY_VERIFICATION_TIMEOUT = 5.0 SUBSCRIPTION_PRICE_DATA = { 'MONTHLY_SUBSCRIPTION': { 'unit_amount': 2000, diff --git a/enterprise/server/routes/api_keys.py b/enterprise/server/routes/api_keys.py index 5cb6939217..99e0996226 100644 --- a/enterprise/server/routes/api_keys.py +++ b/enterprise/server/routes/api_keys.py @@ -4,7 +4,11 @@ import httpx from fastapi import APIRouter, Depends, HTTPException, status from pydantic import BaseModel, field_validator from server.config import get_config -from server.constants import LITE_LLM_API_KEY, LITE_LLM_API_URL +from server.constants import ( + BYOR_KEY_VERIFICATION_TIMEOUT, + LITE_LLM_API_KEY, + LITE_LLM_API_URL, +) from storage.api_key_store import ApiKeyStore from storage.database import session_maker from storage.saas_settings_store import SaasSettingsStore @@ -112,6 +116,70 @@ async def generate_byor_key(user_id: str) -> str | None: return None +async def verify_byor_key_in_litellm(byor_key: str, user_id: str) -> bool: + """Verify that a BYOR key is valid in LiteLLM by making a lightweight API call. + + Args: + byor_key: The BYOR key to verify + user_id: The user ID for logging purposes + + Returns: + True if the key is verified as valid, False if verification fails or key is invalid. + Returns False on network errors/timeouts to ensure we don't return potentially invalid keys. + """ + if not (LITE_LLM_API_URL and byor_key): + return False + + try: + async with httpx.AsyncClient( + verify=httpx_verify_option(), + timeout=BYOR_KEY_VERIFICATION_TIMEOUT, + ) as client: + # Make a lightweight request to verify the key + # Using /v1/models endpoint as it's lightweight and requires authentication + response = await client.get( + f'{LITE_LLM_API_URL}/v1/models', + headers={ + 'Authorization': f'Bearer {byor_key}', + }, + ) + + # Only 200 status code indicates valid key + if response.status_code == 200: + logger.debug( + 'BYOR key verification successful', + extra={'user_id': user_id}, + ) + return True + + # All other status codes (401, 403, 500, etc.) are treated as invalid + # This includes authentication errors and server errors + logger.warning( + 'BYOR key verification failed - treating as invalid', + extra={ + 'user_id': user_id, + 'status_code': response.status_code, + 'key_prefix': byor_key[:10] + '...' + if len(byor_key) > 10 + else byor_key, + }, + ) + return False + + except (httpx.TimeoutException, Exception) as e: + # Any exception (timeout, network error, etc.) means we can't verify + # Return False to trigger regeneration rather than returning potentially invalid key + logger.warning( + 'BYOR key verification error - treating as invalid to ensure key validity', + extra={ + 'user_id': user_id, + 'error': str(e), + 'error_type': type(e).__name__, + }, + ) + return False + + async def delete_byor_key_from_litellm(user_id: str, byor_key: str) -> bool: """Delete the BYOR key from LiteLLM using the key directly.""" if not (LITE_LLM_API_KEY and LITE_LLM_API_URL): @@ -278,18 +346,44 @@ async def delete_api_key(key_id: int, user_id: str = Depends(get_user_id)): @api_router.get('/llm/byor', response_model=LlmApiKeyResponse) async def get_llm_api_key_for_byor(user_id: str = Depends(get_user_id)): - """Get the LLM API key for BYOR (Bring Your Own Runtime) for the authenticated user.""" + """Get the LLM API key for BYOR (Bring Your Own Runtime) for the authenticated user. + + This endpoint validates that the key exists in LiteLLM before returning it. + If validation fails, it automatically generates a new key to ensure users + always receive a working key. + """ try: # Check if the BYOR key exists in the database byor_key = await get_byor_key_from_db(user_id) if byor_key: - return {'key': byor_key} + # Validate that the key is actually registered in LiteLLM + is_valid = await verify_byor_key_in_litellm(byor_key, user_id) + if is_valid: + return {'key': byor_key} + else: + # Key exists in DB but is invalid in LiteLLM - regenerate it + logger.warning( + 'BYOR key found in database but invalid in LiteLLM - regenerating', + extra={ + 'user_id': user_id, + 'key_prefix': byor_key[:10] + '...' + if len(byor_key) > 10 + else byor_key, + }, + ) + # Delete the invalid key from LiteLLM (best effort, don't fail if it doesn't exist) + await delete_byor_key_from_litellm(user_id, byor_key) + # Fall through to generate a new key - # If not, generate a new key for BYOR + # Generate a new key for BYOR (either no key exists or validation failed) key = await generate_byor_key(user_id) if key: # Store the key in the database await store_byor_key_in_db(user_id, key) + logger.info( + 'Successfully generated and stored new BYOR key', + extra={'user_id': user_id}, + ) return {'key': key} else: logger.error( @@ -301,6 +395,9 @@ async def get_llm_api_key_for_byor(user_id: str = Depends(get_user_id)): detail='Failed to generate new BYOR LLM API key', ) + except HTTPException: + # Re-raise HTTP exceptions as-is + raise except Exception as e: logger.exception('Error retrieving BYOR LLM API key', extra={'error': str(e)}) raise HTTPException( diff --git a/enterprise/tests/unit/server/routes/test_api_keys.py b/enterprise/tests/unit/server/routes/test_api_keys.py new file mode 100644 index 0000000000..31c1edba3c --- /dev/null +++ b/enterprise/tests/unit/server/routes/test_api_keys.py @@ -0,0 +1,330 @@ +"""Unit tests for API keys routes, focusing on BYOR key validation and retrieval.""" + +from unittest.mock import AsyncMock, MagicMock, patch + +import httpx +import pytest +from fastapi import HTTPException +from server.routes.api_keys import ( + get_llm_api_key_for_byor, + verify_byor_key_in_litellm, +) + + +class TestVerifyByorKeyInLitellm: + """Test the verify_byor_key_in_litellm function.""" + + @pytest.mark.asyncio + @patch('server.routes.api_keys.LITE_LLM_API_URL', 'https://litellm.example.com') + @patch('server.routes.api_keys.httpx.AsyncClient') + async def test_verify_valid_key_returns_true(self, mock_client_class): + """Test that a valid key (200 response) returns True.""" + # Arrange + byor_key = 'sk-valid-key-123' + user_id = 'user-123' + mock_response = MagicMock() + mock_response.status_code = 200 + mock_response.is_success = True + mock_client = AsyncMock() + mock_client.__aenter__.return_value = mock_client + mock_client.__aexit__.return_value = None + mock_client.get.return_value = mock_response + mock_client_class.return_value = mock_client + + # Act + result = await verify_byor_key_in_litellm(byor_key, user_id) + + # Assert + assert result is True + mock_client.get.assert_called_once_with( + 'https://litellm.example.com/v1/models', + headers={'Authorization': f'Bearer {byor_key}'}, + ) + + @pytest.mark.asyncio + @patch('server.routes.api_keys.LITE_LLM_API_URL', 'https://litellm.example.com') + @patch('server.routes.api_keys.httpx.AsyncClient') + async def test_verify_invalid_key_401_returns_false(self, mock_client_class): + """Test that an invalid key (401 response) returns False.""" + # Arrange + byor_key = 'sk-invalid-key-123' + user_id = 'user-123' + mock_response = MagicMock() + mock_response.status_code = 401 + mock_client = AsyncMock() + mock_client.__aenter__.return_value = mock_client + mock_client.__aexit__.return_value = None + mock_client.get.return_value = mock_response + mock_client_class.return_value = mock_client + + # Act + result = await verify_byor_key_in_litellm(byor_key, user_id) + + # Assert + assert result is False + + @pytest.mark.asyncio + @patch('server.routes.api_keys.LITE_LLM_API_URL', 'https://litellm.example.com') + @patch('server.routes.api_keys.httpx.AsyncClient') + async def test_verify_invalid_key_403_returns_false(self, mock_client_class): + """Test that an invalid key (403 response) returns False.""" + # Arrange + byor_key = 'sk-forbidden-key-123' + user_id = 'user-123' + mock_response = MagicMock() + mock_response.status_code = 403 + mock_client = AsyncMock() + mock_client.__aenter__.return_value = mock_client + mock_client.__aexit__.return_value = None + mock_client.get.return_value = mock_response + mock_client_class.return_value = mock_client + + # Act + result = await verify_byor_key_in_litellm(byor_key, user_id) + + # Assert + assert result is False + + @pytest.mark.asyncio + @patch('server.routes.api_keys.LITE_LLM_API_URL', 'https://litellm.example.com') + @patch('server.routes.api_keys.httpx.AsyncClient') + async def test_verify_server_error_returns_false(self, mock_client_class): + """Test that a server error (500) returns False to ensure key validity.""" + # Arrange + byor_key = 'sk-key-123' + user_id = 'user-123' + mock_response = MagicMock() + mock_response.status_code = 500 + mock_response.is_success = False + mock_client = AsyncMock() + mock_client.__aenter__.return_value = mock_client + mock_client.__aexit__.return_value = None + mock_client.get.return_value = mock_response + mock_client_class.return_value = mock_client + + # Act + result = await verify_byor_key_in_litellm(byor_key, user_id) + + # Assert + assert result is False + + @pytest.mark.asyncio + @patch('server.routes.api_keys.LITE_LLM_API_URL', 'https://litellm.example.com') + @patch('server.routes.api_keys.httpx.AsyncClient') + async def test_verify_timeout_returns_false(self, mock_client_class): + """Test that a timeout returns False to ensure key validity.""" + # Arrange + byor_key = 'sk-key-123' + user_id = 'user-123' + mock_client = AsyncMock() + mock_client.__aenter__.return_value = mock_client + mock_client.__aexit__.return_value = None + mock_client.get.side_effect = httpx.TimeoutException('Request timed out') + mock_client_class.return_value = mock_client + + # Act + result = await verify_byor_key_in_litellm(byor_key, user_id) + + # Assert + assert result is False + + @pytest.mark.asyncio + @patch('server.routes.api_keys.LITE_LLM_API_URL', 'https://litellm.example.com') + @patch('server.routes.api_keys.httpx.AsyncClient') + async def test_verify_network_error_returns_false(self, mock_client_class): + """Test that a network error returns False to ensure key validity.""" + # Arrange + byor_key = 'sk-key-123' + user_id = 'user-123' + mock_client = AsyncMock() + mock_client.__aenter__.return_value = mock_client + mock_client.__aexit__.return_value = None + mock_client.get.side_effect = httpx.NetworkError('Network error') + mock_client_class.return_value = mock_client + + # Act + result = await verify_byor_key_in_litellm(byor_key, user_id) + + # Assert + assert result is False + + @pytest.mark.asyncio + @patch('server.routes.api_keys.LITE_LLM_API_URL', None) + async def test_verify_missing_api_url_returns_false(self): + """Test that missing LITE_LLM_API_URL returns False.""" + # Arrange + byor_key = 'sk-key-123' + user_id = 'user-123' + + # Act + result = await verify_byor_key_in_litellm(byor_key, user_id) + + # Assert + assert result is False + + @pytest.mark.asyncio + @patch('server.routes.api_keys.LITE_LLM_API_URL', 'https://litellm.example.com') + async def test_verify_empty_key_returns_false(self): + """Test that empty key returns False.""" + # Arrange + byor_key = '' + user_id = 'user-123' + + # Act + result = await verify_byor_key_in_litellm(byor_key, user_id) + + # Assert + assert result is False + + +class TestGetLlmApiKeyForByor: + """Test the get_llm_api_key_for_byor endpoint.""" + + @pytest.mark.asyncio + @patch('server.routes.api_keys.store_byor_key_in_db') + @patch('server.routes.api_keys.generate_byor_key') + @patch('server.routes.api_keys.get_byor_key_from_db') + async def test_no_key_in_database_generates_new( + self, mock_get_key, mock_generate_key, mock_store_key + ): + """Test that when no key exists in database, a new one is generated.""" + # Arrange + user_id = 'user-123' + new_key = 'sk-new-generated-key' + mock_get_key.return_value = None + mock_generate_key.return_value = new_key + mock_store_key.return_value = None + + # Act + result = await get_llm_api_key_for_byor(user_id=user_id) + + # Assert + assert result == {'key': new_key} + mock_get_key.assert_called_once_with(user_id) + mock_generate_key.assert_called_once_with(user_id) + mock_store_key.assert_called_once_with(user_id, new_key) + + @pytest.mark.asyncio + @patch('server.routes.api_keys.verify_byor_key_in_litellm') + @patch('server.routes.api_keys.get_byor_key_from_db') + async def test_valid_key_in_database_returns_key( + self, mock_get_key, mock_verify_key + ): + """Test that when a valid key exists in database, it is returned.""" + # Arrange + user_id = 'user-123' + existing_key = 'sk-existing-valid-key' + mock_get_key.return_value = existing_key + mock_verify_key.return_value = True + + # Act + result = await get_llm_api_key_for_byor(user_id=user_id) + + # Assert + assert result == {'key': existing_key} + mock_get_key.assert_called_once_with(user_id) + mock_verify_key.assert_called_once_with(existing_key, user_id) + + @pytest.mark.asyncio + @patch('server.routes.api_keys.store_byor_key_in_db') + @patch('server.routes.api_keys.generate_byor_key') + @patch('server.routes.api_keys.delete_byor_key_from_litellm') + @patch('server.routes.api_keys.verify_byor_key_in_litellm') + @patch('server.routes.api_keys.get_byor_key_from_db') + async def test_invalid_key_in_database_regenerates( + self, + mock_get_key, + mock_verify_key, + mock_delete_key, + mock_generate_key, + mock_store_key, + ): + """Test that when an invalid key exists in database, it is regenerated.""" + # Arrange + user_id = 'user-123' + invalid_key = 'sk-invalid-key' + new_key = 'sk-new-generated-key' + mock_get_key.return_value = invalid_key + mock_verify_key.return_value = False + mock_delete_key.return_value = True + mock_generate_key.return_value = new_key + mock_store_key.return_value = None + + # Act + result = await get_llm_api_key_for_byor(user_id=user_id) + + # Assert + assert result == {'key': new_key} + mock_get_key.assert_called_once_with(user_id) + mock_verify_key.assert_called_once_with(invalid_key, user_id) + mock_delete_key.assert_called_once_with(user_id, invalid_key) + mock_generate_key.assert_called_once_with(user_id) + mock_store_key.assert_called_once_with(user_id, new_key) + + @pytest.mark.asyncio + @patch('server.routes.api_keys.store_byor_key_in_db') + @patch('server.routes.api_keys.generate_byor_key') + @patch('server.routes.api_keys.delete_byor_key_from_litellm') + @patch('server.routes.api_keys.verify_byor_key_in_litellm') + @patch('server.routes.api_keys.get_byor_key_from_db') + async def test_invalid_key_deletion_failure_still_regenerates( + self, + mock_get_key, + mock_verify_key, + mock_delete_key, + mock_generate_key, + mock_store_key, + ): + """Test that even if deletion fails, regeneration still proceeds.""" + # Arrange + user_id = 'user-123' + invalid_key = 'sk-invalid-key' + new_key = 'sk-new-generated-key' + mock_get_key.return_value = invalid_key + mock_verify_key.return_value = False + mock_delete_key.return_value = False # Deletion fails + mock_generate_key.return_value = new_key + mock_store_key.return_value = None + + # Act + result = await get_llm_api_key_for_byor(user_id=user_id) + + # Assert + assert result == {'key': new_key} + mock_delete_key.assert_called_once_with(user_id, invalid_key) + mock_generate_key.assert_called_once_with(user_id) + mock_store_key.assert_called_once_with(user_id, new_key) + + @pytest.mark.asyncio + @patch('server.routes.api_keys.generate_byor_key') + @patch('server.routes.api_keys.get_byor_key_from_db') + async def test_key_generation_failure_raises_exception( + self, mock_get_key, mock_generate_key + ): + """Test that when key generation fails, an HTTPException is raised.""" + # Arrange + user_id = 'user-123' + mock_get_key.return_value = None + mock_generate_key.return_value = None + + # Act & Assert + with pytest.raises(HTTPException) as exc_info: + await get_llm_api_key_for_byor(user_id=user_id) + + assert exc_info.value.status_code == 500 + assert 'Failed to generate new BYOR LLM API key' in exc_info.value.detail + + @pytest.mark.asyncio + @patch('server.routes.api_keys.get_byor_key_from_db') + async def test_database_error_raises_exception(self, mock_get_key): + """Test that database errors are properly handled.""" + # Arrange + user_id = 'user-123' + mock_get_key.side_effect = Exception('Database connection error') + + # Act & Assert + with pytest.raises(HTTPException) as exc_info: + await get_llm_api_key_for_byor(user_id=user_id) + + assert exc_info.value.status_code == 500 + assert 'Failed to retrieve BYOR LLM API key' in exc_info.value.detail