Framework guides
How to add human approvals to LangGraph
Pause LangGraph execution at deterministic checkpoints, route review through CENTCOM, and resume with signed decisions.
LangGraph is a strong fit for checkpointed approval flows because interrupt and resume map cleanly to human review steps.
Use the integration skill
Copy this skill link into your code agent to add LangGraph and Contro1 to your system.
Key takeaways
- LangGraph's native interrupt() pauses a thread without blocking a worker - resume via a signed webhook.
- Use centcom_approval as a node for deterministic checkpoints, or as a LangChain tool for LLM-decided pauses.
- Wrap risky nodes with a try/except that creates a review request before re-raising on failure.
- Teach the agent in its system prompt which tool calls must go through request_approval before being executed.
When to reach for Contro1 in LangGraph
LangGraph gives you explicit control over where a graph pauses and resumes, which maps cleanly to "a human must decide before this edge continues." Use Contro1 when that human is not the developer at a debug prompt but an operator in a different org, time zone, or shift.
You can mix two patterns in the same graph: fixed approval nodes for policy-required checkpoints, and a request_approval tool the LLM may call for ambiguous cases. Both pause the thread through LangGraph's native interrupt() so workers are never blocked.
Installation
Basic integration
Case continuity
LangGraph's config.configurable.thread_id is its own state key. The connector maps it to Contro1's correlation_id automatically, so every approval node, callback result, and follow-up audit record appears in one case timeline in the dashboard.
Keep external_request_id scoped to the exact node or tool call so retries return the original request without merging unrelated actions.
Logging autonomous actions
Use log_action when a graph node finishes an action that was already allowed by policy and does not need human review. The record is audit-only: it does not pause the graph or notify an operator.
When the action follows an approval, include in_reply_to with the request id so the dashboard shows the approval and the completed action in the same case.
Gate the tool before it executes
The tool function itself is the right place to require approval for irreversible actions. The first line of a destructive tool calls Contro1 and blocks until an operator decides. Nothing runs until the human says yes - no prompt engineering needed.
Pause the agent on system error - orchestrator level
Wrap the node that can fail at the graph level. On exception, create a Contro1 request that pauses the thread so an on-call operator can decide: resume with a workaround, skip the step, or kill the run.
Escalate tool errors to a human
Inside a tool the agent owns, wrap the work in a try/except that escalates exceptions to Contro1 before the exception leaves the tool. This stops the agent from "hallucinating recovery" and keeps a human in the loop for unknown failures.
Prompt engineering: force the agent to pause
The following system-prompt block teaches the agent which situations require it to stop and call request_approval before doing anything else. Paste it verbatim into your LangGraph agent's system message.
See our GitHub integration repo
The code above is adapted from production examples published in our open-source connector. Use these files as your reference implementation.
centcom-langgraph on GitHub · simple_webhook.py - minimal order approval · production_webhook.py - full refund flow · fastapi_webhook.py - production webhook receiver
Frequently asked questions
When should I use fixed approval nodes instead of letting the model decide?
Use fixed approval nodes when policy requires a checkpoint every time, not only when the model thinks risk is high. Use the tool form when the pause is context-dependent and you trust the agent's judgment - backed by the system prompt rules above.
Does interrupt() block my worker?
No. LangGraph persists the thread state and frees the worker. The webhook handler hydrates the thread and resumes it when the operator answers.
What happens if the webhook handler fails to resume the thread?
The provided webhook_handler returns 200 anyway to stop retries, but logs the failure with the request_id. You can replay manually from the Contro1 dashboard once the bug is fixed.
How do I prevent duplicate requests when the graph retries?
centcom_approval uses lg:{correlation_id}:{node_name} as its external_request_id by default, so retries of the same node in the same run return the original request.
Can the operator send free-text feedback back into the graph?
Yes. The callback payload includes response.comment. Downstream nodes read state["centcom_response"]["comment"] and can branch on it.