Skip to content

Commit 81d727c

Browse files
committed
fix: update searchbyfilename tool to paginate
1 parent 0ffdde0 commit 81d727c

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

src/codegen/extensions/langchain/tools.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,8 @@ class SearchFilesByNameTool(BaseTool):
10971097
"""Tool for searching files by filename across a codebase."""
10981098

10991099
name: ClassVar[str] = "search_files_by_name"
1100+
page: int = 1
1101+
files_per_page: int = 10
11001102
description: ClassVar[str] = """
11011103
Search for files and directories by glob pattern across the active codebase. This is useful when you need to:
11021104
- Find specific file types (e.g., '*.py', '*.tsx')
@@ -1106,9 +1108,11 @@ class SearchFilesByNameTool(BaseTool):
11061108
args_schema: ClassVar[type[BaseModel]] = SearchFilesByNameInput
11071109
codebase: Codebase = Field(exclude=True)
11081110

1111+
1112+
11091113
def __init__(self, codebase: Codebase):
11101114
super().__init__(codebase=codebase)
11111115

11121116
def _run(self, pattern: str) -> str:
11131117
"""Execute the glob pattern search using fd."""
1114-
return search_files_by_name(self.codebase, pattern).render()
1118+
return search_files_by_name(self.codebase, pattern, page=self.page, files_per_page=self.files_per_page).render()

src/codegen/extensions/tools/search_files_by_name.py

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,55 @@ class SearchFilesByNameResultObservation(Observation):
2020
files: list[str] = Field(
2121
description="List of matching file paths",
2222
)
23+
page: int = Field(
24+
description="Current page number (1-based)",
25+
)
26+
total_pages: int = Field(
27+
description="Total number of pages available",
28+
)
29+
total_files: int = Field(
30+
description="Total number of files with matches",
31+
)
32+
files_per_page: int = Field(
33+
description="Number of files shown per page",
34+
)
2335

24-
str_template: ClassVar[str] = "Found {total} files matching pattern: {pattern}"
36+
str_template: ClassVar[str] = "Found {total_files} files matching pattern: {pattern} (page {page}/{total_pages})"
2537

2638
@property
2739
def total(self) -> int:
28-
return len(self.files)
40+
return self.total_files
2941

3042

3143
def search_files_by_name(
3244
codebase: Codebase,
3345
pattern: str,
46+
page: int = 1,
47+
files_per_page: int = 10,
3448
) -> SearchFilesByNameResultObservation:
3549
"""Search for files by name pattern in the codebase.
3650
3751
Args:
3852
codebase: The codebase to search in
3953
pattern: Glob pattern to search for (e.g. "*.py", "test_*.py")
54+
page: Page number to return (1-based, default: 1)
55+
files_per_page: Number of files to return per page (default: 10)
4056
"""
4157
try:
58+
# Validate pagination parameters
59+
if page < 1:
60+
page = 1
61+
if files_per_page < 1:
62+
files_per_page = 10
63+
4264
if shutil.which("fd") is None:
4365
logger.warning("fd is not installed, falling back to find")
4466
results = subprocess.check_output(
4567
["find", "-name", pattern],
4668
cwd=codebase.repo_path,
4769
timeout=30,
4870
)
49-
files = [path.removeprefix("./") for path in results.decode("utf-8").strip().split("\n")] if results.strip() else []
71+
all_files = [path.removeprefix("./") for path in results.decode("utf-8").strip().split("\n")] if results.strip() else []
5072

5173
else:
5274
logger.info(f"Searching for files with pattern: {pattern}")
@@ -55,12 +77,31 @@ def search_files_by_name(
5577
cwd=codebase.repo_path,
5678
timeout=30,
5779
)
58-
files = results.decode("utf-8").strip().split("\n") if results.strip() else []
80+
all_files = results.decode("utf-8").strip().split("\n") if results.strip() else []
81+
82+
# Sort files for consistent pagination
83+
all_files.sort()
84+
85+
# Calculate pagination
86+
total_files = len(all_files)
87+
total_pages = (total_files + files_per_page - 1) // files_per_page if total_files > 0 else 1
88+
89+
# Ensure page is within valid range
90+
page = min(page, total_pages)
91+
92+
# Get paginated results
93+
start_idx = (page - 1) * files_per_page
94+
end_idx = start_idx + files_per_page
95+
paginated_files = all_files[start_idx:end_idx]
5996

6097
return SearchFilesByNameResultObservation(
6198
status="success",
6299
pattern=pattern,
63-
files=files,
100+
files=paginated_files,
101+
page=page,
102+
total_pages=total_pages,
103+
total_files=total_files,
104+
files_per_page=files_per_page,
64105
)
65106

66107
except Exception as e:
@@ -69,4 +110,8 @@ def search_files_by_name(
69110
error=f"Error searching files: {e!s}",
70111
pattern=pattern,
71112
files=[],
113+
page=page,
114+
total_pages=0,
115+
total_files=0,
116+
files_per_page=files_per_page,
72117
)

0 commit comments

Comments
 (0)