foliko 1.1.7 → 1.1.9
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/.agent/agents/poster-expert.md +228 -0
- package/.agent/data/default.json +10 -0
- package/.agent/data/plugins-state.json +1 -1
- package/.agent/mcp_config.json +0 -6
- package/.agent/plugins/test-plugin.py +15 -0
- package/.agent/plugins/test_nested_plugin.py +85 -0
- package/.agent/sessions/cli_default.json +83 -803
- package/.agent/sessions/weixin_o9cq80zgZqKPA2-s59PN43GdDy1w@im.wechat.json +189 -0
- package/.claude/settings.local.json +8 -1
- package/cli/src/ui/chat-ui.js +32 -21
- package/foliko_poster.png +0 -0
- package/output/business_poster_final.png +0 -0
- package/output/emoji_test_v2.png +0 -0
- package/output/foliko-ai-launch-poster.png +0 -0
- package/output/foliko-poster.png +0 -0
- package/output/muji_style_poster.png +0 -0
- package/output/new_product_launch.png +0 -0
- package/output/news_poster_625yi_subsidy.png +0 -0
- package/output/tech_future_2026.png +0 -0
- package/output/tech_future_poster.png +0 -0
- package/package.json +2 -2
- package/plugins/default-plugins.js +60 -7
- package/plugins/extension-executor-plugin.js +32 -22
- package/plugins/feishu-plugin.js +2 -2
- package/plugins/python-plugin-loader.js +461 -40
- package/plugins/python-plugin-loader.js.bak +856 -0
- package/plugins/subagent-plugin.js +0 -121
- package/plugins/telegram-plugin.js +2 -2
- package/plugins/weixin-plugin.js +40 -31
- package/poster.png +0 -0
- package/skills/foliko-dev/SKILL.md +6 -0
- package/skills/python-plugin-dev/SKILL.md +124 -2
- package/src/core/agent-chat.js +220 -281
- package/src/core/agent.js +127 -29
- package/src/executors/mcp-executor.js +282 -26
- package/src/utils/plugin-helpers.js +22 -4
- package/system.md +362 -109
- package/test-scan.js +18 -0
- package/.agent/memory/feedback/mnt7jrlt-d67qs7.md +0 -15
- package/.agent/memory/feedback/mnt88ja3-al4fuy.md +0 -9
- package/.agent/plugins/poster-plugin/README.md +0 -304
- package/.agent/plugins/poster-plugin/emojis/rocket.png +0 -1
- package/.agent/plugins/poster-plugin/fonts/PatuaOne-Regular.ttf +0 -0
- package/.agent/plugins/poster-plugin/fonts/SegoeUI Emoji.ttf +0 -0
- package/.agent/plugins/poster-plugin/fonts//345/276/256/350/275/257/351/233/205/351/273/221.ttf +0 -0
- package/.agent/plugins/poster-plugin/fonts//345/276/256/350/275/257/351/233/205/351/273/221/347/262/227/344/275/223.ttf +0 -0
- package/.agent/plugins/poster-plugin/index.js +0 -13
- package/.agent/plugins/poster-plugin/package.json +0 -29
- package/.agent/plugins/poster-plugin/src/canvas.js +0 -224
- package/.agent/plugins/poster-plugin/src/components/arrow.js +0 -84
- package/.agent/plugins/poster-plugin/src/components/avatar.js +0 -71
- package/.agent/plugins/poster-plugin/src/components/badge.js +0 -85
- package/.agent/plugins/poster-plugin/src/components/barcode.js +0 -120
- package/.agent/plugins/poster-plugin/src/components/bubble.js +0 -153
- package/.agent/plugins/poster-plugin/src/components/button.js +0 -124
- package/.agent/plugins/poster-plugin/src/components/card.js +0 -88
- package/.agent/plugins/poster-plugin/src/components/chart.js +0 -127
- package/.agent/plugins/poster-plugin/src/components/chip.js +0 -88
- package/.agent/plugins/poster-plugin/src/components/columns.js +0 -107
- package/.agent/plugins/poster-plugin/src/components/cta.js +0 -87
- package/.agent/plugins/poster-plugin/src/components/divider.js +0 -55
- package/.agent/plugins/poster-plugin/src/components/feature.js +0 -85
- package/.agent/plugins/poster-plugin/src/components/featureGrid.js +0 -117
- package/.agent/plugins/poster-plugin/src/components/frame.js +0 -230
- package/.agent/plugins/poster-plugin/src/components/grid.js +0 -118
- package/.agent/plugins/poster-plugin/src/components/highlightText.js +0 -144
- package/.agent/plugins/poster-plugin/src/components/icon.js +0 -94
- package/.agent/plugins/poster-plugin/src/components/imageFrame.js +0 -155
- package/.agent/plugins/poster-plugin/src/components/index.js +0 -81
- package/.agent/plugins/poster-plugin/src/components/listItem.js +0 -147
- package/.agent/plugins/poster-plugin/src/components/notification.js +0 -123
- package/.agent/plugins/poster-plugin/src/components/progress.js +0 -79
- package/.agent/plugins/poster-plugin/src/components/progressCircle.js +0 -117
- package/.agent/plugins/poster-plugin/src/components/qrcode.js +0 -74
- package/.agent/plugins/poster-plugin/src/components/quote.js +0 -97
- package/.agent/plugins/poster-plugin/src/components/rating.js +0 -85
- package/.agent/plugins/poster-plugin/src/components/ribbon.js +0 -193
- package/.agent/plugins/poster-plugin/src/components/seal.js +0 -146
- package/.agent/plugins/poster-plugin/src/components/star.js +0 -70
- package/.agent/plugins/poster-plugin/src/components/statCard.js +0 -105
- package/.agent/plugins/poster-plugin/src/components/stepper.js +0 -118
- package/.agent/plugins/poster-plugin/src/components/table.js +0 -167
- package/.agent/plugins/poster-plugin/src/components/tagCloud.js +0 -85
- package/.agent/plugins/poster-plugin/src/components/timeline.js +0 -117
- package/.agent/plugins/poster-plugin/src/components/watermark.js +0 -52
- package/.agent/plugins/poster-plugin/src/composer.js +0 -2146
- package/.agent/plugins/poster-plugin/src/elements/artText.js +0 -60
- package/.agent/plugins/poster-plugin/src/elements/background.js +0 -84
- package/.agent/plugins/poster-plugin/src/elements/circle.js +0 -31
- package/.agent/plugins/poster-plugin/src/elements/image.js +0 -28
- package/.agent/plugins/poster-plugin/src/elements/index.js +0 -28
- package/.agent/plugins/poster-plugin/src/elements/line.js +0 -23
- package/.agent/plugins/poster-plugin/src/elements/polygon.js +0 -63
- package/.agent/plugins/poster-plugin/src/elements/rectangle.js +0 -32
- package/.agent/plugins/poster-plugin/src/elements/richText.js +0 -230
- package/.agent/plugins/poster-plugin/src/elements/svg.js +0 -108
- package/.agent/plugins/poster-plugin/src/elements/text.js +0 -109
- package/.agent/plugins/poster-plugin/src/fonts.js +0 -243
- package/.agent/plugins/poster-plugin/src/index.js +0 -2081
- package/.agent/plugins/poster-plugin/src/presets.js +0 -36
- package/.agent/plugins/poster-plugin/src/templates/business.js +0 -60
- package/.agent/plugins/poster-plugin/src/templates/gradient.js +0 -64
- package/.agent/plugins/poster-plugin/src/templates/index.js +0 -43
- package/.agent/plugins/poster-plugin/src/templates/modern.js +0 -69
- package/.agent/plugins/poster-plugin/src/templates/simple.js +0 -58
- package/.agent/plugins/poster-plugin/src/templates/social.js +0 -62
- package/.agent/plugins/poster-plugin/src/templates/tech.js +0 -84
- package/.agent/plugins/poster-plugin/src/utils/imageLoader.js +0 -84
- package/.agent/plugins/poster-plugin/test-background.svg +0 -1
- package/.agent/plugins/poster-plugin/test-full-poster.svg +0 -2
- package/.agent/plugins/poster-plugin/test-image.png +0 -0
- package/.agent/plugins/poster-plugin/yarn.lock +0 -1007
- package/output/zen_silence.png +0 -0
|
@@ -172,7 +172,14 @@
|
|
|
172
172
|
"Bash(node -c D:/Code/vb-agent/src/utils/index.js && echo \"Syntax OK\")",
|
|
173
173
|
"Bash(cd \"D:/Code/vb-agent\" && node -c src/core/agent-chat.js 2>&1)",
|
|
174
174
|
"WebFetch(domain:ai-sdk.google.com)",
|
|
175
|
-
"Bash(
|
|
175
|
+
"Bash(cd \"D:/Code/foliko/.agent/plugins\" && rm -rf poster-plugin && ln -s \"D:/Code/foliko-plugins/poster-plugin\" poster-plugin)",
|
|
176
|
+
"Bash(cd \"D:/Code/foliko/.agent/plugins\" && rm -rf poster-plugin && cmd //c \"mklink /D poster-plugin D:\\\\\\\\Code\\\\\\\\foliko-plugins\\\\\\\\poster-plugin\" 2>&1 || echo \"Trying ln -s again\")",
|
|
177
|
+
"Bash(cd \"D:/Code/foliko\" && node -e \"\nconst { Framework } = require\\('./src'\\);\nconst PythonPluginLoader = require\\('./plugins/python-plugin-loader'\\);\nconst ext = require\\('./plugins/extension-executor-plugin'\\);\nconst AIPlugin = require\\('./plugins/ai-plugin'\\);\n\nasync function test\\(\\) {\n const fw = new Framework\\(\\);\n await fw.loadPlugin\\(new ext\\(\\)\\);\n await fw.loadPlugin\\(new PythonPluginLoader\\({ agentDir: '.agent' }\\)\\);\n await fw.loadPlugin\\(new AIPlugin\\({ apiKey: 'test' }\\)\\);\n \n console.log\\('Extensions:', fw.pluginManager.get\\('extension-executor'\\)?._extensions?.keys\\(\\)\\);\n console.log\\('Python plugins:', fw.pluginManager.get\\('python-plugin-loader'\\)?._pythonPlugins?.keys\\(\\)\\);\n}\n\ntest\\(\\).catch\\(console.error\\);\n\" 2>&1 | head -20)",
|
|
178
|
+
"Bash(cd \"D:/Code/foliko\" && node -e \"\nconst { Framework } = require\\('./src'\\);\nconst PythonPluginLoader = require\\('./plugins/python-plugin-loader'\\);\nconst ext = require\\('./plugins/extension-executor-plugin'\\);\nconst AIPlugin = require\\('./plugins/ai-plugin'\\);\n\nasync function test\\(\\) {\n const fw = new Framework\\(\\);\n await fw.loadPlugin\\(new ext\\(\\)\\);\n await fw.loadPlugin\\(new PythonPluginLoader\\({ agentDir: '.agent' }\\)\\);\n await fw.loadPlugin\\(new AIPlugin\\({ apiKey: 'test' }\\)\\);\n \n const executor = fw.pluginManager.get\\('extension-executor'\\);\n const extData = executor._extensions.get\\('python'\\);\n console.log\\('Python ext tools:', extData?.tools?.map\\(t => \\({ name: t.name, desc: t.description }\\)\\)\\);\n}\n\ntest\\(\\).catch\\(console.error\\);\n\" 2>&1 | grep -v \"^\\\\[2m\")",
|
|
179
|
+
"Bash(cd \"D:/Code/foliko\" && node test-python-ext.js 2>&1 | grep -v \"^\\\\[2m\")",
|
|
180
|
+
"Bash(cd \"D:/Code/foliko\" && node -e \"require\\('./plugins/extension-executor-plugin'\\); console.log\\('OK'\\)\")",
|
|
181
|
+
"Bash(cd D:/Code/foliko && timeout 8s node cli/bin/foliko.js chat 2>&1 || true)",
|
|
182
|
+
"Bash(cd /d/Code/foliko-plugins/poster-plugin && node -e \"\nconst LayoutManager = require\\('./src/layout-manager'\\);\nconsole.log\\('LayoutManager loaded successfully'\\);\nconsole.log\\('Methods:', Object.getOwnPropertyNames\\(LayoutManager.prototype\\).join\\(', '\\)\\);\n\")"
|
|
176
183
|
]
|
|
177
184
|
}
|
|
178
185
|
}
|
package/cli/src/ui/chat-ui.js
CHANGED
|
@@ -151,29 +151,40 @@ class ChatUI {
|
|
|
151
151
|
|
|
152
152
|
let lineBuffer = '';
|
|
153
153
|
await runWithContext({ sessionId }, async () => {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
154
|
+
await this.agent.continue(message, sessionId, {
|
|
155
|
+
onChunk: (chunk) => {
|
|
156
|
+
if (interrupted) return;
|
|
157
|
+
|
|
158
|
+
if (chunk.type === 'text') {
|
|
159
|
+
fullResponse += chunk.text;
|
|
160
|
+
lineBuffer += chunk.text;
|
|
161
|
+
|
|
162
|
+
while (lineBuffer.includes('\n')) {
|
|
163
|
+
if (interrupted) break;
|
|
164
|
+
|
|
165
|
+
const nlIndex = lineBuffer.indexOf('\n');
|
|
166
|
+
const line = lineBuffer.substring(0, nlIndex);
|
|
167
|
+
lineBuffer = lineBuffer.substring(nlIndex + 1);
|
|
168
|
+
if (line.trim()) {
|
|
169
|
+
console.log(renderLine(line, renderState));
|
|
170
|
+
}
|
|
169
171
|
}
|
|
172
|
+
} else if (chunk.type === 'tool-call') {
|
|
173
|
+
console.log(
|
|
174
|
+
`\n${colored('[工具调用]', YELLOW)} ${chunk.toolName}`,
|
|
175
|
+
JSON.stringify(chunk.input)
|
|
176
|
+
);
|
|
177
|
+
} else if (chunk.type === 'error') {
|
|
178
|
+
console.error(`\n${colored('[错误]', RED)} ${chunk.error}`);
|
|
170
179
|
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
180
|
+
},
|
|
181
|
+
onComplete: async (full, ctx) => {
|
|
182
|
+
const response = cleanResponse(full);
|
|
183
|
+
if (!response) {
|
|
184
|
+
ctx.push('请继续完成任务', { sessionId });
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
});
|
|
177
188
|
});
|
|
178
189
|
|
|
179
190
|
if (lineBuffer.trim() && !interrupted) {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "foliko",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"description": "简约的插件化 Agent 框架",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@ai-sdk/openai-compatible": "^2.0.35",
|
|
55
55
|
"@anthropic-ai/sdk": "^0.39.0",
|
|
56
56
|
"@chnak/weixin-bot": "^1.2.7",
|
|
57
|
-
"@chnak/zod-to-markdown": "1.0.
|
|
57
|
+
"@chnak/zod-to-markdown": "1.0.7",
|
|
58
58
|
"@hono/node-server": "^1.19.11",
|
|
59
59
|
"@larksuiteoapi/node-sdk": "^1.59.0",
|
|
60
60
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
@@ -21,7 +21,8 @@ function loadAgentConfig(agentDir = '.agent') {
|
|
|
21
21
|
mcpServers: {},
|
|
22
22
|
plugins: [],
|
|
23
23
|
skillsDirs: [],
|
|
24
|
-
agentsDir: null // 子Agent配置目录
|
|
24
|
+
agentsDir: null, // 子Agent配置目录
|
|
25
|
+
pluginLinks: {} // 外部插件链接 { "插件名": "外部路径" }
|
|
25
26
|
}
|
|
26
27
|
const cmdDir=path.resolve(process.cwd())
|
|
27
28
|
const resolvedDir = path.resolve(process.cwd(), agentDir)
|
|
@@ -100,6 +101,13 @@ function loadAgentConfig(agentDir = '.agent') {
|
|
|
100
101
|
if (pluginsConfig.email) {
|
|
101
102
|
config.email = pluginsConfig.email
|
|
102
103
|
}
|
|
104
|
+
// 外部插件链接配置 (pluginLinks: { "poster": "/path/to/poster-plugin" })
|
|
105
|
+
if (pluginsConfig.pluginLinks) {
|
|
106
|
+
config.pluginLinks = pluginsConfig.pluginLinks
|
|
107
|
+
for (const [name, targetPath] of Object.entries(pluginsConfig.pluginLinks)) {
|
|
108
|
+
log.info(` Found plugin link: ${name} -> ${targetPath}`)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
103
111
|
} catch (err) {
|
|
104
112
|
log.error(` Failed to load plugins.json:`, err.message)
|
|
105
113
|
}
|
|
@@ -325,7 +333,8 @@ async function bootstrapDefaults(framework, config = {}) {
|
|
|
325
333
|
args: cfg.args || [],
|
|
326
334
|
env: cfg.env || {},
|
|
327
335
|
url: cfg.url,
|
|
328
|
-
headers: cfg.headers
|
|
336
|
+
headers: cfg.headers,
|
|
337
|
+
enabled: cfg.enabled !== false // 默认为 true
|
|
329
338
|
}))
|
|
330
339
|
const { MCPExecutorPlugin } = require('../src/executors/mcp-executor')
|
|
331
340
|
await framework.loadPlugin(new MCPExecutorPlugin({ servers }))
|
|
@@ -375,6 +384,7 @@ async function bootstrapDefaults(framework, config = {}) {
|
|
|
375
384
|
* 支持两种结构:
|
|
376
385
|
* 1. 文件夹结构: .agent/plugins/my-plugin/index.js
|
|
377
386
|
* 2. 单文件结构: .agent/plugins/my-plugin.js
|
|
387
|
+
* 支持符号链接
|
|
378
388
|
* @param {string} pluginsDir - 插件目录
|
|
379
389
|
* @param {string} name - 插件名称
|
|
380
390
|
* @returns {{path: string, type: 'folder'|'file'}|null} 插件路径和类型
|
|
@@ -383,8 +393,28 @@ function resolvePluginPath(pluginsDir, name) {
|
|
|
383
393
|
const folderPath = path.join(pluginsDir, name)
|
|
384
394
|
const filePath = path.join(pluginsDir, `${name}.js`)
|
|
385
395
|
|
|
386
|
-
//
|
|
387
|
-
if (fs.existsSync(folderPath)
|
|
396
|
+
// 检查文件夹是否存在
|
|
397
|
+
if (!fs.existsSync(folderPath)) {
|
|
398
|
+
// 单文件回退
|
|
399
|
+
if (fs.existsSync(filePath)) {
|
|
400
|
+
return { path: filePath, type: 'file' }
|
|
401
|
+
}
|
|
402
|
+
return null
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// 检查是否为目录(支持符号链接)
|
|
406
|
+
let isDir = false
|
|
407
|
+
try {
|
|
408
|
+
isDir = fs.statSync(folderPath).isDirectory()
|
|
409
|
+
} catch (err) {
|
|
410
|
+
// 无法访问,跳过
|
|
411
|
+
if (fs.existsSync(filePath)) {
|
|
412
|
+
return { path: filePath, type: 'file' }
|
|
413
|
+
}
|
|
414
|
+
return null
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (isDir) {
|
|
388
418
|
const pkgPath = path.join(folderPath, 'package.json')
|
|
389
419
|
if (fs.existsSync(pkgPath)) {
|
|
390
420
|
try {
|
|
@@ -403,7 +433,6 @@ function resolvePluginPath(pluginsDir, name) {
|
|
|
403
433
|
if (fs.existsSync(indexPath)) {
|
|
404
434
|
return { path: indexPath, type: 'folder' }
|
|
405
435
|
}
|
|
406
|
-
//log.warn(` No entry point found for plugin folder: ${name}`)
|
|
407
436
|
return null
|
|
408
437
|
}
|
|
409
438
|
|
|
@@ -417,6 +446,7 @@ function resolvePluginPath(pluginsDir, name) {
|
|
|
417
446
|
|
|
418
447
|
/**
|
|
419
448
|
* 扫描插件目录,返回所有插件名称
|
|
449
|
+
* 支持符号链接
|
|
420
450
|
* @param {string} pluginsDir - 插件目录
|
|
421
451
|
* @returns {string[]} 插件名称列表
|
|
422
452
|
*/
|
|
@@ -429,8 +459,31 @@ function scanPluginNames(pluginsDir) {
|
|
|
429
459
|
const entries = fs.readdirSync(pluginsDir, { withFileTypes: true })
|
|
430
460
|
|
|
431
461
|
for (const entry of entries) {
|
|
432
|
-
|
|
433
|
-
|
|
462
|
+
const fullPath = path.join(pluginsDir, entry.name)
|
|
463
|
+
|
|
464
|
+
// 检查是否为符号链接
|
|
465
|
+
let isSymlink = false
|
|
466
|
+
try {
|
|
467
|
+
const lstat = fs.lstatSync(fullPath)
|
|
468
|
+
isSymlink = lstat.isSymbolicLink()
|
|
469
|
+
} catch (err) {
|
|
470
|
+
// 无法获取信息,跳过
|
|
471
|
+
continue
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// 获取实际类型(跟随符号链接)
|
|
475
|
+
let isDir = entry.isDirectory()
|
|
476
|
+
if (isSymlink) {
|
|
477
|
+
try {
|
|
478
|
+
isDir = fs.statSync(fullPath).isDirectory()
|
|
479
|
+
} catch (err) {
|
|
480
|
+
// 符号链接目标不存在,跳过
|
|
481
|
+
continue
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (isDir) {
|
|
486
|
+
// 文件夹插件(包括符号链接指向的目录)
|
|
434
487
|
names.add(entry.name)
|
|
435
488
|
} else if (entry.isFile() && entry.name.endsWith('.js')) {
|
|
436
489
|
// 单文件插件(排除与文件夹同名的)
|
|
@@ -347,27 +347,14 @@ class ExtensionExecutorPlugin extends Plugin {
|
|
|
347
347
|
const extDesc = this._buildExtensionsDescription();
|
|
348
348
|
if (!extDesc) return;
|
|
349
349
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
//
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
// 尝试其他标记
|
|
359
|
-
extEndIdx = existingPrompt.indexOf('\n\n---\n\n', extStartIdx);
|
|
360
|
-
}
|
|
361
|
-
if (extEndIdx === -1) {
|
|
362
|
-
extEndIdx = existingPrompt.length;
|
|
363
|
-
} else {
|
|
364
|
-
extEndIdx += extEndMarker.length;
|
|
365
|
-
}
|
|
366
|
-
const newPrompt = existingPrompt.substring(0, extStartIdx) + extDesc + existingPrompt.substring(extEndIdx);
|
|
367
|
-
agent.setSystemPrompt(newPrompt);
|
|
368
|
-
} else {
|
|
369
|
-
agent.setSystemPrompt(existingPrompt + '\n\n' + extDesc);
|
|
370
|
-
}
|
|
350
|
+
let existingPrompt = agent._originalPrompt || '';
|
|
351
|
+
|
|
352
|
+
// 移除所有已存在的 ## 【Extensions】 部分(防止重复累积)
|
|
353
|
+
const extRegex = /## 【Extensions】[\s\S]*?(?=\n## 【|$)/;
|
|
354
|
+
existingPrompt = existingPrompt.replace(extRegex, '').trim();
|
|
355
|
+
|
|
356
|
+
// 添加新的 Extensions 部分
|
|
357
|
+
agent.setSystemPrompt(existingPrompt + '\n\n' + extDesc);
|
|
371
358
|
}
|
|
372
359
|
|
|
373
360
|
_buildExtensionsDescription() {
|
|
@@ -550,7 +537,7 @@ class ExtensionExecutorPlugin extends Plugin {
|
|
|
550
537
|
}));
|
|
551
538
|
}
|
|
552
539
|
|
|
553
|
-
reload(framework) {
|
|
540
|
+
async reload(framework) {
|
|
554
541
|
this._framework = framework;
|
|
555
542
|
// 重新扫描所有已加载插件的 tools
|
|
556
543
|
this._extensions.clear();
|
|
@@ -562,6 +549,29 @@ class ExtensionExecutorPlugin extends Plugin {
|
|
|
562
549
|
this._mcpExecutor = framework.pluginManager?.get('mcp') || null;
|
|
563
550
|
// 刷新所有 Agent 的扩展提示词
|
|
564
551
|
this._refreshAllAgentsExtPrompt(framework);
|
|
552
|
+
|
|
553
|
+
// 同时重载 MCP 配置
|
|
554
|
+
await this._reloadMCPConfig(framework);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// 重载 MCP 配置
|
|
558
|
+
async _reloadMCPConfig(framework) {
|
|
559
|
+
const fs = require('fs');
|
|
560
|
+
const path = require('path');
|
|
561
|
+
const mcpExecutor = framework.pluginManager?.get('mcp');
|
|
562
|
+
if (!mcpExecutor) return;
|
|
563
|
+
|
|
564
|
+
try {
|
|
565
|
+
const configPath = path.resolve('.agent/mcp_config.json');
|
|
566
|
+
if (fs.existsSync(configPath)) {
|
|
567
|
+
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
568
|
+
const config = JSON.parse(configContent);
|
|
569
|
+
await mcpExecutor.reloadConfig(config);
|
|
570
|
+
logger.info(' MCP config reloaded via extension-executor');
|
|
571
|
+
}
|
|
572
|
+
} catch (err) {
|
|
573
|
+
logger.warn(' Failed to reload MCP config:', err.message);
|
|
574
|
+
}
|
|
565
575
|
}
|
|
566
576
|
|
|
567
577
|
async uninstall(framework) {
|
package/plugins/feishu-plugin.js
CHANGED
|
@@ -288,7 +288,7 @@ class FeishuPlugin extends Plugin {
|
|
|
288
288
|
* 处理统一通知
|
|
289
289
|
*/
|
|
290
290
|
async _handleNotification(data) {
|
|
291
|
-
const { title, message, source, level, sessionId } = data
|
|
291
|
+
const { title, message, source = '系统消息', level, sessionId } = data
|
|
292
292
|
|
|
293
293
|
// 确定 openId
|
|
294
294
|
let openId = null
|
|
@@ -327,7 +327,7 @@ class FeishuPlugin extends Plugin {
|
|
|
327
327
|
error: '❌'
|
|
328
328
|
}
|
|
329
329
|
const emoji = levelEmoji[level] || 'ℹ️'
|
|
330
|
-
const notificationText = `${emoji} [${source}] ${title}\n\n${message}`
|
|
330
|
+
const notificationText = `${emoji} [${source}] ${title || '通知'}\n\n${message || ''}`
|
|
331
331
|
|
|
332
332
|
try {
|
|
333
333
|
await this._sendTextMessage(openId, notificationText)
|