import { test, expect } from 'vitest';
import {
StateGraph,
START,
END,
MemorySaver,
} from '@langchain/langgraph';
import { z } from "zod/v4";
const State = z.object({
my_key: z.string(),
});
const createGraph = () => {
return new StateGraph(State)
.addNode('node1', (state) => ({ my_key: 'hello from node1' }))
.addNode('node2', (state) => ({ my_key: 'hello from node2' }))
.addNode('node3', (state) => ({ my_key: 'hello from node3' }))
.addNode('node4', (state) => ({ my_key: 'hello from node4' }))
.addEdge(START, 'node1')
.addEdge('node1', 'node2')
.addEdge('node2', 'node3')
.addEdge('node3', 'node4')
.addEdge('node4', END);
};
test('partial execution from node2 to node3', async () => {
const uncompiledGraph = createGraph();
const checkpointer = new MemorySaver();
const compiledGraph = uncompiledGraph.compile({ checkpointer });
await compiledGraph.updateState(
{ configurable: { thread_id: '1' } },
// node 2에 전달되는 상태 - node 1의
// 끝에서의 상태를 시뮬레이션합니다
{ my_key: 'initial_value' },
// node 1에서 온 것처럼 저장된 상태를 업데이트합니다
// 실행은 node 2에서 재개됩니다
'node1',
);
const result = await compiledGraph.invoke(
// None을 전달하여 실행을 재개합니다
null,
{
configurable: { thread_id: '1' },
// node 3 이후에 중단하여 node 4가 실행되지 않도록 합니다
interruptAfter: ['node3']
},
);
expect(result.my_key).toBe('hello from node3');
});