Handle absolute workspace globs
This commit is contained in:
+6
-1
@@ -2169,10 +2169,15 @@ print("\n".join(matches) if matches else "(no matches)")
|
|||||||
if result.exit_code != 0:
|
if result.exit_code != 0:
|
||||||
raise ToolExecutionError(result.stdout.strip() or 'remote glob_search failed')
|
raise ToolExecutionError(result.stdout.strip() or 'remote glob_search failed')
|
||||||
return result.stdout.strip() or '(no matches)'
|
return result.stdout.strip() or '(no matches)'
|
||||||
|
root_resolved = context.root.resolve()
|
||||||
|
if Path(pattern).is_absolute():
|
||||||
|
try:
|
||||||
|
pattern = str(Path(pattern).resolve().relative_to(root_resolved))
|
||||||
|
except ValueError:
|
||||||
|
return '(no matches)'
|
||||||
matches = sorted(context.root.glob(pattern))
|
matches = sorted(context.root.glob(pattern))
|
||||||
if not matches:
|
if not matches:
|
||||||
return '(no matches)'
|
return '(no matches)'
|
||||||
root_resolved = context.root.resolve()
|
|
||||||
validated: list[str] = []
|
validated: list[str] = []
|
||||||
for path in matches:
|
for path in matches:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -99,6 +99,45 @@ class ExtendedToolTests(unittest.TestCase):
|
|||||||
self.assertIn('[line truncated,', result.content)
|
self.assertIn('[line truncated,', result.content)
|
||||||
self.assertLess(len(result.content), 1200)
|
self.assertLess(len(result.content), 1200)
|
||||||
|
|
||||||
|
def test_glob_search_accepts_absolute_path_inside_workspace(self) -> None:
|
||||||
|
registry = default_tool_registry()
|
||||||
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||||
|
workspace = Path(tmp_dir)
|
||||||
|
target_dir = workspace / 'output'
|
||||||
|
target_dir.mkdir()
|
||||||
|
(target_dir / 'records.jsonl').write_text('{}\n', encoding='utf-8')
|
||||||
|
context = build_tool_context(
|
||||||
|
AgentRuntimeConfig(cwd=workspace),
|
||||||
|
tool_registry=registry,
|
||||||
|
)
|
||||||
|
result = execute_tool(
|
||||||
|
registry,
|
||||||
|
'glob_search',
|
||||||
|
{'pattern': str(target_dir / '*.jsonl')},
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(result.ok)
|
||||||
|
self.assertIn('output/records.jsonl', result.content)
|
||||||
|
|
||||||
|
def test_glob_search_external_absolute_path_returns_no_matches(self) -> None:
|
||||||
|
registry = default_tool_registry()
|
||||||
|
with tempfile.TemporaryDirectory() as workspace_dir, tempfile.TemporaryDirectory() as external_dir:
|
||||||
|
external = Path(external_dir) / '*.jsonl'
|
||||||
|
context = build_tool_context(
|
||||||
|
AgentRuntimeConfig(cwd=Path(workspace_dir)),
|
||||||
|
tool_registry=registry,
|
||||||
|
)
|
||||||
|
result = execute_tool(
|
||||||
|
registry,
|
||||||
|
'glob_search',
|
||||||
|
{'pattern': str(external)},
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(result.ok)
|
||||||
|
self.assertEqual(result.content, '(no matches)')
|
||||||
|
|
||||||
def test_read_file_can_read_explicit_external_path(self) -> None:
|
def test_read_file_can_read_explicit_external_path(self) -> None:
|
||||||
registry = default_tool_registry()
|
registry = default_tool_registry()
|
||||||
with tempfile.TemporaryDirectory() as workspace_dir, tempfile.TemporaryDirectory() as external_dir:
|
with tempfile.TemporaryDirectory() as workspace_dir, tempfile.TemporaryDirectory() as external_dir:
|
||||||
|
|||||||
Reference in New Issue
Block a user