Every serious agent framework already has a pause-and-resume concept, and the shape of your approval JSON should follow it. Microsoft's agent framework wraps a function in an approval-required wrapper, and the run completes with a ToolApprovalRequestContent object whose ToolCall property exposes the function name and its arguments, which the caller can show to a person before deciding the Microsoft Learn approval guide. The OpenAI Agents SDK does the same thing with needs_approval: the runner pauses, surfaces interruptions, and lets you serialize the paused run with RunState and resume after a decision the OpenAI Agents SDK HITL docs. LangChain's deep agent stack exposes an interrupt_on map that configures which tools pause and which decisions are allowed for each, with a checkpointer that is required for the flow to work at all the LangChain HITL docs.
The lesson for schema design: the framework gives you the tool name and the argument object for free. Do not restate them in a paragraph. Pass them through as structured fields and spend your own schema budget on what the framework does not know: why the agent wants this, what it read, how bad it could get, and how to undo it.
A second consequence is that the decision itself must be a first class object. The OpenAI SDK scopes per-call approvals to the specific call ID and only persists a decision to future calls when you explicitly ask for it the OpenAI Agents SDK HITL docs. That matches what audits need: an approval is valid for one call, one set of arguments, at one time.



