Suppose an AI agent drafts a reply to a customer about a delayed order. It can find the order and write a helpful message, but it should not send that message just because its plan says to. A human-in-the-loop AI agent pauses at the send-email tool call, shows a person the recipient and exact draft, and continues only if the person approves.
OpenAI Agents and LangGraph can already pause and resume a run. ActionBox handles the review request while the run is paused: it presents the selected context, notifies a reviewer, records a typed answer, and lets the calling application read that answer. The application still checks the decision and sends the email.
A human approval example, without the framework jargon
| Step | What happens in the customer-email example |
|---|---|
| Propose | The agent prepares a reply to one customer. Nothing is sent yet. |
| Review | The application shows the recipient, subject, and exact draft in ActionBox. A reviewer approves or rejects that message. |
| Continue | The application checks the response against the draft it submitted. If the draft or recipient changes, it asks again before sending. |
| Record | The application records whether the email provider actually sent the message. Approval and delivery are separate events. |
If one n8n workflow can use its native review step and you do not need a shared review queue, that may be enough. Use ActionBox when reviewers need to handle requests from several applications in one place or the application needs to re-read a saved Action after a restart. The n8n human-in-the-loop guide shows that choice in a workflow.
Which AI agent tool calls need human approval?
Decide from the effect of the tool call, not from whether an AI model proposed it. A read-only lookup and an external write have different consequences. This is an illustrative starting policy, not a rule that fits every organization:
| Proposed call | Starting control | What changes the decision |
|---|---|---|
| Look up an order using already authorized access | Run within access and rate limits | Sensitive data or a broader-than-expected lookup may need a separate authorization check |
| Draft a reply without sending it | Allow the draft; review can happen later | The draft itself must not be mistaken for permission to send |
| Send a customer-facing email | Review the exact recipient, subject, and draft before sending | A preapproved template with narrow scope may support bounded autonomy |
| Change access, move money, or delete records | Require an explicit checkpoint and an authorized reviewer | The operation, affected resource, and current state must match what was approved |
For the email example, a useful review request says who will receive the message, shows the complete proposed text, and makes the choice explicit: send this version or do not send it. If the agent revises the draft while the request is open, the old approval cannot authorize the new text. The application that owns the send-email credential must enforce that check.
For a shared review queue, ActionBox's human approval API holds the request and decision. The calling application remains responsible for the policy, exact tool arguments, and eventual send result.
What human-in-the-loop AI means at the tool boundary
Put the checkpoint immediately before the side effect. A plan can change before execution; the tool call contains the operation and arguments that would actually run.
For review rules, request context, and queue ownership across conventional workflows, use the human-in-the-loop automation design guide. The framework paths below focus on AI agent tool calls.
Some systems use a bounded decision model to recommend whether a proposal can proceed or needs review. The TypeSafe AI Jev review explains how those typed probabilities differ from generative LLM output. Keep the final allow, review, or deny policy in the application that owns the tool call.
Choose the framework path
Each framework pauses and resumes differently. Use the tutorial for the runtime that owns your agent state. If you are still choosing, the integration recipes show the shorter paths.
| Runtime | Native pause | State owner | Implementation |
|---|---|---|---|
| OpenAI Agents API | agent.session.requires_action function call | Managed OpenAI session | OpenAI Agents API human approval |
| OpenAI Agents SDK | needs_approval=True tool interruption | Agents SDK RunState | OpenAI Agents SDK human-in-the-loop |
| LangGraph | interrupt() and Command(resume=...) | LangGraph checkpointer and thread_id | LangGraph human-in-the-loop |
| CrewAI | Crew proposal or @human_feedback flow | CrewAI flow or calling application | CrewAI human-in-the-loop |
| MCP client | Voluntary ask_human call | Client or orchestrator | Connect an MCP agent |
OpenAI Agents SDK: approve the interruption
Mark a consequential tool with needs_approval=True. The SDK surfaces the exact item in result.interruptions; your driver creates an Actionbox request, applies the typed decision to result.to_state(), and resumes the original run.
Use the tool-call ID as the Actionbox idempotency identity, preserve RunState when the wait can outlive the worker, and use always_approve=False for a one-time decision. The OpenAI Agents SDK integration guide summarizes the supported flow. The approval tutorial includes runnable code for timeout cancellation and multiple interruptions.
OpenAI Agents API: return the human decision
The managed Agents API emits agent.session.requires_action when a function result is pending. Route only allowlisted function calls to Actionbox, build a review object from approved fields, and return agent.session.input.tool_result with the same session, turn, and call identity. The OpenAI Agents API human approval guide explains the streaming and webhook event names, direct MCP connection, and fail-closed adapter.
LangGraph: ask outside the interrupt node
LangGraph owns the checkpoint. A node emits a JSON-serializable interrupt() payload, then the graph driver creates the Actionbox request and resumes the same thread_id with Command(resume=...).
Do not create the Actionbox Action before interrupt() inside the node. LangGraph restarts the node from the beginning on resume, so network side effects before the interrupt can repeat. The LangGraph integration guide explains which system owns each piece. The human-in-the-loop tutorial shows a complete driver with stable interrupt identities, multiple decisions, and fail-closed resume.
MCP agents already work without a framework adapter
An MCP-capable agent can connect directly to Actionbox and voluntarily call ask_human, then retrieve the typed result with get_action. That is the smallest integration when the agent itself knows when it needs a person.
Voluntary human input is not the same as enforced authorization. When the agent must not bypass review, put the allow, ask, or deny policy in the application or gateway that owns the downstream tool call. The MCP security and authorization guide explains that boundary and the current public Actionbox MCP connection.
CrewAI: approve the proposal before execution
CrewAI can prepare a plan without receiving the credential for the protected operation. The application creates one Actionbox request from that proposal, waits for a typed decision, then performs the side effect only after approval. The CrewAI human-in-the-loop tutorial includes the tested adapter, timeout cancellation, and outcome reporting.
Safety rules that make the approval meaningful
- Bind retries to stable IDs. Use the OpenAI tool-call ID or LangGraph
thread_idplus interrupt ID as the Actionbox idempotency key. - Never approve a partial payload. Reject oversized context instead of silently truncating the call the reviewer thinks they approved.
- Remove secrets before sending context. Tool arguments can contain tokens, credentials, or customer data.
- Fail closed. Rejection, expiry, malformed response, and local timeout must not execute the tool.
- Keep state ownership clear. OpenAI stores
RunState; LangGraph stores checkpoints; Actionbox stores Actions and decisions. - Report the execution outcome. After the approved tool runs, report success or failure so the decision history includes what happened next.
Keep state ownership clear
| Record | System of record |
|---|---|
| OpenAI paused run | Agents SDK RunState |
| LangGraph paused graph | LangGraph checkpointer |
| Human request and decision | Actionbox Action |
| Tool execution and credentials | Calling application |
| Execution result | Calling application, reported back as an Action outcome |
This separation lets Actionbox work across frameworks without becoming another agent runtime or workflow engine.
Complete tested examples
The repository examples include bounded context, stable idempotency keys, typed response mapping, timeout cancellation, and multi-interrupt handling. Start with the matching tutorial, then copy the maintained source file:
- OpenAI Agents SDK human-in-the-loop —
integrations/agent_frameworks/openai_agents_hitl.py - OpenAI Agents API human approval —
integrations/agent_frameworks/openai_agents_api_required_action.py - LangGraph human-in-the-loop —
integrations/agent_frameworks/langgraph_interrupts.py - CrewAI human-in-the-loop —
integrations/agent_frameworks/crewai_hitl.py
They use the existing Actionbox API and SDK. No backend migration or framework-specific Actionbox service is required.
For long-running state and restart recovery, read durable execution explained. The AI agent orchestration reference architecture connects that durable state to policy, approval, retries, and execution outcomes. To keep authority narrow, use the AI agent identity and access control guide. For the operating evidence, continue with AI agent governance, AI agent observability, and AI agent audit trail best practices.
If you are deciding where the person belongs in the operating model, compare human-in-the-loop vs human-on-the-loop. It separates approval before execution from runtime supervision and system-level command.
Sources and research
- OpenAI Agents SDK Human-in-the-Loop Documentation —
needs_approval, interruptions,RunState, and pause/approve/resume. - OpenAI Agents API Function Tools — pending function calls,
required_actions, and tool results. - LangGraph Interrupt Documentation — checkpoint persistence, thread IDs, interrupt payloads, and
Command(resume=...). - Python Software Foundation Logo — official Python vector via Wikimedia Commons (GPL Compatible).
Try it
- Install the Python SDK with
pip install actionbox-sdk - Create a Source and export
ACTIONBOX_API_KEY - Choose the OpenAI Agents API, OpenAI Agents SDK, or LangGraph tutorial
- Gate one consequential tool and test approval, rejection, timeout, and restart
Create a free Source · Read the integration guide · Connect an MCP agent
