Skip to content

Changelog

0.3.0 — 2026-09-11

Publish only. The WaitPublisher wrapper, pending(), republish(), is_answer() and resume_command() are gone. The library is ask() / @hitl in the graph and publish_interrupts(result, thread_id, announce) after the run — it reads result["__interrupt__"] and nothing else. No graph handle, no get_state().

@hitl. A tool decorator. mode="interrupt" calls ask() before the tool runs; mode="async" publishes from inside the tool through the decorator's own announcers and returns pending without parking the thread. Both register the policy by tool name.

HumanInTheLoopMiddleware (langchain ≥ 1.0) batches are understood: one envelope for the batch, the answer is {"decisions": [...]}.

Schema. PendingInterruptQuestion; interrupt_idquestion_id; single transition wait.created; policy gains answer_ttl; envelope gains source. The recommended answer message is documented, not received.

Removed from the receive path entirely. DynamoDbAnnounce writes the row and never reads it. Nothing in the library checks, dedupes or expires an answer — LangGraph ignores a duplicate resume on its own (verified), and the rest is the consumer's.

See Migrating.

0.2.1 — 2026-09-11

Documentation only. The README and package description now say what the library is for without underselling it: LangGraph hands an interrupt to whatever called invoke() and stops there — there is no built-in way to get it to anyone else, or for anyone else to answer, regardless of whether the process sticks around. Also adds the Writing an announcer guide. No code changes.

0.2.0 — 2026-09-11

First public release.

The library publishes interrupts and stops. One call — WaitPublisher.invoke() — runs the graph and publishes an envelope for each question it parked on, by diffing the framework's own pending set before and after. pending() reads that set; republish() re-announces it. ask() declares a question and its advisory policy at the interrupt site. There is no store, no inbound handling, no credential, no timer.

Announcers. BaseAnnounce implements the never-raise contract once; subclasses write deliver(). Shipped: WebhookAnnounce (signed, stdlib), LogAnnounce, InMemoryAnnounce, and in agent-wait-aws: SnsAnnounce, SqsAnnounce, EventBridgeAnnounce, DynamoDbAnnounce.

Verified against langgraph 1.2.11, with the observations recorded in reports/langgraph-spike-observations.txt and pinned by tests: interrupt ids are stable across re-entry; tasks[*].interrupts over-reports after a partial parallel resume (task.result is the discriminator); two interrupting tools in one ToolNode share an id.

Coming from 0.1

0.1 (tagged, never published) owned the whole round trip — tokens, a wait store, leases, a scheduler-driven timeout, an inbound dispatch(). All of it was removed. See Migrating for what moved to the caller and why.