Repository navigation
Open
Labels
harness[Issues, PRs], Target: harness-level items[Issues, PRs], Target: harness-level itemspythonUsage: [Issues, PRs], Target: PythonUsage: [Issues, PRs], Target: Python
Description
Description
The existing preview feature is lacking some key tools for editing files, and the tooling name / conventions differs from existing frameworks that popular model providers train on.
Description
- No surgical editing. To change three lines, the model must re-emit the entire file via
save_file. That burns tokens, races with concurrent edits, and frequently corrupts large files when the model "rewrites from memory." - No read-only/read-write split. There's no first-class way to give a sub-agent read access only, so "safe to delegate investigation" agents have to be hand-rolled.
- No per-tool approval gating. Destructive operations (delete/overwrite) can't be individually gated behind an approval step.
- Fixed workdir. The store's root is set at construction, so one agent instance can't safely serve multiple working directories (parallel tasks/sessions) without rebuilding the agent.
Proposal: ship richer file capabilities as ContextProviders (so they inject per-run), split into a read tier and an edit tier:
- Read tier —
read,list_files,grep(recursive,grep -rn-style regex withincludeglob filtering),glob(**-aware path matching). - Edit tier (extends read) —
write,edit(exact-string replace, withreplace_all),apply_patch(unified diff: modify/add/delete/rename),delete_file.
Cross-cutting:
- Per-run workdir scoping: resolve the workdir from
session.state["workdir"]atbefore_run, falling back to a construction default, so a single agent instance serves many workdirs concurrently. - Path safety: workdir-relative paths only, with traversal/symlink protection.
- Approval modes per tool: gate
delete_file(and optionallyedit/apply_patch) behindalways_require.
Code Sample
from agent_framework import (
Agent,
FileReadAccessProvider,
FileEditAccessProvider # subclasses Read
)
# Editing agent: read + write/patch tools, workdir-scoped, delete gated.
editor = Agent(
client=client,
instructions=...,
context_providers=[
FileEditToolsProvider(
default_workdir="/work/project-a",
require_delete_approval=True, # delete_file -> always_require
require_edit_approval=False, # edit/apply_patch auto-run
),
],
)
# Read-only sub-agent: gets read/list_files/grep/glob ONLY — safe to delegate.
investigator = Agent(
client=client,
instructions=...,
context_providers=[FileReadToolsProvider(default_workdir="/work/project-a")],
)
session_a.state["workdir"] = "/work/task-a"
session_b.state["workdir"] = "/work/task-b"
await asyncio.gather(
editor.run("refactor module X", session=session_a),
editor.run("fix failing test", session=session_b),
) # each run's file tools are scoped to its own directory
**Surgical edits instead of whole-file rewrites:**
# exact-string edit
edit(file_name="src/app.py", old_string="DEBUG = True", new_string="DEBUG = False", replace_all=True)
# unified-diff patch (add/modify/delete/rename), the format models produce best
apply_patch(file_name="src/app.py", patch="--- a/src/app.py\n+++ b/src/app.py\n@@ ...")
**Search the tree without reading every file:**
grep(pattern=r"def create_agent", include="*.py") # recursive, like grep -rn
glob(pattern="**/*.sysml") # recursive path match
**Approval loop for gated destructive ops** (when `require_delete_approval=True`):
result = await editor.run("remove the obsolete config", session=session_a)
for req in result.user_input_requests: # delete_file surfaces here for approval
...Language/SDK
Both
Metadata
Metadata
Assignees
Labels
harness[Issues, PRs], Target: harness-level items[Issues, PRs], Target: harness-level itemspythonUsage: [Issues, PRs], Target: PythonUsage: [Issues, PRs], Target: Python
Type
Projects
- StatusShow more project fieldsNo status
Activity
[-][Feature]: Better FileAccessProvider for python harness[/-][+]Python: [Feature]: Better FileAccessProvider for python harness[/+]jhare96 commentedon Jun 26, 2026
I'm happy to implement this myself
westey-m commentedon Jun 29, 2026
Thanks for the suggestions Joshua Hare (@jhare96). These are good suggestions, and most are planned, with some already done.
Per-tool-approval is already supported for all tools via ToolApprovalMiddleware. This eliminates the need for each feature to have its own set of switches. E.g. you can pass rules to ToolApprovalMiddleware, and FileAccessProvider already comes with built in rules for common scenarios. You can also implement your own callable for super fine grained control.
Path safety is also already enforced. If there are gaps, it's a bug.
I appreciate the offer of a contribution, but since we have implementations in python and c# it's typically easier for me to generate a plan and execute it on both. I'll have a PR out soon, and will appreciate your review though.