Resume a pending protocol interrupt by sending a response payload back to the interrupted namespace.
When options.interruptId is omitted, walks getThread()?.interrupts
from newest to oldest and resumes the first not yet resolved by a prior
respond() call. That may be a root or subgraph interrupt and is
not necessarily interrupt (interrupts()[0], root-only).
Safe when exactly one interrupt is pending; otherwise pass an explicit
options.interruptId (and options.namespace for subgraph
interrupts).
The server validates namespace against the pending interrupt. Root
interrupts use namespace: [] (default when omitted). For subgraph
interrupts, copy namespace from getThread()?.interrupts.
Pass options.update (and/or options.goto) to apply a state update
(and/or directed jump) in the same superstep as the resume — mapped
to LangGraph's Command(resume, update, goto). The resumed run produces
a single checkpoint reflecting both, so a HITL card can push its message
into state at the moment it answers the interrupt (no separate state
write, no intermediate checkpoint, no flicker). Messages may be plain
dicts or @langchain/core BaseMessage instances (serialized like
submit()).
respond(response: unknown, options: StreamRespondOptions<ConfigurableType>): Promise<void>| Name | Type | Description |
|---|---|---|
response* | unknown | |
options | StreamRespondOptions<ConfigurableType> |
// Single pending interrupt
await stream.respond({ approved: true });// Resolve the interrupt AND push the card's message into state atomically
await stream.respond({ approved: true }, {
update: { messages: [{ type: "ai", content: "Approved by reviewer." }] },
});// `update` also accepts BaseMessage instances, like `submit()`
import { AIMessage } from "@langchain/core/messages";
await stream.respond({ approved: true }, {
update: { messages: [new AIMessage("Approved by reviewer.")] },
});// Multiple root interrupts
for (const intr of stream.interrupts()) {
await stream.respond(decide(intr.value), { interruptId: intr.id! });
}// Subgraph interrupt — namespace from `getThread()`
const thread = stream.getThread();
for (const entry of thread?.interrupts ?? []) {
await stream.respond(buildResponse(entry.payload), {
interruptId: entry.interruptId,
namespace: entry.namespace,
});
}