What is the proper way to intercept tool calls modify them or dynamically approve/reject them?
The pattern that works today is wrapping your tools rather than intercepting at the framework level.
Instead of looking for a framework-level interception hook, implement your Tool conformance so that the tool's call method is itself the approval gate. Inside it, before performing the actual work, run your validation/approval logic — check the arguments, apply your own repair if they're malformed, and either proceed, throw, or return a result that asks for confirmation.
For dynamic approve/reject specifically: have the tool return a result indicating "needs confirmation" rather than executing, then surface that to the user, and on approval invoke the actual operation in a follow-up turn. This keeps the model from autonomously executing high-impact actions — the tool acknowledges but defers the real work behind your confirmation surface.
For argument validation/repair before execution: don't trust the model's tool arguments blindly. Validate against your own constraints inside the tool, and if they're off, you can either throw (letting the model retry) or coerce to the nearest valid value. This is essentially defensive programming at the tool boundary.
There isn't a first-class "intercept all tool calls" middleware in the framework that was surfaced at the labs — the tool boundary itself is currently the right place to put this logic. If you need it centralized across many tools, a small protocol wrapper that all your tools adopt gives you one place for the approval/validation logic.
— Divya Ravi, Senior iOS Engineer