DockerSandbox + LangChain file/shell tools extracted into a standalone package. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
46 lines
1.4 KiB
Python
46 lines
1.4 KiB
Python
"""grep.py – tool for searching file contents inside the sandbox."""
|
||
|
||
from __future__ import annotations
|
||
|
||
from shlex import quote
|
||
from typing import TYPE_CHECKING
|
||
|
||
from langchain_core.tools import BaseTool, tool
|
||
from loguru import logger
|
||
|
||
if TYPE_CHECKING:
|
||
from docker_agent_sandbox.sandbox import DockerSandbox
|
||
|
||
|
||
def make_grep_tool(sandbox: "DockerSandbox") -> BaseTool:
|
||
"""Return a grep tool bound to *sandbox*."""
|
||
|
||
@tool
|
||
def grep(pattern: str, path: str, recursive: bool = False) -> str:
|
||
"""
|
||
Search for *pattern* (extended regex) in *path*.
|
||
|
||
*path* can be a file or a directory; when *path* is a directory,
|
||
*recursive* must be ``True``. Returns matching lines with file names
|
||
and line numbers, or an error message.
|
||
|
||
Useful for locating strings, symbol names, or byte sequences in
|
||
binaries and text files.
|
||
"""
|
||
logger.debug(
|
||
"Grepping inside sandbox: pattern={!r} path={!r} recursive={}",
|
||
pattern,
|
||
path,
|
||
recursive,
|
||
)
|
||
flags = "-rn" if recursive else "-n"
|
||
exit_code, output = sandbox.exec(
|
||
f"grep -E {flags} -- {quote(pattern)} {quote(path)} 2>&1"
|
||
)
|
||
# grep exits 1 when no matches — that is not an error
|
||
if exit_code not in (0, 1):
|
||
return f"[ERROR grepping {path!r}] {output.strip()}"
|
||
return output.strip() or "[no matches found]"
|
||
|
||
return grep
|