foliko 1.0.34 → 1.0.36

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.
@@ -75,7 +75,9 @@
75
75
  "Bash(node -e \"const {EmailPlugin} = require\\('./plugins/email'\\); const p = new EmailPlugin\\(\\); console.log\\('email plugin loaded ok'\\); console.log\\('enabled:', p.enabled\\); console.log\\('version:', p.version\\);\" 2>&1)",
76
76
  "Bash(cd D:/Code/vb-agent && node -e \"console.log\\('IMAP_HOST:', process.env.IMAP_HOST\\); console.log\\('IMAP_USER:', process.env.IMAP_USER\\); console.log\\('IMAP_PORT:', process.env.IMAP_PORT\\);\")",
77
77
  "Bash(node -e \"const sdk = require\\('@larksuiteoapi/node-sdk'\\); console.log\\(Object.keys\\(sdk\\)\\);\")",
78
- "Bash(node -e \"const { WSClient } = require\\('@larksuiteoapi/node-sdk'\\); const sdk = new WSClient\\({}\\); console.log\\(Object.getOwnPropertyNames\\(Object.getPrototypeOf\\(sdk\\)\\)\\);\")"
78
+ "Bash(node -e \"const { WSClient } = require\\('@larksuiteoapi/node-sdk'\\); const sdk = new WSClient\\({}\\); console.log\\(Object.getOwnPropertyNames\\(Object.getPrototypeOf\\(sdk\\)\\)\\);\")",
79
+ "Bash(node -c src/core/framework.js 2>&1)",
80
+ "Bash(node -c plugins/telegram-plugin.js 2>&1)"
79
81
  ]
80
82
  }
81
83
  }
