diff --git a/enterprise/integrations/github/github_service.py b/enterprise/integrations/github/github_service.py index 1d694e193b..7c58ef6732 100644 --- a/enterprise/integrations/github/github_service.py +++ b/enterprise/integrations/github/github_service.py @@ -4,10 +4,10 @@ from integrations.store_repo_utils import store_repositories_in_db from pydantic import SecretStr from server.auth.token_manager import TokenManager +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.github.github_service import GitHubService from openhands.app_server.integrations.service_types import ProviderType, Repository from openhands.app_server.utils.logger import openhands_logger as logger -from openhands.server.types import AppMode class SaaSGitHubService(GitHubService): diff --git a/enterprise/integrations/gitlab/gitlab_service.py b/enterprise/integrations/gitlab/gitlab_service.py index 9cd6c0288e..2f9e6c9187 100644 --- a/enterprise/integrations/gitlab/gitlab_service.py +++ b/enterprise/integrations/gitlab/gitlab_service.py @@ -7,6 +7,7 @@ from server.auth.token_manager import TokenManager from storage.gitlab_webhook import GitlabWebhook, WebhookStatus from storage.gitlab_webhook_store import GitlabWebhookStore +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.gitlab.gitlab_service import GitLabService from openhands.app_server.integrations.service_types import ( ProviderType, @@ -15,7 +16,6 @@ from openhands.app_server.integrations.service_types import ( RequestMethod, ) from openhands.app_server.utils.logger import openhands_logger as logger -from openhands.server.types import AppMode class SaaSGitLabService(GitLabService): diff --git a/enterprise/server/auth/gitlab_sync.py b/enterprise/server/auth/gitlab_sync.py index 8d20af4b51..f03d6e2899 100644 --- a/enterprise/server/auth/gitlab_sync.py +++ b/enterprise/server/auth/gitlab_sync.py @@ -3,9 +3,9 @@ import asyncio from pydantic import SecretStr from sqlalchemy import select +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.service_types import ProviderType from openhands.app_server.utils.logger import openhands_logger as logger -from openhands.server.types import AppMode async def _user_has_gitlab_provider(user_id: str) -> bool: diff --git a/enterprise/server/config.py b/enterprise/server/config.py index aec2c5af44..c6da43523a 100644 --- a/enterprise/server/config.py +++ b/enterprise/server/config.py @@ -22,9 +22,9 @@ from server.auth.constants import ( ) from server.constants import DEPLOYMENT_MODE +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.service_types import ProviderType from openhands.server.config.server_config import ServerConfig -from openhands.server.types import AppMode def sign_token(payload: dict[str, object], jwt_secret: str, algorithm='HS256') -> str: diff --git a/openhands/app_server/app_conversation/live_status_app_conversation_service.py b/openhands/app_server/app_conversation/live_status_app_conversation_service.py index e16528e70d..bd43f5fe05 100644 --- a/openhands/app_server/app_conversation/live_status_app_conversation_service.py +++ b/openhands/app_server/app_conversation/live_status_app_conversation_service.py @@ -61,6 +61,7 @@ from openhands.app_server.config import ( get_event_callback_service, resolve_provider_llm_base_url, ) +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.errors import SandboxError from openhands.app_server.event.event_service import EventService from openhands.app_server.event_callback.event_callback_models import EventCallback @@ -105,7 +106,6 @@ from openhands.sdk.secret import LookupSecret, StaticSecret from openhands.sdk.settings import ACPAgentSettings from openhands.sdk.utils.paging import page_iterator from openhands.sdk.workspace.remote.async_remote_workspace import AsyncRemoteWorkspace -from openhands.server.types import AppMode from openhands.tools.preset.default import ( get_default_tools, ) diff --git a/openhands/app_server/config.py b/openhands/app_server/config.py index 3188c8dce0..d9713eb629 100644 --- a/openhands/app_server/config.py +++ b/openhands/app_server/config.py @@ -28,6 +28,7 @@ from openhands.app_server.app_lifespan.app_lifespan_service import AppLifespanSe from openhands.app_server.app_lifespan.oss_app_lifespan_service import ( OssAppLifespanService, ) +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.config_api.llm_model_service import ( LLMModelService, LLMModelServiceInjector, @@ -66,7 +67,6 @@ from openhands.app_server.web_client.web_client_config_injector import ( WebClientConfigInjector, ) from openhands.sdk.utils.models import OpenHandsModel -from openhands.server.types import AppMode def get_default_persistence_dir() -> Path: diff --git a/openhands/app_server/config_api/config_models.py b/openhands/app_server/config_api/config_models.py index 4af43101a7..e725e1a953 100644 --- a/openhands/app_server/config_api/config_models.py +++ b/openhands/app_server/config_api/config_models.py @@ -1,8 +1,15 @@ """Config-related models for OpenHands App Server V1 API.""" +from enum import Enum + from pydantic import BaseModel, Field +class AppMode(Enum): + OPENHANDS = 'oss' + SAAS = 'saas' + + class LLMModel(BaseModel): """LLM Model object for API responses.""" diff --git a/openhands/app_server/event_callback/webhook_router.py b/openhands/app_server/event_callback/webhook_router.py index 30e4db2fcc..d32e1466fe 100644 --- a/openhands/app_server/event_callback/webhook_router.py +++ b/openhands/app_server/event_callback/webhook_router.py @@ -28,6 +28,7 @@ from openhands.app_server.config import ( get_global_config, get_sandbox_service, ) +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.errors import AuthError from openhands.app_server.event.event_service import EventService from openhands.app_server.event_callback.event_callback_models import EventCallback @@ -50,7 +51,6 @@ from openhands.app_server.user_auth.user_auth import ( ) from openhands.sdk import ConversationExecutionStatus, Event from openhands.sdk.event import ConversationStateUpdateEvent -from openhands.server.types import AppMode router = APIRouter(prefix='/webhooks', tags=['Webhooks']) event_service_dependency = depends_event_service() diff --git a/openhands/app_server/integrations/azure_devops/service/repos.py b/openhands/app_server/integrations/azure_devops/service/repos.py index de50c1b016..11cd19e7d1 100644 --- a/openhands/app_server/integrations/azure_devops/service/repos.py +++ b/openhands/app_server/integrations/azure_devops/service/repos.py @@ -1,10 +1,10 @@ """Repository operations for Azure DevOps integration.""" +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.azure_devops.service.base import ( AzureDevOpsMixinBase, ) from openhands.app_server.integrations.service_types import ProviderType, Repository -from openhands.server.types import AppMode class AzureDevOpsReposMixin(AzureDevOpsMixinBase): diff --git a/openhands/app_server/integrations/bitbucket/service/repos.py b/openhands/app_server/integrations/bitbucket/service/repos.py index 0c0bba9667..023bfdcadc 100644 --- a/openhands/app_server/integrations/bitbucket/service/repos.py +++ b/openhands/app_server/integrations/bitbucket/service/repos.py @@ -2,9 +2,9 @@ import re from typing import Any from urllib.parse import urlparse +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.bitbucket.service.base import BitBucketMixinBase from openhands.app_server.integrations.service_types import Repository, SuggestedTask -from openhands.server.types import AppMode class BitBucketReposMixin(BitBucketMixinBase): diff --git a/openhands/app_server/integrations/bitbucket_data_center/service/repos.py b/openhands/app_server/integrations/bitbucket_data_center/service/repos.py index c1d58371f1..7403d33afe 100644 --- a/openhands/app_server/integrations/bitbucket_data_center/service/repos.py +++ b/openhands/app_server/integrations/bitbucket_data_center/service/repos.py @@ -1,11 +1,11 @@ from typing import Any from urllib.parse import urlparse +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.bitbucket_data_center.service.base import ( BitbucketDCMixinBase, ) from openhands.app_server.integrations.service_types import Repository, SuggestedTask -from openhands.server.types import AppMode class BitbucketDCReposMixin(BitbucketDCMixinBase): diff --git a/openhands/app_server/integrations/forgejo/service/repos.py b/openhands/app_server/integrations/forgejo/service/repos.py index 03a7f7c7ea..463c838704 100644 --- a/openhands/app_server/integrations/forgejo/service/repos.py +++ b/openhands/app_server/integrations/forgejo/service/repos.py @@ -1,8 +1,8 @@ from __future__ import annotations +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.forgejo.service.base import ForgejoMixinBase from openhands.app_server.integrations.service_types import Repository -from openhands.server.types import AppMode class ForgejoReposMixin(ForgejoMixinBase): diff --git a/openhands/app_server/integrations/github/service/repos.py b/openhands/app_server/integrations/github/service/repos.py index 04f85f8be3..88f120de21 100644 --- a/openhands/app_server/integrations/github/service/repos.py +++ b/openhands/app_server/integrations/github/service/repos.py @@ -1,5 +1,6 @@ from datetime import datetime +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.github.service.base import GitHubMixinBase from openhands.app_server.integrations.service_types import ( OwnerType, @@ -7,7 +8,6 @@ from openhands.app_server.integrations.service_types import ( Repository, ) from openhands.app_server.utils.logger import openhands_logger as logger -from openhands.server.types import AppMode class GitHubReposMixin(GitHubMixinBase): diff --git a/openhands/app_server/integrations/gitlab/service/repos.py b/openhands/app_server/integrations/gitlab/service/repos.py index fe0568fd3f..5fb31c4a53 100644 --- a/openhands/app_server/integrations/gitlab/service/repos.py +++ b/openhands/app_server/integrations/gitlab/service/repos.py @@ -1,3 +1,4 @@ +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.gitlab.service.base import GitLabMixinBase from openhands.app_server.integrations.service_types import ( OwnerType, @@ -5,7 +6,6 @@ from openhands.app_server.integrations.service_types import ( Repository, ) from openhands.app_server.utils.logger import openhands_logger as logger -from openhands.server.types import AppMode class GitLabReposMixin(GitLabMixinBase): diff --git a/openhands/app_server/integrations/provider.py b/openhands/app_server/integrations/provider.py index cb458211ac..cc7f24d41b 100644 --- a/openhands/app_server/integrations/provider.py +++ b/openhands/app_server/integrations/provider.py @@ -14,6 +14,7 @@ from pydantic import ( SecretStr, ) +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.azure_devops.azure_devops_service import ( AzureDevOpsServiceImpl, ) @@ -42,7 +43,6 @@ from openhands.app_server.integrations.service_types import ( ) from openhands.app_server.utils.http_session import httpx_verify_option from openhands.app_server.utils.logger import openhands_logger as logger -from openhands.server.types import AppMode class ProviderToken(BaseModel): diff --git a/openhands/app_server/integrations/service_types.py b/openhands/app_server/integrations/service_types.py index 9676a3618f..2a63944ddb 100644 --- a/openhands/app_server/integrations/service_types.py +++ b/openhands/app_server/integrations/service_types.py @@ -6,7 +6,7 @@ from typing import Any, Protocol from jinja2 import Environment, FileSystemLoader from pydantic import BaseModel, SecretStr -from openhands.server.types import AppMode +from openhands.app_server.config_api.config_models import AppMode class TokenResponse(BaseModel): diff --git a/openhands/app_server/mcp/mcp_router.py b/openhands/app_server/mcp/mcp_router.py index b28fa75925..5d214b1846 100644 --- a/openhands/app_server/mcp/mcp_router.py +++ b/openhands/app_server/mcp/mcp_router.py @@ -12,6 +12,7 @@ from openhands.app_server.config import ( get_app_conversation_info_service, get_global_config, ) +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.azure_devops.azure_devops_service import ( AzureDevOpsServiceImpl, ) @@ -36,7 +37,6 @@ from openhands.app_server.user_auth import ( get_user_id, ) from openhands.app_server.utils.logger import openhands_logger as logger -from openhands.server.types import AppMode mcp_server = FastMCP('mcp', mask_error_details=True) diff --git a/openhands/app_server/sandbox/session_auth.py b/openhands/app_server/sandbox/session_auth.py index ceecfbfb36..6195642f72 100644 --- a/openhands/app_server/sandbox/session_auth.py +++ b/openhands/app_server/sandbox/session_auth.py @@ -23,10 +23,10 @@ from typing import TYPE_CHECKING from fastapi import HTTPException, status from openhands.app_server.config import get_global_config, get_sandbox_service +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.sandbox.sandbox_models import SandboxInfo, SandboxStatus from openhands.app_server.services.injector import InjectorState from openhands.app_server.user.specifiy_user_context import ADMIN, USER_CONTEXT_ATTR -from openhands.server.types import AppMode if TYPE_CHECKING: from openhands.app_server.user.user_context import UserContext diff --git a/openhands/app_server/utils/dependencies.py b/openhands/app_server/utils/dependencies.py index 8ca238a94d..0d1499283d 100644 --- a/openhands/app_server/utils/dependencies.py +++ b/openhands/app_server/utils/dependencies.py @@ -4,7 +4,7 @@ from fastapi import Depends, HTTPException, status from fastapi.security import APIKeyHeader from openhands.app_server.config import get_global_config -from openhands.server.types import AppMode +from openhands.app_server.config_api.config_models import AppMode _SESSION_API_KEY = os.getenv('SESSION_API_KEY') _SESSION_API_KEY_HEADER = APIKeyHeader(name='X-Session-API-Key', auto_error=False) diff --git a/openhands/app_server/web_client/web_client_models.py b/openhands/app_server/web_client/web_client_models.py index a141441a72..8957eef062 100644 --- a/openhands/app_server/web_client/web_client_models.py +++ b/openhands/app_server/web_client/web_client_models.py @@ -3,12 +3,12 @@ from datetime import datetime from pydantic import BaseModel, Field, model_validator from openhands.agent_server.env_parser import DiscriminatedUnionMixin +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.service_types import ProviderType from openhands.app_server.web_client.web_client_deployment_mode import ( DeploymentMode, get_deployment_mode, ) -from openhands.server.types import AppMode class WebClientFeatureFlags(BaseModel): diff --git a/openhands/server/config/server_config.py b/openhands/server/config/server_config.py index f169365a1c..babb44ed1e 100644 --- a/openhands/server/config/server_config.py +++ b/openhands/server/config/server_config.py @@ -8,9 +8,10 @@ # This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/. import os +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.utils.import_utils import get_impl from openhands.app_server.utils.logger import openhands_logger as logger -from openhands.server.types import AppMode, ServerConfigInterface +from openhands.server.types import ServerConfigInterface class ServerConfig(ServerConfigInterface): diff --git a/openhands/server/types.py b/openhands/server/types.py index 1e52bf7984..4e4b9c7501 100644 --- a/openhands/server/types.py +++ b/openhands/server/types.py @@ -7,15 +7,9 @@ # 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 -class AppMode(Enum): - OPENHANDS = 'oss' - SAAS = 'saas' - - class ServerConfigInterface(ABC): @abstractmethod def verify_config(self) -> None: diff --git a/tests/unit/app_server/test_live_status_app_conversation_service.py b/tests/unit/app_server/test_live_status_app_conversation_service.py index 682ef01181..8825057847 100644 --- a/tests/unit/app_server/test_live_status_app_conversation_service.py +++ b/tests/unit/app_server/test_live_status_app_conversation_service.py @@ -26,6 +26,7 @@ from openhands.app_server.app_conversation.app_conversation_models import ( from openhands.app_server.app_conversation.live_status_app_conversation_service import ( LiveStatusAppConversationService, ) +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.provider import ProviderToken, ProviderType from openhands.app_server.integrations.service_types import SuggestedTask, TaskType from openhands.app_server.sandbox.sandbox_models import ( @@ -47,7 +48,6 @@ from openhands.sdk.llm import LLM from openhands.sdk.secret import LookupSecret, StaticSecret from openhands.sdk.settings import AgentSettings, ConversationSettings from openhands.sdk.workspace.remote.async_remote_workspace import AsyncRemoteWorkspace -from openhands.server.types import AppMode # True only on SDK versions that include PR #2984 (secrets acp_compatible=True). # When False, _build_acp_start_conversation_request skips the agent_context path. diff --git a/tests/unit/app_server/test_sandbox_secrets_router.py b/tests/unit/app_server/test_sandbox_secrets_router.py index 1c08dc65a1..6b89f2d729 100644 --- a/tests/unit/app_server/test_sandbox_secrets_router.py +++ b/tests/unit/app_server/test_sandbox_secrets_router.py @@ -135,7 +135,7 @@ class TestValidateSessionKey: mock_get.return_value.__aenter__ = AsyncMock(return_value=mock_svc) mock_get.return_value.__aexit__ = AsyncMock(return_value=False) - from openhands.server.types import AppMode + from openhands.app_server.config_api.config_models import AppMode mock_cfg.return_value.app_mode = AppMode.SAAS diff --git a/tests/unit/app_server/test_webhook_router_auth.py b/tests/unit/app_server/test_webhook_router_auth.py index 3d6880b850..5a0e87488b 100644 --- a/tests/unit/app_server/test_webhook_router_auth.py +++ b/tests/unit/app_server/test_webhook_router_auth.py @@ -11,6 +11,7 @@ import pytest from fastapi import FastAPI, HTTPException, status from fastapi.testclient import TestClient +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.event_callback.webhook_router import ( router as webhook_router, ) @@ -23,7 +24,6 @@ from openhands.app_server.user.specifiy_user_context import ( USER_CONTEXT_ATTR, SpecifyUserContext, ) -from openhands.server.types import AppMode class MockRequestState: diff --git a/tests/unit/integrations/bitbucket/test_bitbucket.py b/tests/unit/integrations/bitbucket/test_bitbucket.py index 5f89e7c47e..112351fe07 100644 --- a/tests/unit/integrations/bitbucket/test_bitbucket.py +++ b/tests/unit/integrations/bitbucket/test_bitbucket.py @@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, patch import pytest from pydantic import SecretStr +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.bitbucket.bitbucket_service import ( BitBucketService, ) @@ -16,7 +17,6 @@ from openhands.app_server.integrations.service_types import ( from openhands.app_server.integrations.utils import validate_provider_token from openhands.app_server.secrets.secrets_router import check_provider_tokens from openhands.app_server.settings.settings_models import POSTProviderModel -from openhands.server.types import AppMode # Provider Token Validation Tests diff --git a/tests/unit/integrations/bitbucket/test_bitbucket_repos.py b/tests/unit/integrations/bitbucket/test_bitbucket_repos.py index 77ab4ec853..72fb656f19 100644 --- a/tests/unit/integrations/bitbucket/test_bitbucket_repos.py +++ b/tests/unit/integrations/bitbucket/test_bitbucket_repos.py @@ -5,6 +5,7 @@ from unittest.mock import patch import pytest from pydantic import SecretStr +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.bitbucket.bitbucket_service import ( BitBucketService, ) @@ -12,7 +13,6 @@ from openhands.app_server.integrations.service_types import OwnerType, Repositor from openhands.app_server.integrations.service_types import ( ProviderType as ServiceProviderType, ) -from openhands.server.types import AppMode @pytest.fixture diff --git a/tests/unit/integrations/bitbucket_data_center/test_bitbucket_dc.py b/tests/unit/integrations/bitbucket_data_center/test_bitbucket_dc.py index d9d6d0de5b..9ddfa204e2 100644 --- a/tests/unit/integrations/bitbucket_data_center/test_bitbucket_dc.py +++ b/tests/unit/integrations/bitbucket_data_center/test_bitbucket_dc.py @@ -6,11 +6,11 @@ from unittest.mock import patch import pytest from pydantic import SecretStr +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.bitbucket_data_center.bitbucket_dc_service import ( BitbucketDCService, ) from openhands.app_server.integrations.service_types import AuthenticationError, User -from openhands.server.types import AppMode # ── init / BASE_URL ─────────────────────────────────────────────────────────── diff --git a/tests/unit/integrations/bitbucket_data_center/test_bitbucket_dc_repos.py b/tests/unit/integrations/bitbucket_data_center/test_bitbucket_dc_repos.py index 03b608f7de..a552deb892 100644 --- a/tests/unit/integrations/bitbucket_data_center/test_bitbucket_dc_repos.py +++ b/tests/unit/integrations/bitbucket_data_center/test_bitbucket_dc_repos.py @@ -5,10 +5,10 @@ from unittest.mock import AsyncMock, patch import pytest from pydantic import SecretStr +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.bitbucket_data_center.bitbucket_dc_service import ( BitbucketDCService, ) -from openhands.server.types import AppMode def make_service(): diff --git a/tests/unit/integrations/github/test_github_service.py b/tests/unit/integrations/github/test_github_service.py index a18e4ace57..c2d86bea14 100644 --- a/tests/unit/integrations/github/test_github_service.py +++ b/tests/unit/integrations/github/test_github_service.py @@ -4,6 +4,7 @@ import httpx import pytest from pydantic import SecretStr +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.github.github_service import GitHubService from openhands.app_server.integrations.service_types import ( AuthenticationError, @@ -12,7 +13,6 @@ from openhands.app_server.integrations.service_types import ( Repository, User, ) -from openhands.server.types import AppMode @pytest.mark.asyncio diff --git a/tests/unit/integrations/gitlab/test_gitlab.py b/tests/unit/integrations/gitlab/test_gitlab.py index b0c63ca7ba..e1cc5ca779 100644 --- a/tests/unit/integrations/gitlab/test_gitlab.py +++ b/tests/unit/integrations/gitlab/test_gitlab.py @@ -6,6 +6,7 @@ from unittest.mock import patch import pytest from pydantic import SecretStr +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations import provider as provider_module from openhands.app_server.integrations.gitlab import ( constants as gitlab_constants_module, @@ -17,7 +18,6 @@ from openhands.app_server.integrations.service_types import ( ProviderType, Repository, ) -from openhands.server.types import AppMode @pytest.mark.asyncio diff --git a/tests/unit/server/routes/test_mcp_routes.py b/tests/unit/server/routes/test_mcp_routes.py index 96cb93cd70..6e84ff957d 100644 --- a/tests/unit/server/routes/test_mcp_routes.py +++ b/tests/unit/server/routes/test_mcp_routes.py @@ -3,9 +3,9 @@ from unittest.mock import AsyncMock, patch import pytest +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.service_types import GitService from openhands.app_server.mcp.mcp_router import get_conversation_link -from openhands.server.types import AppMode def test_mcp_server_no_stateless_http_deprecation_warning(): diff --git a/tests/unit/test_forgejo_service.py b/tests/unit/test_forgejo_service.py index e3fc69941c..59a567ac19 100644 --- a/tests/unit/test_forgejo_service.py +++ b/tests/unit/test_forgejo_service.py @@ -4,6 +4,7 @@ import httpx import pytest from pydantic import SecretStr +from openhands.app_server.config_api.config_models import AppMode from openhands.app_server.integrations.forgejo.forgejo_service import ForgejoService from openhands.app_server.integrations.service_types import ( ProviderType, @@ -11,7 +12,6 @@ from openhands.app_server.integrations.service_types import ( RequestMethod, User, ) -from openhands.server.types import AppMode @pytest.fixture