foliko 1.0.39 → 1.0.41

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.
@@ -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
+ })
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Web 插件测试示例
3
+ * 测试路由注册和请求响应
4
+ */
5
+
6
+ const { WebPlugin } = require('../plugins/web-plugin')
7
+
8
+ async function test() {
9
+ console.log('=== Web 插件测试 ===\n')
10
+
11
+ // 1. 创建插件
12
+ const plugin = new WebPlugin()
13
+ const mockFramework = {
14
+ registerTool: (tool) => console.log(`[工具注册] ${tool.name}`),
15
+ _agents: [],
16
+ pluginManager: { get: () => null }
17
+ }
18
+ plugin.install(mockFramework)
19
+
20
+ // 2. 启动服务
21
+ console.log('\n[1] 启动 Web 服务...')
22
+ const startResult = await plugin._startServer(3099)
23
+ console.log('启动结果:', startResult.success ? '成功' : '失败')
24
+ console.log('服务地址: http://localhost:3099\n')
25
+
26
+ // 3. 注册测试路由
27
+ console.log('[2] 注册测试路由...')
28
+
29
+ // 返回固定字符串
30
+ await plugin._registerRoute('GET', '/test', 'return "1232432"', '返回固定字符串')
31
+ console.log('注册: GET /test -> return "1232432"')
32
+
33
+ // 返回 JSON
34
+ await plugin._registerRoute('GET', '/json', 'return { hello: "world", code: 200 }', '返回 JSON')
35
+ console.log('注册: GET /json -> return { hello: "world", code: 200 }')
36
+
37
+ // 带参数
38
+ await plugin._registerRoute('GET', '/user/:id', 'return { userId: context.params.id }', '路径参数')
39
+ console.log('注册: GET /user/:id -> return { userId: context.params.id }')
40
+
41
+ // POST 路由
42
+ await plugin._registerRoute('POST', '/echo', 'return { received: context.body }', '回显 body')
43
+ console.log('注册: POST /echo -> return { received: context.body }')
44
+
45
+ // 4. 等待服务就绪
46
+ await new Promise(r => setTimeout(r, 500))
47
+
48
+ // 5. 测试各路由
49
+ console.log('\n[3] 测试路由响应...\n')
50
+
51
+ // GET /test
52
+ console.log('GET /test:')
53
+ const r1 = await plugin._sendRequest('GET', '/test')
54
+ console.log(' 状态:', r1.status)
55
+ console.log(' 响应:', JSON.stringify(r1.body))
56
+ console.log()
57
+
58
+ // GET /json
59
+ console.log('GET /json:')
60
+ const r2 = await plugin._sendRequest('GET', '/json')
61
+ console.log(' 状态:', r2.status)
62
+ console.log(' 响应:', JSON.stringify(r2.body))
63
+ console.log()
64
+
65
+ // GET /user/123
66
+ console.log('GET /user/123:')
67
+ const r3 = await plugin._sendRequest('GET', '/user/123')
68
+ console.log(' 状态:', r3.status)
69
+ console.log(' 响应:', JSON.stringify(r3.body))
70
+ console.log()
71
+
72
+ // POST /echo
73
+ console.log('POST /echo (body: { name: "test" }):')
74
+ const r4 = await plugin._sendRequest('POST', '/echo', { name: 'test' })
75
+ console.log(' 状态:', r4.status)
76
+ console.log(' 响应:', JSON.stringify(r4.body))
77
+ console.log()
78
+
79
+ // 6. 列出所有路由
80
+ console.log('[4] 已注册的路由:')
81
+ const routes = plugin._listRoutes()
82
+ routes.routes.forEach(r => {
83
+ console.log(` ${r.method} ${r.path} - ${r.description}`)
84
+ })
85
+ routes.webhooks.forEach(w => {
86
+ console.log(` WEBHOOK ${w.path}`)
87
+ })
88
+ routes.statics.forEach(s => {
89
+ console.log(` STATIC ${s.path} -> ${s.folder}`)
90
+ })
91
+
92
+ // 7. 停止服务
93
+ console.log('\n[5] 停止服务...')
94
+ await plugin._stopServer()
95
+ console.log('测试完成!')
96
+ }
97
+
98
+ test().catch(console.error)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foliko",
3
- "version": "1.0.39",
3
+ "version": "1.0.41",
4
4
  "description": "简约的插件化 Agent 框架",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -25,12 +25,13 @@
