foliko 1.1.67 → 1.1.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 +19 -10
- package/.dockerignore +45 -45
- package/.env.example +56 -56
- package/CLAUDE.md +2 -2
- package/README.md +13 -13
- package/SPEC.md +3 -3
- package/cli/src/commands/chat.js +2 -20
- package/cli/src/commands/list.js +7 -6
- package/cli/src/commands/plugin.js +3 -2
- package/cli/src/daemon.js +2 -2
- package/cli/src/ui/chat-ui-old.js +15 -4
- package/cli/src/ui/chat-ui.js +236 -203
- package/cli/src/ui/footer-bar.js +20 -46
- package/cli/src/ui/message-bubble.js +24 -2
- package/cli/src/ui/status-bar.js +177 -0
- package/cli/src/utils/config.js +29 -0
- package/cli/src/utils/plugin-config.js +1 -1
- package/docker-compose.yml +33 -33
- package/docs/features.md +120 -120
- package/docs/quick-reference.md +160 -160
- package/docs/user-manual.md +1391 -1391
- package/examples/ambient-example.js +2 -2
- package/examples/bootstrap.js +3 -3
- package/examples/test-chat.js +1 -1
- package/examples/test-reload.js +1 -1
- package/examples/test-telegram.js +1 -1
- package/examples/test-tg-bot.js +1 -1
- package/examples/test-tg-simple.js +2 -2
- package/examples/test-tg.js +1 -1
- package/examples/test-think.js +1 -1
- package/examples/test-weixin-feishu.js +3 -3
- package/package.json +3 -1
- package/plugins/ambient-agent/index.js +1 -1
- package/plugins/audit-plugin.js +84 -29
- package/plugins/coordinator-plugin.js +14 -12
- package/plugins/data-splitter-plugin.js +323 -0
- package/plugins/default-plugins.js +23 -12
- package/plugins/email/index.js +1 -1
- package/plugins/extension-executor-plugin.js +87 -9
- package/plugins/feishu-plugin.js +118 -16
- package/plugins/file-system-plugin.js +68 -50
- package/plugins/gate-trading.js +10 -10
- package/plugins/install-plugin.js +7 -7
- package/plugins/memory-plugin.js +9 -12
- package/plugins/plugin-manager-plugin.js +12 -14
- package/plugins/python-executor-plugin.js +1 -1
- package/plugins/python-plugin-loader.js +1 -1
- package/plugins/qq-plugin.js +151 -24
- package/plugins/rules-plugin.js +8 -8
- package/plugins/scheduler-plugin.js +24 -20
- package/plugins/session-plugin.js +313 -397
- package/plugins/storage-plugin.js +235 -175
- package/plugins/subagent-plugin.js +17 -13
- package/plugins/telegram-plugin.js +116 -17
- package/plugins/think-plugin.js +64 -60
- package/plugins/tools-plugin.js +8 -8
- package/plugins/web-plugin.js +2 -2
- package/plugins/weixin-plugin.js +107 -24
- package/skills/find-skills/AGENTS.md +2 -2
- package/skills/find-skills/SKILL.md +133 -133
- package/skills/foliko-dev/AGENTS.md +236 -236
- package/skills/foliko-dev/SKILL.md +19 -19
- package/skills/mcp-usage/SKILL.md +200 -200
- package/skills/plugin-guide/SKILL.md +4 -4
- package/skills/python-plugin-dev/SKILL.md +5 -5
- package/skills/skill-guide/SKILL.md +104 -6
- package/skills/subagent-guide/SKILL.md +237 -237
- package/skills/workflow-guide/SKILL.md +646 -646
- package/src/capabilities/skill-manager.js +124 -17
- package/src/capabilities/workflow-engine.js +3 -3
- package/src/core/agent-chat.js +72 -26
- package/src/core/agent.js +17 -27
- package/src/core/branch-summary-auto.js +206 -0
- package/src/core/chat-session.js +45 -169
- package/src/core/command-registry.js +200 -0
- package/src/core/constants.js +198 -0
- package/src/core/context-compressor.js +702 -326
- package/src/core/context-manager.js +0 -1
- package/src/core/enhanced-context-compressor.js +210 -0
- package/src/core/framework.js +260 -84
- package/src/core/jsonl-storage.js +253 -0
- package/src/core/plugin-base.js +7 -5
- package/src/core/plugin-manager.js +15 -10
- package/src/core/provider-registry.js +159 -0
- package/src/core/provider.js +2 -0
- package/src/core/session-entry.js +225 -0
- package/src/core/session-manager.js +701 -0
- package/src/core/storage-manager.js +494 -0
- package/src/core/sub-agent-config.js +1 -1
- package/src/core/subagent.js +16 -135
- package/src/core/token-counter.js +177 -58
- package/src/core/tool-executor.js +2 -70
- package/src/core/ui-extension-context.js +174 -0
- package/src/executors/mcp-executor.js +27 -16
- package/src/utils/chat-queue.js +11 -22
- package/src/utils/data-splitter.js +345 -0
- package/src/utils/logger.js +152 -180
- package/src/utils/message-validator.js +283 -0
- package/src/utils/plugin-helpers.js +2 -2
- package/src/utils/retry.js +168 -22
- package/website_v2/docs/api.html +1 -1
- package/website_v2/docs/configuration.html +2 -2
- package/website_v2/docs/plugin-development.html +4 -4
- package/website_v2/docs/project-structure.html +2 -2
- package/website_v2/docs/skill-development.html +2 -2
- package/website_v2/index.html +1 -1
- package/website_v2/styles/animations.css +7 -7
- package/.agent/agents/backend-dev.md +0 -102
- package/.agent/agents/data-analyst.md +0 -117
- package/.agent/agents/devops.md +0 -115
- package/.agent/agents/frontend-dev.md +0 -94
- package/.agent/agents/network-requester.md +0 -44
- package/.agent/agents/poster-designer.md +0 -52
- package/.agent/agents/product-manager.md +0 -85
- package/.agent/agents/qa-engineer.md +0 -100
- package/.agent/agents/security-engineer.md +0 -99
- package/.agent/agents/team-lead.md +0 -137
- package/.agent/agents/ui-designer.md +0 -116
- package/.agent/data/default.json +0 -58
- package/.agent/data/email/processed-emails.json +0 -1
- package/.agent/data/plugins-state.json +0 -199
- package/.agent/data/scheduler/tasks.json +0 -1
- package/.agent/data/web/web-config.json +0 -5
- package/.agent/data/weixin/images/file_1776188148383jpg +0 -0
- package/.agent/data/weixin/images/file_1776188458326.jpg +0 -0
- package/.agent/data/weixin/images/file_1776188689423.jpg +0 -0
- package/.agent/data/weixin/images/file_1776188813604.jpg +0 -0
- package/.agent/data/weixin/images/file_1776189097450.jpg +0 -0
- package/.agent/data/weixin/videos/file_1776188318431.mp4 +0 -0
- package/.agent/data/weixin.json +0 -6
- package/.agent/mcp_config.json +0 -14
- package/.agent/memory/user/mof6gk94-kneeuh.md +0 -9
- package/.agent/package.json +0 -8
- package/.agent/plugins/marknative/README.md +0 -134
- package/.agent/plugins/marknative/fonts/SegoeUI Emoji.ttf +0 -0
- package/.agent/plugins/marknative/fonts.zip +0 -0
- package/.agent/plugins/marknative/index.js +0 -256
- package/.agent/plugins/marknative/package.json +0 -12
- package/.agent/plugins/test-plugin.py +0 -99
- package/.agent/plugins.json +0 -14
- package/.agent/python-scripts/test_sample.py +0 -24
- package/.agent/sessions/cli_default.json +0 -247
- package/.agent/skills/agent-browser/SKILL.md +0 -311
- package/.agent/skills/agent-browser/TEST_PLAN.md +0 -200
- package/.agent/skills/sysinfo/SKILL.md +0 -38
- package/.agent/skills/sysinfo/system-info.sh +0 -130
- package/.agent/skills/workflow/SKILL.md +0 -324
- package/.agent/test-agent.js +0 -35
- package/.agent/weixin.json +0 -6
- package/.agent/workflows/email-digest.json +0 -50
- package/.agent/workflows/file-backup.json +0 -21
- package/.agent/workflows/get-ip-notify.json +0 -32
- package/.agent/workflows/news-aggregator.json +0 -93
- package/.agent/workflows/news-dashboard-v2.json +0 -94
- package/.agent/workflows/notification-batch.json +0 -32
- package/src/core/session-context.js +0 -346
- package/src/core/session-storage.js +0 -295
|
@@ -59,7 +59,7 @@ class PythonPluginLoader extends Plugin {
|
|
|
59
59
|
this.version = '1.0.0'
|
|
60
60
|
this.description = 'Python 插件加载器,属于Python的插件'
|
|
61
61
|
|
|
62
|
-
this._agentDir = config.agentDir || '.
|
|
62
|
+
this._agentDir = config.agentDir || '.foliko' // 默认从 .foliko 目录加载 Python 插件
|
|
63
63
|
this._pythonPlugins = new Map()
|
|
64
64
|
this._framework = null
|
|
65
65
|
this.system = true
|
package/plugins/qq-plugin.js
CHANGED
|
@@ -26,7 +26,7 @@ class QQPlugin extends Plugin {
|
|
|
26
26
|
this.description = 'QQ 对话插件,使用 QQ 开放平台进行对话'
|
|
27
27
|
this.priority = 80
|
|
28
28
|
this.enabled = false
|
|
29
|
-
this.path = `.
|
|
29
|
+
this.path = `.foliko/data`
|
|
30
30
|
|
|
31
31
|
this.config = {
|
|
32
32
|
appId: config.appId || process.env.QQ_APP_ID,
|
|
@@ -49,7 +49,7 @@ class QQPlugin extends Plugin {
|
|
|
49
49
|
this.agent = null
|
|
50
50
|
this.sessionId = null
|
|
51
51
|
|
|
52
|
-
const saveDir = path.join(process.cwd(), '.
|
|
52
|
+
const saveDir = path.join(process.cwd(), '.foliko', 'data', this.name)
|
|
53
53
|
this.downloader = new FileDownloader({
|
|
54
54
|
retries: 3,
|
|
55
55
|
baseDir: saveDir
|
|
@@ -175,7 +175,7 @@ class QQPlugin extends Plugin {
|
|
|
175
175
|
// 降级为普通发送
|
|
176
176
|
await this._client.sendC2CMessage({ openid, content })
|
|
177
177
|
}
|
|
178
|
-
return { success: true,
|
|
178
|
+
return { success: true, data: '消息发送成功' }
|
|
179
179
|
} catch (err) {
|
|
180
180
|
log.error(`消息发送失败: ${err.message}`)
|
|
181
181
|
return { error: err.message }
|
|
@@ -198,7 +198,7 @@ class QQPlugin extends Plugin {
|
|
|
198
198
|
imageUrl,
|
|
199
199
|
content,
|
|
200
200
|
})
|
|
201
|
-
return { success: true,
|
|
201
|
+
return { success: true, data: '图片发送成功' }
|
|
202
202
|
} catch (err) {
|
|
203
203
|
log.error(`图片发送失败: ${err.message}`)
|
|
204
204
|
return { error: err.message }
|
|
@@ -227,13 +227,13 @@ class QQPlugin extends Plugin {
|
|
|
227
227
|
try {
|
|
228
228
|
if (imageExts.includes(ext)) {
|
|
229
229
|
await this._client.sendC2CLocalImageMessage({ openid, filePath, content })
|
|
230
|
-
return { success: true,
|
|
230
|
+
return { success: true, data: '图片发送成功' }
|
|
231
231
|
} else if (voiceExts.includes(ext)) {
|
|
232
232
|
await this._client.sendC2CLocalVoiceMessage({ openid, filePath })
|
|
233
|
-
return { success: true,
|
|
233
|
+
return { success: true, data: '语音发送成功' }
|
|
234
234
|
} else if (videoExts.includes(ext)) {
|
|
235
235
|
await this._client.sendC2CLocalVideoMessage({ openid, filePath, content })
|
|
236
|
-
return { success: true,
|
|
236
|
+
return { success: true, data: '视频发送成功' }
|
|
237
237
|
} else {
|
|
238
238
|
// 未知格式,当作文件处理
|
|
239
239
|
return this._sendFile(openid, filePath, content)
|
|
@@ -263,7 +263,7 @@ class QQPlugin extends Plugin {
|
|
|
263
263
|
filePath,
|
|
264
264
|
content,
|
|
265
265
|
})
|
|
266
|
-
return { success: true,
|
|
266
|
+
return { success: true, data: '文件发送成功' }
|
|
267
267
|
} catch (err) {
|
|
268
268
|
log.error(`文件发送失败: ${err.message}`)
|
|
269
269
|
return { error: err.message }
|
|
@@ -285,7 +285,7 @@ class QQPlugin extends Plugin {
|
|
|
285
285
|
groupOpenid,
|
|
286
286
|
content,
|
|
287
287
|
})
|
|
288
|
-
return { success: true,
|
|
288
|
+
return { success: true, data: '群消息发送成功' }
|
|
289
289
|
} catch (err) {
|
|
290
290
|
log.error(`群消息发送失败: ${err.message}`)
|
|
291
291
|
return { error: err.message }
|
|
@@ -311,7 +311,7 @@ class QQPlugin extends Plugin {
|
|
|
311
311
|
filePath: imagePath,
|
|
312
312
|
content,
|
|
313
313
|
})
|
|
314
|
-
return { success: true,
|
|
314
|
+
return { success: true, data: '群图片发送成功' }
|
|
315
315
|
} catch (err) {
|
|
316
316
|
log.error(`群图片发送失败: ${err.message}`)
|
|
317
317
|
return { error: err.message }
|
|
@@ -679,17 +679,28 @@ class QQPlugin extends Plugin {
|
|
|
679
679
|
const command = parts[0].substring(1)
|
|
680
680
|
const args = parts.slice(1).join(' ')
|
|
681
681
|
|
|
682
|
+
// 检查 skill 命令 (格式: skillname:cmdname)
|
|
683
|
+
if (command.includes(':')) {
|
|
684
|
+
const result = await this._executeSkillCommand(command, args)
|
|
685
|
+
if (result) {
|
|
686
|
+
await this._sendMessage(openid, `✅ ${result.data || result}`)
|
|
687
|
+
return
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
682
691
|
switch (command.toLowerCase()) {
|
|
683
692
|
case 'start':
|
|
684
693
|
case 'help':
|
|
685
|
-
await this.
|
|
686
|
-
'👋 欢迎使用 AI 助手!\n\n直接发送消息即可与我对话。\n\n可用命令:\n/clean - 清除对话上下文\n/history - 查看历史消息数')
|
|
694
|
+
await this._sendMessageHelp(openid)
|
|
687
695
|
break
|
|
688
696
|
case 'clean':
|
|
689
697
|
case 'clear':
|
|
690
698
|
await this._clearSessionContext(openid)
|
|
691
699
|
await this._sendMessage(openid, '✅ 对话上下文已清除')
|
|
692
700
|
break
|
|
701
|
+
case 'compress':
|
|
702
|
+
await this._compressSessionContext(openid)
|
|
703
|
+
break
|
|
693
704
|
case 'history':
|
|
694
705
|
const sessionInfo = this._getSessionAgent(openid)
|
|
695
706
|
if (sessionInfo && this._framework) {
|
|
@@ -701,10 +712,55 @@ class QQPlugin extends Plugin {
|
|
|
701
712
|
}
|
|
702
713
|
break
|
|
703
714
|
default:
|
|
715
|
+
// 检查是否是 skill 命令 (格式: skillname:cmdname)
|
|
716
|
+
if (text.startsWith('/')) {
|
|
717
|
+
const cmdParts = command.split(':')
|
|
718
|
+
if (cmdParts.length === 2) {
|
|
719
|
+
const skillCmd = `${cmdParts[0]}:${cmdParts[1]}`
|
|
720
|
+
try {
|
|
721
|
+
const result = await this._framework.executeTool('ext_call', {
|
|
722
|
+
plugin: 'skill',
|
|
723
|
+
tool: skillCmd,
|
|
724
|
+
args: { args }
|
|
725
|
+
})
|
|
726
|
+
if (result.success !== false) {
|
|
727
|
+
await this._sendMessage(openid, `✅ ${result.data || result}`)
|
|
728
|
+
return
|
|
729
|
+
}
|
|
730
|
+
} catch (err) {
|
|
731
|
+
log.warn('Skill command failed:', err.message)
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
704
735
|
await this._processChat(openid, text, originalMsg, 'c2c')
|
|
705
736
|
}
|
|
706
737
|
}
|
|
707
738
|
|
|
739
|
+
/**
|
|
740
|
+
* 检查并执行 skill 命令
|
|
741
|
+
*/
|
|
742
|
+
async _executeSkillCommand(command, args) {
|
|
743
|
+
const extExecutor = this._framework?.pluginManager?.get('extension-executor')
|
|
744
|
+
if (!extExecutor || typeof extExecutor.executeSkillCommand !== 'function') return null
|
|
745
|
+
return await extExecutor.executeSkillCommand(command, args)
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* 发送帮助信息
|
|
750
|
+
*/
|
|
751
|
+
async _sendMessageHelp(openid) {
|
|
752
|
+
const extExecutor = this._framework?.pluginManager?.get('extension-executor')
|
|
753
|
+
const skillHelp = extExecutor?.getSkillCommandsHelp?.() || ''
|
|
754
|
+
|
|
755
|
+
let helpText = '👋 欢迎使用 AI 助手!\n\n直接发送消息即可与我对话。\n\n可用命令:\n/clean - 清除对话上下文\n/compress - 压缩上下文\n/history - 查看历史消息数'
|
|
756
|
+
|
|
757
|
+
if (skillHelp) {
|
|
758
|
+
helpText += '\n\n【技能命令】\n' + skillHelp.split('\n').map(line => line.replace(/^\//, '/')).join('\n')
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
await this._sendMessage(openid, helpText)
|
|
762
|
+
}
|
|
763
|
+
|
|
708
764
|
/**
|
|
709
765
|
* 处理群命令
|
|
710
766
|
*/
|
|
@@ -713,17 +769,28 @@ class QQPlugin extends Plugin {
|
|
|
713
769
|
const command = parts[0].substring(1)
|
|
714
770
|
const args = parts.slice(1).join(' ')
|
|
715
771
|
|
|
772
|
+
// 检查 skill 命令 (格式: skillname:cmdname)
|
|
773
|
+
if (command.includes(':')) {
|
|
774
|
+
const result = await this._executeSkillCommand(command, args)
|
|
775
|
+
if (result) {
|
|
776
|
+
await this._sendGroupMessage(groupOpenid, `✅ ${result.data || result}`)
|
|
777
|
+
return
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
716
781
|
switch (command.toLowerCase()) {
|
|
717
782
|
case 'start':
|
|
718
783
|
case 'help':
|
|
719
|
-
await this.
|
|
720
|
-
'👋 欢迎使用 AI 助手!\n\n可用命令:\n/clean - 清除对话上下文\n/history - 查看历史消息数')
|
|
784
|
+
await this._sendGroupMessageHelp(groupOpenid)
|
|
721
785
|
break
|
|
722
786
|
case 'clean':
|
|
723
787
|
case 'clear':
|
|
724
788
|
await this._clearSessionContext(groupOpenid)
|
|
725
789
|
await this._sendGroupMessage(groupOpenid, '✅ 对话上下文已清除')
|
|
726
790
|
break
|
|
791
|
+
case 'compress':
|
|
792
|
+
await this._compressSessionContext(groupOpenid)
|
|
793
|
+
break
|
|
727
794
|
case 'history':
|
|
728
795
|
const sessionInfo = this._getSessionAgent(groupOpenid, 'group')
|
|
729
796
|
if (sessionInfo && this._framework) {
|
|
@@ -739,6 +806,22 @@ class QQPlugin extends Plugin {
|
|
|
739
806
|
}
|
|
740
807
|
}
|
|
741
808
|
|
|
809
|
+
/**
|
|
810
|
+
* 发送群组帮助信息
|
|
811
|
+
*/
|
|
812
|
+
async _sendGroupMessageHelp(groupOpenid) {
|
|
813
|
+
const extExecutor = this._framework?.pluginManager?.get('extension-executor')
|
|
814
|
+
const skillHelp = extExecutor?.getSkillCommandsHelp?.() || ''
|
|
815
|
+
|
|
816
|
+
let helpText = '👋 欢迎使用 AI 助手!\n\n可用命令:\n/clean - 清除对话上下文\n/compress - 压缩上下文\n/history - 查看历史消息数'
|
|
817
|
+
|
|
818
|
+
if (skillHelp) {
|
|
819
|
+
helpText += '\n\n【技能命令】\n' + skillHelp.split('\n').map(line => line.replace(/^\//, '/')).join('\n')
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
await this._sendGroupMessage(groupOpenid, helpText)
|
|
823
|
+
}
|
|
824
|
+
|
|
742
825
|
/**
|
|
743
826
|
* 清除会话上下文
|
|
744
827
|
*/
|
|
@@ -752,18 +835,62 @@ class QQPlugin extends Plugin {
|
|
|
752
835
|
}
|
|
753
836
|
|
|
754
837
|
if (this._framework) {
|
|
755
|
-
const
|
|
756
|
-
if (
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
838
|
+
const manager = this._framework.getSessionContext(sessionId)
|
|
839
|
+
if (manager) {
|
|
840
|
+
manager.clearMessages()
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
/**
|
|
846
|
+
* 压缩会话上下文
|
|
847
|
+
*/
|
|
848
|
+
async _compressSessionContext(identifier) {
|
|
849
|
+
const sessionId = `qq_c2c_${identifier}`
|
|
850
|
+
|
|
851
|
+
const { agent } = this._getSessionAgent(identifier)
|
|
852
|
+
|
|
853
|
+
if (agent._chatHandler) {
|
|
854
|
+
const chatHandler = agent._chatHandler
|
|
855
|
+
|
|
856
|
+
const messageStore = chatHandler._chatSession.getSessionMessageStore(sessionId)
|
|
857
|
+
messageStore.historyLoaded = false
|
|
858
|
+
chatHandler._chatSession.loadHistory(sessionId)
|
|
859
|
+
|
|
860
|
+
let messages = messageStore.messages
|
|
861
|
+
|
|
862
|
+
if (!messages || messages.length === 0) {
|
|
863
|
+
if (this._framework) {
|
|
864
|
+
const sessionCtx = this._framework.getSessionContext(sessionId)
|
|
865
|
+
if (sessionCtx) {
|
|
866
|
+
messages = sessionCtx.getMessages()
|
|
867
|
+
messageStore.messages = messages
|
|
868
|
+
}
|
|
869
|
+
}
|
|
760
870
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
871
|
+
|
|
872
|
+
const beforeCount = messages ? messages.length : 0
|
|
873
|
+
await this._sendMessage(identifier, `📦 开始压缩上下文,当前 ${beforeCount} 条消息...`)
|
|
874
|
+
|
|
875
|
+
if (messages && messages.length > 0) {
|
|
876
|
+
if (chatHandler._contextCompressor) {
|
|
877
|
+
await chatHandler._contextCompressor.compress(sessionId, messages, messageStore)
|
|
878
|
+
const afterCount = messages.length
|
|
879
|
+
if (this._framework) {
|
|
880
|
+
const sessionCtx = this._framework.getSessionContext(sessionId)
|
|
881
|
+
if (sessionCtx) {
|
|
882
|
+
sessionCtx.replaceMessages(messages)
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
await this._sendMessage(identifier, `✅ 压缩完成:${beforeCount} → ${afterCount} 条(保留 ${chatHandler._contextCompressor._keepRecentMessages} 条)`)
|
|
886
|
+
} else {
|
|
887
|
+
await this._sendMessage(identifier, '❌ 压缩器不可用')
|
|
888
|
+
}
|
|
889
|
+
} else {
|
|
890
|
+
await this._sendMessage(identifier, '❌ 没有消息需要压缩')
|
|
766
891
|
}
|
|
892
|
+
} else {
|
|
893
|
+
await this._sendMessage(identifier, '❌ ChatHandler 不可用')
|
|
767
894
|
}
|
|
768
895
|
}
|
|
769
896
|
|
package/plugins/rules-plugin.js
CHANGED
|
@@ -41,7 +41,7 @@ class RulesPlugin extends Plugin {
|
|
|
41
41
|
this.system = true
|
|
42
42
|
|
|
43
43
|
this.config = {
|
|
44
|
-
rulesDir: config.rulesDir || '.
|
|
44
|
+
rulesDir: config.rulesDir || '.foliko/rules',
|
|
45
45
|
autoLoad: config.autoLoad !== false
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -74,14 +74,14 @@ class RulesPlugin extends Plugin {
|
|
|
74
74
|
execute: async () => {
|
|
75
75
|
return {
|
|
76
76
|
success: true,
|
|
77
|
-
|
|
77
|
+
data: this._rules.map(r => ({
|
|
78
78
|
name: r.name,
|
|
79
79
|
type: r.type,
|
|
80
80
|
target: r.target,
|
|
81
81
|
description: r.description,
|
|
82
82
|
enabled: r.enabled
|
|
83
83
|
})),
|
|
84
|
-
total: this._rules.length
|
|
84
|
+
metadata: { total: this._rules.length }
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
})
|
|
@@ -108,7 +108,7 @@ class RulesPlugin extends Plugin {
|
|
|
108
108
|
enabled: true
|
|
109
109
|
}
|
|
110
110
|
this._rules.push(rule)
|
|
111
|
-
return { success: true,
|
|
111
|
+
return { success: true, data: `规则已添加: ${rule.name}` }
|
|
112
112
|
}
|
|
113
113
|
})
|
|
114
114
|
|
|
@@ -124,7 +124,7 @@ class RulesPlugin extends Plugin {
|
|
|
124
124
|
return { success: false, error: 'Rule not found' }
|
|
125
125
|
}
|
|
126
126
|
this._rules.splice(index, 1)
|
|
127
|
-
return { success: true,
|
|
127
|
+
return { success: true, data: `规则已移除: ${args.name}` }
|
|
128
128
|
}
|
|
129
129
|
})
|
|
130
130
|
|
|
@@ -135,7 +135,7 @@ class RulesPlugin extends Plugin {
|
|
|
135
135
|
execute: async () => {
|
|
136
136
|
return {
|
|
137
137
|
success: true,
|
|
138
|
-
|
|
138
|
+
data: { ...this._ruleStats }
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
})
|
|
@@ -151,8 +151,8 @@ class RulesPlugin extends Plugin {
|
|
|
151
151
|
const result = this.evaluate(args.target, args.input || {})
|
|
152
152
|
return {
|
|
153
153
|
success: true,
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
data: {
|
|
155
|
+
target: args.target,
|
|
156
156
|
allowed: result.allowed,
|
|
157
157
|
ruleName: result.rule?.name || null,
|
|
158
158
|
ruleType: result.rule?.type || null
|
|
@@ -20,7 +20,7 @@ try {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// ============================================================================
|
|
23
|
-
// TaskStore - 持久化任务到 .
|
|
23
|
+
// TaskStore - 持久化任务到 .foliko/data/scheduler/tasks.json
|
|
24
24
|
// ============================================================================
|
|
25
25
|
class TaskStore {
|
|
26
26
|
constructor(persistencePath) {
|
|
@@ -130,7 +130,7 @@ class SchedulerPlugin extends Plugin {
|
|
|
130
130
|
this.system = true
|
|
131
131
|
this.config = {
|
|
132
132
|
checkInterval: config.checkInterval || 1000, // 每秒检查一次
|
|
133
|
-
persistencePath: config.persistencePath || '.
|
|
133
|
+
persistencePath: config.persistencePath || '.foliko/data/scheduler'
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
this._framework = null
|
|
@@ -227,15 +227,17 @@ class SchedulerPlugin extends Plugin {
|
|
|
227
227
|
this._saveTasks()
|
|
228
228
|
return {
|
|
229
229
|
success: true,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
230
|
+
data: repeat ? 'Shell 定时任务已创建 (重复执行)' : 'Shell 任务已创建',
|
|
231
|
+
metadata: {
|
|
232
|
+
taskId: task.id,
|
|
233
|
+
name: task.name,
|
|
234
|
+
type: 'shell',
|
|
235
|
+
shell,
|
|
236
|
+
scheduleTime,
|
|
237
|
+
cronExpression: task.cronExpression,
|
|
238
|
+
sessionId: sessionId || 'default',
|
|
239
|
+
notify: task.notify
|
|
240
|
+
}
|
|
239
241
|
}
|
|
240
242
|
} else {
|
|
241
243
|
// 一次性 Shell 任务
|
|
@@ -276,15 +278,17 @@ class SchedulerPlugin extends Plugin {
|
|
|
276
278
|
this._saveTasks()
|
|
277
279
|
return {
|
|
278
280
|
success: true,
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
281
|
+
data: 'Shell 任务已创建',
|
|
282
|
+
metadata: {
|
|
283
|
+
taskId: task.id,
|
|
284
|
+
name: task.name,
|
|
285
|
+
type: 'shell',
|
|
286
|
+
shell,
|
|
287
|
+
scheduleTime,
|
|
288
|
+
executeAt: runAt.toISOString(),
|
|
289
|
+
sessionId: sessionId || 'default',
|
|
290
|
+
notify: task.notify
|
|
291
|
+
}
|
|
288
292
|
}
|
|
289
293
|
}
|
|
290
294
|
}
|