Add Bitbucket microagent and backend implementation (#9021)

Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
Co-authored-by: Rohit Malhotra <rohitvinodmalhotra@gmail.com>
This commit is contained in:
Graham Neubig
2025-06-18 00:04:29 -04:00
committed by GitHub
parent b7efeb11d9
commit e074b2d36f
47 changed files with 2174 additions and 115 deletions

View File

@@ -8,6 +8,7 @@ from fastmcp.server.dependencies import get_http_request
from pydantic import Field
from openhands.core.logger import openhands_logger as logger
from openhands.integrations.bitbucket.bitbucket_service import BitbucketService
from openhands.integrations.github.github_service import GithubServiceImpl
from openhands.integrations.gitlab.gitlab_service import GitLabServiceImpl
from openhands.integrations.provider import ProviderToken
@@ -206,3 +207,71 @@ async def create_mr(
raise ToolError(str(error))
return response
@mcp_server.tool()
async def create_bitbucket_pr(
repo_name: Annotated[
str, Field(description='Bitbucket repository (workspace/repo_slug)')
],
source_branch: Annotated[str, Field(description='Source branch on repo')],
target_branch: Annotated[str, Field(description='Target branch on repo')],
title: Annotated[
str,
Field(
description='PR Title. Start title with `DRAFT:` or `WIP:` if applicable.'
),
],
description: Annotated[str | None, Field(description='PR description')],
) -> str:
"""Open a PR in Bitbucket"""
logger.info('Calling OpenHands MCP create_bitbucket_pr')
request = get_http_request()
headers = request.headers
conversation_id = headers.get('X-OpenHands-ServerConversation-ID', None)
provider_tokens = await get_provider_tokens(request)
access_token = await get_access_token(request)
user_id = await get_user_id(request)
bitbucket_token = (
provider_tokens.get(ProviderType.BITBUCKET, ProviderToken())
if provider_tokens
else ProviderToken()
)
bitbucket_service = BitbucketService(
user_id=bitbucket_token.user_id,
external_auth_id=user_id,
external_auth_token=access_token,
token=bitbucket_token.token,
base_domain=bitbucket_token.host,
)
try:
description = await get_convo_link(
bitbucket_service, conversation_id, description or ''
)
except Exception as e:
logger.warning(f'Failed to append convo link: {e}')
try:
response = await bitbucket_service.create_pr(
repo_name=repo_name,
source_branch=source_branch,
target_branch=target_branch,
title=title,
body=description,
)
if conversation_id and user_id:
await save_pr_metadata(user_id, conversation_id, response)
except Exception as e:
error = f'Error creating pull request: {e}'
logger.error(error)
raise ToolError(str(error))
return response