From 023293eed64b6c891d0979be01aaefa2dbeeb0aa Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 18:58:32 +0000 Subject: [PATCH 1/2] Add GitHub view issue tool --- src/codegen/extensions/tools/__init__.py | 1 + .../extensions/tools/github/__init__.py | 1 + .../tools/github/github_view_issue.py | 88 ++++++++++++++++++ .../tools/github/view_github_issue.py | 89 +++++++++++++++++++ 4 files changed, 179 insertions(+) create mode 100644 src/codegen/extensions/tools/__init__.py create mode 100644 src/codegen/extensions/tools/github/__init__.py create mode 100644 src/codegen/extensions/tools/github/github_view_issue.py create mode 100644 src/codegen/extensions/tools/github/view_github_issue.py diff --git a/src/codegen/extensions/tools/__init__.py b/src/codegen/extensions/tools/__init__.py new file mode 100644 index 000000000..1cd3d4f0d --- /dev/null +++ b/src/codegen/extensions/tools/__init__.py @@ -0,0 +1 @@ +"""Tools for Codegen.""" \ No newline at end of file diff --git a/src/codegen/extensions/tools/github/__init__.py b/src/codegen/extensions/tools/github/__init__.py new file mode 100644 index 000000000..d4ad26f35 --- /dev/null +++ b/src/codegen/extensions/tools/github/__init__.py @@ -0,0 +1 @@ +"""GitHub tools for Codegen.""" \ No newline at end of file diff --git a/src/codegen/extensions/tools/github/github_view_issue.py b/src/codegen/extensions/tools/github/github_view_issue.py new file mode 100644 index 000000000..bc3364329 --- /dev/null +++ b/src/codegen/extensions/tools/github/github_view_issue.py @@ -0,0 +1,88 @@ +"""Tool for viewing GitHub issues.""" + +from typing import Dict + +from codegen.sdk.core.codebase import Codebase +from codegen.shared.logging.get_logger import get_logger +from github import Github +from github.GithubException import UnknownObjectException + +logger = get_logger(__name__) + + +def github_view_issue( + codebase: Codebase, + repo_full_name: str, + issue_number: int, +) -> Dict: + """ + View a GitHub issue by its number. + + Args: + codebase: The codebase instance + repo_full_name: The full name of the repository (e.g., "owner/repo") + issue_number: The issue number to view + + Returns: + Dict containing the issue details + """ + try: + # Get GitHub token from environment + token = codebase._op.access_token + if not token: + return {"error": "GitHub token not available"} + + # Initialize GitHub client + g = Github(token) + + try: + # Get repository + repo = g.get_repo(repo_full_name) + + # Get issue + issue = repo.get_issue(issue_number) + + # Format issue data + issue_data = { + "number": issue.number, + "title": issue.title, + "state": issue.state, + "created_at": issue.created_at.isoformat() if issue.created_at else None, + "updated_at": issue.updated_at.isoformat() if issue.updated_at else None, + "closed_at": issue.closed_at.isoformat() if issue.closed_at else None, + "user": { + "login": issue.user.login, + "id": issue.user.id, + "type": issue.user.type, + } if issue.user else None, + "body": issue.body, + "labels": [label.name for label in issue.labels], + "assignees": [assignee.login for assignee in issue.assignees], + "comments_count": issue.comments, + "html_url": issue.html_url, + } + + # Get comments if available + if issue.comments > 0: + comments = [] + for comment in issue.get_comments(): + comments.append({ + "id": comment.id, + "user": comment.user.login if comment.user else None, + "created_at": comment.created_at.isoformat() if comment.created_at else None, + "updated_at": comment.updated_at.isoformat() if comment.updated_at else None, + "body": comment.body, + }) + issue_data["comments"] = comments + + return {"success": True, "issue": issue_data} + + except UnknownObjectException: + return {"success": False, "error": f"Issue #{issue_number} not found in repository {repo_full_name}"} + except Exception as e: + logger.error(f"Error fetching GitHub issue: {str(e)}") + return {"success": False, "error": f"Error fetching GitHub issue: {str(e)}"} + + except Exception as e: + logger.error(f"Error in github_view_issue: {str(e)}") + return {"success": False, "error": f"Error in github_view_issue: {str(e)}"} \ No newline at end of file diff --git a/src/codegen/extensions/tools/github/view_github_issue.py b/src/codegen/extensions/tools/github/view_github_issue.py new file mode 100644 index 000000000..1a4183c3f --- /dev/null +++ b/src/codegen/extensions/tools/github/view_github_issue.py @@ -0,0 +1,89 @@ +"""Tool for viewing GitHub issues.""" + +from typing import Dict, Optional + +from github import Github +from github.GithubException import UnknownObjectException + +from codegen.sdk.core.codebase import Codebase +from codegen.shared.logging.get_logger import get_logger + +logger = get_logger(__name__) + + +def view_github_issue( + codebase: Codebase, + repo_full_name: str, + issue_number: int, +) -> Dict: + """ + View a GitHub issue by its number. + + Args: + codebase: The codebase instance + repo_full_name: The full name of the repository (e.g., "owner/repo") + issue_number: The issue number to view + + Returns: + Dict containing the issue details + """ + try: + # Get GitHub token from environment + token = codebase._op.access_token + if not token: + return {"error": "GitHub token not available"} + + # Initialize GitHub client + g = Github(token) + + try: + # Get repository + repo = g.get_repo(repo_full_name) + + # Get issue + issue = repo.get_issue(issue_number) + + # Format issue data + issue_data = { + "number": issue.number, + "title": issue.title, + "state": issue.state, + "created_at": issue.created_at.isoformat() if issue.created_at else None, + "updated_at": issue.updated_at.isoformat() if issue.updated_at else None, + "closed_at": issue.closed_at.isoformat() if issue.closed_at else None, + "user": { + "login": issue.user.login, + "id": issue.user.id, + "type": issue.user.type, + } if issue.user else None, + "body": issue.body, + "labels": [label.name for label in issue.labels], + "assignees": [assignee.login for assignee in issue.assignees], + "comments_count": issue.comments, + "html_url": issue.html_url, + } + + # Get comments if available + if issue.comments > 0: + comments = [] + for comment in issue.get_comments(): + comments.append({ + "id": comment.id, + "user": comment.user.login if comment.user else None, + "created_at": comment.created_at.isoformat() if comment.created_at else None, + "updated_at": comment.updated_at.isoformat() if comment.updated_at else None, + "body": comment.body, + }) + issue_data["comments"] = comments + + return {"success": True, "issue": issue_data} + + except UnknownObjectException: + return {"success": False, "error": f"Issue #{issue_number} not found in repository {repo_full_name}"} + except Exception as e: + logger.error(f"Error fetching GitHub issue: {str(e)}") + return {"success": False, "error": f"Error fetching GitHub issue: {str(e)}"} + + except Exception as e: + logger.error(f"Error in view_github_issue: {str(e)}") + return {"success": False, "error": f"Error in view_github_issue: {str(e)}"} \ No newline at end of file From 614fae2ae25ca205048923f69d80ba259e2554a8 Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 18:59:26 +0000 Subject: [PATCH 2/2] Automated pre-commit update --- src/codegen/extensions/tools/__init__.py | 2 +- .../extensions/tools/github/__init__.py | 2 +- .../tools/github/github_view_issue.py | 52 ++++++++++--------- .../tools/github/view_github_issue.py | 49 ++++++++--------- 4 files changed, 54 insertions(+), 51 deletions(-) diff --git a/src/codegen/extensions/tools/__init__.py b/src/codegen/extensions/tools/__init__.py index 1cd3d4f0d..06eab34fa 100644 --- a/src/codegen/extensions/tools/__init__.py +++ b/src/codegen/extensions/tools/__init__.py @@ -1 +1 @@ -"""Tools for Codegen.""" \ No newline at end of file +"""Tools for Codegen.""" diff --git a/src/codegen/extensions/tools/github/__init__.py b/src/codegen/extensions/tools/github/__init__.py index d4ad26f35..0f189a7e8 100644 --- a/src/codegen/extensions/tools/github/__init__.py +++ b/src/codegen/extensions/tools/github/__init__.py @@ -1 +1 @@ -"""GitHub tools for Codegen.""" \ No newline at end of file +"""GitHub tools for Codegen.""" diff --git a/src/codegen/extensions/tools/github/github_view_issue.py b/src/codegen/extensions/tools/github/github_view_issue.py index bc3364329..fc521fc93 100644 --- a/src/codegen/extensions/tools/github/github_view_issue.py +++ b/src/codegen/extensions/tools/github/github_view_issue.py @@ -1,11 +1,10 @@ """Tool for viewing GitHub issues.""" -from typing import Dict +from github import Github +from github.GithubException import UnknownObjectException from codegen.sdk.core.codebase import Codebase from codegen.shared.logging.get_logger import get_logger -from github import Github -from github.GithubException import UnknownObjectException logger = get_logger(__name__) @@ -14,9 +13,8 @@ def github_view_issue( codebase: Codebase, repo_full_name: str, issue_number: int, -) -> Dict: - """ - View a GitHub issue by its number. +) -> dict: + """View a GitHub issue by its number. Args: codebase: The codebase instance @@ -34,14 +32,14 @@ def github_view_issue( # Initialize GitHub client g = Github(token) - + try: # Get repository repo = g.get_repo(repo_full_name) - + # Get issue issue = repo.get_issue(issue_number) - + # Format issue data issue_data = { "number": issue.number, @@ -54,35 +52,39 @@ def github_view_issue( "login": issue.user.login, "id": issue.user.id, "type": issue.user.type, - } if issue.user else None, + } + if issue.user + else None, "body": issue.body, "labels": [label.name for label in issue.labels], "assignees": [assignee.login for assignee in issue.assignees], "comments_count": issue.comments, "html_url": issue.html_url, } - + # Get comments if available if issue.comments > 0: comments = [] for comment in issue.get_comments(): - comments.append({ - "id": comment.id, - "user": comment.user.login if comment.user else None, - "created_at": comment.created_at.isoformat() if comment.created_at else None, - "updated_at": comment.updated_at.isoformat() if comment.updated_at else None, - "body": comment.body, - }) + comments.append( + { + "id": comment.id, + "user": comment.user.login if comment.user else None, + "created_at": comment.created_at.isoformat() if comment.created_at else None, + "updated_at": comment.updated_at.isoformat() if comment.updated_at else None, + "body": comment.body, + } + ) issue_data["comments"] = comments - + return {"success": True, "issue": issue_data} - + except UnknownObjectException: return {"success": False, "error": f"Issue #{issue_number} not found in repository {repo_full_name}"} except Exception as e: - logger.error(f"Error fetching GitHub issue: {str(e)}") - return {"success": False, "error": f"Error fetching GitHub issue: {str(e)}"} - + logger.exception(f"Error fetching GitHub issue: {e!s}") + return {"success": False, "error": f"Error fetching GitHub issue: {e!s}"} + except Exception as e: - logger.error(f"Error in github_view_issue: {str(e)}") - return {"success": False, "error": f"Error in github_view_issue: {str(e)}"} \ No newline at end of file + logger.exception(f"Error in github_view_issue: {e!s}") + return {"success": False, "error": f"Error in github_view_issue: {e!s}"} diff --git a/src/codegen/extensions/tools/github/view_github_issue.py b/src/codegen/extensions/tools/github/view_github_issue.py index 1a4183c3f..f56190bdf 100644 --- a/src/codegen/extensions/tools/github/view_github_issue.py +++ b/src/codegen/extensions/tools/github/view_github_issue.py @@ -1,7 +1,5 @@ """Tool for viewing GitHub issues.""" -from typing import Dict, Optional - from github import Github from github.GithubException import UnknownObjectException @@ -15,9 +13,8 @@ def view_github_issue( codebase: Codebase, repo_full_name: str, issue_number: int, -) -> Dict: - """ - View a GitHub issue by its number. +) -> dict: + """View a GitHub issue by its number. Args: codebase: The codebase instance @@ -35,14 +32,14 @@ def view_github_issue( # Initialize GitHub client g = Github(token) - + try: # Get repository repo = g.get_repo(repo_full_name) - + # Get issue issue = repo.get_issue(issue_number) - + # Format issue data issue_data = { "number": issue.number, @@ -55,35 +52,39 @@ def view_github_issue( "login": issue.user.login, "id": issue.user.id, "type": issue.user.type, - } if issue.user else None, + } + if issue.user + else None, "body": issue.body, "labels": [label.name for label in issue.labels], "assignees": [assignee.login for assignee in issue.assignees], "comments_count": issue.comments, "html_url": issue.html_url, } - + # Get comments if available if issue.comments > 0: comments = [] for comment in issue.get_comments(): - comments.append({ - "id": comment.id, - "user": comment.user.login if comment.user else None, - "created_at": comment.created_at.isoformat() if comment.created_at else None, - "updated_at": comment.updated_at.isoformat() if comment.updated_at else None, - "body": comment.body, - }) + comments.append( + { + "id": comment.id, + "user": comment.user.login if comment.user else None, + "created_at": comment.created_at.isoformat() if comment.created_at else None, + "updated_at": comment.updated_at.isoformat() if comment.updated_at else None, + "body": comment.body, + } + ) issue_data["comments"] = comments - + return {"success": True, "issue": issue_data} - + except UnknownObjectException: return {"success": False, "error": f"Issue #{issue_number} not found in repository {repo_full_name}"} except Exception as e: - logger.error(f"Error fetching GitHub issue: {str(e)}") - return {"success": False, "error": f"Error fetching GitHub issue: {str(e)}"} - + logger.exception(f"Error fetching GitHub issue: {e!s}") + return {"success": False, "error": f"Error fetching GitHub issue: {e!s}"} + except Exception as e: - logger.error(f"Error in view_github_issue: {str(e)}") - return {"success": False, "error": f"Error in view_github_issue: {str(e)}"} \ No newline at end of file + logger.exception(f"Error in view_github_issue: {e!s}") + return {"success": False, "error": f"Error in view_github_issue: {e!s}"}