diff --git a/enterprise/integrations/resolver_context.py b/enterprise/integrations/resolver_context.py index 5829122e6f..b395696057 100644 --- a/enterprise/integrations/resolver_context.py +++ b/enterprise/integrations/resolver_context.py @@ -29,7 +29,9 @@ class ResolverUserContext(UserContext): return UserInfo(id=user_id) - async def get_authenticated_git_url(self, repository: str) -> str: + async def get_authenticated_git_url( + self, repository: str, is_optional: bool = False + ) -> str: # This would need to be implemented based on the git provider tokens # For now, return a basic HTTPS URL return f'https://github.com/{repository}.git' diff --git a/openhands/app_server/app_conversation/skill_loader.py b/openhands/app_server/app_conversation/skill_loader.py index 88c58fb036..c1cf5df327 100644 --- a/openhands/app_server/app_conversation/skill_loader.py +++ b/openhands/app_server/app_conversation/skill_loader.py @@ -465,7 +465,9 @@ async def _get_org_repository_url( Authenticated Git URL if successful, None otherwise """ try: - remote_url = await user_context.get_authenticated_git_url(org_openhands_repo) + remote_url = await user_context.get_authenticated_git_url( + org_openhands_repo, is_optional=True + ) return remote_url except AuthenticationError as e: _logger.debug( diff --git a/openhands/app_server/user/auth_user_context.py b/openhands/app_server/user/auth_user_context.py index e896fb0356..c6f7df07de 100644 --- a/openhands/app_server/user/auth_user_context.py +++ b/openhands/app_server/user/auth_user_context.py @@ -63,9 +63,13 @@ class AuthUserContext(UserContext): self._provider_handler = provider_handler return provider_handler - async def get_authenticated_git_url(self, repository: str) -> str: + async def get_authenticated_git_url( + self, repository: str, is_optional: bool = False + ) -> str: provider_handler = await self.get_provider_handler() - url = await provider_handler.get_authenticated_git_url(repository) + url = await provider_handler.get_authenticated_git_url( + repository, is_optional=is_optional + ) return url async def get_latest_token(self, provider_type: ProviderType) -> str | None: diff --git a/openhands/app_server/user/specifiy_user_context.py b/openhands/app_server/user/specifiy_user_context.py index 51e6233972..0127d13129 100644 --- a/openhands/app_server/user/specifiy_user_context.py +++ b/openhands/app_server/user/specifiy_user_context.py @@ -21,7 +21,9 @@ class SpecifyUserContext(UserContext): async def get_user_info(self) -> UserInfo: raise NotImplementedError() - async def get_authenticated_git_url(self, repository: str) -> str: + async def get_authenticated_git_url( + self, repository: str, is_optional: bool = False + ) -> str: raise NotImplementedError() async def get_provider_tokens(self) -> PROVIDER_TOKEN_TYPE | None: diff --git a/openhands/app_server/user/user_context.py b/openhands/app_server/user/user_context.py index 4102df5cf9..36aee854ae 100644 --- a/openhands/app_server/user/user_context.py +++ b/openhands/app_server/user/user_context.py @@ -23,8 +23,16 @@ class UserContext(ABC): """Get the user info.""" @abstractmethod - async def get_authenticated_git_url(self, repository: str) -> str: - """Get the provider tokens for the user""" + async def get_authenticated_git_url( + self, repository: str, is_optional: bool = False + ) -> str: + """Get an authenticated git URL for a repository. + + Args: + repository: Repository name (owner/repo) + is_optional: If True, logs at debug level instead of error level + when repository is not found. Use for optional repositories. + """ @abstractmethod async def get_provider_tokens(self) -> PROVIDER_TOKEN_TYPE | None: diff --git a/tests/unit/app_server/test_skill_loader.py b/tests/unit/app_server/test_skill_loader.py index 45ee7c8825..c709b8333f 100644 --- a/tests/unit/app_server/test_skill_loader.py +++ b/tests/unit/app_server/test_skill_loader.py @@ -916,7 +916,7 @@ class TestGetOrgRepositoryUrl: # Assert assert result == expected_url mock_user_context.get_authenticated_git_url.assert_called_once_with( - 'owner/.openhands' + 'owner/.openhands', is_optional=True ) @pytest.mark.asyncio