package/cli/bin/foliko.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  /**
3
3
  * Foliko CLI 入口
4
4
  * Usage: foliko <command> [options]
package/examples/basic.js CHANGED
@@ -1,110 +1,110 @@
1
- /**
2
- * 基础示例
3
- * 展示如何使用 Framework 和 Agent
4
- */
5
-
6
- const { Framework } = require('../src')
7
- const { AIPlugin } = require('../plugins/ai-plugin')
8
- const { z } = require('zod')
9
-
10
- async function main() {
11
- // 创建框架实例
12
- const framework = new Framework({ debug: true })
13
-
14
- // 加载 AI 插件
15
- await framework.loadPlugin(new AIPlugin({
16
- provider: 'deepseek',
17
- model: 'deepseek-chat',
18
- apiKey: process.env.DEEPSEEK_API_KEY || 'your-api-key'
19
- }))
20
-
21
- // 注册自定义工具(使用 inputSchema 格式)
22
- framework.registerTool({
23
- name: 'hello',
24
- description: '打招呼工具',
25
- inputSchema: z.object({
26
- name: z.string().optional().describe('姓名')
27
- }),
28
- execute: async (args) => {
29
- return `Hello, ${args.name || 'World'}!`
30
- }
31
- })
32
-
33
- // 注册计算器工具
34
- framework.registerTool({
35
- name: 'calculate',
36
- description: '简单的计算器',
37
- inputSchema: z.object({
38
- expression: z.string().describe('数学表达式,如 2+3*4')
39
- }),
40
- execute: async (args) => {
41
- try {
42
- // 安全计算(仅支持基本运算)
43
- const result = Function(`"use strict"; return (${args.expression})`)()
44
- return { result }
45
- } catch (e) {
46
- return { error: e.message }
47
- }
48
- }
49
- })
50
-
51
- console.log('[Framework] Ready!')
52
- console.log('[Tools]', framework.getTools().map(t => t.name))
53
-
54
- // 创建 Agent
55
- const agent = framework.createAgent({
56
- name: 'MyAgent',
57
- systemPrompt: '你是一个有帮助的助手。当需要计算时,使用 calculate 工具。'
58
- })
59
-
60
- // 监听事件
61
- agent.on('tool-call', (tool) => {
62
- console.log('[Agent] Tool call:', tool.name, tool.args)
63
- })
64
-
65
- agent.on('tool-result', (result) => {
66
- console.log('[Agent] Tool result:', result.name, result.result)
67
- })
68
-
69
- // AI 对话示例
70
- console.log('\n=== AI Chat Example ===')
71
- try {
72
- const response = await agent.chat('你好!')
73
- console.log('[Agent] Response:', response.message)
74
- } catch (err) {
75
- console.error('[Agent] Error:', err.message)
76
- }
77
-
78
- // 使用工具的对话示例
79
- console.log('\n=== AI Chat with Tool Call ===')
80
- try {
81
- const response = await agent.chat('请帮我计算 (15 + 25) * 2 等于多少?')
82
- console.log('[Agent] Response:', response.message)
83
- } catch (err) {
84
- console.error('[Agent] Error:', err.message)
85
- }
86
-
87
- // 流式对话示例
88
- console.log('\n=== Streaming Chat ===')
89
- try {
90
- for await (const chunk of agent.chatStream('请用中文介绍一下你自己')) {
91
- if (chunk.type === 'text') {
92
- process.stdout.write(chunk.text)
93
- }
94
- }
95
- console.log('\n')
96
- } catch (err) {
97
- console.error('[Agent] Stream Error:', err.message)
98
- }
99
-
100
- // 热重载示例
101
- console.log('\n=== Hot Reload ===')
102
- await framework.reloadPlugin('ai')
103
- console.log('AI plugin reloaded!')
104
-
105
- // 清理
106
- await framework.destroy()
107
- console.log('\n[Done]')
108
- }
109
-
110
- main().catch(console.error)
1
+ /**
2
+ * 基础示例
3
+ * 展示如何使用 Framework 和 Agent
4
+ */
5
+
6
+ const { Framework } = require('../src')
7
+ const { AIPlugin } = require('../plugins/ai-plugin')
8
+ const { z } = require('zod')
9
+
10
+ async function main() {
11
+ // 创建框架实例
12
+ const framework = new Framework({ debug: true })
13
+
14
+ // 加载 AI 插件
15
+ await framework.loadPlugin(new AIPlugin({
16
+ provider: 'deepseek',
17
+ model: 'deepseek-chat',
18
+ apiKey: process.env.DEEPSEEK_API_KEY || 'your-api-key'
19
+ }))
20
+
21
+ // 注册自定义工具(使用 inputSchema 格式)
22
+ framework.registerTool({
23
+ name: 'hello',
24
+ description: '打招呼工具',
25
+ inputSchema: z.object({
26
+ name: z.string().optional().describe('姓名')
27
+ }),
28
+ execute: async (args) => {
29
+ return `Hello, ${args.name || 'World'}!`
30
+ }
31
+ })
32
+
33
+ // 注册计算器工具
34
+ framework.registerTool({
35
+ name: 'calculate',
36
+ description: '简单的计算器',
37
+ inputSchema: z.object({
38
+ expression: z.string().describe('数学表达式,如 2+3*4')
39
+ }),
40
+ execute: async (args) => {
41
+ try {
42
+ // 安全计算(仅支持基本运算)
43
+ const result = Function(`"use strict"; return (${args.expression})`)()
44
+ return { result }
45
+ } catch (e) {
46
+ return { error: e.message }
47
+ }
48
+ }
49
+ })
50
+
51
+ console.log('[Framework] Ready!')
52
+ console.log('[Tools]', framework.getTools().map(t => t.name))
53
+
54
+ // 创建 Agent
55
+ const agent = framework.createAgent({
56
+ name: 'MyAgent',
57
+ systemPrompt: '你是一个有帮助的助手。当需要计算时,使用 calculate 工具。'
58
+ })
59
+
60
+ // 监听事件
61
+ agent.on('tool-call', (tool) => {
62
+ console.log('[Agent] Tool call:', tool.name, tool.args)
63
+ })
64
+
65
+ agent.on('tool-result', (result) => {
66
+ console.log('[Agent] Tool result:', result.name, result.result)
67
+ })
68
+
69
+ // AI 对话示例
70
+ console.log('\n=== AI Chat Example ===')
71
+ try {
72
+ const response = await agent.chat('你好!')
73
+ console.log('[Agent] Response:', response.message)
74
+ } catch (err) {
75
+ console.error('[Agent] Error:', err.message)
76
+ }
77
+
78
+ // 使用工具的对话示例
79
+ console.log('\n=== AI Chat with Tool Call ===')
80
+ try {
81
+ const response = await agent.chat('请帮我计算 (15 + 25) * 2 等于多少?')
82
+ console.log('[Agent] Response:', response.message)
83
+ } catch (err) {
84
+ console.error('[Agent] Error:', err.message)
85
+ }
86
+
87
+ // 流式对话示例
88
+ console.log('\n=== Streaming Chat ===')
89
+ try {
90
+ for await (const chunk of agent.chatStream('请用中文介绍一下你自己')) {
91
+ if (chunk.type === 'text') {
92
+ process.stdout.write(chunk.text)
93
+ }
94
+ }
95
+ console.log('\n')
96
+ } catch (err) {
97
+ console.error('[Agent] Stream Error:', err.message)
98
+ }
99
+
100
+ // 热重载示例
101
+ console.log('\n=== Hot Reload ===')
102
+ await framework.reloadPlugin('ai')
103
+ console.log('AI plugin reloaded!')
104
+
105
+ // 清理
106
+ await framework.destroy()
107
+ console.log('\n[Done]')
108
+ }
109
+
110
+ main().catch(console.error)
@@ -1,53 +1,53 @@
1
- /**
2
- * MCP 执行器示例
3
- * 展示如何连接 MCP 服务器
4
- */
5
-
6
- const { Framework } = require('../src')
7
- const { MCPExecutorPlugin } = require('../src/executors/mcp-executor')
8
-
9
- async function main() {
10
- console.log('=== MCP Executor Example ===\n')
11
-
12
- // 创建框架
13
- const framework = new Framework({ debug: true })
14
-
15
- // 创建 MCP 执行器插件
16
- const mcpPlugin = new MCPExecutorPlugin({
17
- servers: [
18
- // 示例:添加一个 MCP 服务器
19
- // {
20
- // name: 'example',
21
- // command: 'uvx',
22
- // args: ['example-mcp-server'],
23
- // env: {}
24
- // }
25
- ]
26
- })
27
-
28
- // 加载插件
29
- await framework.loadPlugin(mcpPlugin)
30
-
31
- // 列出服务器
32
- console.log('\n--- MCP Servers ---')
33
- const servers = mcpPlugin.getServers()
34
- console.log('Servers:', servers)
35
-
36
- // 列出所有 MCP 工具
37
- console.log('\n--- MCP Tools ---')
38
- const tools = framework.getTools().filter(t => t.name.startsWith('mcp_'))
39
- console.log('MCP tools:', tools.map(t => t.name))
40
-
41
- // 如果有配置的服务器,可以这样调用:
42
- // const result = await framework.executeTool('mcp_call', {
43
- // server: 'example',
44
- // tool: 'tool_name',
45
- // args: { /* tool arguments */ }
46
- // })
47
-
48
- // 清理
49
- await framework.destroy()
50
- console.log('\n[Done]')
51
- }
52
-
53
- main().catch(console.error)
1
+ /**
2
+ * MCP 执行器示例
3
+ * 展示如何连接 MCP 服务器
4
+ */
5
+
6
+ const { Framework } = require('../src')
7
+ const { MCPExecutorPlugin } = require('../src/executors/mcp-executor')
8
+
9
+ async function main() {
10
+ console.log('=== MCP Executor Example ===\n')
11
+
12
+ // 创建框架
13
+ const framework = new Framework({ debug: true })
14
+
15
+ // 创建 MCP 执行器插件
16
+ const mcpPlugin = new MCPExecutorPlugin({
17
+ servers: [
18
+ // 示例:添加一个 MCP 服务器
19
+ // {
20
+ // name: 'example',
21
+ // command: 'uvx',
22
+ // args: ['example-mcp-server'],
23
+ // env: {}
24
+ // }
25
+ ]
26
+ })
27
+
28
+ // 加载插件
29
+ await framework.loadPlugin(mcpPlugin)
30
+
31
+ // 列出服务器
32
+ console.log('\n--- MCP Servers ---')
33
+ const servers = mcpPlugin.getServers()
34
+ console.log('Servers:', servers)
35
+
36
+ // 列出所有 MCP 工具
37
+ console.log('\n--- MCP Tools ---')
38
+ const tools = framework.getTools().filter(t => t.name.startsWith('mcp_'))
39
+ console.log('MCP tools:', tools.map(t => t.name))
40
+
41
+ // 如果有配置的服务器,可以这样调用:
42
+ // const result = await framework.executeTool('mcp_call', {
43
+ // server: 'example',
44
+ // tool: 'tool_name',
45
+ // args: { /* tool arguments */ }
46
+ // })
47
+
48
+ // 清理
49
+ await framework.destroy()
50
+ console.log('\n[Done]')
51
+ }
52
+
53
+ main().catch(console.error)
@@ -1,49 +1,49 @@
1
- /**
2
- * Skill 管理器示例
3
- * 展示如何加载和使用 Skill
4
- */
5
-
6
- const { Framework } = require('../src')
7
- const { SkillManagerPlugin } = require('../src/capabilities/skill-manager')
8
-
9
- async function main() {
10
- console.log('=== Skill Manager Example ===\n')
11
-
12
- // 创建框架
13
- const framework = new Framework({ debug: true })
14
-
15
- // 创建 skills 目录(如果没有)
16
- const fs = require('fs')
17
- const skillsDir = './skills'
18
- if (!fs.existsSync(skillsDir)) {
19
- fs.mkdirSync(skillsDir, { recursive: true })
20
- }
21
-
22
- // 加载 Skill 管理器插件
23
- const skillPlugin = new SkillManagerPlugin({
24
- skillsDir: skillsDir
25
- })
26
-
27
- await framework.loadPlugin(skillPlugin)
28
-
29
- // 列出所有加载的 skills
30
- console.log('\n--- Loaded Skills ---')
31
- const skills = skillPlugin.getAllSkills()
32
- console.log(`Found ${skills.length} skills:`)
33
- for (const skill of skills) {
34
- console.log(` - ${skill.name}: ${skill.metadata.description}`)
35
- }
36
-
37
- // 获取单个 skill
38
- if (skillPlugin.hasSkill('hello-skill')) {
39
- console.log('\n--- Hello Skill ---')
40
- const helloSkill = skillPlugin.getSkill('hello-skill')
41
- console.log('Content preview:', helloSkill.content.substring(0, 100) + '...')
42
- }
43
-
44
- // 清理
45
- await framework.destroy()
46
- console.log('\n[Done]')
47
- }
48
-
49
- main().catch(console.error)
1
+ /**
2
+ * Skill 管理器示例
3
+ * 展示如何加载和使用 Skill
4
+ */
5
+
6
+ const { Framework } = require('../src')
7
+ const { SkillManagerPlugin } = require('../src/capabilities/skill-manager')
8
+
9
+ async function main() {
10
+ console.log('=== Skill Manager Example ===\n')
11
+
12
+ // 创建框架
13
+ const framework = new Framework({ debug: true })
14
+
15
+ // 创建 skills 目录(如果没有)
16
+ const fs = require('fs')
17
+ const skillsDir = './skills'
18
+ if (!fs.existsSync(skillsDir)) {
19
+ fs.mkdirSync(skillsDir, { recursive: true })
20
+ }
21
+
22
+ // 加载 Skill 管理器插件
23
+ const skillPlugin = new SkillManagerPlugin({
24
+ skillsDir: skillsDir
25
+ })
26
+
27
+ await framework.loadPlugin(skillPlugin)
28
+
29
+ // 列出所有加载的 skills
30
+ console.log('\n--- Loaded Skills ---')
31
+ const skills = skillPlugin.getAllSkills()
32
+ console.log(`Found ${skills.length} skills:`)
33
+ for (const skill of skills) {
34
+ console.log(` - ${skill.name}: ${skill.metadata.description}`)
35
+ }
36
+
37
+ // 获取单个 skill
38
+ if (skillPlugin.hasSkill('hello-skill')) {
39
+ console.log('\n--- Hello Skill ---')
40
+ const helloSkill = skillPlugin.getSkill('hello-skill')
41
+ console.log('Content preview:', helloSkill.content.substring(0, 100) + '...')
42
+ }
43
+
44
+ // 清理
45
+ await framework.destroy()
46
+ console.log('\n[Done]')
47
+ }
48
+
49
+ main().catch(console.error)
@@ -1,79 +1,79 @@
1
- /**
2
- * MCP 插件测试脚本
3
- */
4
-
5
- const { Framework } = require('../src')
6
- const { MCPExecutorPlugin } = require('../src/executors/mcp-executor')
7
-
8
- async function test() {
9
- console.log('=== MCP Plugin Test ===\n')
10
-
11
- console.log('1. Creating framework...')
12
- const framework = new Framework({ debug: true })
13
-
14
- console.log('2. Creating MCP plugin with fetch server...')
15
- const mcpPlugin = new MCPExecutorPlugin({
16
- servers: [
17
- {
18
- name: 'fetch',
19
- command: 'uvx',
20
- args: ['mcp-server-fetch']
21
- }
22
- ]
23
- })
24
-
25
- console.log('3. Loading MCP plugin...')
26
- await framework.loadPlugin(mcpPlugin)
27
-
28
- console.log('4. Starting framework...')
29
- await framework.pluginManager.startAll()
30
-
31
- // 等待 MCP 服务器连接
32
- console.log('\n5. Waiting for MCP connection...')
33
- await new Promise(resolve => setTimeout(resolve, 2000))
34
-
35
- console.log('\n6. Listing MCP servers...')
36
- const servers = mcpPlugin.getServers()
37
- console.log('Servers:', JSON.stringify(servers, null, 2))
38
-
39
- console.log('\n7. Listing MCP tools...')
40
- const mcpTools = framework.getTools().filter(t => t.name.startsWith('mcp_'))
41
- console.log('MCP Tools:', mcpTools.map(t => t.name))
42
-
43
- if (mcpTools.length > 0) {
44
- console.log('\n8. Testing mcp_list_servers...')
45
- const listResult = await framework.executeTool('mcp_list_servers', {})
46
- console.log('List Servers Result:', JSON.stringify(listResult, null, 2))
47
-
48
- console.log('\n9. Testing mcp_tool_schema...')
49
- const schemaResult = await framework.executeTool('mcp_tool_schema', {
50
- server: 'fetch',
51
- tool: 'fetch'
52
- })
53
- console.log('Tool Schema:', JSON.stringify(schemaResult, null, 2))
54
-
55
- console.log('\n10. Testing mcp_call (fetch a webpage)...')
56
- const callResult = await framework.executeTool('mcp_call', {
57
- server: 'fetch',
58
- tool: 'fetch',
59
- args_json: JSON.stringify({ url: 'https://httpbin.org/get' })
60
- })
61
- console.log('Fetch Result (truncated):', JSON.stringify(callResult, null, 2).substring(0, 500) + '...')
62
- }
63
-
64
- console.log('\n11. Destroying framework...')
65
- await framework.destroy()
66
-
67
- console.log('\n=== Test Complete ===')
68
- }
69
-
70
- test()
71
- .then(() => {
72
- console.log('\n✓ Test completed successfully')
73
- process.exit(0)
74
- })
75
- .catch(err => {
76
- console.error('\n✗ Test failed:', err.message)
77
- console.error(err.stack)
78
- process.exit(1)
79
- })
1
+ /**
2
+ * MCP 插件测试脚本
3
+ */
4
+
5
+ const { Framework } = require('../src')
6
+ const { MCPExecutorPlugin } = require('../src/executors/mcp-executor')
7
+
8
+ async function test() {
9
+ console.log('=== MCP Plugin Test ===\n')
10
+
11
+ console.log('1. Creating framework...')
12
+ const framework = new Framework({ debug: true })
13
+
14
+ console.log('2. Creating MCP plugin with fetch server...')
15
+ const mcpPlugin = new MCPExecutorPlugin({
16
+ servers: [
17
+ {
18
+ name: 'fetch',
19
+ command: 'uvx',
20
+ args: ['mcp-server-fetch']
21
+ }
22
+ ]
23
+ })
24
+
25
+ console.log('3. Loading MCP plugin...')
26
+ await framework.loadPlugin(mcpPlugin)
27
+
28
+ console.log('4. Starting framework...')
29
+ await framework.pluginManager.startAll()
30
+
31
+ // 等待 MCP 服务器连接
32
+ console.log('\n5. Waiting for MCP connection...')
33
+ await new Promise(resolve => setTimeout(resolve, 2000))
34
+
35
+ console.log('\n6. Listing MCP servers...')
36
+ const servers = mcpPlugin.getServers()
37
+ console.log('Servers:', JSON.stringify(servers, null, 2))
38
+
39
+ console.log('\n7. Listing MCP tools...')
40
+ const mcpTools = framework.getTools().filter(t => t.name.startsWith('mcp_'))
41
+ console.log('MCP Tools:', mcpTools.map(t => t.name))
42
+
43
+ if (mcpTools.length > 0) {
44
+ console.log('\n8. Testing mcp_list_servers...')
45
+ const listResult = await framework.executeTool('mcp_list_servers', {})
46
+ console.log('List Servers Result:', JSON.stringify(listResult, null, 2))
47
+
48
+ console.log('\n9. Testing mcp_tool_schema...')
49
+ const schemaResult = await framework.executeTool('mcp_tool_schema', {
50
+ server: 'fetch',
51
+ tool: 'fetch'
52
+ })
53
+ console.log('Tool Schema:', JSON.stringify(schemaResult, null, 2))
54
+
55
+ console.log('\n10. Testing mcp_call (fetch a webpage)...')
56
+ const callResult = await framework.executeTool('mcp_call', {
57
+ server: 'fetch',
58
+ tool: 'fetch',
59
+ args_json: JSON.stringify({ url: 'https://httpbin.org/get' })
60
+ })
61
+ console.log('Fetch Result (truncated):', JSON.stringify(callResult, null, 2).substring(0, 500) + '...')
62
+ }
63
+
64
+ console.log('\n11. Destroying framework...')
65
+ await framework.destroy()
66
+
67
+ console.log('\n=== Test Complete ===')
68
+ }
69
+
70
+ test()
71
+ .then(() => {
72
+ console.log('\n✓ Test completed successfully')
73
+ process.exit(0)
74
+ })
75
+ .catch(err => {
76
+ console.error('\n✗ Test failed:', err.message)
77
+ console.error(err.stack)
78
+ process.exit(1)
79
+ })
@@ -1,61 +1,61 @@
1
- /**
2
- * MCP mcp_reload 功能测试
3
- */
4
-
5
- const { Framework } = require('../src')
6
- const { MCPExecutorPlugin } = require('../src/executors/mcp-executor')
7
- const fs = require('fs')
8
- const path = require('path')
9
-
10
- async function test() {
11
- console.log('=== Testing mcp_reload ===\n')
12
-
13
- // 创建框架
14
- const framework = new Framework({ debug: true })
15
-
16
- // 创建 MCP 插件
17
- const mcpPlugin = new MCPExecutorPlugin({
18
- servers: [
19
- { name: 'fetch', command: 'uvx', args: ['mcp-server-fetch'] }
20
- ]
21
- })
22
-
23
- // 加载并启动
24
- await framework.loadPlugin(mcpPlugin)
25
- await framework.pluginManager.startAll()
26
-
27
- // 等待连接
28
- await new Promise(r => setTimeout(r, 2000))
29
-
30
- console.log('\n1. 初始服务器列表:')
31
- const initialServers = mcpPlugin.getServers()
32
- console.log(JSON.stringify(initialServers, null, 2))
33
-
34
- // 测试 mcp_reload
35
- console.log('\n2. 调用 mcp_reload...')
36
- const result = await framework.executeTool('mcp_reload', {})
37
- console.log('mcp_reload 结果:')
38
- console.log(JSON.stringify(result, null, 2))
39
-
40
- // 检查配置
41
- console.log('\n3. 当前配置文件:')
42
- const configPath = path.resolve('.agent/mcp_config.json')
43
- if (fs.existsSync(configPath)) {
44
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'))
45
- console.log(JSON.stringify(config, null, 2))
46
- } else {
47
- console.log('配置文件不存在: ' + configPath)
48
- }
49
-
50
- // 清理
51
- await framework.destroy()
52
-
53
- console.log('\n=== 测试完成 ===')
54
- }
55
-
56
- test()
57
- .then(() => process.exit(0))
58
- .catch(err => {
59
- console.error('测试失败:', err)
60
- process.exit(1)
61
- })
1
+ /**
2
+ * MCP mcp_reload 功能测试
3
+ */
4
+
5
+ const { Framework } = require('../src')
6
+ const { MCPExecutorPlugin } = require('../src/executors/mcp-executor')
7
+ const fs = require('fs')
8
+ const path = require('path')
9
+
10
+ async function test() {
11
+ console.log('=== Testing mcp_reload ===\n')
12
+
13
+ // 创建框架
14
+ const framework = new Framework({ debug: true })
15
+
16
+ // 创建 MCP 插件
17
+ const mcpPlugin = new MCPExecutorPlugin({
18
+ servers: [
19
+ { name: 'fetch', command: 'uvx', args: ['mcp-server-fetch'] }
20
+ ]
21
+ })
22
+
23
+ // 加载并启动
24
+ await framework.loadPlugin(mcpPlugin)
25
+ await framework.pluginManager.startAll()
26
+
27
+ // 等待连接
28
+ await new Promise(r => setTimeout(r, 2000))
29
+
30
+ console.log('\n1. 初始服务器列表:')
31
+ const initialServers = mcpPlugin.getServers()
32
+ console.log(JSON.stringify(initialServers, null, 2))
33
+
34
+ // 测试 mcp_reload
35
+ console.log('\n2. 调用 mcp_reload...')
36
+ const result = await framework.executeTool('mcp_reload', {})
37
+ console.log('mcp_reload 结果:')
38
+ console.log(JSON.stringify(result, null, 2))
39
+
40
+ // 检查配置
41
+ console.log('\n3. 当前配置文件:')
42
+ const configPath = path.resolve('.agent/mcp_config.json')
43
+ if (fs.existsSync(configPath)) {
44
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'))
45
+ console.log(JSON.stringify(config, null, 2))
46
+ } else {
47
+ console.log('配置文件不存在: ' + configPath)
48
+ }
49
+
50
+ // 清理
51
+ await framework.destroy()
52
+
53
+ console.log('\n=== 测试完成 ===')
54
+ }
55
+
56
+ test()
57
+ .then(() => process.exit(0))
58
+ .catch(err => {
59
+ console.error('测试失败:', err)
60
+ process.exit(1)
61
+ })
package/package.json CHANGED
@@ -1,44 +1,44 @@
1
- {
2
- "name": "foliko",
3
- "version": "1.0.34",
4
- "description": "简约的插件化 Agent 框架",
5
- "main": "src/index.js",
6
- "bin": {
7
- "foliko": "./cli/bin/foliko.js"
8
- },
9
- "scripts": {
10
- "start": "node examples/basic.js",
11
- "chat": "node cli/bin/foliko.js chat",
12
- "test": "echo \"No tests yet\""
13
- },
14
- "keywords": [
15
- "agent",
16
- "ai",
17
- "framework",
18
- "plugin"
19
- ],
20
- "author": "",
21
- "license": "MIT",
22
- "dependencies": {
23
- "@ai-sdk/anthropic": "^3.0.58",
24
- "@ai-sdk/mcp": "^1.0.25",
25
- "@ai-sdk/openai": "^3.0.41",
26
- "@ai-sdk/openai-compatible": "^2.0.35",
27
- "@anthropic-ai/sdk": "^0.39.0",
28
- "@chnak/weixin-bot": "^1.2.0",
29
- "@larksuiteoapi/node-sdk": "^1.59.0",
30
- "@modelcontextprotocol/sdk": "^1.27.1",
31
- "ai": "^6.0.116",
32
- "dotenv": "^17.3.1",
33
- "imap": "^0.8.19",
34
- "imap-mkl": "^1.0.2",
35
- "mailparser": "^3.7.2",
36
- "marked": "^11.2.0",
37
- "marked-terminal": "6",
38
- "node-cron": "^4.2.1",
39
- "node-telegram-bot-api": "^0.67.0",
40
- "nodemailer": "^6.10.0",
41
- "qrcode-terminal": "^0.12.0",
42
- "zod": "^3.24.0"
43
- }
44
- }
1
+ {
2
+ "name": "foliko",
3
+ "version": "1.0.36",
4
+ "description": "简约的插件化 Agent 框架",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "foliko": "./cli/bin/foliko.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node examples/basic.js",
11
+ "chat": "node cli/bin/foliko.js chat",
12
+ "test": "echo \"No tests yet\""
13
+ },
14
+ "keywords": [
15
+ "agent",
16
+ "ai",
17
+ "framework",
18
+ "plugin"
19
+ ],
20
+ "author": "",
21
+ "license": "MIT",
22
+ "dependencies": {
23
+ "@ai-sdk/anthropic": "^3.0.58",
24
+ "@ai-sdk/mcp": "^1.0.25",
25
+ "@ai-sdk/openai": "^3.0.41",
26
+ "@ai-sdk/openai-compatible": "^2.0.35",
27
+ "@anthropic-ai/sdk": "^0.39.0",
28
+ "@chnak/weixin-bot": "^1.2.0",
29
+ "@larksuiteoapi/node-sdk": "^1.59.0",
30
+ "@modelcontextprotocol/sdk": "^1.27.1",
31
+ "ai": "^6.0.116",
32
+ "dotenv": "^17.3.1",
33
+ "imap": "^0.8.19",
34
+ "imap-mkl": "^1.0.2",
35
+ "mailparser": "^3.7.2",
36
+ "marked": "^11.2.0",
37
+ "marked-terminal": "6",
38
+ "node-cron": "^4.2.1",
39
+ "node-telegram-bot-api": "^0.67.0",
40
+ "nodemailer": "^6.10.0",
41
+ "qrcode-terminal": "^0.12.0",
42
+ "zod": "^3.24.0"
43
+ }
44
+ }
@@ -20,12 +20,12 @@ module.exports = function(Plugin) {
20
20
  this.priority = 80
21
21
  // 默认不启用,需要在 plugins.json 中设置 enabled: true
22
22
  this.enabled = false
23
+ this.systemPrompt='你是一个飞书助手。回复内容不要使用markdown格式文本。'
23
24
 
24
25
  this.config = {
25
26
  appId: config.appId || process.env.FEISHU_APP_ID,
26
27
  appSecret: config.appSecret || process.env.FEISHU_APP_SECRET,
27
- allowedUsers: config.allowedUsers || [],
28
- systemPrompt: '你是一个飞书助手。回复内容不要使用markdown格式文本。'
28
+ allowedUsers: config.allowedUsers || []
29
29
  }
30
30
 
31
31
  this._framework = null
@@ -265,7 +265,7 @@ module.exports = function(Plugin) {
265
265
 
266
266
  // 创建新 agent
267
267
  const agent = this._framework.createSessionAgent(`feishu_${openId}`, {
268
- systemPrompt: this.config.systemPrompt
268
+ systemPrompt: this.systemPrompt
269
269
  })
270
270
  this._sessionAgents.set(openId, agent)
271
271
  console.log('[Feishu] Created new session agent for openId:', openId)
@@ -29,13 +29,13 @@ module.exports = function(Plugin) {
29
29
  this.priority = 80
30
30
  // 默认不启用,需要在 plugins.json 中设置 enabled: true
31
31
  this.enabled = false
32
+ this.systemPrompt='你是一个有帮助的AI助手。回复内容不要使用markdown格式文本。'
32
33
 
33
34
  this.config = {
34
35
  botToken: config.botToken || process.env.TELEGRAM_BOT_TOKEN,
35
36
  allowedChats: config.allowedChats || [],
36
37
  groupMode: config.groupMode || false,
37
- prefix: config.prefix || '/',
38
- systemPrompt: config.systemPrompt || '你是一个有帮助的AI助手。回复内容不要使用markdown格式文本。'
38
+ prefix: config.prefix || '/'
39
39
  }
40
40
 
41
41
  this._framework = null
@@ -213,7 +213,9 @@ module.exports = function(Plugin) {
213
213
  }
214
214
 
215
215
  // 创建新 agent
216
- const agent = this._framework.createSessionAgent(`telegram_${chatId}`)
216
+ const agent = this._framework.createSessionAgent(`telegram_${chatId}`, {
217
+ systemPrompt: this.systemPrompt
218
+ })
217
219
  this._sessionAgents.set(chatId, agent)
218
220
  console.log('[Telegram] Created new session agent for chatId:', chatId)
219
221
 
@@ -20,11 +20,12 @@ module.exports = function(Plugin) {
20
20
  this.priority = 80
21
21
  // 默认不启用,需要在 plugins.json 中设置 enabled: true
22
22
  this.enabled = false
23
+ this.path=`./agent/data`
24
+ this.systemPrompt='你是一个微信助手。回复内容不要使用markdown格式文本'
23
25
 
24
26
  this.config = {
25
27
  forceLogin: config.forceLogin || process.env.WEIXIN_FORCE_LOGIN === 'true',
26
28
  qrcodeTerminal: config.qrcodeTerminal !== false && process.env.WEIXIN_QRCODE_TERMINAL !== 'false',
27
- systemPrompt: '你是一个微信助手。回复内容不要使用markdown格式文本',
28
29
  allowedUsers: config.allowedUsers || []
29
30
  }
30
31
 
@@ -92,6 +93,7 @@ module.exports = function(Plugin) {
92
93
  }
93
94
 
94
95
  this._bot = new WeixinBot({
96
+ tokenPath:`${this.path}/${this.name}.json`,
95
97
  onError: (err) => {
96
98
  console.error('[WeChat] Error:', err instanceof Error ? err.stack ?? err.message : String(err))
97
99
  },
@@ -160,7 +162,7 @@ module.exports = function(Plugin) {
160
162
 
161
163
  // 创建新 agent
162
164
  const agent = this._framework.createSessionAgent(`weixin_${userId}`, {
163
- systemPrompt: this.config.systemPrompt
165
+ systemPrompt: this.systemPrompt
164
166
  })
165
167
  this._sessionAgents.set(userId, agent)
166
168
  console.log('[WeChat] Created new session agent for userId:', userId)
@@ -194,6 +194,12 @@ class Framework extends EventEmitter {
194
194
 
195
195
  const agent = new Agent(this, agentConfig)
196
196
  this._agents.push(agent)
197
+
198
+ // 如果提供了 systemPrompt,需要更新 AgentChatHandler
199
+ if (agentConfig.systemPrompt) {
200
+ agent.setSystemPrompt(agentConfig.systemPrompt)
201
+ }
202
+
197
203
  this.emit('agent:created', agent)
198
204
  return agent
199
205
  }
@@ -1,58 +1,58 @@
1
- /**
2
- * Executor 基类
3
- * 执行器的基类,定义执行器接口
4
- */
5
-
6
- const { EventEmitter } = require('../utils/event-emitter')
7
-
8
- class ExecutorBase extends EventEmitter {
9
- /**
10
- * @param {string} name - 执行器名称
11
- */
12
- constructor(name) {
13
- super()
14
- this.name = name
15
- this._enabled = true
16
- }
17
-
18
- /**
19
- * 执行
20
- * @param {Object} params - 执行参数
21
- * @returns {Promise<any>}
22
- */
23
- async execute(params) {
24
- throw new Error('execute() must be implemented')
25
- }
26
-
27
- /**
28
- * 启用执行器
29
- */
30
- enable() {
31
- this._enabled = true
32
- return this
33
- }
34
-
35
- /**
36
- * 禁用执行器
37
- */
38
- disable() {
39
- this._enabled = false
40
- return this
41
- }
42
-
43
- /**
44
- * 是否启用
45
- */
46
- isEnabled() {
47
- return this._enabled
48
- }
49
-
50
- /**
51
- * 销毁
52
- */
53
- destroy() {
54
- this.removeAllListeners()
55
- }
56
- }
57
-
58
- module.exports = { ExecutorBase }
1
+ /**
2
+ * Executor 基类
3
+ * 执行器的基类,定义执行器接口
4
+ */
5
+
6
+ const { EventEmitter } = require('../utils/event-emitter')
7
+
8
+ class ExecutorBase extends EventEmitter {
9
+ /**
10
+ * @param {string} name - 执行器名称
11
+ */
12
+ constructor(name) {
13
+ super()
14
+ this.name = name
15
+ this._enabled = true
16
+ }
17
+
18
+ /**
19
+ * 执行
20
+ * @param {Object} params - 执行参数
21
+ * @returns {Promise<any>}
22
+ */
23
+ async execute(params) {
24
+ throw new Error('execute() must be implemented')
25
+ }
26
+
27
+ /**
28
+ * 启用执行器
29
+ */
30
+ enable() {
31
+ this._enabled = true
32
+ return this
33
+ }
34
+
35
+ /**
36
+ * 禁用执行器
37
+ */
38
+ disable() {
39
+ this._enabled = false
40
+ return this
41
+ }
42
+
43
+ /**
44
+ * 是否启用
45
+ */
46
+ isEnabled() {
47
+ return this._enabled
48
+ }
49
+
50
+ /**
51
+ * 销毁
52
+ */
53
+ destroy() {
54
+ this.removeAllListeners()
55
+ }
56
+ }
57
+
58
+ module.exports = { ExecutorBase }