1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//! WorkflowState + Mutation + MergeStrategy — Typed State 框架。
//!
//! v0.4+ 终局:砸碎 `HashMap<String, Value>`,引入编译期类型安全。
//!
//! 核心原则:
//! - 状态是强类型 struct,不是动态 HashMap
//! - 状态变更通过 Mutation(确定性命令),不是节点直接写
//! - Mutation 自己知道如何修改 State(CQRS / Event Sourcing 职责划分)
//! - 并行合并规则由 Graph 层的 MergeStrategy 决定,不是 State 内建属性
//! - Checkpoint 采用 Snapshot 实现快速恢复;Mutation Log 用于审计、调试和可选的
//! 确定性重放,两者共同构成完整的恢复与追踪体系
//!
//! Graph 层提供 trait 框架,各业务层(agent/mcp/...)定义自己的 State + Mutation。
use Debug;
// ─── StateMutation ──────────────────────────────────────────────
/// 状态变更命令 — 描述一次对 State 的确定性修改。
///
/// Mutation 自己知道如何修改对应的 State(`apply(self, &mut S)`)。
/// State 只是数据,Mutation 是变更逻辑,Executor 负责调度。
///
/// # 设计原则
///
/// - **Command 而非 Patch**:`AppendMessage` 而非 `SetMessages`
/// - **Enum 分发**:顶层 enum 只做一层 match,具体逻辑在各 variant 的 `apply()` 中
/// - **无 Serialize 强制**:只有需要 Replay 的运行时才加 `Serialize` bound
// ─── WorkflowState ──────────────────────────────────────────────
/// 工作流状态 — 编译期类型安全的状态容器。
///
/// 替代 `HashMap<String, Value>` 动态模型。
/// 每个工作流定义自己的 State struct 和 Mutation enum,
/// 实现此 trait 以声明关联类型。
///
/// **State 只是数据。** 状态变更逻辑在 [`StateMutation`] trait 中。
/// **Merge 职责已从 `WorkflowState` 剥离到 [`MergeStrategy`]。**
///
/// # 示例
///
/// ```rust,ignore
/// // State 只是数据
/// pub struct AgentState {
/// pub messages: Vec<Message>,
/// pub iterations: usize,
/// pub output_tokens: usize,
/// }
///
/// // Mutation 自己知道怎么改 State
/// pub enum AgentMutation {
/// AppendMessage(Message),
/// IncrementIteration,
/// RecordOutputTokens(usize),
/// }
///
/// impl StateMutation<AgentState> for AgentMutation {
/// fn apply(self, state: &mut AgentState) {
/// match self {
/// AgentMutation::AppendMessage(msg) => state.messages.push(msg),
/// AgentMutation::IncrementIteration => state.iterations += 1,
/// AgentMutation::RecordOutputTokens(n) => state.output_tokens += n,
/// }
/// }
/// }
///
/// // WorkflowState 只声明关联类型 — 没有 apply()
/// impl WorkflowState for AgentState {
/// type Mutation = AgentMutation;
/// }
/// ```
// ─── MergeStrategy ──────────────────────────────────────────────
/// 并行分支合并策略 — Graph 层职责,非 State 内建属性。
///
/// 将多个并行分支执行后产生的状态合并为一个。
/// 合并规则由 Graph 编排层决定,而非 State 自身。
///
/// # 职责边界
///
/// - **State** = 数据
/// - **MergeStrategy** = 并行语义
/// - **ExecutionEngine** = 调度 + commit
/// - **Node** = Mutation Producer
///
/// # 示例
///
/// ```rust,ignore
/// // 为 AgentState 定义合并策略
/// pub struct AgentStateMerge;
/// impl MergeStrategy<AgentState> for AgentStateMerge {
/// fn merge(branches: Vec<AgentState>) -> Result<AgentState, WorkflowError> {
/// // messages: concat, iterations: max, tokens: sum
/// }
/// }
///
/// // ParallelNode 使用
/// ParallelNode::builder()
/// .merge_strategy(AgentStateMerge)
/// .branch("search", search_node)
/// .branch("analyze", analyze_node)
/// .build();
/// ```
/// 默认合并策略 — 最后一个分支获胜。
///
/// 适用于大多数场景:各分支从同一 base 出发,
/// 最后一个分支的写入覆盖前面的。
;
// ─── WorkflowError ──────────────────────────────────────────────
/// 工作流状态操作错误。