Feat/tools/gitlab (#10407)
parent
0e8ab0588f
commit
c9f785e00f
@ -0,0 +1,78 @@
|
||||
import urllib.parse
|
||||
from typing import Any, Union
|
||||
|
||||
import requests
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
|
||||
|
||||
class GitlabMergeRequestsTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self, user_id: str, tool_parameters: dict[str, Any]
|
||||
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
|
||||
repository = tool_parameters.get("repository", "")
|
||||
branch = tool_parameters.get("branch", "")
|
||||
start_time = tool_parameters.get("start_time", "")
|
||||
end_time = tool_parameters.get("end_time", "")
|
||||
state = tool_parameters.get("state", "opened") # Default to "opened"
|
||||
|
||||
if not repository:
|
||||
return self.create_text_message("Repository is required")
|
||||
|
||||
access_token = self.runtime.credentials.get("access_tokens")
|
||||
site_url = self.runtime.credentials.get("site_url")
|
||||
|
||||
if not access_token:
|
||||
return self.create_text_message("Gitlab API Access Tokens is required.")
|
||||
if not site_url:
|
||||
site_url = "https://gitlab.com"
|
||||
|
||||
# Get merge requests
|
||||
result = self.get_merge_requests(site_url, access_token, repository, branch, start_time, end_time, state)
|
||||
|
||||
return [self.create_json_message(item) for item in result]
|
||||
|
||||
def get_merge_requests(
|
||||
self, site_url: str, access_token: str, repository: str, branch: str, start_time: str, end_time: str, state: str
|
||||
) -> list[dict[str, Any]]:
|
||||
domain = site_url
|
||||
headers = {"PRIVATE-TOKEN": access_token}
|
||||
results = []
|
||||
|
||||
try:
|
||||
# URL encode the repository path
|
||||
encoded_repository = urllib.parse.quote(repository, safe="")
|
||||
merge_requests_url = f"{domain}/api/v4/projects/{encoded_repository}/merge_requests"
|
||||
params = {"state": state}
|
||||
|
||||
# Add time filters if provided
|
||||
if start_time:
|
||||
params["created_after"] = start_time
|
||||
if end_time:
|
||||
params["created_before"] = end_time
|
||||
|
||||
response = requests.get(merge_requests_url, headers=headers, params=params)
|
||||
response.raise_for_status()
|
||||
merge_requests = response.json()
|
||||
|
||||
for mr in merge_requests:
|
||||
# Filter by target branch
|
||||
if branch and mr["target_branch"] != branch:
|
||||
continue
|
||||
|
||||
results.append(
|
||||
{
|
||||
"id": mr["id"],
|
||||
"title": mr["title"],
|
||||
"author": mr["author"]["name"],
|
||||
"web_url": mr["web_url"],
|
||||
"target_branch": mr["target_branch"],
|
||||
"created_at": mr["created_at"],
|
||||
"state": mr["state"],
|
||||
}
|
||||
)
|
||||
except requests.RequestException as e:
|
||||
print(f"Error fetching merge requests from GitLab: {e}")
|
||||
|
||||
return results
|
||||
@ -0,0 +1,81 @@
|
||||
import urllib.parse
|
||||
from typing import Any, Union
|
||||
|
||||
import requests
|
||||
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
from core.tools.tool.builtin_tool import BuiltinTool
|
||||
|
||||
|
||||
class GitlabProjectsTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self, user_id: str, tool_parameters: dict[str, Any]
|
||||
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
|
||||
project_name = tool_parameters.get("project_name", "")
|
||||
page = tool_parameters.get("page", 1)
|
||||
page_size = tool_parameters.get("page_size", 20)
|
||||
|
||||
access_token = self.runtime.credentials.get("access_tokens")
|
||||
site_url = self.runtime.credentials.get("site_url")
|
||||
|
||||
if not access_token:
|
||||
return self.create_text_message("Gitlab API Access Tokens is required.")
|
||||
if not site_url:
|
||||
site_url = "https://gitlab.com"
|
||||
|
||||
# Get project content
|
||||
result = self.fetch_projects(site_url, access_token, project_name, page, page_size)
|
||||
|
||||
return [self.create_json_message(item) for item in result]
|
||||
|
||||
def fetch_projects(
|
||||
self,
|
||||
site_url: str,
|
||||
access_token: str,
|
||||
project_name: str,
|
||||
page: str,
|
||||
page_size: str,
|
||||
) -> list[dict[str, Any]]:
|
||||
domain = site_url
|
||||
headers = {"PRIVATE-TOKEN": access_token}
|
||||
results = []
|
||||
|
||||
try:
|
||||
if project_name:
|
||||
# URL encode the project name for the search query
|
||||
encoded_project_name = urllib.parse.quote(project_name, safe="")
|
||||
projects_url = (
|
||||
f"{domain}/api/v4/projects?search={encoded_project_name}&page={page}&per_page={page_size}"
|
||||
)
|
||||
else:
|
||||
projects_url = f"{domain}/api/v4/projects?page={page}&per_page={page_size}"
|
||||
|
||||
response = requests.get(projects_url, headers=headers)
|
||||
response.raise_for_status()
|
||||
projects = response.json()
|
||||
|
||||
for project in projects:
|
||||
# Filter projects by exact name match if necessary
|
||||
if project_name and project["name"].lower() == project_name.lower():
|
||||
results.append(
|
||||
{
|
||||
"id": project["id"],
|
||||
"name": project["name"],
|
||||
"description": project.get("description", ""),
|
||||
"web_url": project["web_url"],
|
||||
}
|
||||
)
|
||||
elif not project_name:
|
||||
# If no specific project name is provided, add all projects
|
||||
results.append(
|
||||
{
|
||||
"id": project["id"],
|
||||
"name": project["name"],
|
||||
"description": project.get("description", ""),
|
||||
"web_url": project["web_url"],
|
||||
}
|
||||
)
|
||||
except requests.RequestException as e:
|
||||
print(f"Error fetching data from GitLab: {e}")
|
||||
|
||||
return results
|
||||
@ -0,0 +1,45 @@
|
||||
identity:
|
||||
name: gitlab_projects
|
||||
author: Leo.Wang
|
||||
label:
|
||||
en_US: GitLab Projects
|
||||
zh_Hans: GitLab 项目列表查询
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for query GitLab projects, Input should be a project name.
|
||||
zh_Hans: 一个用于查询 GitLab 项目列表的工具,输入的内容应该是一个项目名称。
|
||||
llm: A tool for query GitLab projects, Input should be a project name.
|
||||
parameters:
|
||||
- name: project_name
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: project_name
|
||||
zh_Hans: 项目名称
|
||||
human_description:
|
||||
en_US: project_name
|
||||
zh_Hans: 项目名称
|
||||
llm_description: Project name for GitLab
|
||||
form: llm
|
||||
- name: page
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: page
|
||||
zh_Hans: 页码
|
||||
human_description:
|
||||
en_US: page
|
||||
zh_Hans: 页码
|
||||
llm_description: Page index for GitLab
|
||||
form: llm
|
||||
- name: page_size
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: page_size
|
||||
zh_Hans: 每页数量
|
||||
human_description:
|
||||
en_US: page_size
|
||||
zh_Hans: 每页数量
|
||||
llm_description: Page size for GitLab
|
||||
form: llm
|
||||
Loading…
Reference in New Issue