Spaces:
Sleeping
Sleeping
| """ | |
| read_file tool β returns the current content of a file in the task workdir. | |
| Allows the agent to inspect source files before deciding what to edit, | |
| rather than guessing from test error messages alone. | |
| """ | |
| import logging | |
| import os | |
| from pydantic import ValidationError | |
| from debug_env.server.schemas import ReadFileArgs, ToolResult | |
| from debug_env.server.utils import validate_workdir_path | |
| logger = logging.getLogger(__name__) | |
| def read_file(workdir: str, path: str) -> ToolResult: | |
| """ | |
| Read *path* (relative to *workdir*) and return its content in ``logs``. | |
| Pass rate is preserved from the last test run β reading a file does not | |
| affect the score. The content is returned in ``logs`` so the agent can | |
| inspect it in the same observation field it already reads. | |
| Args: | |
| workdir: Absolute path to the task working directory. | |
| path: Filename to read, e.g. ``"broken_code.py"`` or ``"helper.py"``. | |
| Returns: | |
| :class:`ToolResult` with ``pass_rate=0.0`` and file content in ``logs``. | |
| """ | |
| try: | |
| args = ReadFileArgs(path=path) | |
| except ValidationError as e: | |
| messages = [f"{' -> '.join(str(loc) for loc in err['loc'])}: {err['msg']}" for err in e.errors()] | |
| msg = "Invalid read_file args β " + "; ".join(messages) | |
| logger.warning(msg) | |
| return ToolResult(pass_rate=0.0, logs=msg, success=False) | |
| try: | |
| full_path = validate_workdir_path(workdir, args.path) | |
| except ValueError as e: | |
| logger.warning(str(e)) | |
| return ToolResult(pass_rate=0.0, logs=str(e), success=False) | |
| logger.info(f"Reading file: {full_path}") | |
| if not os.path.exists(full_path): | |
| available = [f for f in os.listdir(workdir) if f.endswith(".py") and not f.startswith("test_")] | |
| msg = ( | |
| f"File '{args.path}' not found. " | |
| f"Editable source files: {available}" | |
| ) | |
| logger.warning(msg) | |
| return ToolResult(pass_rate=0.0, logs=msg, success=False) | |
| try: | |
| with open(full_path) as f: | |
| content = f.read() | |
| logger.info(f"Read {len(content)} chars from '{args.path}'") | |
| return ToolResult( | |
| pass_rate=0.0, | |
| logs=f"# {args.path}\n{content}", | |
| success=True, | |
| ) | |
| except OSError as e: | |
| msg = f"Failed to read '{args.path}': {e}" | |
| logger.error(msg) | |
| return ToolResult(pass_rate=0.0, logs=msg, success=False) | |