result-tracker.js
4.2 KB
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
/**
* ResultTracker - 跟踪多轮执行结果和验证状态
*
* 职责:
* - 累积各轮次的 agent 执行结果
* - 状态机校验:防止状态退化(如 DONE → ERROR)
* - 保留历史轨迹供调试
* - 查询全局验证状态(哪些 validator 已通过/未通过)
* - 判断整体任务是否完成
*/
const { Scheduler } = require('./scheduler');
/**
* Agent 状态转换合法性矩阵
* key: `${agentType}:${oldStatus}→${newStatus}`
* value: 'allow' | 'warn' | 'deny'
*
* 未列出的转换默认 'allow'
*/
const STATE_TRANSITIONS = {
// executor: DONE 不应退化为 ERROR(任务已完成,不应回滚)
'executor:DONE→ERROR': 'warn',
// validator: PASS 退化为 FAIL 需要 warn(可能是重新验证后失败)
'validator:PASS→FAIL': 'warn',
// 正常的修复链路
'executor:ERROR→DONE': 'allow',
'validator:FAIL→PASS': 'allow',
};
class ResultTracker {
/**
* @param {Object} agents - Agent 配置 { name: { type, ... } }
*/
constructor(agents) {
this.agents = agents;
this._results = new Map();
/** 历史轨迹:记录每次状态变更 */
this._history = [];
}
/**
* 合并一轮执行结果(带状态机检查)
* @param {Array<{agent, status, message, output}>} results
* @param {number} [loop] - 当前循环轮次(用于历史记录)
*/
merge(results, loop) {
for (const r of results) {
this._mergeOne(r, loop);
}
}
/**
* 合并单个结果(内部方法)
* @private
*/
_mergeOne(result, loop) {
const { agent, status } = result;
const agentType = this.agents[agent]?.type || 'unknown';
const existing = this._results.get(agent);
const oldStatus = existing?.status || null;
// 状态机检查
if (oldStatus) {
const transitionKey = `${agentType}:${oldStatus}→${status}`;
const rule = STATE_TRANSITIONS[transitionKey] || 'allow';
if (rule === 'warn') {
console.warn(
`[ResultTracker] ⚠️ 状态退化: ${agent} (${agentType}) ${oldStatus} → ${status}。` +
`允许覆盖但记录告警。`
);
}
// 'deny' 暂不启用:线上更安全的做法是 warn + 覆盖,而非阻断
}
// 记录历史
this._history.push({
agent,
agentType,
oldStatus,
newStatus: status,
message: result.message,
loop: loop || null,
timestamp: Date.now(),
});
// 覆盖写入
this._results.set(agent, result);
}
/**
* 手动设置某个 agent 的结果
*/
set(agent, result) {
this._mergeOne(result);
}
/** 获取所有累积结果 */
getAll() {
return Array.from(this._results.values());
}
/** 是否还没有任何结果 */
isEmpty() {
return this._results.size === 0;
}
/** 任务是否完成(所有 validator PASS + 所有 executor DONE) */
isComplete() {
return Scheduler.isComplete(this.agents, this.getAll());
}
/**
* 获取历史轨迹
* @param {string} [agentName] - 可选,过滤特定 Agent
* @returns {Array<{agent, agentType, oldStatus, newStatus, message, loop, timestamp}>}
*/
getHistory(agentName) {
if (agentName) {
return this._history.filter(h => h.agent === agentName);
}
return [...this._history];
}
// ── 验证状态查询 ──
/** 所有配置的 validator 名称 */
get allValidators() {
return Object.entries(this.agents)
.filter(([_, cfg]) => cfg.type === 'validator')
.map(([name]) => name);
}
/** 已通过的 validator */
get passedValidators() {
const all = this.getAll();
return this.allValidators.filter(name =>
all.find(r => r.agent === name && r.status === 'PASS')
);
}
/** 未通过的 validator */
get unpassedValidators() {
const all = this.getAll();
return this.allValidators.filter(name =>
!all.find(r => r.agent === name && r.status === 'PASS')
);
}
// ── Agent 类型查询 ──
/** 所有配置的 executor / orchestrator 名称 */
get allExecutors() {
return Object.entries(this.agents)
.filter(([_, cfg]) => cfg.type === 'executor' || cfg.type === 'orchestrator')
.map(([name]) => name);
}
}
module.exports = { ResultTracker };