Skip to content

.NET: Python: [Feature]: line-range reads in the harness file tools (file_access_read_lines or offset/limit on file_access_read) #7571

Description

Description

Problem

The harness file tools are asymmetric about lines. On the edit side they are line-precise: file_access_replace_lines targets 1-based line numbers, and file_access_grep reports matching_lines with those same numbers (the two share the \n-only, keepends split of _split_lines_keepends, so a grep number always addresses the same line the editor touches). On the read side there is no line access at all: file_access_read takes only file_name and returns the entire content (_ReadFileInput, _file_access.py), and the AgentFileStore.read(path) contract underneath is likewise all-or-nothing.

That leaves a hole in exactly the workflow the line-precise edit tools exist for. The natural point-edit loop is:

  1. file_access_grep — find the location (line numbers),
  2. see the surrounding lines to write a correct edit,
  3. file_access_replace_lines / file_access_replace — make the point edit.

Step 2 has no tool. The model's options are:

  • Re-read the whole file — token-expensive on large artifacts, and self-defeating under any tool-result cap: an application that truncates or spools oversized tool results (ours caps them and spills to the store) truncates precisely the large files where partial reads matter most, so the model may never see the region it needs.
  • Grep again with a broader patternfile_access_grep's snippet and matching_lines are anchored to the pattern, not to a requested range; "show me lines 120–160" is not expressible.

Observed effect in production (harness + AG-UI, advisor + headless sub-agents): models told to point-edit fall back to whole-file file_access_read before nearly every replace_lines, and smaller models then skip the read and guess — producing the wrong-line edits the line-precise editor was added to prevent.

Requested

Either shape works; the essential property is numbering parity with grep/replace_lines (same _split_lines_keepends semantics, including the trailing-newline final empty line):

  1. New tool file_access_read_lines(file_name, start_line, end_line=None) — 1-based inclusive range, end_line=None → end of file, out-of-range end_line clamps. Returning line-numbered text lets the model feed numbers straight back into file_access_replace_lines.
  2. Optional params on the existing readfile_access_read(file_name, start_line=None, end_line=None) (or offset/limit), defaulting to today's whole-file behavior.

Implementation stays inside FileAccessProvider — read the full content via the existing AgentFileStore.read, slice with _split_lines_keepends, no store-protocol change needed. (A store-level partial read would be a separate optimization; the context-window win comes from not returning the whole file to the model.)

A new tool (option 1) composes with the existing surface: disable_write_tools children keep it (it is a read), disable_readonly_tool_approval should govern it exactly like file_access_read, and read_only_tools_auto_approval_rule should match it.

Workaround (application-side, today)

A hand-rolled @tool bound to the same store the provider holds (ats.tools.read_lines.make_read_lines_tool): normalizes paths with the provider's own _normalize_relative_path, splits with _split_lines_keepends (both imported from agent_framework._harness._file_access with fallbacks — private imports this FR would remove), mirrors the provider's read-approval mode, and is wired separately into the advisor and each headless sub-agent. It works, but it reaches into two private helpers to guarantee numbering parity, and every consumer has to remember to wire it beside the provider — exactly the kind of duplication a provider-native range read would remove.

Code Sample

Language/SDK

Python

Metadata

Metadata

Labels

harness[Issues, PRs], Target: harness-level itemspythonUsage: [Issues, PRs], Target: Python

Projects

Status
No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions