foliko 1.0.68 → 1.0.69
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 +148 -145
- package/examples/basic.js +110 -110
- package/examples/mcp-example.js +53 -53
- package/examples/skill-example.js +49 -49
- package/examples/test-mcp.js +79 -79
- package/examples/test-reload.js +61 -61
- package/news-20260329-1774794949179.html +39 -0
- package/news-20260329-1774794970785.html +39 -0
- package/news-20260329-1774797491928.html +39 -0
- package/package.json +1 -1
- package/plugins/ambient-agent-plugin.js +333 -22
- package/plugins/email.js +106 -20
- package/plugins/file-system-plugin.js +76 -30
- package/plugins/python-executor-plugin.js +41 -8
- package/plugins/scheduler-plugin.js +6 -10
- package/plugins/web-plugin.js +8 -6
- package/skills/ambient-agent/SKILL.md +84 -14
- package/skills/workflow-guide/SKILL.md +214 -2
- package/skills/workflow-troubleshooting/DEBUGGING.md +182 -0
- package/skills/workflow-troubleshooting/SKILL.md +314 -0
- package/src/capabilities/workflow-engine.js +367 -22
- package/src/core/agent-chat.js +106 -14
- package/src/core/framework.js +81 -1
- package/src/executors/executor-base.js +58 -58
- package/test-server.js +0 -25
- package/test.txt +0 -3
|
@@ -115,13 +115,15 @@ class GoalManager {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
createGoal(goalData) {
|
|
118
|
+
const actions = goalData.actions || []
|
|
118
119
|
const goal = {
|
|
119
120
|
id: generateId(),
|
|
120
121
|
title: goalData.title || '未命名目标',
|
|
121
122
|
description: goalData.description || '',
|
|
122
123
|
priority: goalData.priority || 5,
|
|
123
124
|
state: GoalState.PENDING,
|
|
124
|
-
actions:
|
|
125
|
+
actions: actions,
|
|
126
|
+
_originalActions: actions.slice(), // 保存原始 actions,用于事件驱动目标重置
|
|
125
127
|
conditions: goalData.conditions || {},
|
|
126
128
|
createdAt: new Date(),
|
|
127
129
|
updatedAt: new Date(),
|
|
@@ -203,9 +205,22 @@ class GoalManager {
|
|
|
203
205
|
addEventToGoal(goalId, event) {
|
|
204
206
|
const goal = this._goals.get(goalId)
|
|
205
207
|
if (!goal) return
|
|
208
|
+
|
|
209
|
+
// 通用去重:如果最近 2 秒内已有相同类型的事件,跳过
|
|
210
|
+
const now = Date.now()
|
|
211
|
+
const recentSameEvent = goal.eventsReceived.find(e =>
|
|
212
|
+
e.event === event.type && (now - new Date(e.timestamp).getTime()) < 2000
|
|
213
|
+
)
|
|
214
|
+
if (recentSameEvent) {
|
|
215
|
+
console.log(`[Ambient] 跳过重复事件: ${event.type} (2秒内不重复添加)`)
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// event 格式: { type: 'email:received', email: {...}, timestamp: ... }
|
|
220
|
+
// 需要提取 type 和 data(email 对象)
|
|
206
221
|
goal.eventsReceived.push({
|
|
207
222
|
event: event.type,
|
|
208
|
-
data: event.data,
|
|
223
|
+
data: event.data || event.email || event,
|
|
209
224
|
timestamp: new Date()
|
|
210
225
|
})
|
|
211
226
|
this._persist()
|
|
@@ -257,11 +272,27 @@ class EventWatcher {
|
|
|
257
272
|
|
|
258
273
|
_handleEvent(type, data) {
|
|
259
274
|
const activeGoals = this._goalManager.getActiveGoals()
|
|
275
|
+
console.log(`[Ambient] _handleEvent: type=${type}, activeGoals=${activeGoals.length}`)
|
|
260
276
|
for (const goal of activeGoals) {
|
|
261
277
|
// 检查目标条件是否匹配此事件
|
|
262
|
-
|
|
278
|
+
const isRelevant = this._isRelevantToGoal(goal, type, data)
|
|
279
|
+
console.log(`[Ambient] goal=${goal.id}, isRelevant=${isRelevant}, conditions=${JSON.stringify(goal.conditions)}`)
|
|
280
|
+
if (isRelevant) {
|
|
263
281
|
// 将 data 展平到事件对象中,方便通过 {{_event.xxx}} 访问
|
|
264
282
|
this._goalManager.addEventToGoal(goal.id, { type, ...data })
|
|
283
|
+
console.log(`[Ambient] Event added to goal ${goal.id}`)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// 检查是否有 pending 目标需要激活
|
|
288
|
+
const pendingGoals = this._goalManager.getPendingGoals()
|
|
289
|
+
for (const goal of pendingGoals) {
|
|
290
|
+
if (this._isRelevantToGoal(goal, type, data)) {
|
|
291
|
+
// 激活目标
|
|
292
|
+
this._goalManager.activateGoal(goal.id)
|
|
293
|
+
// 添加事件
|
|
294
|
+
this._goalManager.addEventToGoal(goal.id, { type, ...data })
|
|
295
|
+
console.log(`[Ambient] 事件触发激活目标: ${goal.id} (事件: ${type})`)
|
|
265
296
|
}
|
|
266
297
|
}
|
|
267
298
|
}
|
|
@@ -300,10 +331,17 @@ class Reflector {
|
|
|
300
331
|
evaluateOutcome(goal, actionResult) {
|
|
301
332
|
if (!goal) return null
|
|
302
333
|
|
|
334
|
+
// 检查是否是事件驱动目标
|
|
335
|
+
const isEventDriven = goal.conditions?.events && goal.conditions.events.length > 0
|
|
336
|
+
|
|
303
337
|
// 检查错误
|
|
304
338
|
if (actionResult && actionResult.error) {
|
|
305
339
|
// 增加尝试次数但不立即失败
|
|
306
340
|
goal.attempts++
|
|
341
|
+
// 事件驱动目标:错误不导致失败或完成
|
|
342
|
+
if (isEventDriven) {
|
|
343
|
+
return { shouldContinue: true, goalComplete: false }
|
|
344
|
+
}
|
|
307
345
|
return {
|
|
308
346
|
shouldContinue: goal.attempts < goal.maxAttempts,
|
|
309
347
|
actionTaken: false
|
|
@@ -314,6 +352,11 @@ class Reflector {
|
|
|
314
352
|
if (actionResult && actionResult.success === true) {
|
|
315
353
|
goal.attempts++
|
|
316
354
|
|
|
355
|
+
// 事件驱动目标:永远不会完成,持续等待下一事件
|
|
356
|
+
if (isEventDriven) {
|
|
357
|
+
return { shouldContinue: true, goalComplete: false }
|
|
358
|
+
}
|
|
359
|
+
|
|
317
360
|
// 检查目标是否完成
|
|
318
361
|
if (goal.actions.length === 0 || goal.attempts >= goal.maxAttempts) {
|
|
319
362
|
return { shouldContinue: false, goalComplete: true }
|
|
@@ -325,6 +368,11 @@ class Reflector {
|
|
|
325
368
|
// 工具执行无错误 - 视为成功
|
|
326
369
|
goal.attempts++
|
|
327
370
|
|
|
371
|
+
// 事件驱动目标:永远不会完成
|
|
372
|
+
if (isEventDriven) {
|
|
373
|
+
return { shouldContinue: true, goalComplete: false }
|
|
374
|
+
}
|
|
375
|
+
|
|
328
376
|
// 检查目标是否完成(没有更多操作)
|
|
329
377
|
if (goal.actions.length === 0 || goal.attempts >= goal.maxAttempts) {
|
|
330
378
|
return { shouldContinue: false, goalComplete: true }
|
|
@@ -510,9 +558,59 @@ class ExplorerLoop {
|
|
|
510
558
|
// 检查目标是否有未处理的事件
|
|
511
559
|
const hasNewEvents = goal.eventsReceived && goal.eventsReceived.length > 0
|
|
512
560
|
|
|
561
|
+
// 检查是否是事件驱动目标
|
|
562
|
+
const isEventDriven = goal.conditions?.events && goal.conditions.events.length > 0
|
|
563
|
+
|
|
564
|
+
// 事件驱动目标:只有在新事件时才执行 actions
|
|
565
|
+
if (isEventDriven && !hasNewEvents) {
|
|
566
|
+
continue
|
|
567
|
+
}
|
|
568
|
+
|
|
513
569
|
// 获取下一个操作
|
|
514
570
|
if (goal.actions && goal.actions.length > 0) {
|
|
515
|
-
|
|
571
|
+
// 如果有多个 action,按顺序执行所有 action
|
|
572
|
+
if (goal.actions.length > 1) {
|
|
573
|
+
const eventData = hasNewEvents ? goal.eventsReceived[0] : null
|
|
574
|
+
const results = await this._executeAllActions(goal.actions, eventData)
|
|
575
|
+
|
|
576
|
+
// 最后一个结果用于评估
|
|
577
|
+
const lastResult = results.length > 0 ? results[results.length - 1].result : null
|
|
578
|
+
|
|
579
|
+
// 评估结果
|
|
580
|
+
const outcome = this._reflector.evaluateOutcome(goal, lastResult)
|
|
581
|
+
|
|
582
|
+
// 检查是否是事件驱动目标
|
|
583
|
+
const isEventDriven = goal.conditions?.events && goal.conditions.events.length > 0
|
|
584
|
+
|
|
585
|
+
if (outcome.goalComplete && !isEventDriven) {
|
|
586
|
+
// 非事件驱动目标可以完成
|
|
587
|
+
this._goalManager.completeGoal(goal.id)
|
|
588
|
+
this._addActivity('goal_completed', { goalId: goal.id, attempts: goal.attempts })
|
|
589
|
+
this._notifyUser('目标完成', `目标 "${goal.title}" 已完成(尝试次数:${goal.attempts})`, 'success')
|
|
590
|
+
} else if (!outcome.shouldContinue && !isEventDriven) {
|
|
591
|
+
// 非事件驱动目标可以失败
|
|
592
|
+
this._goalManager.failGoal(goal.id, '达到最大尝试次数')
|
|
593
|
+
this._addActivity('goal_failed', { goalId: goal.id, reason: '达到最大尝试次数' })
|
|
594
|
+
this._notifyUser('目标失败', `目标 "${goal.title}" 失败:达到最大尝试次数`, 'error')
|
|
595
|
+
} else {
|
|
596
|
+
// 事件驱动目标:不论结果如何,都重置并继续等待下一事件
|
|
597
|
+
this._addActivity('actions_completed', { goalId: goal.id, actionCount: results.length })
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// 执行操作后清除已处理的事件,并重置 actions 以处理下一事件
|
|
601
|
+
if (hasNewEvents) {
|
|
602
|
+
goal.eventsReceived = []
|
|
603
|
+
// 重置 actions 为原始 actions,以便处理下一事件
|
|
604
|
+
if (goal._originalActions) {
|
|
605
|
+
goal.actions = goal._originalActions.slice()
|
|
606
|
+
}
|
|
607
|
+
this._goalManager.updateGoal(goal.id, { eventsReceived: [], actions: goal.actions })
|
|
608
|
+
}
|
|
609
|
+
continue
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// 单个 action,使用原有逻辑
|
|
613
|
+
const action = goal.actions[0]
|
|
516
614
|
|
|
517
615
|
// 循环检测(仅用于非事件驱动的操作)
|
|
518
616
|
if (!hasNewEvents && this._reflector.checkLoopDetection(goal, action.id)) {
|
|
@@ -540,14 +638,21 @@ class ExplorerLoop {
|
|
|
540
638
|
this._notifyUser('目标失败', `目标 "${goal.title}" 失败:达到最大尝试次数`, 'error')
|
|
541
639
|
} else if (outcome.actionTaken) {
|
|
542
640
|
// 从队列中移除已完成的操作
|
|
543
|
-
|
|
641
|
+
// 注意:对于事件驱动目标,如果 hasNewEvents 为 true,不移除 action 而是在下面重置
|
|
642
|
+
if (!hasNewEvents) {
|
|
643
|
+
goal.actions.shift()
|
|
644
|
+
}
|
|
544
645
|
this._addActivity('action_executed', { goalId: goal.id, action: action.id, hasEvents: hasNewEvents })
|
|
545
646
|
}
|
|
546
647
|
|
|
547
|
-
//
|
|
548
|
-
if (hasNewEvents
|
|
648
|
+
// 执行操作后清除已处理的事件,并重置 actions 以处理下一事件
|
|
649
|
+
if (hasNewEvents) {
|
|
549
650
|
goal.eventsReceived = []
|
|
550
|
-
|
|
651
|
+
// 重置 actions 为原始 actions,以便处理下一事件
|
|
652
|
+
if (goal._originalActions) {
|
|
653
|
+
goal.actions = goal._originalActions.slice()
|
|
654
|
+
}
|
|
655
|
+
this._goalManager.updateGoal(goal.id, { eventsReceived: [], actions: goal.actions })
|
|
551
656
|
}
|
|
552
657
|
}
|
|
553
658
|
}
|
|
@@ -555,33 +660,59 @@ class ExplorerLoop {
|
|
|
555
660
|
// 激活满足条件的待处理目标
|
|
556
661
|
const pendingGoals = this._goalManager.getPendingGoals()
|
|
557
662
|
for (const goal of pendingGoals) {
|
|
558
|
-
//
|
|
663
|
+
// 自动激活没有条件的目标
|
|
664
|
+
// 有条件的目标会在事件触发时被 EventWatcher 自动激活
|
|
559
665
|
if (!goal.conditions || Object.keys(goal.conditions).length === 0) {
|
|
560
666
|
this._goalManager.activateGoal(goal.id)
|
|
561
667
|
this._addActivity('goal_activated', { goalId: goal.id })
|
|
668
|
+
} else {
|
|
669
|
+
// 有条件的目标,立即激活以便开始监听事件
|
|
670
|
+
this._goalManager.activateGoal(goal.id)
|
|
671
|
+
this._addActivity('goal_activated', { goalId: goal.id, reason: '事件监听目标已激活' })
|
|
562
672
|
}
|
|
563
673
|
}
|
|
564
674
|
}
|
|
565
675
|
|
|
566
|
-
|
|
676
|
+
/**
|
|
677
|
+
* 执行单个 action
|
|
678
|
+
* @param {Object} action - action 配置
|
|
679
|
+
* @param {Object} eventData - 事件数据
|
|
680
|
+
* @param {Object} context - 执行上下文(包含 stepOutputs 等)
|
|
681
|
+
* @returns {Promise<Object>} 执行结果
|
|
682
|
+
*/
|
|
683
|
+
async _executeAction(action, eventData = null, context = null) {
|
|
567
684
|
if (!this._framework) {
|
|
568
685
|
return { success: false, error: '框架不可用' }
|
|
569
686
|
}
|
|
570
687
|
|
|
571
688
|
try {
|
|
572
|
-
//
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
689
|
+
// 如果没有提供 context,创建一个新的
|
|
690
|
+
if (!context) {
|
|
691
|
+
context = {
|
|
692
|
+
input: {},
|
|
693
|
+
variables: {
|
|
694
|
+
_event: eventData?.data || eventData || null,
|
|
695
|
+
_eventRaw: eventData || null,
|
|
696
|
+
_action: action
|
|
697
|
+
},
|
|
698
|
+
lastResult: null
|
|
699
|
+
}
|
|
700
|
+
} else {
|
|
701
|
+
// 更新 context 中的 _action
|
|
702
|
+
context.variables._action = action
|
|
580
703
|
}
|
|
581
704
|
|
|
582
705
|
// 将 action 转换为 step 配置
|
|
583
706
|
const step = this._actionToStep(action)
|
|
584
707
|
|
|
708
|
+
// 解析 step.args 中的变量引用(支持 ${actionId.output} 格式)
|
|
709
|
+
if (step.args) {
|
|
710
|
+
step.args = this._resolveActionArgs(step.args, context)
|
|
711
|
+
}
|
|
712
|
+
if (step.input) {
|
|
713
|
+
step.input = this._resolveActionArgs(step.input, context)
|
|
714
|
+
}
|
|
715
|
+
|
|
585
716
|
// message 和 think 类型使用专用子 agent 执行
|
|
586
717
|
if (step.type === 'message' || step.type === 'think') {
|
|
587
718
|
return await this._executeWithAmbientAgent(step, context)
|
|
@@ -595,6 +726,154 @@ class ExplorerLoop {
|
|
|
595
726
|
}
|
|
596
727
|
}
|
|
597
728
|
|
|
729
|
+
/**
|
|
730
|
+
* 解析 action 参数中的变量引用
|
|
731
|
+
* 支持 ${actionId.output}、${actionId.output.field} 和 ${event.xxx} 格式
|
|
732
|
+
* @param {Object} args - 参数对象
|
|
733
|
+
* @param {Object} context - 执行上下文
|
|
734
|
+
* @returns {Object} 解析后的参数
|
|
735
|
+
*/
|
|
736
|
+
_resolveActionArgs(args, context) {
|
|
737
|
+
if (!args || typeof args !== 'object') return args
|
|
738
|
+
|
|
739
|
+
const stepOutputs = context.variables._stepOutputs || {}
|
|
740
|
+
const eventData = context.variables._event || {}
|
|
741
|
+
|
|
742
|
+
const resolved = {}
|
|
743
|
+
for (const [key, value] of Object.entries(args)) {
|
|
744
|
+
resolved[key] = this._resolveActionValue(value, stepOutputs, eventData)
|
|
745
|
+
}
|
|
746
|
+
return resolved
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* 解析单个值中的 ${actionId.output} 引用和 ${event.xxx} 引用
|
|
751
|
+
*/
|
|
752
|
+
_resolveActionValue(value, stepOutputs, eventData) {
|
|
753
|
+
if (typeof value === 'string') {
|
|
754
|
+
// 处理 ${actionId.output} 和 ${actionId.output.field} 格式
|
|
755
|
+
const result = value.replace(/\$\{([^}]+)\}/g, (match, path) => {
|
|
756
|
+
if (path === 'output' || path === 'result') {
|
|
757
|
+
// {{result}} 引用上一步结果
|
|
758
|
+
return stepOutputs._lastResult ?? match
|
|
759
|
+
}
|
|
760
|
+
if (path.startsWith('event.')) {
|
|
761
|
+
// ${event.xxx} 引用事件数据
|
|
762
|
+
let eventPath = path.replace(/^event\./, '')
|
|
763
|
+
// 优先在 eventData.data 中查找(因为事件数据通常存储在 data 字段)
|
|
764
|
+
if (eventData?.data) {
|
|
765
|
+
let val = this._getNestedValue(eventData.data, eventPath)
|
|
766
|
+
if (val !== undefined) return val
|
|
767
|
+
}
|
|
768
|
+
// 再尝试直接在 eventData 中查找
|
|
769
|
+
let val = this._getNestedValue(eventData, eventPath)
|
|
770
|
+
if (val !== undefined) return val
|
|
771
|
+
// 兼容:如果 path 是 event.data.xxx 但 eventData 没有 data,尝试跳过一层
|
|
772
|
+
if (eventPath.startsWith('data.')) {
|
|
773
|
+
eventPath = eventPath.replace(/^data\./, '')
|
|
774
|
+
val = this._getNestedValue(eventData, eventPath)
|
|
775
|
+
if (val !== undefined) return val
|
|
776
|
+
}
|
|
777
|
+
// 特殊回退:如果查找 body 但找不到,尝试 text(邮件数据中用 text)
|
|
778
|
+
if (eventPath === 'body' || eventPath === 'text') {
|
|
779
|
+
const textVal = this._getNestedValue(eventData?.data, 'text')
|
|
780
|
+
if (textVal !== undefined) return textVal
|
|
781
|
+
}
|
|
782
|
+
return match
|
|
783
|
+
}
|
|
784
|
+
if (path === 'event') {
|
|
785
|
+
// ${event} 引用整个事件数据对象
|
|
786
|
+
return eventData ?? match
|
|
787
|
+
}
|
|
788
|
+
if (path.includes('.')) {
|
|
789
|
+
// ${actionId.output.field} 格式
|
|
790
|
+
const [actionId, ...fieldParts] = path.split('.')
|
|
791
|
+
if (actionId === 'result' || actionId === 'output') {
|
|
792
|
+
// {{result.field}} 格式
|
|
793
|
+
const val = this._getNestedValue(stepOutputs._lastResult, fieldParts.join('.'))
|
|
794
|
+
return val !== undefined ? val : match
|
|
795
|
+
}
|
|
796
|
+
const actionOutput = stepOutputs[actionId]
|
|
797
|
+
if (actionOutput !== undefined) {
|
|
798
|
+
const val = this._getNestedValue(actionOutput, fieldParts.join('.'))
|
|
799
|
+
return val !== undefined ? val : match
|
|
800
|
+
}
|
|
801
|
+
} else {
|
|
802
|
+
// ${actionId.output} 格式
|
|
803
|
+
const actionOutput = stepOutputs[path]
|
|
804
|
+
if (actionOutput !== undefined) return actionOutput
|
|
805
|
+
}
|
|
806
|
+
return match
|
|
807
|
+
})
|
|
808
|
+
return result
|
|
809
|
+
} else if (Array.isArray(value)) {
|
|
810
|
+
return value.map(v => this._resolveActionValue(v, stepOutputs, eventData))
|
|
811
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
812
|
+
const resolved = {}
|
|
813
|
+
for (const [k, v] of Object.entries(value)) {
|
|
814
|
+
resolved[k] = this._resolveActionValue(v, stepOutputs, eventData)
|
|
815
|
+
}
|
|
816
|
+
return resolved
|
|
817
|
+
}
|
|
818
|
+
return value
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
_getNestedValue(obj, path) {
|
|
822
|
+
if (!obj) return undefined
|
|
823
|
+
const parts = path.split('.')
|
|
824
|
+
let current = obj
|
|
825
|
+
for (const part of parts) {
|
|
826
|
+
if (current === null || current === undefined) return undefined
|
|
827
|
+
current = current[part]
|
|
828
|
+
}
|
|
829
|
+
return current
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* 按顺序执行所有 actions
|
|
834
|
+
* @param {Array} actions - action 数组
|
|
835
|
+
* @param {Object} eventData - 事件数据
|
|
836
|
+
* @returns {Promise<Array>} 所有执行结果
|
|
837
|
+
*/
|
|
838
|
+
async _executeAllActions(actions, eventData = null) {
|
|
839
|
+
const results = []
|
|
840
|
+
const stepOutputs = {}
|
|
841
|
+
|
|
842
|
+
const context = {
|
|
843
|
+
input: {},
|
|
844
|
+
variables: {
|
|
845
|
+
_event: eventData?.data || eventData || null,
|
|
846
|
+
_eventRaw: eventData || null,
|
|
847
|
+
_stepOutputs: stepOutputs
|
|
848
|
+
},
|
|
849
|
+
lastResult: null
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
for (const action of actions) {
|
|
853
|
+
// 执行前更新 stepOutputs
|
|
854
|
+
context.variables._stepOutputs = stepOutputs
|
|
855
|
+
|
|
856
|
+
const result = await this._executeAction(action, eventData, context)
|
|
857
|
+
|
|
858
|
+
// 保存结果:使用 action id 作为键
|
|
859
|
+
if (action.id) {
|
|
860
|
+
stepOutputs[action.id] = result
|
|
861
|
+
}
|
|
862
|
+
// 同时保存为 _lastResult 供 {{result}} 引用
|
|
863
|
+
stepOutputs._lastResult = result
|
|
864
|
+
context.lastResult = result
|
|
865
|
+
|
|
866
|
+
results.push({ actionId: action.id, result })
|
|
867
|
+
|
|
868
|
+
// 如果执行失败,停止执行
|
|
869
|
+
if (result && result.success === false) {
|
|
870
|
+
break
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
return results
|
|
875
|
+
}
|
|
876
|
+
|
|
598
877
|
/**
|
|
599
878
|
* 使用 ambient 子 agent 执行 AI 相关操作
|
|
600
879
|
*/
|
|
@@ -735,7 +1014,20 @@ class AmbientAgentPlugin extends Plugin {
|
|
|
735
1014
|
super()
|
|
736
1015
|
this.name = 'ambient'
|
|
737
1016
|
this.version = '1.0.0'
|
|
738
|
-
|
|
1017
|
+
this.description = `Ambient Agent - 持续后台运行的智能代理,用于主动监控事件并执行操作
|
|
1018
|
+
|
|
1019
|
+
## 支持的事件类型(创建目标时 conditions.events 必须使用这些确切的名称):
|
|
1020
|
+
- email:received - 收到新邮件(参数:from, subject, text, messageId)
|
|
1021
|
+
- tool:result - 工具执行完成(参数:name, args, result)
|
|
1022
|
+
- scheduler:reminder - 定时提醒(参数:taskId, message, time)
|
|
1023
|
+
- scheduler:task_completed - 任务完成(参数:taskId, result)
|
|
1024
|
+
- scheduler:task_failed - 任务失败(参数:taskId, error)
|
|
1025
|
+
- agent:message - 代理消息(参数:content, sessionId)
|
|
1026
|
+
- think:thought_completed - 思考完成(参数:mode, topic, thought)
|
|
1027
|
+
- webhook:received - Webhook接收(参数:headers, body, query, path)
|
|
1028
|
+
|
|
1029
|
+
## 在 action 参数中引用事件数据:
|
|
1030
|
+
使用 \${event.xxx} 语法,例如:\${event.from}、\${event.subject}、\${event.text}`
|
|
739
1031
|
this.priority = 18
|
|
740
1032
|
this.system = true
|
|
741
1033
|
|
|
@@ -785,10 +1077,29 @@ class AmbientAgentPlugin extends Plugin {
|
|
|
785
1077
|
this._eventWatcher = new EventWatcher(this._goalManager, this._framework)
|
|
786
1078
|
this._eventWatcher.start()
|
|
787
1079
|
|
|
788
|
-
// 动态更新description
|
|
789
|
-
const
|
|
1080
|
+
// 动态更新description显示支持的事件及参数
|
|
1081
|
+
const eventDescriptions = {
|
|
1082
|
+
'tool:result': '工具执行结果事件 - 参数: name(工具名), args(执行参数), result(执行结果), error(错误信息)',
|
|
1083
|
+
'scheduler:reminder': '定时提醒事件 - 参数: taskId(任务ID), message(提醒消息), time(触发时间)',
|
|
1084
|
+
'scheduler:task_completed': '任务完成事件 - 参数: taskId(任务ID), result(任务结果)',
|
|
1085
|
+
'scheduler:task_failed': '任务失败事件 - 参数: taskId(任务ID), error(错误信息)',
|
|
1086
|
+
'agent:message': '代理消息事件 - 参数: content(消息内容), sessionId(会话ID), agentId(代理ID)',
|
|
1087
|
+
'think:thought_completed': '思考完成事件 - 参数: mode(思考模式), topic(思考主题), thought(思考内容), depth(思考深度)',
|
|
1088
|
+
'email:received': '收到邮件事件 - 参数: from(发件人), to(收件人), subject(主题), text(正文), body(HTML正文), messageId(消息ID), timestamp(时间戳)',
|
|
1089
|
+
'webhook:received': 'Webhook接收事件 - 参数: headers(HTTP头), body(请求体), query(查询参数), path(请求路径)'
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
const events = Array.from(this._eventWatcher._relevantEvents)
|
|
1093
|
+
const eventList = events.map(e => {
|
|
1094
|
+
const desc = eventDescriptions[e] || e
|
|
1095
|
+
return ` - ${desc}`
|
|
1096
|
+
}).join('\n')
|
|
1097
|
+
|
|
790
1098
|
this.description = `Ambient Agent - 持续后台运行的智能代理,用于主动监控和执行操作
|
|
791
|
-
|
|
1099
|
+
支持的事件及参数:
|
|
1100
|
+
${eventList}
|
|
1101
|
+
|
|
1102
|
+
使用 \${event.xxx} 在 action 参数中引用事件数据`
|
|
792
1103
|
|
|
793
1104
|
// 启动探索循环
|
|
794
1105
|
this._explorerLoop = new ExplorerLoop(this._goalManager, this._reflector, this._framework, {
|