foliko 2.0.17 → 2.0.18
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 +1 -3
- package/package.json +1 -1
- package/plugins/ambient/ExplorerLoop.js +10 -10
- package/plugins/core/scheduler/index.js +1 -1
- package/plugins/core/session/index.js +1 -0
- package/plugins/messaging/feishu/index.js +5 -5
- package/plugins/messaging/qq/index.js +3 -3
- package/plugins/messaging/telegram/index.js +3 -3
- package/plugins/messaging/weixin/index.js +5 -5
- package/src/session/session.js +2 -1
|
@@ -239,9 +239,7 @@
|
|
|
239
239
|
"Bash(npm start *)",
|
|
240
240
|
"Bash(xxd)",
|
|
241
241
|
"Bash(python fix_ext2.py)",
|
|
242
|
-
"Bash(npx vitest *)"
|
|
243
|
-
"Bash(ls node_modules | wc -l && ls -d node_modules/@* 2>/dev/null | head -5)",
|
|
244
|
-
"Bash(node -e \"console.log\\(require.resolve\\('croner'\\)\\)\")"
|
|
242
|
+
"Bash(npx vitest *)"
|
|
245
243
|
]
|
|
246
244
|
}
|
|
247
245
|
}
|
package/package.json
CHANGED
|
@@ -234,12 +234,12 @@ class ExplorerLoop {
|
|
|
234
234
|
// 非事件驱动目标可以完成
|
|
235
235
|
this._goalManager.completeGoal(goal.id)
|
|
236
236
|
this._addActivity('goal_completed', { goalId: goal.id, attempts: goal.attempts })
|
|
237
|
-
this._notifyUser('目标完成', `目标 "${goal.title}" 已完成(尝试次数:${goal.attempts})`, 'success')
|
|
237
|
+
await this._notifyUser('目标完成', `目标 "${goal.title}" 已完成(尝试次数:${goal.attempts})`, 'success')
|
|
238
238
|
} else if (!outcome.shouldContinue && !isEventDriven) {
|
|
239
239
|
// 非事件驱动目标可以失败
|
|
240
240
|
this._goalManager.failGoal(goal.id, '达到最大尝试次数')
|
|
241
241
|
this._addActivity('goal_failed', { goalId: goal.id, reason: '达到最大尝试次数' })
|
|
242
|
-
this._notifyUser('目标失败', `目标 "${goal.title}" 失败:达到最大尝试次数`, 'error')
|
|
242
|
+
await this._notifyUser('目标失败', `目标 "${goal.title}" 失败:达到最大尝试次数`, 'error')
|
|
243
243
|
} else {
|
|
244
244
|
// 事件驱动目标:不论结果如何,都重置并继续等待下一事件
|
|
245
245
|
this._addActivity('actions_completed', { goalId: goal.id, actionCount: results.length })
|
|
@@ -250,7 +250,7 @@ class ExplorerLoop {
|
|
|
250
250
|
// 一次性目标:所有 actions 完成后直接完成
|
|
251
251
|
this._goalManager.completeGoal(goal.id)
|
|
252
252
|
this._addActivity('goal_completed', { goalId: goal.id, reason: '一次性任务执行完成' })
|
|
253
|
-
this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
|
|
253
|
+
await this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
|
|
254
254
|
} else if (hasNewEvents) {
|
|
255
255
|
// 持久化目标且有新事件,重置 actions
|
|
256
256
|
this._resetGoalForNextEvent(goal)
|
|
@@ -269,7 +269,7 @@ class ExplorerLoop {
|
|
|
269
269
|
// 一次性目标:所有 actions 完成后直接完成
|
|
270
270
|
this._goalManager.completeGoal(goal.id)
|
|
271
271
|
this._addActivity('goal_completed', { goalId: goal.id, reason: '一次性任务执行完成' })
|
|
272
|
-
this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
|
|
272
|
+
await this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
|
|
273
273
|
} else {
|
|
274
274
|
// 持久化目标:等待下一事件
|
|
275
275
|
this._resetGoalForNextEvent(goal)
|
|
@@ -281,7 +281,7 @@ class ExplorerLoop {
|
|
|
281
281
|
if (!hasNewEvents && this._reflector.checkLoopDetection(goal, action.id)) {
|
|
282
282
|
this._addActivity('goal_failed', { goalId: goal.id, reason: '检测到循环' })
|
|
283
283
|
// 通知用户目标失败
|
|
284
|
-
this._notifyUser('目标失败', `目标 "${goal.title}" 失败:检测到循环(同一操作连续重复)`, 'error')
|
|
284
|
+
await this._notifyUser('目标失败', `目标 "${goal.title}" 失败:检测到循环(同一操作连续重复)`, 'error')
|
|
285
285
|
continue
|
|
286
286
|
}
|
|
287
287
|
|
|
@@ -298,12 +298,12 @@ class ExplorerLoop {
|
|
|
298
298
|
this._goalManager.completeGoal(goal.id)
|
|
299
299
|
this._addActivity('goal_completed', { goalId: goal.id, attempts: goal.attempts })
|
|
300
300
|
// 通知用户目标完成
|
|
301
|
-
this._notifyUser('目标完成', `目标 "${goal.title}" 已完成(尝试次数:${goal.attempts})`, 'success')
|
|
301
|
+
await this._notifyUser('目标完成', `目标 "${goal.title}" 已完成(尝试次数:${goal.attempts})`, 'success')
|
|
302
302
|
} else if (!outcome.shouldContinue) {
|
|
303
303
|
this._goalManager.failGoal(goal.id, '达到最大尝试次数')
|
|
304
304
|
this._addActivity('goal_failed', { goalId: goal.id, reason: '达到最大尝试次数' })
|
|
305
305
|
// 通知用户目标失败
|
|
306
|
-
this._notifyUser('目标失败', `目标 "${goal.title}" 失败:达到最大尝试次数`, 'error')
|
|
306
|
+
await this._notifyUser('目标失败', `目标 "${goal.title}" 失败:达到最大尝试次数`, 'error')
|
|
307
307
|
} else {
|
|
308
308
|
this._addActivity('action_executed', { goalId: goal.id, action: action.id, hasEvents: hasNewEvents })
|
|
309
309
|
|
|
@@ -313,7 +313,7 @@ class ExplorerLoop {
|
|
|
313
313
|
// 一次性目标:所有 actions 完成后直接完成
|
|
314
314
|
this._goalManager.completeGoal(goal.id)
|
|
315
315
|
this._addActivity('goal_completed', { goalId: goal.id, reason: '一次性任务执行完成' })
|
|
316
|
-
this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
|
|
316
|
+
await this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
|
|
317
317
|
} else if (hasNewEvents) {
|
|
318
318
|
// 持久化目标且有新事件,重置 actions
|
|
319
319
|
this._resetGoalForNextEvent(goal)
|
|
@@ -1019,14 +1019,14 @@ ${lastResultStr}
|
|
|
1019
1019
|
/**
|
|
1020
1020
|
* 通知用户(通过事件发送给消息插件)
|
|
1021
1021
|
*/
|
|
1022
|
-
_notifyUser(title, message, level = 'info') {
|
|
1022
|
+
async _notifyUser(title, message, level = 'info') {
|
|
1023
1023
|
if (!this._framework) return
|
|
1024
1024
|
|
|
1025
1025
|
// 获取目标相关的sessionId(如果有)
|
|
1026
1026
|
let sessionId = null
|
|
1027
1027
|
const sessionPlugin = this._framework.pluginManager.get('session')
|
|
1028
1028
|
if (sessionPlugin) {
|
|
1029
|
-
const sessions = sessionPlugin.listSessions()
|
|
1029
|
+
const sessions = await sessionPlugin.listSessions()
|
|
1030
1030
|
if (sessions.length > 0) {
|
|
1031
1031
|
// 取最新的会话
|
|
1032
1032
|
sessions.sort((a, b) => new Date(b.lastActive).getTime() - new Date(a.lastActive).getTime())
|
|
@@ -391,7 +391,7 @@ class SchedulerPlugin extends Plugin {
|
|
|
391
391
|
if (!targetSessionId) {
|
|
392
392
|
const sessionPlugin = this._framework?.pluginManager?.get('session');
|
|
393
393
|
if (sessionPlugin) {
|
|
394
|
-
const sessions = sessionPlugin.listSessions();
|
|
394
|
+
const sessions = await sessionPlugin.listSessions();
|
|
395
395
|
if (sessions.length > 0) {
|
|
396
396
|
sessions.sort((a, b) => {
|
|
397
397
|
const aTime = a.lastActive ? new Date(a.lastActive).getTime() : 0;
|
|
@@ -84,6 +84,7 @@ class SessionPlugin extends Plugin {
|
|
|
84
84
|
try {
|
|
85
85
|
const manager = SessionManager.open(filePath, sessionDir, cwd);
|
|
86
86
|
sessions.push({
|
|
87
|
+
id:path.basename(filePath, path.extname(filePath)),
|
|
87
88
|
sessionId: manager.getSessionId(),
|
|
88
89
|
sessionFile: manager.getSessionFile(),
|
|
89
90
|
messageCount: manager.getEntries().length,
|
|
@@ -221,7 +221,7 @@ class FeishuPlugin extends Plugin {
|
|
|
221
221
|
case 'history':
|
|
222
222
|
if (this._sessionPlugin) {
|
|
223
223
|
const session = this._sessionPlugin.getSession(`feishu_${openId}`)
|
|
224
|
-
const sessions = this._sessionPlugin.listSessions().filter(s => s.id.startsWith('feishu_'))
|
|
224
|
+
const sessions = (await this._sessionPlugin.listSessions()).filter(s => s.id.startsWith('feishu_'))
|
|
225
225
|
await this._sendMessage(openId,
|
|
226
226
|
`📊 当前状态\n\n会话数:${sessions.length}\n历史消息:${session?.messages?.length || 0}\n最后活跃:${session?.lastActive?.toLocaleString() || '无'}`,
|
|
227
227
|
originalMsg)
|
|
@@ -312,7 +312,7 @@ class FeishuPlugin extends Plugin {
|
|
|
312
312
|
}
|
|
313
313
|
|
|
314
314
|
if (this._sessionPlugin) {
|
|
315
|
-
const sessions = this._sessionPlugin.listSessions()
|
|
315
|
+
const sessions = (await this._sessionPlugin.listSessions())
|
|
316
316
|
.filter(s => s.id.startsWith('feishu_'))
|
|
317
317
|
.sort((a, b) => new Date(b.lastActive).getTime() - new Date(a.lastActive).getTime())
|
|
318
318
|
|
|
@@ -370,7 +370,7 @@ class FeishuPlugin extends Plugin {
|
|
|
370
370
|
openId = effectiveSessionId.replace('feishu_', '')
|
|
371
371
|
} else if (this._sessionPlugin) {
|
|
372
372
|
// 获取最近的 feishu 会话
|
|
373
|
-
const sessions = this._sessionPlugin.listSessions()
|
|
373
|
+
const sessions = (await this._sessionPlugin.listSessions())
|
|
374
374
|
.filter(s => s.id.startsWith('feishu_'))
|
|
375
375
|
.sort((a, b) => new Date(b.lastActive).getTime() - new Date(a.lastActive).getTime())
|
|
376
376
|
if (sessions.length > 0) {
|
|
@@ -587,10 +587,10 @@ class FeishuPlugin extends Plugin {
|
|
|
587
587
|
}
|
|
588
588
|
}
|
|
589
589
|
|
|
590
|
-
getStatus() {
|
|
590
|
+
async getStatus() {
|
|
591
591
|
let sessions = []
|
|
592
592
|
if (this._sessionPlugin) {
|
|
593
|
-
sessions = this._sessionPlugin.listSessions()
|
|
593
|
+
sessions = (await this._sessionPlugin.listSessions())
|
|
594
594
|
.filter(s => s.id.startsWith('feishu_'))
|
|
595
595
|
.map(s => ({
|
|
596
596
|
openId: s.id.replace('feishu_', ''),
|
|
@@ -958,7 +958,7 @@ class QQPlugin extends Plugin {
|
|
|
958
958
|
identifier = sessionId.replace('qq_c2c_', '')
|
|
959
959
|
}
|
|
960
960
|
} else if (this._sessionPlugin) {
|
|
961
|
-
const sessions = this._sessionPlugin.listSessions()
|
|
961
|
+
const sessions = (await this._sessionPlugin.listSessions())
|
|
962
962
|
.filter(s => s.id.startsWith('qq_'))
|
|
963
963
|
.sort((a, b) => new Date(b.lastActive).getTime() - new Date(a.lastActive).getTime())
|
|
964
964
|
if (sessions.length > 0) {
|
|
@@ -1000,10 +1000,10 @@ class QQPlugin extends Plugin {
|
|
|
1000
1000
|
/**
|
|
1001
1001
|
* 获取插件状态
|
|
1002
1002
|
*/
|
|
1003
|
-
getStatus() {
|
|
1003
|
+
async getStatus() {
|
|
1004
1004
|
let sessions = []
|
|
1005
1005
|
if (this._sessionPlugin) {
|
|
1006
|
-
const allSessions = this._sessionPlugin.listSessions()
|
|
1006
|
+
const allSessions = await this._sessionPlugin.listSessions()
|
|
1007
1007
|
sessions = allSessions
|
|
1008
1008
|
.filter(s => s.id.startsWith('qq_'))
|
|
1009
1009
|
.map(s => ({
|
|
@@ -157,7 +157,7 @@ class TelegramPlugin extends Plugin {
|
|
|
157
157
|
chatId = effectiveSessionId.replace('telegram_', '')
|
|
158
158
|
} else if (this._sessionPlugin) {
|
|
159
159
|
// 获取最近的 telegram 会话
|
|
160
|
-
const sessions = this._sessionPlugin.listSessions()
|
|
160
|
+
const sessions = (await this._sessionPlugin.listSessions())
|
|
161
161
|
.filter(s => s.id.startsWith('telegram_'))
|
|
162
162
|
.sort((a, b) => new Date(b.lastActive).getTime() - new Date(a.lastActive).getTime())
|
|
163
163
|
if (sessions.length > 0) {
|
|
@@ -607,10 +607,10 @@ class TelegramPlugin extends Plugin {
|
|
|
607
607
|
return this._bot.sendMessage(chatId, text, { reply_to_message_id: replyToMessageId })
|
|
608
608
|
}
|
|
609
609
|
|
|
610
|
-
getStatus() {
|
|
610
|
+
async getStatus() {
|
|
611
611
|
let sessions = []
|
|
612
612
|
if (this._sessionPlugin) {
|
|
613
|
-
sessions = this._sessionPlugin.listSessions()
|
|
613
|
+
sessions = (await this._sessionPlugin.listSessions())
|
|
614
614
|
.filter(s => s.id.startsWith('telegram_'))
|
|
615
615
|
.map(s => ({
|
|
616
616
|
chatId: s.id.replace('telegram_', ''),
|
|
@@ -905,7 +905,7 @@ class WeixinPlugin extends Plugin {
|
|
|
905
905
|
|
|
906
906
|
// 其他情况(包括 null 或其他 sessionId),发送到最近的 WeChat 会话
|
|
907
907
|
if (this._sessionPlugin) {
|
|
908
|
-
const allSessions = this._sessionPlugin
|
|
908
|
+
const allSessions = await this._sessionPlugin?.listSessions()
|
|
909
909
|
const weixinSessions = allSessions
|
|
910
910
|
.filter(s => s.id.startsWith('weixin_'))
|
|
911
911
|
.sort((a, b) => new Date(b.lastActive).getTime() - new Date(a.lastActive).getTime())
|
|
@@ -977,8 +977,8 @@ class WeixinPlugin extends Plugin {
|
|
|
977
977
|
userId = effectiveSessionId.replace('weixin_', '')
|
|
978
978
|
} else if (this._sessionPlugin) {
|
|
979
979
|
// 获取最近的 weixin 会话
|
|
980
|
-
const
|
|
981
|
-
|
|
980
|
+
const allSessions=await this._sessionPlugin?.listSessions()
|
|
981
|
+
const sessions = (allSessions||[]).filter(s => s.id.startsWith('weixin_'))
|
|
982
982
|
.sort((a, b) => new Date(b.lastActive).getTime() - new Date(a.lastActive).getTime())
|
|
983
983
|
if (sessions.length > 0) {
|
|
984
984
|
userId = sessions[0].id.replace('weixin_', '')
|
|
@@ -1011,11 +1011,11 @@ class WeixinPlugin extends Plugin {
|
|
|
1011
1011
|
/**
|
|
1012
1012
|
* 获取插件状态
|
|
1013
1013
|
*/
|
|
1014
|
-
getStatus() {
|
|
1014
|
+
async getStatus() {
|
|
1015
1015
|
// 从 SessionPlugin 获取 WeChat 相关会话
|
|
1016
1016
|
let sessions = []
|
|
1017
1017
|
if (this._sessionPlugin) {
|
|
1018
|
-
const allSessions = this._sessionPlugin.listSessions()
|
|
1018
|
+
const allSessions = await this._sessionPlugin.listSessions()
|
|
1019
1019
|
sessions = allSessions
|
|
1020
1020
|
.filter(s => s.id.startsWith('weixin_'))
|
|
1021
1021
|
.map(s => ({
|
package/src/session/session.js
CHANGED
|
@@ -54,7 +54,7 @@ class SessionManager {
|
|
|
54
54
|
this.labelTimestampsById = new Map();
|
|
55
55
|
this.leafId = null;
|
|
56
56
|
this.sessionId = '';
|
|
57
|
-
|
|
57
|
+
this.fileName=''
|
|
58
58
|
if (persist && sessionDir && !fs.existsSync(sessionDir)) {
|
|
59
59
|
fs.mkdirSync(sessionDir, { recursive: true });
|
|
60
60
|
}
|
|
@@ -84,6 +84,7 @@ class SessionManager {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
const header = this.fileEntries.find(e => e.type === 'session');
|
|
87
|
+
this.fileName = path.basename(sessionFile);
|
|
87
88
|
this.sessionId = header?.id || createSessionId();
|
|
88
89
|
|
|
89
90
|
this._buildIndex();
|