fix:Fix a bug that returns null when the passed path is a file. (#12775)

Co-authored-by: 刘江波 <jiangbo721@163.com>
This commit is contained in:
jiangbo721 2025-01-22 10:10:03 +08:00 committed by GitHub
parent 162a8c4393
commit 2f41bd495d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 45 deletions

View File

@ -11,19 +11,21 @@ class GitlabFilesTool(BuiltinTool):
def _invoke( def _invoke(
self, user_id: str, tool_parameters: dict[str, Any] self, user_id: str, tool_parameters: dict[str, Any]
) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
project = tool_parameters.get("project", "")
repository = tool_parameters.get("repository", "") repository = tool_parameters.get("repository", "")
project = tool_parameters.get("project", "")
branch = tool_parameters.get("branch", "") branch = tool_parameters.get("branch", "")
path = tool_parameters.get("path", "") path = tool_parameters.get("path", "")
file_path = tool_parameters.get("file_path", "")
if not project and not repository: if not repository and not project:
return self.create_text_message("Either project or repository is required") return self.create_text_message("Either repository or project is required")
if not branch: if not branch:
return self.create_text_message("Branch is required") return self.create_text_message("Branch is required")
if not path: if not path and not file_path:
return self.create_text_message("Path is required") return self.create_text_message("Either path or file_path is required")
access_token = self.runtime.credentials.get("access_tokens") access_token = self.runtime.credentials.get("access_tokens")
headers = {"PRIVATE-TOKEN": access_token}
site_url = self.runtime.credentials.get("site_url") site_url = self.runtime.credentials.get("site_url")
if "access_tokens" not in self.runtime.credentials or not self.runtime.credentials.get("access_tokens"): if "access_tokens" not in self.runtime.credentials or not self.runtime.credentials.get("access_tokens"):
@ -31,33 +33,45 @@ class GitlabFilesTool(BuiltinTool):
if "site_url" not in self.runtime.credentials or not self.runtime.credentials.get("site_url"): if "site_url" not in self.runtime.credentials or not self.runtime.credentials.get("site_url"):
site_url = "https://gitlab.com" site_url = "https://gitlab.com"
# Get file content
if repository: if repository:
result = self.fetch_files(site_url, access_token, repository, branch, path, is_repository=True) # URL encode the repository path
identifier = urllib.parse.quote(repository, safe="")
else: else:
result = self.fetch_files(site_url, access_token, project, branch, path, is_repository=False) identifier = self.get_project_id(site_url, access_token, project)
if not identifier:
raise Exception(f"Project '{project}' not found.)")
return [self.create_json_message(item) for item in result] # Get file content
if path:
results = self.fetch_files(site_url, headers, identifier, branch, path)
return [self.create_json_message(item) for item in results]
else:
result = self.fetch_file(site_url, headers, identifier, branch, file_path)
return [self.create_json_message(result)]
@staticmethod
def fetch_file(
site_url: str,
headers: dict[str, str],
identifier: str,
branch: str,
path: str,
) -> dict[str, Any]:
encoded_file_path = urllib.parse.quote(path, safe="")
file_url = f"{site_url}/api/v4/projects/{identifier}/repository/files/{encoded_file_path}/raw?ref={branch}"
file_response = requests.get(file_url, headers=headers)
file_response.raise_for_status()
file_content = file_response.text
return {"path": path, "branch": branch, "content": file_content}
def fetch_files( def fetch_files(
self, site_url: str, access_token: str, identifier: str, branch: str, path: str, is_repository: bool self, site_url: str, headers: dict[str, str], identifier: str, branch: str, path: str
) -> list[dict[str, Any]]: ) -> list[dict[str, Any]]:
domain = site_url
headers = {"PRIVATE-TOKEN": access_token}
results = [] results = []
try: try:
if is_repository: tree_url = f"{site_url}/api/v4/projects/{identifier}/repository/tree?path={path}&ref={branch}"
# URL encode the repository path
encoded_identifier = urllib.parse.quote(identifier, safe="")
tree_url = f"{domain}/api/v4/projects/{encoded_identifier}/repository/tree?path={path}&ref={branch}"
else:
# Get project ID from project name
project_id = self.get_project_id(site_url, access_token, identifier)
if not project_id:
return self.create_text_message(f"Project '{identifier}' not found.")
tree_url = f"{domain}/api/v4/projects/{project_id}/repository/tree?path={path}&ref={branch}"
response = requests.get(tree_url, headers=headers) response = requests.get(tree_url, headers=headers)
response.raise_for_status() response.raise_for_status()
items = response.json() items = response.json()
@ -65,26 +79,10 @@ class GitlabFilesTool(BuiltinTool):
for item in items: for item in items:
item_path = item["path"] item_path = item["path"]
if item["type"] == "tree": # It's a directory if item["type"] == "tree": # It's a directory
results.extend( results.extend(self.fetch_files(site_url, headers, identifier, branch, item_path))
self.fetch_files(site_url, access_token, identifier, branch, item_path, is_repository)
)
else: # It's a file else: # It's a file
encoded_item_path = urllib.parse.quote(item_path, safe="") result = self.fetch_file(site_url, headers, identifier, branch, item_path)
if is_repository: results.append(result)
file_url = (
f"{domain}/api/v4/projects/{encoded_identifier}/repository/files"
f"/{encoded_item_path}/raw?ref={branch}"
)
else:
file_url = (
f"{domain}/api/v4/projects/{project_id}/repository/files"
f"{encoded_item_path}/raw?ref={branch}"
)
file_response = requests.get(file_url, headers=headers)
file_response.raise_for_status()
file_content = file_response.text
results.append({"path": item_path, "branch": branch, "content": file_content})
except requests.RequestException as e: except requests.RequestException as e:
print(f"Error fetching data from GitLab: {e}") print(f"Error fetching data from GitLab: {e}")

View File

@ -29,7 +29,7 @@ parameters:
zh_Hans: 项目 zh_Hans: 项目
human_description: human_description:
en_US: project en_US: project
zh_Hans: 项目 zh_Hans: 项目(和仓库路径二选一,都填写以仓库路径优先)
llm_description: Project for GitLab llm_description: Project for GitLab
form: llm form: llm
- name: branch - name: branch
@ -45,12 +45,21 @@ parameters:
form: llm form: llm
- name: path - name: path
type: string type: string
required: true
label: label:
en_US: path en_US: path
zh_Hans: 文件路径 zh_Hans: 文件
human_description: human_description:
en_US: path en_US: path
zh_Hans: 文件夹
llm_description: Dir path for GitLab
form: llm
- name: file_path
type: string
label:
en_US: file_path
zh_Hans: 文件路径 zh_Hans: 文件路径
human_description:
en_US: file_path
zh_Hans: 文件路径(和文件夹二选一,都填写以文件夹优先)
llm_description: File path for GitLab llm_description: File path for GitLab
form: llm form: llm