Coding Agent
Coding
Filesystem tools
Middleware
Tracing
The problem
A chat model that cannot open your repo has to guess, and a coding agent that can open anything is something you cannot safely leave running.
How it goes today
- You paste files into a chat window one at a time and paste the answer back by hand.
- The model invents a function name that does not exist because it never read the file.
- Agents that do have file access get a blanket grant, so you supervise every step anyway.
What you'll build
- An agent whose file tools are locked to one workspace root by configuration, not by prompt instructions.
- An explicit list of which tools it may call, checked before every call.
- A log of every tool call plus a structured report of what the run did.
Done looks like
- A path outside the workspace root is refused by the tool, not by the model's good judgment.
- Writing is possible only because you granted the write permission on purpose.
- You can read back every tool call the run made, in order.
- The run ends with a structured report you can store next to the diff.
Paste into Claude, Codex, Cursor, or another coding agent to scaffold this harness.
SDK example
# Context: Vidbyte SDK
Vidbyte SDK is a Python package (import as `vidbyte`) for building agent workflows yourself.
Use it when you want to own the agent loop: system prompts, model/provider choice, tools, managed context, middleware, pipelines, tracing, evals, and multi-agent composition.
Core mental model:
1. Create an Agent or BaseAgent.
2. Attach a system prompt, provider/model, optional tools, context, middleware, and runtime choices.
3. Call run() or arun().
4. Let the SDK handle message assembly, tool schemas/calls, iteration limits, and optional pipelines.
Public package boundary: reusable local agent infrastructure. It does not ship private Vidbyte learning models or proprietary platform internals.
Build it step by step
Every step adds to the same file. By the end you have one runnable coding_agent.py.
- 01
Scope the filesystem to one directory
FileSystemToolConfigOne config object carries the root and whether writing is allowed, and every filesystem tool takes it. Path escapes are rejected by the tool itself, so you are not writing your own path checks.
+ read, list, and write tools scoped to one root
SDK example
Pythonfrom pathlib import Path from vidbyte.tools.filesystem import ( FileSystemToolConfig, ListDirTool, ReadTextTool, WriteTextTool, ) WORKSPACE = Path("./my-project").resolve() fs = FileSystemToolConfig(root=WORKSPACE, allow_write=True) workspace_tools = [ReadTextTool(fs), ListDirTool(fs), WriteTextTool(fs)] - 02
Let it find the right file
GrepTool / GlobToolReading files only helps if the agent knows which ones to open. Grep and glob are prebuilt, root-scoped, and cheap enough to call several times per run.
+ find the file before reading it
SDK example
Pythonfrom vidbyte.tools.builtins.code_search import GlobTool, GrepTool search_tools = [GrepTool(WORKSPACE), GlobTool(WORKSPACE)] - 03
Opt into writing on purpose
PermissionPolicyTools declare a permission tier, and the default policy allows only the safe and read-only ones. Writing needs a policy you passed deliberately — forgetting is a denial, not an accident.
+ explicit consent to mutate files
SDK example
Pythonfrom vidbyte.tools.security import PermissionPolicy # WriteTextTool declares ToolPermission.WRITE, which the default policy denies. permission_policy = PermissionPolicy.allow_all() - 04
Name exactly which tools it may call
ToolPolicyMiddlewareThe permission tier says what kind of tool is acceptable; the allow-list says which specific tools. Anything not on the list is denied before it runs.
+ an allow-list checked per call
SDK example
Pythonfrom vidbyte import ToolPolicyMiddleware tool_policy = ToolPolicyMiddleware( allow_tools={"read_text", "list_dir", "write_text", "grep", "glob"}, ) - 05
Record what it touched
AuditLogMiddlewarePoint the audit middleware at any list and it appends a structured event for each hook it sees. That list is your review trail after the run.
+ every tool call, in order
SDK example
Pythonfrom vidbyte import AuditLogMiddleware audit: list = [] audit_log = AuditLogMiddleware(audit) - 06
Bound the loop
ToolSettings + ToolErrorPolicyAn agent with file access and no ceiling is how you get a four-hundred-call run. These settings cap total calls, truncate huge tool results, and give up after repeated failures.
+ hard limits on a runaway loop
SDK example
Pythonfrom vidbyte.agents import AgentLoopSettings, ToolErrorPolicy, ToolSettings loop_settings = AgentLoopSettings( max_iterations=12, tool_settings=ToolSettings(max_calls=40, result_max_chars=4000), tool_error_policy=ToolErrorPolicy(max_retries_per_tool_call=2, max_total_tool_errors=6), ) - 07
Assemble it and run one narrow task
TraceOption.continualA continual trace keeps a structured report up to date during the run and hands it back on reply.metadata. Give the agent a narrow task first — broad rewrites are how agents thrash.
+ the agent, plus a report that writes itself
SDK example
Pythonfrom vidbyte import ActionTrace, Agent, TraceOption agent = Agent( name="coding-agent", system_prompt=( "Find the relevant files before editing anything. " "Prefer small, reviewable changes. " "Report what you changed and what you checked." ), provider="openai", model_name="gpt-5.5", tools=[*workspace_tools, *search_tools], permission_policy=permission_policy, middleware=[tool_policy, audit_log], agent_loop_settings=loop_settings, trace_option=TraceOption.continual(ActionTrace), ) reply = await agent.arun( "Find where user settings are loaded and add a default theme of 'dark' when none is set." ) print(reply.content) print("run report:", reply.metadata["trace"]) print("tool calls recorded:", len(audit)) - 08
The finished harness
The seven steps above, in one file.
coding_agent.py — complete
SDK example
Python"""Coding Agent - inspects a workspace, makes bounded edits, records what it did.""" import asyncio from pathlib import Path from vidbyte import ActionTrace, Agent, AuditLogMiddleware, ToolPolicyMiddleware, TraceOption from vidbyte.agents import AgentLoopSettings, ToolErrorPolicy, ToolSettings from vidbyte.tools.builtins.code_search import GlobTool, GrepTool from vidbyte.tools.filesystem import ( FileSystemToolConfig, ListDirTool, ReadTextTool, WriteTextTool, ) from vidbyte.tools.security import PermissionPolicy WORKSPACE = Path("./my-project").resolve() fs = FileSystemToolConfig(root=WORKSPACE, allow_write=True) workspace_tools = [ReadTextTool(fs), ListDirTool(fs), WriteTextTool(fs)] search_tools = [GrepTool(WORKSPACE), GlobTool(WORKSPACE)] audit: list = [] agent = Agent( name="coding-agent", system_prompt=( "Find the relevant files before editing anything. " "Prefer small, reviewable changes. " "Report what you changed and what you checked." ), provider="openai", model_name="gpt-5.5", tools=[*workspace_tools, *search_tools], permission_policy=PermissionPolicy.allow_all(), middleware=[ ToolPolicyMiddleware(allow_tools={"read_text", "list_dir", "write_text", "grep", "glob"}), AuditLogMiddleware(audit), ], agent_loop_settings=AgentLoopSettings( max_iterations=12, tool_settings=ToolSettings(max_calls=40, result_max_chars=4000), tool_error_policy=ToolErrorPolicy(max_retries_per_tool_call=2, max_total_tool_errors=6), ), trace_option=TraceOption.continual(ActionTrace), ) async def main() -> None: reply = await agent.arun( "Find where user settings are loaded and add a default theme of 'dark' when none is set." ) print(reply.content) print("run report:", reply.metadata["trace"]) print("tool calls recorded:", len(audit)) if __name__ == "__main__": asyncio.run(main())