mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
Add get_issue_comments method to GitLabService (#10361)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
parent
587b4c311a
commit
daec23b5d7
@ -1,4 +1,5 @@
|
||||
import os
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
@ -7,6 +8,7 @@ from pydantic import SecretStr
|
||||
from openhands.integrations.service_types import (
|
||||
BaseGitService,
|
||||
Branch,
|
||||
Comment,
|
||||
GitService,
|
||||
OwnerType,
|
||||
ProviderType,
|
||||
@ -673,6 +675,80 @@ class GitLabService(BaseGitService, GitService):
|
||||
# Parse the content to extract triggers from frontmatter
|
||||
return self._parse_microagent_content(response, file_path)
|
||||
|
||||
async def get_issue_comments(
|
||||
self, project_id: str, issue_iid: int, limit: int = 100
|
||||
) -> list[Comment]:
|
||||
"""Get the last n comments for a specific issue.
|
||||
|
||||
Args:
|
||||
project_id: The GitLab project ID (can be numeric ID or URL-encoded path)
|
||||
issue_iid: The issue internal ID (iid) in GitLab
|
||||
limit: Maximum number of comments to retrieve (default: 100)
|
||||
|
||||
Returns:
|
||||
List of Comment objects, ordered by creation date (newest first)
|
||||
|
||||
Raises:
|
||||
UnknownException: If the request fails or the issue is not found
|
||||
"""
|
||||
# URL-encode the project_id if it contains special characters
|
||||
if '/' in str(project_id):
|
||||
encoded_project_id = str(project_id).replace('/', '%2F')
|
||||
else:
|
||||
encoded_project_id = str(project_id)
|
||||
|
||||
url = f'{self.BASE_URL}/projects/{encoded_project_id}/issues/{issue_iid}/notes'
|
||||
|
||||
all_comments: list[Comment] = []
|
||||
page = 1
|
||||
per_page = min(limit, 100) # GitLab API max per_page is 100
|
||||
|
||||
while len(all_comments) < limit:
|
||||
# Get comments with pagination, ordered by creation date descending
|
||||
params = {
|
||||
'per_page': per_page,
|
||||
'page': page,
|
||||
'order_by': 'created_at',
|
||||
'sort': 'desc', # Get newest comments first
|
||||
}
|
||||
|
||||
response, headers = await self._make_request(url, params)
|
||||
|
||||
if not response: # No more comments
|
||||
break
|
||||
|
||||
# Filter out system comments and convert to Comment objects
|
||||
for comment_data in response:
|
||||
if len(all_comments) >= limit:
|
||||
break
|
||||
|
||||
# Skip system-generated comments unless explicitly requested
|
||||
if comment_data.get('system', False):
|
||||
continue
|
||||
|
||||
comment = Comment(
|
||||
id=comment_data['id'],
|
||||
body=comment_data['body'],
|
||||
author=comment_data.get('author', {}).get('username', 'unknown'),
|
||||
created_at=datetime.fromisoformat(
|
||||
comment_data['created_at'].replace('Z', '+00:00')
|
||||
),
|
||||
updated_at=datetime.fromisoformat(
|
||||
comment_data['updated_at'].replace('Z', '+00:00')
|
||||
),
|
||||
system=comment_data.get('system', False),
|
||||
)
|
||||
all_comments.append(comment)
|
||||
|
||||
# Check if we have more pages
|
||||
link_header = headers.get('Link', '')
|
||||
if 'rel="next"' not in link_header or len(all_comments) >= limit:
|
||||
break
|
||||
|
||||
page += 1
|
||||
|
||||
return all_comments
|
||||
|
||||
|
||||
gitlab_service_cls = os.environ.get(
|
||||
'OPENHANDS_GITLAB_SERVICE_CLS',
|
||||
|
||||
@ -140,6 +140,15 @@ class Repository(BaseModel):
|
||||
main_branch: str | None = None # The main/default branch of the repository
|
||||
|
||||
|
||||
class Comment(BaseModel):
|
||||
id: int
|
||||
body: str
|
||||
author: str
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
system: bool = False # Whether this is a system-generated comment
|
||||
|
||||
|
||||
class AuthenticationError(ValueError):
|
||||
"""Raised when there is an issue with GitHub authentication."""
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user