feat: Initial library extraction from PIN LLM benchmark
DockerSandbox + LangChain file/shell tools extracted into a standalone package. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
60
docker_agent_sandbox/tools/read_file.py
Normal file
60
docker_agent_sandbox/tools/read_file.py
Normal file
@@ -0,0 +1,60 @@
|
||||
"""read_file.py – tool for reading files 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_read_file_tool(sandbox: "DockerSandbox") -> BaseTool:
|
||||
"""Return a read_file tool bound to *sandbox*."""
|
||||
|
||||
@tool
|
||||
def read_file(path: str, offset: int = 0, length: int = 5000) -> str:
|
||||
"""
|
||||
Read a file at *path*.
|
||||
|
||||
*path* can be absolute (``/tmp/re-agent/result.csv``) or relative to the
|
||||
working directory.
|
||||
|
||||
*offset* is the number of bytes to skip from the start of the file.
|
||||
*length* is the maximum number of bytes to return. If the file is
|
||||
longer than ``offset + length``, the
|
||||
output is trimmed and a summary line is appended showing how many
|
||||
bytes were omitted.
|
||||
|
||||
Returns the (possibly trimmed) file contents as text, or an error message.
|
||||
"""
|
||||
logger.debug(
|
||||
"Reading file inside sandbox: {} offset={} length={}", path, offset, length
|
||||
)
|
||||
exit_code, wc_out = sandbox.exec(f"wc -c -- {quote(path)}")
|
||||
if exit_code != 0:
|
||||
return f"[ERROR reading {path!r}] {wc_out.strip()}"
|
||||
try:
|
||||
total = int(wc_out.split()[0])
|
||||
except (ValueError, IndexError):
|
||||
return f"[ERROR parsing file size for {path!r}] {wc_out.strip()}"
|
||||
|
||||
exit_code, chunk = sandbox.exec(
|
||||
f"dd if={quote(path)} iflag=skip_bytes,count_bytes"
|
||||
f" skip={offset} count={length} 2>/dev/null"
|
||||
)
|
||||
if exit_code != 0:
|
||||
return f"[ERROR reading {path!r}] {chunk.strip()}"
|
||||
|
||||
suffix = ""
|
||||
if offset + length < total:
|
||||
remaining = total - (offset + length)
|
||||
suffix = f"\n[... {remaining} more bytes not shown (total {total} bytes). Use offset/length to read further.]"
|
||||
elif offset > 0 or total > length:
|
||||
suffix = f"\n[File total: {total} bytes, showing {len(chunk)} chars from offset {offset}.]"
|
||||
return chunk + suffix
|
||||
|
||||
return read_file
|
||||
Reference in New Issue
Block a user