Skip to content
Aabha AI Academy

All courses · Course overview · Lesson sequence

Skip to lesson text

Move the contract to LangGraph

The hand-written driver is small, but a larger workflow may need a graph runtime that exposes its next node and can pause for a decision. Rewriting the code in a framework can accidentally change its behavior. A visually impressive graph is not enough; the contract should survive migration.

This module runs actual LangGraph 1.2.16 around the deterministic engine. The planner and tools are still synthetic. Framework execution and model execution are separate claims: only the former occurs here.

Keep the controller underneath the graph

Open langgraph_migration.py. Graph state holds only run_id and phase; the Engine's checkpoint store owns the detailed job. Nodes call public controller methods rather than duplicating validation and authority logic.

The plan node routes RESERVED to invoke, REVIEW to review, and STOPPED to END. The invoke node returns ACTIVE to plan or STOPPED to END. The review node routes approval to finalization and rejection or stopping to END. Finalization ends the graph. The visual shows this selected route; the source code is the complete edge definition.

If the diagram extends beyond the screen, scroll inside it or read the text version below.

Actual framework execution preserves the controller contract Actual framework execution preserves the controller contract
plan node / Engine proposes / and checks; invoke node / Reserved read / then checkpoint; plan node / Loop on ACTIVE / or prepare draft; review node / interrupt; resume / with Command; finalize node / Simulation receipt / then END. Every return route is explicit: unsupported work and exhausted limits route to END. LangGraph 1.2.16 ran locally with sockets blocked in tests. InMemorySaver is not disk persistence.
Read the diagram as text
  • Actual framework execution preserves the controller contract
  • Selected approved path; rejection and stops route to END
  • plan node
  • Engine proposes
  • and checks
  • invoke node
  • Reserved read
  • then checkpoint
  • plan node
  • Loop on ACTIVE
  • or prepare draft
  • review node
  • interrupt; resume
  • with Command
  • finalize node
  • Simulation receipt
  • then END
  • Every return route is explicit: unsupported work and exhausted limits route to END.
  • LangGraph 1.2.16 ran locally with sockets blocked in tests. InMemorySaver is not disk persistence.

The Engine's budgets remain the application bound. recursion_limit=64 is an additional framework bound in the demonstration configuration. Do not remove application budgets because a graph runtime can limit node execution: the two counters measure different units and provide different explanations.

Pause without doing the action twice

The review node loads the saved draft and calls interrupt with a simulation-labelled payload containing its revision, digest, draft and deadline. It performs no write before that interrupt. On resume, LangGraph restarts the node, so work before the pause can run again. The application must be designed with that replay behavior in mind.

The resume value must have exactly the expected decision fields. Engine.review then checks the revision, digest, fixture reviewer and logical time. The graph does not turn an arbitrary resume object into approval. The finalization node calls the same simulation-only method used without the framework.

The demonstration fixes draft creation tick at 5 and finalization tick at 6. decision_for supplies tick 6. These are reproducible fixtures, not a real-time user interface. A future interactive adapter must pass consistent trusted times rather than reuse these constants. See the official interrupt documentation for node replay and pause/resume behavior.

Use a separate dependency environment

The core course runs on the standard library. Module 7 additionally needs the pinned requirements file. The resolved receipt records the exact packages used for the authoring run on Python 3.14.4. It is an environment receipt, not a cross-platform hash lock or a promise that those packages are right for every future platform.

Use an existing approved isolated Python environment with that dependency, or install it into a separate disposable environment under your own normal setup policy. No environment is bundled in this package. No provider key, model account, tracing service or paid service is required. Set AABHA_GRAPH_PYTHON to that environment's Python, then from the course folder run:

LANGSMITH_TRACING=false LANGCHAIN_TRACING_V2=false PYTHONDONTWRITEBYTECODE=1 "$AABHA_GRAPH_PYTHON" -m unittest discover -s framework_tests -v
LANGSMITH_TRACING=false LANGCHAIN_TRACING_V2=false PYTHONDONTWRITEBYTECODE=1 "$AABHA_GRAPH_PYTHON" project/langgraph_migration.py

If the dependency is absent, the normal project test command reports one clearly labelled optional-suite skip. That is not a framework pass. In the supplied authoring environment the explicit framework command ran all seven tests with no skips. The tests block Python socket connections during graph operations and disable tracing through the documented environment flags.

Inspect what persistence means here

InMemorySaver keeps graph checkpoints in RAM. The Engine also uses RAM SQLite. A thread ID selects a graph execution in that saver; it is not a reviewer identity, permission token or durable backup. Closing the process loses both stores unless state is transferred through a separately designed persistence mechanism.

LangGraph's overview describes an orchestration runtime that can mix fixed and model-driven steps. This course uses its fixed-step side. CrewAI is an optional catalogue comparison, not a second implementation in this edition. No CrewAI behavior or live agent performance is claimed.

Practice

  1. Run the explicit framework suite in a permitted isolated environment and record its version, test count and skip count. If unavailable, record that blocker and inspect the code without claiming execution.
  2. Inspect graph.get_state(config) at the pause. Explain why next names the review node even though the Engine phase is already REVIEW. Compare the draft with the standard-library baseline.
  3. Resume independent runs with approval, rejection and a stale revision. Verify phase, receipt availability and tool count. Explain why restarting the review node does not perform a second lookup.
  4. Run the always-lookup planner through the graph. Confirm that the application's tool budget still stops it. Describe which result would count as a migration regression.

Check yourself: which store owns the detailed museum fact? Is a thread ID proof of authorization? What would need to change before claiming recovery across an actual process restart?

Keep framework evidence separate from the standard-library result and from unperformed model testing. A successful migration preserves behavior; it does not magically add autonomy, durable operations or production approval.

Read separate answers and explanations