FEATURE: improve Github tools (#36075)

add some maximum results to file search and handle invalid calls to tool
better
push error message out of tool
This commit is contained in:
Sam
2025-11-18 16:02:17 +11:00
committed by GitHub
parent 7d50a448ec
commit 32af7bd19e
5 changed files with 51 additions and 3 deletions
@@ -561,7 +561,8 @@ module DiscourseAi
rescue => e
if reply_post
details = e.message.to_s
reply = "#{reply}\n\n#{I18n.t("discourse_ai.ai_bot.reply_error", details: details)}"
reply =
"#{reply}#{started_thinking ? "\n\n</details>" : ""}\n\n#{I18n.t("discourse_ai.ai_bot.reply_error", details: details)}"
reply_post.revise(
bot.bot_user,
{ raw: reply },
@@ -58,7 +58,12 @@ module DiscourseAi
end
def invoke
owner, repo = repo_name.split("/")
owner, repo = repo_name.to_s.split("/")
if owner.blank? || repo.blank?
return { error: "Invalid repo_name format. Expected 'owner/repo'." }
end
ref = branch || default_branch
retrieved_entries = []
missing_files = []
@@ -54,6 +54,8 @@ module DiscourseAi
{ repo: repo, keywords: keywords.join(", "), branch: @branch_name }
end
MAX_FILE_SEARCH_RESULTS = 25
def invoke
# Fetch the default branch if no branch is specified
branch_name = branch || fetch_default_branch(repo)
@@ -89,8 +91,15 @@ module DiscourseAi
keywords.any? { |keyword| item["path"].include?(keyword) }
end
.map { |item| item["path"] }
.take(MAX_FILE_SEARCH_RESULTS)
{ matching_files: matching_files, branch: branch_name }
result = { matching_files: matching_files, branch: branch_name }
if matching_files.length == MAX_FILE_SEARCH_RESULTS
result[
:note
] = "Result limit reached (#{MAX_FILE_SEARCH_RESULTS} files). There may be more matching files."
end
result
else
{ error: "Failed to perform file search. Status code: #{response_code}" }
end
@@ -109,6 +109,21 @@ RSpec.describe DiscourseAi::Personas::Tools::GithubFileContent do
expect(result[:file_contents]).to include("File Path: lib/sample.rb (lines 2-3):")
end
end
context "when repo_name is invalid" do
let(:invalid_tool) do
described_class.new(
{ repo_name: "invalid-repo-name", file_paths: ["lib/sample.rb"] },
bot_user: nil,
llm: llm,
)
end
it "returns an error for invalid repo_name format" do
result = invalid_tool.invoke
expect(result[:error]).to eq("Invalid repo_name format. Expected 'owner/repo'.")
end
end
end
describe ".signature" do
@@ -88,5 +88,23 @@ RSpec.describe DiscourseAi::Personas::Tools::GithubSearchFiles do
)
expect(result[:error]).to be_nil
end
it "limits results to MAX_FILE_SEARCH_RESULTS and adds a note when limit is reached" do
max_results = described_class::MAX_FILE_SEARCH_RESULTS
matching_files = (1..max_results + 1).map { |i| "lib/tools/search_tool_#{i}.rb" }
stub_request(
:get,
"https://api.github.com/repos/discourse/discourse-ai/git/trees/#{default_branch}?recursive=1",
).to_return(
status: 200,
body: { tree: matching_files.map { |path| { path: path, type: "blob" } } }.to_json,
)
result = tool.invoke
expect(result[:matching_files].length).to eq(max_results)
expect(result[:note]).to eq(
"Result limit reached (#{max_results} files). There may be more matching files.",
)
end
end
end