103 lines
2.9 KiB
Ruby
103 lines
2.9 KiB
Ruby
# frozen_string_literal: true
|
|
module DiscourseAi
|
|
module AiBot
|
|
module Tools
|
|
class GithubFileContent < Tool
|
|
def self.signature
|
|
{
|
|
name: name,
|
|
description: "Retrieves the content of specified GitHub files",
|
|
parameters: [
|
|
{
|
|
name: "repo_name",
|
|
description: "The name of the GitHub repository (e.g., 'discourse/discourse')",
|
|
type: "string",
|
|
required: true,
|
|
},
|
|
{
|
|
name: "file_paths",
|
|
description: "The paths of the files to retrieve within the repository",
|
|
type: "array",
|
|
item_type: "string",
|
|
required: true,
|
|
},
|
|
{
|
|
name: "branch",
|
|
description:
|
|
"The branch or commit SHA to retrieve the files from (default: 'main')",
|
|
type: "string",
|
|
required: false,
|
|
},
|
|
],
|
|
}
|
|
end
|
|
|
|
def self.name
|
|
"github_file_content"
|
|
end
|
|
|
|
def repo_name
|
|
parameters[:repo_name]
|
|
end
|
|
|
|
def file_paths
|
|
parameters[:file_paths]
|
|
end
|
|
|
|
def branch
|
|
parameters[:branch] || "main"
|
|
end
|
|
|
|
def description_args
|
|
{ repo_name: repo_name, file_paths: file_paths.join(", "), branch: branch }
|
|
end
|
|
|
|
def invoke(_bot_user, llm)
|
|
owner, repo = repo_name.split("/")
|
|
file_contents = {}
|
|
missing_files = []
|
|
|
|
file_paths.each do |file_path|
|
|
api_url =
|
|
"https://api.github.com/repos/#{owner}/#{repo}/contents/#{file_path}?ref=#{branch}"
|
|
|
|
response_code = "-1 unknown"
|
|
body = nil
|
|
|
|
send_http_request(
|
|
api_url,
|
|
headers: {
|
|
"Accept" => "application/vnd.github.v3+json",
|
|
},
|
|
authenticate_github: true,
|
|
) do |response|
|
|
response_code = response.code
|
|
body = read_response_body(response)
|
|
end
|
|
|
|
if response_code == "200"
|
|
file_data = JSON.parse(body)
|
|
content = Base64.decode64(file_data["content"])
|
|
file_contents[file_path] = content
|
|
else
|
|
missing_files << file_path
|
|
end
|
|
end
|
|
|
|
result = {}
|
|
unless file_contents.empty?
|
|
blob =
|
|
file_contents.map { |path, content| "File Path: #{path}:\n#{content}" }.join("\n")
|
|
truncated_blob = truncate(blob, max_length: 20_000, percent_length: 0.3, llm: llm)
|
|
result[:file_contents] = truncated_blob
|
|
end
|
|
|
|
result[:missing_files] = missing_files unless missing_files.empty?
|
|
|
|
result.empty? ? { error: "No files found or retrieved." } : result
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|