Skip to content

Commit a3460a9

Browse files
committed
Do file matching when raw API returns error
1 parent f663214 commit a3460a9

File tree

1 file changed

+36
-27
lines changed

1 file changed

+36
-27
lines changed

pkg/github/repositories.go

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,6 @@ func GetFileContents(getClient GetClientFn, getRawClient raw.GetRawClientFn, t t
612612
ref = rawOpts.SHA
613613
}
614614

615-
var rawAPIResponseCode int
616615
var fileSHA string
617616
opts := &github.RepositoryContentGetOptions{Ref: ref}
618617

@@ -625,32 +624,7 @@ func GetFileContents(getClient GetClientFn, getRawClient raw.GetRawClientFn, t t
625624
// The path does not point to a file or directory.
626625
// Instead let's try to find it in the Git Tree by matching the end of the path.
627626
if err != nil || (fileContent == nil && dirContent == nil) {
628-
// Step 1: Get Git Tree recursively
629-
tree, response, err := client.Git.GetTree(ctx, owner, repo, ref, true)
630-
if err != nil {
631-
return ghErrors.NewGitHubAPIErrorResponse(ctx,
632-
"failed to get git tree",
633-
response,
634-
err,
635-
), nil, nil
636-
}
637-
defer func() { _ = response.Body.Close() }()
638-
639-
// Step 2: Filter tree for matching paths
640-
const maxMatchingFiles = 3
641-
matchingFiles := filterPaths(tree.Entries, path, maxMatchingFiles)
642-
if len(matchingFiles) > 0 {
643-
matchingFilesJSON, err := json.Marshal(matchingFiles)
644-
if err != nil {
645-
return utils.NewToolResultError(fmt.Sprintf("failed to marshal matching files: %s", err)), nil, nil
646-
}
647-
resolvedRefs, err := json.Marshal(rawOpts)
648-
if err != nil {
649-
return utils.NewToolResultError(fmt.Sprintf("failed to marshal resolved refs: %s", err)), nil, nil
650-
}
651-
return utils.NewToolResultError(fmt.Sprintf("Resolved potential matches in the repository tree (resolved refs: %s, matching files: %s), but the raw content API returned an unexpected status code %d.", string(resolvedRefs), string(matchingFilesJSON), rawAPIResponseCode)), nil, nil
652-
}
653-
return utils.NewToolResultError("Failed to get file contents. The path does not point to a file or directory, or the file does not exist in the repository."), nil, nil
627+
return matchFiles(ctx, client, owner, repo, ref, path, rawOpts, 0)
654628
}
655629

656630
if fileContent != nil && fileContent.SHA != nil {
@@ -726,6 +700,9 @@ func GetFileContents(getClient GetClientFn, getRawClient raw.GetRawClientFn, t t
726700
}
727701
return utils.NewToolResultResource("successfully downloaded binary file", result), nil, nil
728702
}
703+
704+
// Raw API call failed
705+
return matchFiles(ctx, client, owner, repo, ref, path, rawOpts, resp.StatusCode)
729706
} else if dirContent != nil {
730707
// file content or file SHA is nil which means it's a directory
731708
r, err := json.Marshal(dirContent)
@@ -2100,3 +2077,35 @@ func UnstarRepository(getClient GetClientFn, t translations.TranslationHelperFun
21002077

21012078
return tool, handler
21022079
}
2080+
2081+
func matchFiles(ctx context.Context, client *github.Client, owner, repo, ref, path string, rawOpts *raw.ContentOpts, rawAPIResponseCode int) (*mcp.CallToolResult, any, error) {
2082+
// Step 1: Get Git Tree recursively
2083+
tree, response, err := client.Git.GetTree(ctx, owner, repo, ref, true)
2084+
if err != nil {
2085+
return ghErrors.NewGitHubAPIErrorResponse(ctx,
2086+
"failed to get git tree",
2087+
response,
2088+
err,
2089+
), nil, nil
2090+
}
2091+
defer func() { _ = response.Body.Close() }()
2092+
2093+
// Step 2: Filter tree for matching paths
2094+
const maxMatchingFiles = 3
2095+
matchingFiles := filterPaths(tree.Entries, path, maxMatchingFiles)
2096+
if len(matchingFiles) > 0 {
2097+
matchingFilesJSON, err := json.Marshal(matchingFiles)
2098+
if err != nil {
2099+
return utils.NewToolResultError(fmt.Sprintf("failed to marshal matching files: %s", err)), nil, nil
2100+
}
2101+
resolvedRefs, err := json.Marshal(rawOpts)
2102+
if err != nil {
2103+
return utils.NewToolResultError(fmt.Sprintf("failed to marshal resolved refs: %s", err)), nil, nil
2104+
}
2105+
if rawAPIResponseCode > 0 {
2106+
return utils.NewToolResultText(fmt.Sprintf("Resolved potential matches in the repository tree (resolved refs: %s, matching files: %s), but the content API returned an unexpected status code %d.", string(resolvedRefs), string(matchingFilesJSON), rawAPIResponseCode)), nil, nil
2107+
}
2108+
return utils.NewToolResultText(fmt.Sprintf("Resolved potential matches in the repository tree (resolved refs: %s, matching files: %s).", string(resolvedRefs), string(matchingFilesJSON))), nil, nil
2109+
}
2110+
return utils.NewToolResultError("Failed to get file contents. The path does not point to a file or directory, or the file does not exist in the repository."), nil, nil
2111+
}

0 commit comments

Comments
 (0)