ActionBoxDOCS

LangGraph

Connect LangGraph interrupts to durable ActionBox decisions without moving graph checkpoint state into ActionBox.

LangGraph owns graph checkpoints and paused-run state. ActionBox supplies the durable human request and typed response; your graph driver owns the side effect and its credentials.

Ownership boundary

ConcernOwner
Graph state, checkpoint, and resumeLangGraph checkpointer
Interrupt ID and stable thread_idLangGraph
Reviewer inbox and typed responseActionBox
The approved operation and its credentialsYour graph or tool adapter

ActionBox does not replace the LangGraph checkpointer and does not execute the operation for you. Use a durable checkpointer when a human response can outlive the worker that first surfaced the interrupt.

Supported flow

  1. Run the graph with a stable thread_id and a checkpointer.
  2. Call interrupt(...) inside the node with a bounded, JSON-serializable review payload. Do not create the ActionBox Action inside the node: LangGraph can re-execute the node when it resumes.
  3. Let the graph driver observe result["__interrupt__"], then create one ActionBox Action per surfaced interrupt using a stable idempotency key.
  4. Wait for the typed response. A boolean response is the envelope {"type":"boolean","value":true} or false.
  5. Map the response to the value your node expects and resume the same checkpoint with Command(resume=...).
  6. Run the side effect only after the resumed graph confirms approval. If you need an execution record, report its real result to ActionBox after it finishes.

The core resume helper looks like this after your driver has received a pending interrupt and resolved its ActionBox request:

from langgraph.types import Command

async def resume_interrupt(graph, pending, response, thread_id: str):
    approved = (
        isinstance(response, dict)
        and response.get("type") == "boolean"
        and response.get("value") is True
    )
    return await graph.ainvoke(
        Command(resume={pending.id: {"approved": approved}}),
        config={"configurable": {"thread_id": thread_id}},
    )

Install the public SDKs in the environment that runs the graph:

python -m pip install actionbox-sdk langgraph

Keep the reviewed payload complete

Remove credentials and secret-bearing arguments before creating the Action. Reject an oversized payload instead of silently truncating it; the person must see the operation that the graph will resume.

Do not serialize framework-owned checkpoint state into an Action payload. Use a stable external ID, the interrupt ID, and bounded context blocks to correlate the Action with the graph run. Hash the stable thread_id and interrupt ID into the idempotency key so a retried driver recovers the same human request.

When multiple interrupts surface, resolve every item and pass an interrupt-ID map to Command(resume=...); do not assume the first item is the only one. Treat rejection, expiry, timeout, and a malformed response as approved=False.

For a complete walkthrough, see LangGraph human-in-the-loop approval.

On this page