State Maintenance and Refactoring Mechanism#
During the operation of the graph engine, the system maintains state information through a tree structure to achieve state traceability and efficient reconstruction.
State Tree Structure#
Each node’s input is a complete
Stateobject.The node’s output is not the full state, but rather the node’s state delta (delta).
During runtime, all states are stored as a tree:
The root node represents the input state of the graph engine.
Each child node contains its parent node reference and the current node’s
delta.During state recovery, the system recursively merges upward from the parent node, reconstructing the complete state level by level.
State Reconstruction Logic#
When nodes or edges require the full state, the graph engine will execute the following steps:
Merge all
deltafrom the root node downward according to the declared update strategy.After performing a deep copy of the complete state, pass it to nodes or edges for execution.
Note
Due to the deep copy strategy, modifications to the input state by nodes and edges will not affect the state tree maintained internally by the engine.
The impact of changing the state strategy#
There are two special strategies in the graph engine that may cause the root of the state tree to be reset:
node’s
multi_input_merge_strategyedge’s
state_filter
Since both of these are user-customizable merge logic, the engine cannot guarantee that their results are fully compatible with the original state. Therefore:
Once the above strategy is executed, the root node will be reset to the state output by the strategy.
If these strategies delete some state information, this information cannot be recovered in subsequent nodes.
Example: Difference between having and not having state_filter
Assume there is a linear path: A -> B -> C -> End
Initial state (input):
state = {"user": {"name": "Alice", "age": 20}, "score": 90}
The execution logic for each node is as follows:
A Output increment:
{"user": {"age": 21}}B Output increment:
{"score": 95}
Case 1: No state_filter
Edge B -> C does not define state_filter, therefore the state is fully passed:
# Input state of Node C:
{"user": {"name": "Alice", "age": 21}, "score": 95}
# GraphEngine output:
{"user": {"name": "Alice", "age": 21}, "score": 95}
Case 2: With state_filter
Assume edge B -> C defines the following filter:
def state_filter(state):
return {"score": state["score"]}
At this point, the output of state_filter is treated as the new root state, causing the user field to be permanently discarded.
# Input state of Node C:
{"score": 95}
# GraphEngine output:
{"score": 95}
Because state_filter deleted the user information, subsequent nodes can no longer receive this field.
Final State Output#
During the execution of the graph, the end node will construct the state queue, collecting all incoming states:
The states in the queue are arranged in routing order.
The engine will sequentially merge the states in the queue according to the defined update strategy.
The final output is the complete
Stateobject after merging all states.
Through this mechanism, the graph engine can achieve flexible state reconstruction and traceability while ensuring state consistency.