Skip to content

Sandbox file tools: add a built-in edit_file (str_replace) tool so agents stop regenerating whole files #1523

Description

@Lukavyi

What problem are you trying to solve?

The sandbox file toolset currently exposes read_file, write_file, glob, and grep (see #1459 for the current tool surface). There is no partial-edit primitive, so any change to an existing file forces the model to regenerate the entire file through write_file.

On large files this is a major latency and cost driver. A production run of a coding agent on eve@0.27.6 (Vercel Agent Runs trace; private task data, so no run link) shows the pattern:

  • A ~13.8k-character instructions file was fully regenerated twice via write_file, plus a ~13.2k-character test file once.
  • Those three writes alone account for ~215 s of pure LLM output generation in a ~19-minute run.
  • Each full rewrite also re-enters the context as a complete file body, inflating input tokens for every subsequent step (the run averaged ~100k input tokens per step across ~40 tool calls).

The edits themselves were small relative to the file size — a str_replace-style tool would have reduced each of them to a few hundred output tokens.

Checked eve up to 0.29.4: no built-in edit tool exists. The documented escape hatch is an authored tool via defineTool + ctx.getSandbox(), which works, but every agent project has to reimplement the same well-understood primitive (and its guidance prompt) independently.

Current behavior

  • Editing an existing sandbox file requires read_file followed by write_file with the complete new content.
  • The framework already tracks read-before-write evidence for write_file, so the harness has the right foundation — but the only write primitive is whole-file replacement.
  • Output tokens, wall-clock time, and context growth all scale with file size rather than edit size.

Proposed behavior

Add a built-in edit_file tool alongside the existing sandbox file tools, with the widely used str_replace semantics:

  • Input: path, old_string, new_string.
  • The tool reads the file via the sandbox, requires old_string to occur exactly once, and replaces it.
  • Zero matches or multiple matches fail with a structured error without writing, instructing the model to expand the match context (the established contract from Anthropic's text-editor tool and most coding harnesses, so models are already heavily trained on it).
  • Reuse the existing read-before-write tracking: editing a file the model has not read in its current state should fail the same way write_file does.
  • Optional but valuable: replace_all: boolean for intentional multi-site renames.

Built-in tool guidance should steer edits of existing files to edit_file, keeping write_file for new files or full rewrites — mirroring how Claude Code, OpenAI Codex, and other harnesses split the two.

Bounded regression tests

Case Setup Required result
Unique match old_string occurs exactly once File updated; only the replaced span changes
No match old_string absent Structured error, no write, hint to re-read the file
Ambiguous match old_string occurs twice Structured error, no write, hint to expand context
Read-before-edit File never read (or changed since last read) Same failure contract as write_file
$HOME paths Path starts with $HOME Resolved like the other file tools after #1459

Expected behavior

Small edits to large files cost output tokens proportional to the edit, not the file. Whole-file write_file remains available for file creation and full replacement.

Version

  • Observed on: eve@0.27.6
  • Checked through: eve@0.29.4 (no built-in edit tool)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions