Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions openhands-tools/openhands/tools/glob/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,17 +168,14 @@ def _execute_with_ripgrep(
env=sanitized_env(),
)

# Parse output into file paths
file_paths = []
# Parse output into file paths (ripgrep already sorted by --sortr=modified)
lines = []
if result.stdout:
for line in result.stdout.strip().split("\n"):
if line:
file_paths.append(str(Path(line).resolve()))
# Limit to first 100 files
if len(file_paths) >= 100:
break

truncated = len(file_paths) >= 100
lines = [line for line in result.stdout.strip().split("\n") if line]

# Limit to first 100 files; truncated only if matches were actually dropped
truncated = len(lines) > 100
file_paths = [str(Path(line).resolve()) for line in lines[:100]]

return file_paths, truncated

Expand Down
30 changes: 30 additions & 0 deletions tests/tools/glob/test_glob_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,36 @@ def test_glob_executor_truncation():
assert observation.truncated is True


def test_glob_executor_exactly_100_files_not_truncated():
"""Exactly 100 matches must not be reported as truncated.

Regression test: the ripgrep backend used to stop collecting at 100 and
then flag ``truncated = len >= 100``, so a result set of exactly 100 files
was reported as truncated even though nothing was dropped. The Python
fallback backend already used a strict ``> 100`` comparison.
"""
with tempfile.TemporaryDirectory() as temp_dir:
for i in range(100):
(Path(temp_dir) / f"file_{i:03d}.txt").write_text(f"Content {i}")

# Default backend (ripgrep when available)
executor = GlobExecutor(working_dir=temp_dir)
observation = executor(GlobAction(pattern="*.txt"))

assert observation.is_error is False
assert len(observation.files) == 100
assert observation.truncated is False

# Forced Python fallback backend must agree
fallback_executor = GlobExecutor(working_dir=temp_dir)
fallback_executor._ripgrep_available = False
fallback_observation = fallback_executor(GlobAction(pattern="*.txt"))

assert fallback_observation.is_error is False
assert len(fallback_observation.files) == 100
assert fallback_observation.truncated is False


def test_glob_executor_complex_patterns():
"""Test complex glob patterns."""
with tempfile.TemporaryDirectory() as temp_dir:
Expand Down
Loading