foliko 1.0.75 → 1.0.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +159 -157
- package/cli/bin/foliko.js +12 -12
- package/cli/src/commands/chat.js +143 -143
- package/cli/src/commands/list.js +93 -93
- package/cli/src/index.js +75 -75
- package/cli/src/ui/chat-ui.js +201 -201
- package/cli/src/utils/ansi.js +40 -40
- package/cli/src/utils/markdown.js +292 -292
- package/examples/ambient-example.js +194 -194
- package/examples/basic.js +115 -115
- package/examples/bootstrap.js +121 -121
- package/examples/mcp-example.js +56 -56
- package/examples/skill-example.js +49 -49
- package/examples/test-chat.js +137 -137
- package/examples/test-mcp.js +85 -85
- package/examples/test-reload.js +59 -59
- package/examples/test-telegram.js +50 -50
- package/examples/test-tg-bot.js +45 -45
- package/examples/test-tg-simple.js +47 -47
- package/examples/test-tg.js +62 -62
- package/examples/test-think.js +43 -43
- package/examples/test-web-plugin.js +103 -103
- package/examples/test-weixin-feishu.js +103 -103
- package/examples/workflow.js +158 -158
- package/package.json +1 -1
- package/plugins/ai-plugin.js +102 -102
- package/plugins/ambient-agent/EventWatcher.js +113 -113
- package/plugins/ambient-agent/ExplorerLoop.js +640 -640
- package/plugins/ambient-agent/GoalManager.js +197 -197
- package/plugins/ambient-agent/Reflector.js +95 -95
- package/plugins/ambient-agent/StateStore.js +90 -90
- package/plugins/ambient-agent/constants.js +101 -101
- package/plugins/ambient-agent/index.js +579 -579
- package/plugins/audit-plugin.js +187 -187
- package/plugins/default-plugins.js +662 -662
- package/plugins/email/constants.js +64 -64
- package/plugins/email/handlers.js +461 -461
- package/plugins/email/index.js +278 -278
- package/plugins/email/monitor.js +269 -269
- package/plugins/email/parser.js +138 -138
- package/plugins/email/reply.js +151 -151
- package/plugins/email/utils.js +124 -124
- package/plugins/feishu-plugin.js +481 -481
- package/plugins/file-system-plugin.js +826 -826
- package/plugins/install-plugin.js +199 -199
- package/plugins/python-executor-plugin.js +367 -367
- package/plugins/python-plugin-loader.js +481 -481
- package/plugins/rules-plugin.js +294 -294
- package/plugins/scheduler-plugin.js +691 -691
- package/plugins/session-plugin.js +369 -369
- package/plugins/shell-executor-plugin.js +197 -197
- package/plugins/storage-plugin.js +240 -240
- package/plugins/subagent-plugin.js +845 -845
- package/plugins/telegram-plugin.js +482 -482
- package/plugins/think-plugin.js +345 -345
- package/plugins/tools-plugin.js +196 -196
- package/plugins/web-plugin.js +606 -606
- package/plugins/weixin-plugin.js +545 -545
- package/src/capabilities/index.js +11 -11
- package/src/capabilities/skill-manager.js +609 -609
- package/src/capabilities/workflow-engine.js +1109 -1109
- package/src/core/agent-chat.js +882 -882
- package/src/core/agent.js +892 -892
- package/src/core/framework.js +465 -465
- package/src/core/index.js +19 -19
- package/src/core/plugin-base.js +219 -219
- package/src/core/plugin-manager.js +863 -863
- package/src/core/provider.js +114 -114
- package/src/core/sub-agent-config.js +264 -264
- package/src/core/system-prompt-builder.js +120 -120
- package/src/core/tool-registry.js +517 -517
- package/src/core/tool-router.js +297 -297
- package/src/executors/executor-base.js +58 -58
- package/src/executors/mcp-executor.js +741 -741
- package/src/index.js +25 -25
- package/src/utils/circuit-breaker.js +301 -301
- package/src/utils/error-boundary.js +363 -363
- package/src/utils/error.js +374 -374
- package/src/utils/event-emitter.js +97 -97
- package/src/utils/id.js +133 -133
- package/src/utils/index.js +217 -217
- package/src/utils/logger.js +181 -181
- package/src/utils/plugin-helpers.js +90 -90
- package/src/utils/retry.js +122 -122
- package/src/utils/sandbox.js +292 -292
- package/test/tool-registry-validation.test.js +218 -218
- package/website/script.js +136 -136
- package/foliko-1.0.75.tgz +0 -0
|
@@ -1,197 +1,197 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GoalManager - 管理目标及其生命周期状态
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const { logger } = require('../../src/utils/logger')
|
|
6
|
-
const { GoalState } = require('./constants')
|
|
7
|
-
const { generateId } = require('../../src/utils/id')
|
|
8
|
-
|
|
9
|
-
const log = logger.child('Ambient:GoalManager')
|
|
10
|
-
|
|
11
|
-
class GoalManager {
|
|
12
|
-
constructor(stateStore) {
|
|
13
|
-
this._goals = new Map()
|
|
14
|
-
this._stateStore = stateStore
|
|
15
|
-
this._loadGoals()
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
_loadGoals() {
|
|
19
|
-
const savedGoals = this._stateStore.loadGoals()
|
|
20
|
-
for (const goal of savedGoals) {
|
|
21
|
-
this._goals.set(goal.id, goal)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
_persist() {
|
|
26
|
-
const goalsArray = Array.from(this._goals.values())
|
|
27
|
-
this._stateStore.saveGoals(goalsArray)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 创建新目标
|
|
32
|
-
* @param {Object} goalData - 目标数据
|
|
33
|
-
* @returns {Object} 创建的目标
|
|
34
|
-
*/
|
|
35
|
-
createGoal(goalData) {
|
|
36
|
-
const actions = goalData.actions || []
|
|
37
|
-
const goal = {
|
|
38
|
-
id: generateId(),
|
|
39
|
-
title: goalData.title || '未命名目标',
|
|
40
|
-
description: goalData.description || '',
|
|
41
|
-
priority: goalData.priority || 5,
|
|
42
|
-
state: GoalState.PENDING,
|
|
43
|
-
actions: actions,
|
|
44
|
-
_originalActions: actions.slice(), // 保存原始 actions,用于事件驱动目标重置
|
|
45
|
-
conditions: goalData.conditions || {},
|
|
46
|
-
createdAt: new Date(),
|
|
47
|
-
updatedAt: new Date(),
|
|
48
|
-
activatedAt: null,
|
|
49
|
-
completedAt: null,
|
|
50
|
-
failedAt: null,
|
|
51
|
-
attempts: 0,
|
|
52
|
-
maxAttempts: goalData.maxAttempts || 10,
|
|
53
|
-
consecutiveSameActions: 0,
|
|
54
|
-
lastActionId: null,
|
|
55
|
-
eventsReceived: []
|
|
56
|
-
}
|
|
57
|
-
this._goals.set(goal.id, goal)
|
|
58
|
-
this._persist()
|
|
59
|
-
return goal
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* 获取目标
|
|
64
|
-
* @param {string} id - 目标ID
|
|
65
|
-
* @returns {Object|null} 目标对象
|
|
66
|
-
*/
|
|
67
|
-
getGoal(id) {
|
|
68
|
-
return this._goals.get(id)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* 获取所有目标
|
|
73
|
-
* @returns {Array} 所有目标数组
|
|
74
|
-
*/
|
|
75
|
-
getAllGoals() {
|
|
76
|
-
return Array.from(this._goals.values())
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* 获取活跃目标
|
|
81
|
-
* @returns {Array} 活跃目标数组
|
|
82
|
-
*/
|
|
83
|
-
getActiveGoals() {
|
|
84
|
-
return Array.from(this._goals.values()).filter(g => g.state === GoalState.ACTIVE)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* 获取待处理目标
|
|
89
|
-
* @returns {Array} 待处理目标数组
|
|
90
|
-
*/
|
|
91
|
-
getPendingGoals() {
|
|
92
|
-
return Array.from(this._goals.values()).filter(g => g.state === GoalState.PENDING)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* 更新目标
|
|
97
|
-
* @param {string} id - 目标ID
|
|
98
|
-
* @param {Object} updates - 更新数据
|
|
99
|
-
* @returns {Object|null} 更新后的目标
|
|
100
|
-
*/
|
|
101
|
-
updateGoal(id, updates) {
|
|
102
|
-
const goal = this._goals.get(id)
|
|
103
|
-
if (!goal) return null
|
|
104
|
-
Object.assign(goal, updates, { updatedAt: new Date() })
|
|
105
|
-
this._persist()
|
|
106
|
-
return goal
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* 激活目标
|
|
111
|
-
* @param {string} id - 目标ID
|
|
112
|
-
* @returns {Object|null} 激活后的目标
|
|
113
|
-
*/
|
|
114
|
-
activateGoal(id) {
|
|
115
|
-
const goal = this._goals.get(id)
|
|
116
|
-
if (!goal || goal.state !== GoalState.PENDING) return null
|
|
117
|
-
goal.state = GoalState.ACTIVE
|
|
118
|
-
goal.activatedAt = new Date()
|
|
119
|
-
goal.updatedAt = new Date()
|
|
120
|
-
this._persist()
|
|
121
|
-
return goal
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* 标记目标为已完成
|
|
126
|
-
* @param {string} id - 目标ID
|
|
127
|
-
* @returns {Object|null} 目标对象
|
|
128
|
-
*/
|
|
129
|
-
completeGoal(id) {
|
|
130
|
-
const goal = this._goals.get(id)
|
|
131
|
-
if (!goal) return null
|
|
132
|
-
goal.state = GoalState.COMPLETED
|
|
133
|
-
goal.completedAt = new Date()
|
|
134
|
-
goal.updatedAt = new Date()
|
|
135
|
-
this._persist()
|
|
136
|
-
return goal
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* 标记目标为失败
|
|
141
|
-
* @param {string} id - 目标ID
|
|
142
|
-
* @param {string} reason - 失败原因
|
|
143
|
-
* @returns {Object|null} 目标对象
|
|
144
|
-
*/
|
|
145
|
-
failGoal(id, reason) {
|
|
146
|
-
const goal = this._goals.get(id)
|
|
147
|
-
if (!goal) return null
|
|
148
|
-
goal.state = GoalState.FAILED
|
|
149
|
-
goal.failedAt = new Date()
|
|
150
|
-
goal.failureReason = reason
|
|
151
|
-
goal.updatedAt = new Date()
|
|
152
|
-
this._persist()
|
|
153
|
-
return goal
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* 删除目标
|
|
158
|
-
* @param {string} id - 目标ID
|
|
159
|
-
* @returns {boolean} 是否删除成功
|
|
160
|
-
*/
|
|
161
|
-
deleteGoal(id) {
|
|
162
|
-
const deleted = this._goals.delete(id)
|
|
163
|
-
if (deleted) this._persist()
|
|
164
|
-
return deleted
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* 向目标添加事件(带去重)
|
|
169
|
-
* @param {string} goalId - 目标ID
|
|
170
|
-
* @param {Object} event - 事件数据
|
|
171
|
-
*/
|
|
172
|
-
addEventToGoal(goalId, event) {
|
|
173
|
-
const goal = this._goals.get(goalId)
|
|
174
|
-
if (!goal) return
|
|
175
|
-
|
|
176
|
-
// 通用去重:如果最近 2 秒内已有相同类型的事件,跳过
|
|
177
|
-
const now = Date.now()
|
|
178
|
-
const recentSameEvent = goal.eventsReceived.find(e =>
|
|
179
|
-
e.event === event.type && (now - new Date(e.timestamp).getTime()) < 2000
|
|
180
|
-
)
|
|
181
|
-
if (recentSameEvent) {
|
|
182
|
-
log.info(`跳过重复事件: ${event.type} (2秒内不重复添加)`)
|
|
183
|
-
return
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// event 格式: { type: 'email:received', email: {...}, timestamp: ... }
|
|
187
|
-
// 需要提取 type 和 data(email 对象)
|
|
188
|
-
goal.eventsReceived.push({
|
|
189
|
-
event: event.type,
|
|
190
|
-
data: event.data || event.email || event,
|
|
191
|
-
timestamp: new Date()
|
|
192
|
-
})
|
|
193
|
-
this._persist()
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
module.exports = { GoalManager }
|
|
1
|
+
/**
|
|
2
|
+
* GoalManager - 管理目标及其生命周期状态
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { logger } = require('../../src/utils/logger')
|
|
6
|
+
const { GoalState } = require('./constants')
|
|
7
|
+
const { generateId } = require('../../src/utils/id')
|
|
8
|
+
|
|
9
|
+
const log = logger.child('Ambient:GoalManager')
|
|
10
|
+
|
|
11
|
+
class GoalManager {
|
|
12
|
+
constructor(stateStore) {
|
|
13
|
+
this._goals = new Map()
|
|
14
|
+
this._stateStore = stateStore
|
|
15
|
+
this._loadGoals()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
_loadGoals() {
|
|
19
|
+
const savedGoals = this._stateStore.loadGoals()
|
|
20
|
+
for (const goal of savedGoals) {
|
|
21
|
+
this._goals.set(goal.id, goal)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
_persist() {
|
|
26
|
+
const goalsArray = Array.from(this._goals.values())
|
|
27
|
+
this._stateStore.saveGoals(goalsArray)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 创建新目标
|
|
32
|
+
* @param {Object} goalData - 目标数据
|
|
33
|
+
* @returns {Object} 创建的目标
|
|
34
|
+
*/
|
|
35
|
+
createGoal(goalData) {
|
|
36
|
+
const actions = goalData.actions || []
|
|
37
|
+
const goal = {
|
|
38
|
+
id: generateId(),
|
|
39
|
+
title: goalData.title || '未命名目标',
|
|
40
|
+
description: goalData.description || '',
|
|
41
|
+
priority: goalData.priority || 5,
|
|
42
|
+
state: GoalState.PENDING,
|
|
43
|
+
actions: actions,
|
|
44
|
+
_originalActions: actions.slice(), // 保存原始 actions,用于事件驱动目标重置
|
|
45
|
+
conditions: goalData.conditions || {},
|
|
46
|
+
createdAt: new Date(),
|
|
47
|
+
updatedAt: new Date(),
|
|
48
|
+
activatedAt: null,
|
|
49
|
+
completedAt: null,
|
|
50
|
+
failedAt: null,
|
|
51
|
+
attempts: 0,
|
|
52
|
+
maxAttempts: goalData.maxAttempts || 10,
|
|
53
|
+
consecutiveSameActions: 0,
|
|
54
|
+
lastActionId: null,
|
|
55
|
+
eventsReceived: []
|
|
56
|
+
}
|
|
57
|
+
this._goals.set(goal.id, goal)
|
|
58
|
+
this._persist()
|
|
59
|
+
return goal
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 获取目标
|
|
64
|
+
* @param {string} id - 目标ID
|
|
65
|
+
* @returns {Object|null} 目标对象
|
|
66
|
+
*/
|
|
67
|
+
getGoal(id) {
|
|
68
|
+
return this._goals.get(id)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 获取所有目标
|
|
73
|
+
* @returns {Array} 所有目标数组
|
|
74
|
+
*/
|
|
75
|
+
getAllGoals() {
|
|
76
|
+
return Array.from(this._goals.values())
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 获取活跃目标
|
|
81
|
+
* @returns {Array} 活跃目标数组
|
|
82
|
+
*/
|
|
83
|
+
getActiveGoals() {
|
|
84
|
+
return Array.from(this._goals.values()).filter(g => g.state === GoalState.ACTIVE)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* 获取待处理目标
|
|
89
|
+
* @returns {Array} 待处理目标数组
|
|
90
|
+
*/
|
|
91
|
+
getPendingGoals() {
|
|
92
|
+
return Array.from(this._goals.values()).filter(g => g.state === GoalState.PENDING)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* 更新目标
|
|
97
|
+
* @param {string} id - 目标ID
|
|
98
|
+
* @param {Object} updates - 更新数据
|
|
99
|
+
* @returns {Object|null} 更新后的目标
|
|
100
|
+
*/
|
|
101
|
+
updateGoal(id, updates) {
|
|
102
|
+
const goal = this._goals.get(id)
|
|
103
|
+
if (!goal) return null
|
|
104
|
+
Object.assign(goal, updates, { updatedAt: new Date() })
|
|
105
|
+
this._persist()
|
|
106
|
+
return goal
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 激活目标
|
|
111
|
+
* @param {string} id - 目标ID
|
|
112
|
+
* @returns {Object|null} 激活后的目标
|
|
113
|
+
*/
|
|
114
|
+
activateGoal(id) {
|
|
115
|
+
const goal = this._goals.get(id)
|
|
116
|
+
if (!goal || goal.state !== GoalState.PENDING) return null
|
|
117
|
+
goal.state = GoalState.ACTIVE
|
|
118
|
+
goal.activatedAt = new Date()
|
|
119
|
+
goal.updatedAt = new Date()
|
|
120
|
+
this._persist()
|
|
121
|
+
return goal
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* 标记目标为已完成
|
|
126
|
+
* @param {string} id - 目标ID
|
|
127
|
+
* @returns {Object|null} 目标对象
|
|
128
|
+
*/
|
|
129
|
+
completeGoal(id) {
|
|
130
|
+
const goal = this._goals.get(id)
|
|
131
|
+
if (!goal) return null
|
|
132
|
+
goal.state = GoalState.COMPLETED
|
|
133
|
+
goal.completedAt = new Date()
|
|
134
|
+
goal.updatedAt = new Date()
|
|
135
|
+
this._persist()
|
|
136
|
+
return goal
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 标记目标为失败
|
|
141
|
+
* @param {string} id - 目标ID
|
|
142
|
+
* @param {string} reason - 失败原因
|
|
143
|
+
* @returns {Object|null} 目标对象
|
|
144
|
+
*/
|
|
145
|
+
failGoal(id, reason) {
|
|
146
|
+
const goal = this._goals.get(id)
|
|
147
|
+
if (!goal) return null
|
|
148
|
+
goal.state = GoalState.FAILED
|
|
149
|
+
goal.failedAt = new Date()
|
|
150
|
+
goal.failureReason = reason
|
|
151
|
+
goal.updatedAt = new Date()
|
|
152
|
+
this._persist()
|
|
153
|
+
return goal
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 删除目标
|
|
158
|
+
* @param {string} id - 目标ID
|
|
159
|
+
* @returns {boolean} 是否删除成功
|
|
160
|
+
*/
|
|
161
|
+
deleteGoal(id) {
|
|
162
|
+
const deleted = this._goals.delete(id)
|
|
163
|
+
if (deleted) this._persist()
|
|
164
|
+
return deleted
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* 向目标添加事件(带去重)
|
|
169
|
+
* @param {string} goalId - 目标ID
|
|
170
|
+
* @param {Object} event - 事件数据
|
|
171
|
+
*/
|
|
172
|
+
addEventToGoal(goalId, event) {
|
|
173
|
+
const goal = this._goals.get(goalId)
|
|
174
|
+
if (!goal) return
|
|
175
|
+
|
|
176
|
+
// 通用去重:如果最近 2 秒内已有相同类型的事件,跳过
|
|
177
|
+
const now = Date.now()
|
|
178
|
+
const recentSameEvent = goal.eventsReceived.find(e =>
|
|
179
|
+
e.event === event.type && (now - new Date(e.timestamp).getTime()) < 2000
|
|
180
|
+
)
|
|
181
|
+
if (recentSameEvent) {
|
|
182
|
+
log.info(`跳过重复事件: ${event.type} (2秒内不重复添加)`)
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// event 格式: { type: 'email:received', email: {...}, timestamp: ... }
|
|
187
|
+
// 需要提取 type 和 data(email 对象)
|
|
188
|
+
goal.eventsReceived.push({
|
|
189
|
+
event: event.type,
|
|
190
|
+
data: event.data || event.email || event,
|
|
191
|
+
timestamp: new Date()
|
|
192
|
+
})
|
|
193
|
+
this._persist()
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
module.exports = { GoalManager }
|
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reflector - 评估操作结果,更新目标状态
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const { logger } = require('../../src/utils/logger')
|
|
6
|
-
|
|
7
|
-
const log = logger.child('Ambient:Reflector')
|
|
8
|
-
|
|
9
|
-
class Reflector {
|
|
10
|
-
constructor(goalManager) {
|
|
11
|
-
this._goalManager = goalManager
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* 评估操作结果
|
|
16
|
-
* @param {Object} goal - 目标对象
|
|
17
|
-
* @param {Object} actionResult - 操作结果
|
|
18
|
-
* @returns {Object} 评估结果 { shouldContinue, goalComplete, actionTaken }
|
|
19
|
-
*/
|
|
20
|
-
evaluateOutcome(goal, actionResult) {
|
|
21
|
-
if (!goal) return null
|
|
22
|
-
|
|
23
|
-
// 检查是否是事件驱动目标
|
|
24
|
-
const isEventDriven = goal.conditions?.events && goal.conditions.events.length > 0
|
|
25
|
-
|
|
26
|
-
// 检查错误
|
|
27
|
-
if (actionResult && actionResult.error) {
|
|
28
|
-
// 增加尝试次数但不立即失败
|
|
29
|
-
goal.attempts++
|
|
30
|
-
// 事件驱动目标:错误不导致失败或完成
|
|
31
|
-
if (isEventDriven) {
|
|
32
|
-
return { shouldContinue: true, goalComplete: false }
|
|
33
|
-
}
|
|
34
|
-
return {
|
|
35
|
-
shouldContinue: goal.attempts < goal.maxAttempts,
|
|
36
|
-
actionTaken: false
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// 检查是否成功完成
|
|
41
|
-
if (actionResult && actionResult.success === true) {
|
|
42
|
-
goal.attempts++
|
|
43
|
-
|
|
44
|
-
// 事件驱动目标:永远不会完成,持续等待下一事件
|
|
45
|
-
if (isEventDriven) {
|
|
46
|
-
return { shouldContinue: true, goalComplete: false }
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// 检查目标是否完成
|
|
50
|
-
if (goal.actions.length === 0 || goal.attempts >= goal.maxAttempts) {
|
|
51
|
-
return { shouldContinue: false, goalComplete: true }
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return { shouldContinue: true, actionTaken: true }
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// 工具执行无错误 - 视为成功
|
|
58
|
-
goal.attempts++
|
|
59
|
-
|
|
60
|
-
// 事件驱动目标:永远不会完成
|
|
61
|
-
if (isEventDriven) {
|
|
62
|
-
return { shouldContinue: true, goalComplete: false }
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// 检查目标是否完成(没有更多操作)
|
|
66
|
-
if (goal.actions.length === 0 || goal.attempts >= goal.maxAttempts) {
|
|
67
|
-
return { shouldContinue: false, goalComplete: true }
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return { shouldContinue: true, actionTaken: true }
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* 检查循环检测
|
|
75
|
-
* @param {Object} goal - 目标对象
|
|
76
|
-
* @param {string} actionId - 操作ID
|
|
77
|
-
* @returns {boolean} 是否检测到循环
|
|
78
|
-
*/
|
|
79
|
-
checkLoopDetection(goal, actionId) {
|
|
80
|
-
// 如果同一操作连续重复3次,则目标失败
|
|
81
|
-
if (goal.lastActionId === actionId) {
|
|
82
|
-
goal.consecutiveSameActions++
|
|
83
|
-
if (goal.consecutiveSameActions >= 3) {
|
|
84
|
-
this._goalManager.failGoal(goal.id, '检测到循环:同一操作连续重复3次')
|
|
85
|
-
return true
|
|
86
|
-
}
|
|
87
|
-
} else {
|
|
88
|
-
goal.consecutiveSameActions = 1
|
|
89
|
-
goal.lastActionId = actionId
|
|
90
|
-
}
|
|
91
|
-
return false
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
module.exports = { Reflector }
|
|
1
|
+
/**
|
|
2
|
+
* Reflector - 评估操作结果,更新目标状态
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { logger } = require('../../src/utils/logger')
|
|
6
|
+
|
|
7
|
+
const log = logger.child('Ambient:Reflector')
|
|
8
|
+
|
|
9
|
+
class Reflector {
|
|
10
|
+
constructor(goalManager) {
|
|
11
|
+
this._goalManager = goalManager
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 评估操作结果
|
|
16
|
+
* @param {Object} goal - 目标对象
|
|
17
|
+
* @param {Object} actionResult - 操作结果
|
|
18
|
+
* @returns {Object} 评估结果 { shouldContinue, goalComplete, actionTaken }
|
|
19
|
+
*/
|
|
20
|
+
evaluateOutcome(goal, actionResult) {
|
|
21
|
+
if (!goal) return null
|
|
22
|
+
|
|
23
|
+
// 检查是否是事件驱动目标
|
|
24
|
+
const isEventDriven = goal.conditions?.events && goal.conditions.events.length > 0
|
|
25
|
+
|
|
26
|
+
// 检查错误
|
|
27
|
+
if (actionResult && actionResult.error) {
|
|
28
|
+
// 增加尝试次数但不立即失败
|
|
29
|
+
goal.attempts++
|
|
30
|
+
// 事件驱动目标:错误不导致失败或完成
|
|
31
|
+
if (isEventDriven) {
|
|
32
|
+
return { shouldContinue: true, goalComplete: false }
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
shouldContinue: goal.attempts < goal.maxAttempts,
|
|
36
|
+
actionTaken: false
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 检查是否成功完成
|
|
41
|
+
if (actionResult && actionResult.success === true) {
|
|
42
|
+
goal.attempts++
|
|
43
|
+
|
|
44
|
+
// 事件驱动目标:永远不会完成,持续等待下一事件
|
|
45
|
+
if (isEventDriven) {
|
|
46
|
+
return { shouldContinue: true, goalComplete: false }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 检查目标是否完成
|
|
50
|
+
if (goal.actions.length === 0 || goal.attempts >= goal.maxAttempts) {
|
|
51
|
+
return { shouldContinue: false, goalComplete: true }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return { shouldContinue: true, actionTaken: true }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 工具执行无错误 - 视为成功
|
|
58
|
+
goal.attempts++
|
|
59
|
+
|
|
60
|
+
// 事件驱动目标:永远不会完成
|
|
61
|
+
if (isEventDriven) {
|
|
62
|
+
return { shouldContinue: true, goalComplete: false }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 检查目标是否完成(没有更多操作)
|
|
66
|
+
if (goal.actions.length === 0 || goal.attempts >= goal.maxAttempts) {
|
|
67
|
+
return { shouldContinue: false, goalComplete: true }
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return { shouldContinue: true, actionTaken: true }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 检查循环检测
|
|
75
|
+
* @param {Object} goal - 目标对象
|
|
76
|
+
* @param {string} actionId - 操作ID
|
|
77
|
+
* @returns {boolean} 是否检测到循环
|
|
78
|
+
*/
|
|
79
|
+
checkLoopDetection(goal, actionId) {
|
|
80
|
+
// 如果同一操作连续重复3次,则目标失败
|
|
81
|
+
if (goal.lastActionId === actionId) {
|
|
82
|
+
goal.consecutiveSameActions++
|
|
83
|
+
if (goal.consecutiveSameActions >= 3) {
|
|
84
|
+
this._goalManager.failGoal(goal.id, '检测到循环:同一操作连续重复3次')
|
|
85
|
+
return true
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
goal.consecutiveSameActions = 1
|
|
89
|
+
goal.lastActionId = actionId
|
|
90
|
+
}
|
|
91
|
+
return false
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = { Reflector }
|