25
25
  "@ai-sdk/openai": "^3.0.41",
26
26
  "@ai-sdk/openai-compatible": "^2.0.35",
27
27
  "@anthropic-ai/sdk": "^0.39.0",
28
- "@chnak/weixin-bot": "^1.2.0",
28
+ "@chnak/weixin-bot": "^1.2.1",
29
+ "@hono/node-server": "^1.19.11",
29
30
  "@larksuiteoapi/node-sdk": "^1.59.0",
30
31
  "@modelcontextprotocol/sdk": "^1.27.1",
31
32
  "ai": "^6.0.116",
32
33
  "dotenv": "^17.3.1",
33
- "imap": "^0.8.19",
34
+ "hono": "^4.12.9",
34
35
  "imap-mkl": "^1.0.2",
35
36
  "mailparser": "^3.7.2",
36
37
  "marked": "^11.2.0",
@@ -226,7 +226,7 @@ async function bootstrapDefaults(framework, config = {}) {
226
226
  // 核心插件列表(不能禁用,必须加载)
227
227
  const CORE_PLUGINS = new Set([
228
228
  'install', 'ai', 'storage', 'tools', 'workflow', 'skill-manager',
229
- 'mcp-executor', 'shell-executor', 'python-executor', 'session',
229
+ 'mcp-executor', 'shell-executor', 'python-executor', 'session', 'web',
230
230
  'audit', 'rules', 'scheduler', 'file-system', 'think',
231
231
  'python-plugin-loader', 'telegram', 'weixin', 'subagent-manager'
232
232
  ])
@@ -357,6 +357,13 @@ async function bootstrapDefaults(framework, config = {}) {
357
357
  console.log('[Bootstrap] Python Executor loaded')
358
358
  }
359
359
 
360
+ // 8.5 Web Web服务插件
361
+ if (shouldLoad('web')) {
362
+ const { WebPlugin } = require('./web-plugin')
363
+ await framework.loadPlugin(new WebPlugin())
364
+ console.log('[Bootstrap] Web Plugin loaded')
365
+ }
366
+
360
367
  // 9. Session 会话管理插件
361
368
  if (shouldLoad('session')) {
362
369
  const { SessionPlugin } = require('./session-plugin')
@@ -408,9 +415,7 @@ async function bootstrapDefaults(framework, config = {}) {
408
415
 
409
416
  // 12.6 Telegram 插件(默认禁用,需要在 plugins.json 中设置 enabled: true)
410
417
  if (shouldLoad('telegram')) {
411
- const { Plugin } = require('../src/core/plugin-base')
412
- const createTelegramPlugin = require('./telegram-plugin')
413
- const TelegramPlugin = createTelegramPlugin(Plugin)
418
+ const { TelegramPlugin } = require('./telegram-plugin')
414
419
  const telegramConfig = {
415
420
  botToken: process.env.TELEGRAM_BOT_TOKEN || agentConfig.telegram?.botToken
416
421
  }
@@ -420,9 +425,7 @@ async function bootstrapDefaults(framework, config = {}) {
420
425
  // 12.7 WeChat 插件(默认禁用,需要在 plugins.json 中设置 enabled: true)
421
426
  if (shouldLoad('weixin')) {
422
427
  try {
423
- const { Plugin } = require('../src/core/plugin-base')
424
- const createWeixinPlugin = require('./weixin-plugin')
425
- const WeixinPlugin = createWeixinPlugin(Plugin)
428
+ const { WeixinPlugin } = require('./weixin-plugin')
426
429
  const weixinConfig = {
427
430
  forceLogin: agentConfig.weixin?.forceLogin || false,
428
431
  qrcodeTerminal: agentConfig.weixin?.qrcodeTerminal !== false,
@@ -456,9 +459,7 @@ async function bootstrapDefaults(framework, config = {}) {
456
459
  // 12.9 Feishu 插件(默认禁用,需要在 plugins.json 中设置 enabled: true)
457
460
  if (shouldLoad('feishu')) {
458
461
  try {
459
- const { Plugin } = require('../src/core/plugin-base')
460
- const createFeishuPlugin = require('./feishu-plugin')
461
- const FeishuPlugin = createFeishuPlugin(Plugin)
462
+ const { FeishuPlugin } = require('./feishu-plugin')
462
463
  const feishuConfig = {
463
464
  allowedUsers: agentConfig.feishu?.allowedUsers || []
464
465
  }