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.
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
...
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
save_file. That burns tokens, races with concurrent edits, and frequently corrupts large files when the model "rewrites from memory."Proposal: ship richer file capabilities as
ContextProviders (so they inject per-run), split into a read tier and an edit tier:read,list_files,grep(recursive,grep -rn-style regex withincludeglob filtering),glob(**-aware path matching).write,edit(exact-string replace, withreplace_all),apply_patch(unified diff: modify/add/delete/rename),delete_file.Cross-cutting:
session.state["workdir"]atbefore_run, falling back to a construction default, so a single agent instance serves many workdirs concurrently.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