Skip to content

feat(tools): make read tool useful standalone, disable by default#1266

Merged
ErikBjare merged 3 commits into
masterfrom
feat/read-tool-standalone
Feb 16, 2026
Merged

feat(tools): make read tool useful standalone, disable by default#1266
ErikBjare merged 3 commits into
masterfrom
feat/read-tool-standalone

Conversation

@TimeToBuildBob

@TimeToBuildBob TimeToBuildBob commented Feb 16, 2026

Copy link
Copy Markdown
Member

Summary

  • Reworked the read tool from a shell passthrough into a proper standalone file reader
  • Disabled by default (was previously enabled but just said "use shell instead")
  • Enables sandboxed read/write workflows with --tools read,patch,save

Changes

  • gptme/tools/read.py: Full implementation with execute_read() function
    • Reads files with line numbers (cat -n style output)
    • Supports line range via start_line/end_line kwargs
    • Handles errors: binary files, missing files, directories, permissions
    • Uses disabled_by_default=True to remove from default toolset
    • Registers read block type for markdown codeblock execution
  • tests/test_tools_read.py: 10 tests covering all functionality
  • tests/test_prompt_tools.py: Updated expectations (read no longer references shell)

Motivation

From #1259: when restricting tools (e.g. --tools patch,save), having a read tool that actually works independently completes the read/write workflow without needing shell. Previously the read tool just said "use shell instead", which is useless when shell is disabled.

Usage

# Enable read tool explicitly
gptme --tools read,patch,save "refactor this file"

# Read tool works in markdown format:
# ```read hello.py
# ```
# → Returns file contents with line numbers

Closes #1259


Important

Reworks read tool to function independently with error handling and line range support, and updates tests accordingly.

  • Behavior:
    • Reworks read tool in gptme/tools/read.py to function as a standalone file reader with execute_read().
    • Supports line number output and line range selection via start_line/end_line.
    • Handles errors for binary files, missing files, directories, and permissions.
    • Disables read tool by default using disabled_by_default=True.
    • Registers read block type for markdown codeblock execution.
  • Tests:
    • Adds tests/test_tools_read.py with 10 tests covering full functionality.
    • Updates tests/test_prompt_tools.py to reflect changes in read tool behavior.

This description was created by Ellipsis for eb0c22b. You can customize this summary. It will automatically update as commits are pushed.

Reworked the read tool from a shell passthrough into a proper standalone tool:
- Implements actual file reading without shell dependency
- Adds line number output (cat -n style)
- Supports line range via kwargs (start_line, end_line)
- Handles errors gracefully (binary files, missing files, permissions)
- Disabled by default since it was redundant with shell
- Enables sandboxed read/write workflows with --tools read,patch,save

Closes #1259
@TimeToBuildBob

Copy link
Copy Markdown
Member Author

@greptileai review

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to eb0c22b in 11 seconds. Click for details.
  • Reviewed 306 lines of code in 3 files
  • Skipped 0 files when reviewing.
  • Skipped posting 0 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.

Workflow ID: wflow_d3D3dHoL4nzaNOHC

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@greptile-apps

greptile-apps Bot commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR rewrites the read tool from a non-functional shell passthrough ("use shell instead") into a standalone file reader with line numbers, line range support, and proper error handling. The tool is marked disabled_by_default=True, requiring explicit opt-in via --tools read,patch,save for sandboxed read/write workflows.

  • Implementation: execute_read() reads files with cat -n style line numbers, supports start_line/end_line kwargs, and handles binary files, missing files, directories, and permission errors
  • Path traversal gap: The save and patch tools both validate that relative paths resolve within cwd; the new read tool does not, which is inconsistent with the "sandboxed" framing
  • Undeclared parameters: start_line and end_line are functional in kwargs but not declared in the ToolSpec.parameters list, making them invisible to LLMs using the tool-call format
  • Tests: 10 new tests cover all major code paths; prompt tool tests updated to match the new behavior

Confidence Score: 3/5

  • PR is functionally sound but has a security inconsistency: unlike sibling tools, it lacks path traversal protection for a feature described as "sandboxed"
  • The core implementation is clean with good error handling and test coverage. However, the missing path traversal protection is a meaningful gap when the tool is specifically intended for sandboxed workflows. The undeclared parameters are a usability gap rather than a correctness issue.
  • gptme/tools/read.py needs path traversal protection to match the security posture of save.py and patch.py

Important Files Changed

Filename Overview
gptme/tools/read.py Full rewrite from shell passthrough to standalone file reader. Clean implementation with good error handling, but lacks path traversal protection present in sibling tools (save, patch) and omits start_line/end_line from the parameter declarations.
tests/test_tools_read.py New test file with 10 tests covering all major code paths: normal reads, line ranges, binary files, missing files, directories, empty files, and no-path error. Good coverage; could benefit from a path traversal test if that protection is added.
tests/test_prompt_tools.py Updated test expectations to remove old shell-reference assertions from the read tool prompt, replacing them with shell tool description checks. Changes are consistent with the read tool rewrite.

Flowchart

flowchart TD
    A[execute_read called] --> B{Path provided?}
    B -- No --> C[Return: No path provided]
    B -- Yes --> D{File exists?}
    D -- No --> E[Return: File not found]
    D -- Yes --> F{Is a file?}
    F -- No --> G[Return: Not a file]
    F -- Yes --> H[Parse start_line / end_line kwargs]
    H --> I[Read file text]
    I -- UnicodeDecodeError --> J[Return: Cannot read binary file]
    I -- PermissionError --> K[Return: Permission denied]
    I -- Success --> L[Split into lines]
    L --> M[Apply line range selection]
    M --> N[Format with line numbers]
    N --> O[Return formatted output with range info]
Loading

Last reviewed commit: eb0c22b

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment thread gptme/tools/read.py
Comment thread gptme/tools/read.py
@codecov

codecov Bot commented Feb 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.87324% with 15 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
gptme/tools/read.py 79.10% 14 Missing ⚠️
gptme/tools/base.py 75.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

…declarations

- Add path traversal protection consistent with save.py and patch.py
- Declare start_line and end_line in parameters list for tool schema
@TimeToBuildBob

Copy link
Copy Markdown
Member Author

Review Feedback Addressed

Both Greptile review comments fixed in commit 0caa71f:

  1. Path traversal protection — Added validation consistent with save.py/patch.py. Relative paths are checked to stay within cwd; absolute paths are allowed (intentional).
  2. Missing parameter declarations — Added start_line and end_line to the parameters list so they appear in the tool schema.

All 10 read tool tests pass, mypy clean.

When a tool has optional parameters (like read's start_line/end_line),
the positional arg mapping would crash with IndexError if fewer args
were provided than total parameters. Now skips optional params that
have no corresponding arg.
@ErikBjare ErikBjare merged commit 1c05d1f into master Feb 16, 2026
11 checks passed
@TimeToBuildBob TimeToBuildBob deleted the feat/read-tool-standalone branch February 28, 2026 20:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: make read tool useful standalone, remove from defaults

2 participants