discourse-ai/lib/ai_bot/tools/github_search_files.rb

102 lines
2.8 KiB
Ruby

# frozen_string_literal: true
module DiscourseAi
module AiBot
module Tools
class GithubSearchFiles < Tool
def self.signature
{
name: name,
description:
"Searches for files in a GitHub repository containing specific keywords in their paths or names",
parameters: [
{
name: "repo",
description: "The repository name in the format 'owner/repo'",
type: "string",
required: true,
},
{
name: "keywords",
description: "An array of keywords to match in file paths or names",
type: "array",
item_type: "string",
required: true,
},
{
name: "branch",
description:
"The branch or commit SHA to search within (default: repository's default branch)",
type: "string",
required: false,
},
],
}
end
def self.name
"github_search_files"
end
def repo
parameters[:repo]
end
def keywords
parameters[:keywords]
end
def branch
parameters[:branch]
end
def description_args
{ repo: repo, keywords: keywords.join(", "), branch: @branch_name }
end
def invoke
# Fetch the default branch if no branch is specified
branch_name = branch || fetch_default_branch(repo)
@branch_name = branch_name
api_url = "https://api.github.com/repos/#{repo}/git/trees/#{branch_name}?recursive=1"
response_code = "unknown error"
tree_data = nil
send_http_request(
api_url,
headers: {
"Accept" => "application/vnd.github.v3+json",
},
authenticate_github: true,
) do |response|
response_code = response.code
if response_code == "200"
begin
tree_data = JSON.parse(read_response_body(response))
rescue JSON::ParserError
response_code = "500 - JSON parse error"
end
end
end
if response_code == "200"
matching_files =
tree_data["tree"]
.select do |item|
item["type"] == "blob" &&
keywords.any? { |keyword| item["path"].include?(keyword) }
end
.map { |item| item["path"] }
{ matching_files: matching_files, branch: branch_name }
else
{ error: "Failed to perform file search. Status code: #{response_code}" }
end
end
end
end
end
end