Skip to content

List history and rehydrate

For the complete documentation index see: llms.txt

All documentation pages available in markdown.

Phase 1 resolved a refund for ORD-10482. Phases 2 and 3 set up the fork: the customer changes their mind, then you locate the checkpoint worth resuming from.

Keep the demo terminal open from Run the original resolution. If you exited, re-run uv run python cookbooks/agent-path-correction/demo.py and advance to Phase 3.

Phase 2: the customer changes their mind

  1. Advance to Phase 2:

    Phase 1 ended with a refund resolution for ORD-10482. Before touching checkpoint history, the demo introduces what changed. The customer now wants a replacement instead of a refund. The corrected message deliberately does not mention headphones, so a fresh graph run would have no way to know which order to act on. Phase 2 states that problem in plain language. The fix comes in Phase 3.

    Press Enter when prompted.

  2. Review the Phase 2 output:

    ================================================================
    Phase 2 - The customer changes their mind
    ================================================================
    customer > On second thought, please send a replacement instead.
    This request does not mention headphones, so a fresh run would not know
    which order to use. You need a saved checkpoint that already has order_id.

Phase 3: find the reuse point in Aerospike

  1. Advance to Phase 3:

    You need a checkpoint that already knows ORD-10482 but has not committed to refund or replacement yet. Phase 1 wrote five checkpoints to Aerospike as the graph ran. Phase 3 prints that full timeline so you can pick the right row.

    The demo calls saver.list() on the thread from Phase 1 and prints one row per checkpoint: when it was saved, and the order_id, intent, and resolution values frozen at that moment. It then scans for the earliest row where order_id is set and resolution is still unset. That is checkpoint seq 3 in the table: right after identify_order ran, before classify or resolve chose an outcome. A final get_tuple() on that row loads the reuse point into memory without re-running the lookup.

    Press Enter when prompted.

  2. Review the checkpoint table:

    Look for row 3. It is the reuse point: order_id is set to ORD-10482 but intent and resolution are still None.

    ================================================================
    Phase 3 - Find the reuse point in Aerospike
    ================================================================
    pending request: "On second thought, please send a replacement instead."
    Need: order_id set, but no decision selected yet.
    seq checkpoint saved after order_id intent resolution
    1 ... thread start None None None
    2 ... request received None None None
    3 ... order identified ORD-10482 None None
    4 ... intent classified ORD-10482 refund None
    5 ... decision selected ORD-10482 refund Refund selected for order ORD-10482
    -> 5 checkpoints saved for this thread.
    reuse point : ... (order identified, not yet resolved)
    order_id : ORD-10482 <- already derived, sitting in the checkpoint
    -> Restored the checkpoint state; the order lookup node did not run again.
  3. Confirm the reuse point and rehydrated state:

    Row 3 is the reuse point: order_id is ORD-10482 with intent and resolution still unset. The demo scans for the earliest checkpoint where order_id is set and resolution is still unset. Row 4 also matches that criterion but comes later in the timeline, after classify set intent=refund. Row 5 holds the final refund resolution. Rows 4 and 5 stay in Aerospike for audit, but the fork starts from row 3 so classify and resolve run on the replacement request. The demo loaded row 3 with get_tuple() and confirmed identify_order did not run again.

    • The reuse point row is labeled order identified, not yet resolved (checkpoint seq 3 in the table).
    • Rehydrated state shows order_id is ORD-10482 with intent and resolution still unset.

    You now have the checkpoint config for the replacement request. Fork and write the handoff note passes it to graph.invoke() so LangGraph resumes from that moment instead of the refund outcome at the end of the thread.

Feedback

Was this page helpful?

What type of feedback are you giving?

What would you like us to know?

+Capture screenshot

Can we reach out to you?