Ask Before You Delete
An agent with a delete_file tool will, sooner or later, delete a file you wanted, because the loop runs it the same way it runs list_files. A call that cannot be undone needs a human before it runs.
Implement run_with_approval(question, model, tools, destructive, approve, max_turns=6): the standard tool loop with one gate. destructive is the set of tool names that need sign-off. approve(name, arguments) is the human; it returns True or False.
- A tool that is not in
destructiveruns without asking. - A destructive call is passed to
approvebefore it runs. Approved: run it, feed the result back, carry on. Denied: do not run it, and end the run there withstopped: "denied"and no answer. - Process a turn's calls in order and stop at the first denial. The calls before it have already run, and that is fine.
- Return
{"answer", "turns", "stopped", "approvals"}.stoppedis"done"when the model finished,"denied"when the gate ended the run,"turns"whenmax_turnsran out.approvalsis every decision as(name, approved), in order.
The model is scripted. The fixture records every tool that actually executed, so never ran is checked, not assumed.