diff --git a/tests/tools/test_code_execution.py b/tests/tools/test_code_execution.py index 66ed46a686..b09636fa18 100644 --- a/tests/tools/test_code_execution.py +++ b/tests/tools/test_code_execution.py @@ -475,10 +475,11 @@ class TestStubSchemaDrift(unittest.TestCase): compile(src, "hermes_tools.py", "exec") # Verify specific parameter signatures are in the source - # search_files must accept context, offset, output_mode + # search_files must accept its pagination, output, and ordering controls self.assertIn("context", src) self.assertIn("offset", src) self.assertIn("output_mode", src) + self.assertIn("order", src) # patch must accept mode and patch params self.assertIn("mode", src) diff --git a/tests/tools/test_file_operations_edge_cases.py b/tests/tools/test_file_operations_edge_cases.py index e9875f236e..103c172884 100644 --- a/tests/tools/test_file_operations_edge_cases.py +++ b/tests/tools/test_file_operations_edge_cases.py @@ -236,7 +236,7 @@ class TestPaginationBounds: commands.append(command) if command.startswith("test -e"): return MagicMock(exit_code=0, stdout="exists") - if command.startswith("rg --files"): + if "--files" in command: return MagicMock(exit_code=0, stdout="a.py\n") return MagicMock(exit_code=0, stdout="") @@ -245,9 +245,9 @@ class TestPaginationBounds: result = ops.search("*.py", target="files", path=".", offset=-4, limit=-2) assert result.files == ["a.py"] - rg_commands = [cmd for cmd in commands if cmd.startswith("rg --files")] + rg_commands = [cmd for cmd in commands if "--files" in cmd] assert rg_commands - assert "| head -n 1" in rg_commands[0] + assert "| head -n 2" in rg_commands[0] # ========================================================================= diff --git a/tests/tools/test_macos_protected_search.py b/tests/tools/test_macos_protected_search.py index cde5d6fc7b..20609b6c3b 100644 --- a/tests/tools/test_macos_protected_search.py +++ b/tests/tools/test_macos_protected_search.py @@ -239,7 +239,12 @@ def test_rg_multi_root_keeps_explicit_protected_root_and_reports_actual_skips( ) command = _rg_files_commands(env.commands)[0] - assert downloads.as_posix() in command + absolute_operand = downloads.as_posix() in command + anchored_operand = ( + f"cd {ops._escape_shell_arg(downloads.parent.as_posix())} &&" in command + and " -- '.' 'Downloads' 2>/dev/null" in command + ) + assert absolute_operand or anchored_operand assert "!Downloads/**" not in command assert "path contained 2 entries" in (result.warning or "") assert "macOS protected folders" in (result.warning or "") diff --git a/tools/code_execution_tool.py b/tools/code_execution_tool.py index 470f956732..f268ef8df2 100644 --- a/tools/code_execution_tool.py +++ b/tools/code_execution_tool.py @@ -408,9 +408,9 @@ _TOOL_STUBS = { ), "search_files": ( "search_files", - 'pattern: str, target: str = "content", path: str = ".", file_glob: str = None, limit: int = 50, offset: int = 0, output_mode: str = "content", context: int = 0', + 'pattern: str, target: str = "content", path: str = ".", file_glob: str = None, limit: int = 50, offset: int = 0, output_mode: str = "content", context: int = 0, order: str = "discovery"', '"""Search file contents (target="content") or find files by name (target="files"). Returns dict with "matches"."""', - '{"pattern": pattern, "target": target, "path": path, "file_glob": file_glob, "limit": limit, "offset": offset, "output_mode": output_mode, "context": context}', + '{"pattern": pattern, "target": target, "path": path, "file_glob": file_glob, "limit": limit, "offset": offset, "output_mode": output_mode, "context": context, "order": order}', ), "patch": ( "patch", @@ -2331,7 +2331,7 @@ _TOOL_DOC_LINES = [ " write_file(path: str, content: str) -> dict\n" " Always overwrites the entire file."), ("search_files", - " search_files(pattern: str, target=\"content\", path=\".\", file_glob=None, limit=50) -> dict\n" + " search_files(pattern: str, target=\"content\", path=\".\", file_glob=None, limit=50, order=\"discovery\") -> dict\n" " target: \"content\" (search inside files) or \"files\" (find files by name). Returns {\"matches\": [...]}"), ("patch", " patch(path: str, old_string: str, new_string: str, replace_all: bool = False) -> dict\n"