mirror of
https://github.com/hwchase17/langchain.git
synced 2025-06-25 16:13:25 +00:00
community: adds support for getting github releases for the configured repository (#29318)
**Description:** adds support for github tool to query github releases on the configure respository **Issue:** N/A **Dependencies:** N/A **Twitter handle:** @macsdickinson --------- Co-authored-by: Chester Curme <chester.curme@gmail.com>
This commit is contained in:
parent
ef1610e24a
commit
7378c955db
@ -200,6 +200,37 @@
|
|||||||
"8. **Delete File**- deletes a file from the repository."
|
"8. **Delete File**- deletes a file from the repository."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Include release tools\n",
|
||||||
|
"\n",
|
||||||
|
"By default, the toolkit does not include release-related tools. You can include them by setting `include_release_tools=True` when initializing the toolkit:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"toolkit = GitHubToolkit.from_github_api_wrapper(github, include_release_tools=True)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Settings `include_release_tools=True` will include the following tools:\n",
|
||||||
|
"\n",
|
||||||
|
"* **Get Latest Release**- fetches the latest release from the repository.\n",
|
||||||
|
"\n",
|
||||||
|
"* **Get Releases**- fetches the latest 5 releases from the repository.\n",
|
||||||
|
"\n",
|
||||||
|
"* **Get Release**- fetches a specific release from the repository by tag name, e.g. `v1.0.0`.\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@ -321,7 +352,7 @@
|
|||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.10.4"
|
"version": "3.13.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
|
@ -16,7 +16,10 @@ from langchain_community.tools.github.prompt import (
|
|||||||
GET_FILES_FROM_DIRECTORY_PROMPT,
|
GET_FILES_FROM_DIRECTORY_PROMPT,
|
||||||
GET_ISSUE_PROMPT,
|
GET_ISSUE_PROMPT,
|
||||||
GET_ISSUES_PROMPT,
|
GET_ISSUES_PROMPT,
|
||||||
|
GET_LATEST_RELEASE_PROMPT,
|
||||||
GET_PR_PROMPT,
|
GET_PR_PROMPT,
|
||||||
|
GET_RELEASE_PROMPT,
|
||||||
|
GET_RELEASES_PROMPT,
|
||||||
LIST_BRANCHES_IN_REPO_PROMPT,
|
LIST_BRANCHES_IN_REPO_PROMPT,
|
||||||
LIST_PRS_PROMPT,
|
LIST_PRS_PROMPT,
|
||||||
LIST_PULL_REQUEST_FILES,
|
LIST_PULL_REQUEST_FILES,
|
||||||
@ -152,6 +155,15 @@ class SearchIssuesAndPRs(BaseModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TagName(BaseModel):
|
||||||
|
"""Schema for operations that require a tag name as input."""
|
||||||
|
|
||||||
|
tag_name: str = Field(
|
||||||
|
...,
|
||||||
|
description="The tag name of the release, e.g. `v1.0.0`.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class GitHubToolkit(BaseToolkit):
|
class GitHubToolkit(BaseToolkit):
|
||||||
"""GitHub Toolkit.
|
"""GitHub Toolkit.
|
||||||
|
|
||||||
@ -218,6 +230,25 @@ class GitHubToolkit(BaseToolkit):
|
|||||||
Search code
|
Search code
|
||||||
Create review request
|
Create review request
|
||||||
|
|
||||||
|
Include release tools:
|
||||||
|
By default, the toolkit does not include release-related tools.
|
||||||
|
You can include them by setting ``include_release_tools=True`` when
|
||||||
|
initializing the toolkit:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
toolkit = GitHubToolkit.from_github_api_wrapper(
|
||||||
|
github, include_release_tools=True
|
||||||
|
)
|
||||||
|
|
||||||
|
Setting ``include_release_tools=True`` will include the following tools:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
Get latest release
|
||||||
|
Get releases
|
||||||
|
Get release
|
||||||
|
|
||||||
Use within an agent:
|
Use within an agent:
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
@ -268,12 +299,14 @@ class GitHubToolkit(BaseToolkit):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_github_api_wrapper(
|
def from_github_api_wrapper(
|
||||||
cls, github_api_wrapper: GitHubAPIWrapper
|
cls, github_api_wrapper: GitHubAPIWrapper, include_release_tools: bool = False
|
||||||
) -> "GitHubToolkit":
|
) -> "GitHubToolkit":
|
||||||
"""Create a GitHubToolkit from a GitHubAPIWrapper.
|
"""Create a GitHubToolkit from a GitHubAPIWrapper.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
github_api_wrapper: GitHubAPIWrapper. The GitHub API wrapper.
|
github_api_wrapper: GitHubAPIWrapper. The GitHub API wrapper.
|
||||||
|
include_release_tools: bool. Whether to include release-related tools.
|
||||||
|
Defaults to False.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
GitHubToolkit. The GitHub toolkit.
|
GitHubToolkit. The GitHub toolkit.
|
||||||
@ -406,6 +439,29 @@ class GitHubToolkit(BaseToolkit):
|
|||||||
"args_schema": CreateReviewRequest,
|
"args_schema": CreateReviewRequest,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
release_operations: List[Dict] = [
|
||||||
|
{
|
||||||
|
"mode": "get_latest_release",
|
||||||
|
"name": "Get latest release",
|
||||||
|
"description": GET_LATEST_RELEASE_PROMPT,
|
||||||
|
"args_schema": NoInput,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "get_releases",
|
||||||
|
"name": "Get releases",
|
||||||
|
"description": GET_RELEASES_PROMPT,
|
||||||
|
"args_schema": NoInput,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "get_release",
|
||||||
|
"name": "Get release",
|
||||||
|
"description": GET_RELEASE_PROMPT,
|
||||||
|
"args_schema": TagName,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = operations + (release_operations if include_release_tools else [])
|
||||||
tools = [
|
tools = [
|
||||||
GitHubAction(
|
GitHubAction(
|
||||||
name=action["name"],
|
name=action["name"],
|
||||||
|
@ -98,3 +98,12 @@ This tool will create a new branch in the repository. **VERY IMPORTANT**: You mu
|
|||||||
|
|
||||||
GET_FILES_FROM_DIRECTORY_PROMPT = """
|
GET_FILES_FROM_DIRECTORY_PROMPT = """
|
||||||
This tool will fetch a list of all files in a specified directory. **VERY IMPORTANT**: You must specify the path of the directory as a string input parameter."""
|
This tool will fetch a list of all files in a specified directory. **VERY IMPORTANT**: You must specify the path of the directory as a string input parameter."""
|
||||||
|
|
||||||
|
GET_LATEST_RELEASE_PROMPT = """
|
||||||
|
This tool will fetch the latest release of the repository. No input parameters are required."""
|
||||||
|
|
||||||
|
GET_RELEASES_PROMPT = """
|
||||||
|
This tool will fetch the latest 5 releases of the repository. No input parameters are required."""
|
||||||
|
|
||||||
|
GET_RELEASE_PROMPT = """
|
||||||
|
This tool will fetch a specific release of the repository. **VERY IMPORTANT**: You must specify the tag name of the release as a string input parameter."""
|
||||||
|
@ -813,6 +813,56 @@ class GitHubAPIWrapper(BaseModel):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"Failed to create a review request with error {e}"
|
return f"Failed to create a review request with error {e}"
|
||||||
|
|
||||||
|
def get_latest_release(self) -> str:
|
||||||
|
"""
|
||||||
|
Fetches the latest release of the repository.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The latest release
|
||||||
|
"""
|
||||||
|
release = self.github_repo_instance.get_latest_release()
|
||||||
|
return (
|
||||||
|
f"Latest title: {release.title} "
|
||||||
|
f"tag: {release.tag_name} "
|
||||||
|
f"body: {release.body}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_releases(self) -> str:
|
||||||
|
"""
|
||||||
|
Fetches all releases of the repository.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The releases
|
||||||
|
"""
|
||||||
|
releases = self.github_repo_instance.get_releases()
|
||||||
|
max_results = min(5, releases.totalCount)
|
||||||
|
results = [f"Top {max_results} results:"]
|
||||||
|
for release in releases[:max_results]:
|
||||||
|
results.append(
|
||||||
|
f"Title: {release.title}, "
|
||||||
|
f"Tag: {release.tag_name}, "
|
||||||
|
f"Body: {release.body}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return "\n".join(results)
|
||||||
|
|
||||||
|
def get_release(self, tag_name: str) -> str:
|
||||||
|
"""
|
||||||
|
Fetches a specific release of the repository.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
tag_name(str): The tag name of the release
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The release
|
||||||
|
"""
|
||||||
|
release = self.github_repo_instance.get_release(tag_name)
|
||||||
|
return (
|
||||||
|
f"Release: {release.title} "
|
||||||
|
f"tag: {release.tag_name} "
|
||||||
|
f"body: {release.body}"
|
||||||
|
)
|
||||||
|
|
||||||
def run(self, mode: str, query: str) -> str:
|
def run(self, mode: str, query: str) -> str:
|
||||||
if mode == "get_issue":
|
if mode == "get_issue":
|
||||||
return json.dumps(self.get_issue(int(query)))
|
return json.dumps(self.get_issue(int(query)))
|
||||||
@ -854,5 +904,11 @@ class GitHubAPIWrapper(BaseModel):
|
|||||||
return self.search_code(query)
|
return self.search_code(query)
|
||||||
elif mode == "create_review_request":
|
elif mode == "create_review_request":
|
||||||
return self.create_review_request(query)
|
return self.create_review_request(query)
|
||||||
|
elif mode == "get_latest_release":
|
||||||
|
return self.get_latest_release()
|
||||||
|
elif mode == "get_releases":
|
||||||
|
return self.get_releases()
|
||||||
|
elif mode == "get_release":
|
||||||
|
return self.get_release(query)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Invalid mode" + mode)
|
raise ValueError("Invalid mode" + mode)
|
||||||
|
@ -22,6 +22,18 @@ def test_get_open_issues(api_client: GitHubAPIWrapper) -> None:
|
|||||||
assert len(issues) != 0
|
assert len(issues) != 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_latest_release(api_client: GitHubAPIWrapper) -> None:
|
||||||
|
"""Basic test to fetch latest release"""
|
||||||
|
release = api_client.get_latest_release()
|
||||||
|
assert release is not None
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_releases(api_client: GitHubAPIWrapper) -> None:
|
||||||
|
"""Basic test to fetch releases"""
|
||||||
|
releases = api_client.get_releases()
|
||||||
|
assert releases is not None
|
||||||
|
|
||||||
|
|
||||||
def test_search_issues_and_prs(api_client: GitHubAPIWrapper) -> None:
|
def test_search_issues_and_prs(api_client: GitHubAPIWrapper) -> None:
|
||||||
"""Basic test to search issues and PRs"""
|
"""Basic test to search issues and PRs"""
|
||||||
results = api_client.search_issues_and_prs("is:pr is:merged")
|
results = api_client.search_issues_and_prs("is:pr is:merged")
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from langchain_community.agent_toolkits.github.toolkit import GitHubToolkit
|
||||||
|
from langchain_community.utilities.github import GitHubAPIWrapper
|
||||||
|
|
||||||
|
|
||||||
|
def test_github_toolkit() -> None:
|
||||||
|
# Create a mock GitHub wrapper with required attributes
|
||||||
|
mock_github = MagicMock(spec=GitHubAPIWrapper)
|
||||||
|
mock_github.github_repository = "fake/repo"
|
||||||
|
mock_github.github_app_id = "fake_id"
|
||||||
|
mock_github.github_app_private_key = "fake_key"
|
||||||
|
mock_github.active_branch = "main"
|
||||||
|
mock_github.github_base_branch = "main"
|
||||||
|
|
||||||
|
# Test without release tools
|
||||||
|
toolkit = GitHubToolkit.from_github_api_wrapper(mock_github)
|
||||||
|
tools = toolkit.get_tools()
|
||||||
|
assert len(tools) == 21 # Base number of tools
|
||||||
|
|
||||||
|
# Test with release tools
|
||||||
|
toolkit_with_releases = GitHubToolkit.from_github_api_wrapper(
|
||||||
|
mock_github, include_release_tools=True
|
||||||
|
)
|
||||||
|
tools_with_releases = toolkit_with_releases.get_tools()
|
||||||
|
assert len(tools_with_releases) == 24 # Base tools + 3 release tools
|
Loading…
Reference in New Issue
Block a user