Human in the Loopinterrupt() and Command({ resume })
No narration yet
Module 5, Lesson 120 min

interrupt() and Command({ resume })

Your todoist bridge is half-manual for one reason: destructive actions (close, graduate) are held in a needs-review.md file because nothing can safely gate them. This module makes those actions pause the graph and wait for your decision. The gap that keeps the bridge from being autonomous closes here.

interrupt() pauses a running graph and hands control back to the caller. Inside a node you call it with a payload; the graph stops, surfaces that payload, and waits. You resume by invoking again with a Command({ resume }).

Pausing a node with interrupt()
import { interrupt, Command } from "@langchain/langgraph";

const approveNode = (state) => {
  const answer = interrupt({
    action: "close",
    taskId: state.taskId,
    title: state.title,
  });
  // execution suspends HERE. `answer` is filled in on resume.
  if (answer === "approve") return { decision: "close" };
  return { decision: "skip" };
};
Resuming an interrupted thread
const result = await graph.invoke(inputs, config);
if (result.__interrupt__) {
  // show result.__interrupt__ payload to the human, get a decision
  await graph.invoke(new Command({ resume: "approve" }), config);
}
Practice

Try it yourself

Recall

Why interrupt needs a checkpointer

Answer by walking what happens at resume time, not only at the moment of the pause.

What breaks if you call interrupt() on a graph with no checkpointer?