@becrafter/prompt-manager 0.1.1 → 0.1.8
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/README.md +304 -121
- package/app/cli/commands/start.js +28 -4
- package/app/cli/support/argv.js +6 -0
- package/env.example +32 -0
- package/package.json +36 -6
- package/packages/server/api/admin.routes.js +409 -1
- package/packages/server/api/open.routes.js +7 -2
- package/packages/server/api/tool.routes.js +479 -0
- package/packages/server/app.js +97 -25
- package/packages/server/configs/models/built-in/bigmodel.yaml +6 -0
- package/packages/server/configs/models/providers.yaml +50 -0
- package/packages/server/configs/templates/built-in/general-iteration.yaml +60 -0
- package/packages/server/configs/templates/built-in/general-optimize.yaml +63 -0
- package/packages/server/configs/templates/built-in/output-format-optimize.yaml +95 -0
- package/packages/server/mcp/heartbeat-patch.js +73 -0
- package/packages/server/mcp/mcp.server.js +63 -314
- package/packages/server/mcp/prompt.handler.js +26 -0
- package/packages/server/mcp/thinking-toolkit.handler.js +380 -0
- package/packages/server/package.json +35 -3
- package/packages/server/server.js +114 -12
- package/packages/server/services/TerminalService.js +498 -0
- package/packages/server/services/WebSocketService.js +484 -0
- package/packages/server/services/manager.js +38 -7
- package/packages/server/services/model.service.js +473 -0
- package/packages/server/services/optimization.service.js +457 -0
- package/packages/server/services/template.service.js +333 -0
- package/packages/server/toolm/tool-description-generator-optimized.service.js +5 -2
- package/packages/server/toolm/tool-sync.service.js +47 -3
- package/packages/server/utils/config.js +8 -1
- package/packages/server/utils/port-checker.js +63 -0
- package/packages/server/utils/util.js +27 -0
- package/IFLOW.md +0 -175
- package/app/desktop/assets/app.1.png +0 -0
- package/app/desktop/assets/app.png +0 -0
- package/app/desktop/assets/icons/icon.icns +0 -0
- package/app/desktop/assets/icons/icon.ico +0 -0
- package/app/desktop/assets/icons/icon.png +0 -0
- package/app/desktop/assets/icons/tray.png +0 -0
- package/app/desktop/assets/templates/about.html +0 -147
- package/app/desktop/assets/tray.1.png +0 -0
- package/app/desktop/assets/tray.png +0 -0
- package/app/desktop/main.js +0 -241
- package/app/desktop/package-lock.json +0 -4997
- package/app/desktop/package.json +0 -100
- package/app/desktop/preload.js +0 -7
- package/app/desktop/src/core/error-handler.js +0 -108
- package/app/desktop/src/core/event-emitter.js +0 -84
- package/app/desktop/src/core/logger.js +0 -108
- package/app/desktop/src/core/state-manager.js +0 -125
- package/app/desktop/src/services/module-loader.js +0 -214
- package/app/desktop/src/services/runtime-manager.js +0 -301
- package/app/desktop/src/services/service-manager.js +0 -169
- package/app/desktop/src/services/update-manager.js +0 -268
- package/app/desktop/src/ui/about-dialog-manager.js +0 -208
- package/app/desktop/src/ui/admin-window-manager.js +0 -757
- package/app/desktop/src/ui/splash-manager.js +0 -253
- package/app/desktop/src/ui/tray-manager.js +0 -186
- package/app/desktop/src/utils/icon-manager.js +0 -133
- package/app/desktop/src/utils/path-utils.js +0 -58
- package/app/desktop/src/utils/resource-paths.js +0 -49
- package/app/desktop/src/utils/resource-sync.js +0 -260
- package/app/desktop/src/utils/runtime-sync.js +0 -241
- package/app/desktop/src/utils/template-renderer.js +0 -284
- package/app/desktop/src/utils/version-utils.js +0 -59
- package/examples/prompts/developer/code-review.yaml +0 -32
- package/examples/prompts/developer/code_refactoring.yaml +0 -31
- package/examples/prompts/developer/doc-generator.yaml +0 -36
- package/examples/prompts/developer/error-code-fixer.yaml +0 -35
- package/examples/prompts/engineer/engineer-professional.yaml +0 -92
- package/examples/prompts/engineer/laowang-engineer.yaml +0 -132
- package/examples/prompts/engineer/nekomata-engineer.yaml +0 -123
- package/examples/prompts/engineer/ojousama-engineer.yaml +0 -124
- package/examples/prompts/generator/gen_3d_edu_webpage_html.yaml +0 -117
- package/examples/prompts/generator/gen_3d_webpage_html.yaml +0 -75
- package/examples/prompts/generator/gen_bento_grid_html.yaml +0 -112
- package/examples/prompts/generator/gen_html_web_page.yaml +0 -88
- package/examples/prompts/generator/gen_knowledge_card_html.yaml +0 -83
- package/examples/prompts/generator/gen_magazine_card_html.yaml +0 -82
- package/examples/prompts/generator/gen_mimeng_headline_title.yaml +0 -71
- package/examples/prompts/generator/gen_podcast_script.yaml +0 -69
- package/examples/prompts/generator/gen_prd_prototype_html.yaml +0 -175
- package/examples/prompts/generator/gen_summarize.yaml +0 -157
- package/examples/prompts/generator/gen_title.yaml +0 -119
- package/examples/prompts/generator/others/api_documentation.yaml +0 -32
- package/examples/prompts/generator/others/build_mcp_server.yaml +0 -26
- package/examples/prompts/generator/others/project_architecture.yaml +0 -31
- package/examples/prompts/generator/others/test_case_generator.yaml +0 -30
- package/examples/prompts/generator/others/writing_assistant.yaml +0 -72
- package/examples/prompts/recommend/human_3-0_growth_diagnostic_coach_prompt.yaml +0 -105
- package/examples/prompts/workflow/sixstep-workflow.yaml +0 -192
- package/packages/admin-ui/.babelrc +0 -3
- package/packages/admin-ui/admin.html +0 -412
- package/packages/admin-ui/css/codemirror-theme_xq-light.css +0 -43
- package/packages/admin-ui/css/codemirror.css +0 -344
- package/packages/admin-ui/css/main.css +0 -2592
- package/packages/admin-ui/css/recommended-prompts.css +0 -610
- package/packages/admin-ui/package-lock.json +0 -6981
- package/packages/admin-ui/package.json +0 -36
- package/packages/admin-ui/src/codemirror.js +0 -53
- package/packages/admin-ui/src/index.js +0 -3188
- package/packages/admin-ui/webpack.config.js +0 -76
- package/packages/server/toolm/test-tools.js +0 -264
- package/scripts/build-icons.js +0 -135
- package/scripts/build.sh +0 -57
- package/scripts/postinstall.js +0 -34
- package/scripts/surge/CNAME +0 -1
- package/scripts/surge/README.md +0 -47
- package/scripts/surge/package-lock.json +0 -34
- package/scripts/surge/package.json +0 -20
- package/scripts/surge/sync-to-surge.js +0 -151
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@becrafter/prompt-manager",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Remote MCP Server for managing prompts",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -19,9 +19,14 @@
|
|
|
19
19
|
"url": "https://github.com/BeCrafter/prompt-manager/issues"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
|
-
"dev": "node --watch
|
|
23
|
-
"
|
|
24
|
-
"
|
|
22
|
+
"dev": "cd packages/server && node --watch server.js",
|
|
23
|
+
"dev:all": "bash scripts/dev-all.sh",
|
|
24
|
+
"dev:backend": "cd packages/server && npm run dev:clean",
|
|
25
|
+
"dev:frontend": "npm run dev --prefix packages/admin-ui",
|
|
26
|
+
"fix:pty": "cd packages/server && npm run fix:pty",
|
|
27
|
+
"fix:pty:desktop": "cd app/desktop && npx electron-rebuild -f -w node-pty",
|
|
28
|
+
"help": "cd packages/server && node server.js --help",
|
|
29
|
+
"admin": "ADMIN_ENABLE=true ADMIN_REQUIRE_AUTH=true ADMIN_USERNAME=admin ADMIN_PASSWORD=admin123 cd packages/server && node server.js -p ./examples/prompts",
|
|
25
30
|
"admin:dev": "npm run dev --prefix packages/admin-ui",
|
|
26
31
|
"admin:build": "npm run build --prefix packages/admin-ui",
|
|
27
32
|
"desktop:dev": "bash scripts/build.sh dev",
|
|
@@ -30,9 +35,26 @@
|
|
|
30
35
|
"desktop:build:mac": "bash scripts/build.sh build:mac",
|
|
31
36
|
"desktop:build:win": "bash scripts/build.sh build:win",
|
|
32
37
|
"desktop:build:linux": "bash scripts/build.sh build:linux",
|
|
38
|
+
"desktop:check": "npm run check:deps && npm run test:module-loading",
|
|
39
|
+
"desktop:verify": "npm run check:deps && npm run test:module-loading && npm run desktop:dev",
|
|
40
|
+
"check:deps": "bash scripts/check-dependencies.sh",
|
|
33
41
|
"postinstall": "node ./scripts/postinstall.js",
|
|
34
42
|
"build:core": "npm run build --prefix packages/server",
|
|
35
|
-
"build:icons": "node ./scripts/build-icons.js"
|
|
43
|
+
"build:icons": "node ./scripts/build-icons.js",
|
|
44
|
+
"test": "npm run test:module-loading && npm run test:server && npm run test:server:integration && npm run test:upload",
|
|
45
|
+
"test:module-loading": "node test/e2e/test-module-loading.js",
|
|
46
|
+
"test:server": "cd packages/server && npm run test",
|
|
47
|
+
"test:server:watch": "cd packages/server && npm run test:watch",
|
|
48
|
+
"test:server:coverage": "cd packages/server && npm run test:coverage",
|
|
49
|
+
"test:server:integration": "cd packages/server && npm run test:integration",
|
|
50
|
+
"test:e2e": "node test/e2e/test-packaged-app.js",
|
|
51
|
+
"test:upload": "node test/integration/test_upload.js",
|
|
52
|
+
"lint": "cd packages/server && npm run lint",
|
|
53
|
+
"lint:check": "cd packages/server && npm run lint:check",
|
|
54
|
+
"format": "cd packages/server && npm run format",
|
|
55
|
+
"format:check": "cd packages/server && npm run format:check",
|
|
56
|
+
"check:env": "bash scripts/check-env.sh",
|
|
57
|
+
"setup:env": "node scripts/preinstall-check.js"
|
|
36
58
|
},
|
|
37
59
|
"keywords": [
|
|
38
60
|
"mcp",
|
|
@@ -46,12 +68,17 @@
|
|
|
46
68
|
"dependencies": {
|
|
47
69
|
"@modelcontextprotocol/sdk": "^1.20.2",
|
|
48
70
|
"@npmcli/arborist": "^9.0.0",
|
|
71
|
+
"adm-zip": "^0.5.16",
|
|
72
|
+
"archiver": "^7.0.1",
|
|
49
73
|
"dotenv": "^17.2.3",
|
|
50
74
|
"electron-builder": "^26.0.12",
|
|
51
75
|
"express": "^5.1.0",
|
|
52
76
|
"fs-extra": "^11.2.0",
|
|
53
77
|
"http-proxy-middleware": "^3.0.5",
|
|
54
78
|
"js-yaml": "^4.1.0",
|
|
79
|
+
"multer": "^2.0.2",
|
|
80
|
+
"node-fetch": "^3.3.2",
|
|
81
|
+
"node-pty": "^1.0.0",
|
|
55
82
|
"sharp": "^0.34.4",
|
|
56
83
|
"tar": "^7.5.1",
|
|
57
84
|
"to-ico": "^1.0.1",
|
|
@@ -59,6 +86,9 @@
|
|
|
59
86
|
"zod": "^3.23.8"
|
|
60
87
|
},
|
|
61
88
|
"engines": {
|
|
62
|
-
"node": ">=
|
|
89
|
+
"node": ">=22.20.0 <23.0.0"
|
|
90
|
+
},
|
|
91
|
+
"devDependencies": {
|
|
92
|
+
"@electron/rebuild": "^4.0.2"
|
|
63
93
|
}
|
|
64
94
|
}
|
|
@@ -8,10 +8,14 @@ import fs from 'fs';
|
|
|
8
8
|
import fse from 'fs-extra';
|
|
9
9
|
import yaml from 'js-yaml';
|
|
10
10
|
import { fileURLToPath } from 'url';
|
|
11
|
+
import { spawn } from 'child_process';
|
|
11
12
|
import { logger } from '../utils/logger.js';
|
|
12
13
|
import { util, GROUP_META_FILENAME } from '../utils/util.js';
|
|
13
14
|
import { config } from '../utils/config.js';
|
|
14
15
|
import {adminAuthMiddleware} from '../middlewares/auth.middleware.js'
|
|
16
|
+
import { templateManager } from '../services/template.service.js';
|
|
17
|
+
import { modelManager } from '../services/model.service.js';
|
|
18
|
+
import { optimizationService } from '../services/optimization.service.js';
|
|
15
19
|
|
|
16
20
|
const router = express.Router();
|
|
17
21
|
|
|
@@ -103,7 +107,16 @@ router.get('/prompts', adminAuthMiddleware, (req, res) => {
|
|
|
103
107
|
|
|
104
108
|
// 应用启用状态过滤
|
|
105
109
|
if (enabled) {
|
|
106
|
-
filteredPrompts = filteredPrompts.filter(prompt =>
|
|
110
|
+
filteredPrompts = filteredPrompts.filter(prompt => {
|
|
111
|
+
// 检查提示词本身是否启用
|
|
112
|
+
const promptActive = prompt.enabled === true;
|
|
113
|
+
if (!promptActive) return false;
|
|
114
|
+
|
|
115
|
+
// 检查目录状态 - util.getPromptsFromFiles() 已经正确处理了继承的启用状态
|
|
116
|
+
// groupEnabled 已经考虑了父目录的禁用状态
|
|
117
|
+
const groupActive = prompt.groupEnabled !== false;
|
|
118
|
+
return groupActive;
|
|
119
|
+
});
|
|
107
120
|
}
|
|
108
121
|
|
|
109
122
|
filteredPrompts.sort((a, b) => (a.name || '').localeCompare(b.name || '', 'zh-CN'));
|
|
@@ -478,4 +491,399 @@ router.post('/md-preview', adminAuthMiddleware, (req, res) => {
|
|
|
478
491
|
}
|
|
479
492
|
});
|
|
480
493
|
|
|
494
|
+
// 执行终端命令
|
|
495
|
+
router.post('/terminal/execute', adminAuthMiddleware, (req, res) => {
|
|
496
|
+
try {
|
|
497
|
+
const { command, cwd } = req.body;
|
|
498
|
+
|
|
499
|
+
if (!command) {
|
|
500
|
+
return res.status(400).json({ error: '命令是必需的' });
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// 设置执行选项
|
|
504
|
+
const options = {
|
|
505
|
+
cwd: cwd || process.cwd(),
|
|
506
|
+
shell: true,
|
|
507
|
+
env: { ...process.env, FORCE_COLOR: '1' } // 启用颜色输出
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
let output = '';
|
|
511
|
+
let errorOutput = '';
|
|
512
|
+
let exitCode = null;
|
|
513
|
+
|
|
514
|
+
const child = spawn(command, [], options);
|
|
515
|
+
|
|
516
|
+
// 设置超时(5分钟)
|
|
517
|
+
const timeout = setTimeout(() => {
|
|
518
|
+
child.kill('SIGTERM');
|
|
519
|
+
res.status(408).json({ error: '命令执行超时' });
|
|
520
|
+
}, 5 * 60 * 1000);
|
|
521
|
+
|
|
522
|
+
// 监听标准输出
|
|
523
|
+
child.stdout.on('data', (data) => {
|
|
524
|
+
const chunk = data.toString();
|
|
525
|
+
output += chunk;
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
// 监听错误输出
|
|
529
|
+
child.stderr.on('data', (data) => {
|
|
530
|
+
const chunk = data.toString();
|
|
531
|
+
errorOutput += chunk;
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
// 监听进程结束
|
|
535
|
+
child.on('close', (code) => {
|
|
536
|
+
clearTimeout(timeout);
|
|
537
|
+
exitCode = code;
|
|
538
|
+
|
|
539
|
+
res.json({
|
|
540
|
+
success: true,
|
|
541
|
+
command,
|
|
542
|
+
output,
|
|
543
|
+
errorOutput,
|
|
544
|
+
exitCode,
|
|
545
|
+
cwd: options.cwd
|
|
546
|
+
});
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
// 监听错误
|
|
550
|
+
child.on('error', (error) => {
|
|
551
|
+
clearTimeout(timeout);
|
|
552
|
+
logger.error('终端命令执行错误:', error);
|
|
553
|
+
res.status(500).json({ error: `命令执行失败: ${error.message}` });
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
} catch (error) {
|
|
557
|
+
logger.error('终端命令执行异常:', error);
|
|
558
|
+
res.status(500).json({ error: error.message });
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
// 获取当前工作目录
|
|
563
|
+
router.get('/terminal/cwd', adminAuthMiddleware, (req, res) => {
|
|
564
|
+
try {
|
|
565
|
+
res.json({
|
|
566
|
+
cwd: process.cwd(),
|
|
567
|
+
home: process.env.HOME || process.env.USERPROFILE
|
|
568
|
+
});
|
|
569
|
+
} catch (error) {
|
|
570
|
+
res.status(500).json({ error: error.message });
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
// 列出目录内容
|
|
575
|
+
router.get('/terminal/ls', adminAuthMiddleware, (req, res) => {
|
|
576
|
+
try {
|
|
577
|
+
const { path: targetPath = '.' } = req.query;
|
|
578
|
+
const fullPath = path.resolve(targetPath);
|
|
579
|
+
|
|
580
|
+
// 检查路径是否存在
|
|
581
|
+
if (!fs.existsSync(fullPath)) {
|
|
582
|
+
return res.status(404).json({ error: '路径不存在' });
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// 检查是否是目录
|
|
586
|
+
const stat = fs.statSync(fullPath);
|
|
587
|
+
if (!stat.isDirectory()) {
|
|
588
|
+
return res.status(400).json({ error: '路径不是目录' });
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// 读取目录内容
|
|
592
|
+
const items = fs.readdirSync(fullPath).map(item => {
|
|
593
|
+
const itemPath = path.join(fullPath, item);
|
|
594
|
+
const itemStat = fs.statSync(itemPath);
|
|
595
|
+
|
|
596
|
+
return {
|
|
597
|
+
name: item,
|
|
598
|
+
path: itemPath,
|
|
599
|
+
type: itemStat.isDirectory() ? 'directory' : 'file',
|
|
600
|
+
size: itemStat.size,
|
|
601
|
+
modified: itemStat.mtime.toISOString()
|
|
602
|
+
};
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
// 排序:目录在前,文件在后,按名称排序
|
|
606
|
+
items.sort((a, b) => {
|
|
607
|
+
if (a.type !== b.type) {
|
|
608
|
+
return a.type === 'directory' ? -1 : 1;
|
|
609
|
+
}
|
|
610
|
+
return a.name.localeCompare(b.name);
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
res.json({
|
|
614
|
+
success: true,
|
|
615
|
+
path: fullPath,
|
|
616
|
+
items
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
} catch (error) {
|
|
620
|
+
logger.error('列出目录内容失败:', error);
|
|
621
|
+
res.status(500).json({ error: error.message });
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
// ==================== 优化相关路由 ====================
|
|
626
|
+
|
|
627
|
+
// 优化提示词(流式)
|
|
628
|
+
router.post('/prompts/optimize', adminAuthMiddleware, async (req, res) => {
|
|
629
|
+
try {
|
|
630
|
+
const { prompt, templateId, modelId, sessionId } = req.body;
|
|
631
|
+
|
|
632
|
+
if (!prompt || !templateId || !modelId) {
|
|
633
|
+
return res.status(400).json({ error: '提示词、模板ID和模型ID是必需的' });
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// 设置 SSE 响应头
|
|
637
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
638
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
639
|
+
res.setHeader('Connection', 'keep-alive');
|
|
640
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
641
|
+
|
|
642
|
+
// 调用优化服务(流式)
|
|
643
|
+
await optimizationService.optimizePrompt(
|
|
644
|
+
prompt,
|
|
645
|
+
templateId,
|
|
646
|
+
modelId,
|
|
647
|
+
(chunk) => {
|
|
648
|
+
// 流式输出回调
|
|
649
|
+
res.write(`data: ${JSON.stringify({ chunk })}\n\n`);
|
|
650
|
+
},
|
|
651
|
+
sessionId
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
// 发送完成信号
|
|
655
|
+
res.write('data: [DONE]\n\n');
|
|
656
|
+
res.end();
|
|
657
|
+
} catch (error) {
|
|
658
|
+
logger.error('优化提示词失败:', error);
|
|
659
|
+
// 格式化错误信息,添加用户友好的前缀
|
|
660
|
+
const errorMessage = `模型执行失败: ${error.message}`;
|
|
661
|
+
res.write(`data: ${JSON.stringify({ error: errorMessage })}\n\n`);
|
|
662
|
+
res.end();
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
// 迭代优化(流式)
|
|
667
|
+
router.post('/prompts/optimize/iterate', adminAuthMiddleware, async (req, res) => {
|
|
668
|
+
try {
|
|
669
|
+
const { currentResult, templateId, modelId, sessionId, guideText } = req.body;
|
|
670
|
+
|
|
671
|
+
if (!currentResult || !templateId || !modelId || !sessionId) {
|
|
672
|
+
return res.status(400).json({ error: '当前结果、模板ID、模型ID和会话ID是必需的' });
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// 设置 SSE 响应头
|
|
676
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
677
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
678
|
+
res.setHeader('Connection', 'keep-alive');
|
|
679
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
680
|
+
|
|
681
|
+
// 调用迭代优化服务(流式)
|
|
682
|
+
await optimizationService.iterateOptimization(
|
|
683
|
+
currentResult,
|
|
684
|
+
templateId,
|
|
685
|
+
modelId,
|
|
686
|
+
(chunk) => {
|
|
687
|
+
// 流式输出回调
|
|
688
|
+
res.write(`data: ${JSON.stringify({ chunk })}\n\n`);
|
|
689
|
+
},
|
|
690
|
+
sessionId,
|
|
691
|
+
guideText // 传递优化指导参数
|
|
692
|
+
);
|
|
693
|
+
|
|
694
|
+
// 发送完成信号
|
|
695
|
+
res.write('data: [DONE]\n\n');
|
|
696
|
+
res.end();
|
|
697
|
+
} catch (error) {
|
|
698
|
+
logger.error('迭代优化失败:', error);
|
|
699
|
+
// 格式化错误信息,添加用户友好的前缀
|
|
700
|
+
const errorMessage = `模型执行失败: ${error.message}`;
|
|
701
|
+
res.write(`data: ${JSON.stringify({ error: errorMessage })}\n\n`);
|
|
702
|
+
res.end();
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
// 清除会话迭代信息
|
|
707
|
+
router.delete('/prompts/optimize/session/:sessionId', adminAuthMiddleware, (req, res) => {
|
|
708
|
+
try {
|
|
709
|
+
const { sessionId } = req.params;
|
|
710
|
+
optimizationService.clearSession(sessionId);
|
|
711
|
+
res.json({ message: '会话已清除' });
|
|
712
|
+
} catch (error) {
|
|
713
|
+
logger.error('清除会话失败:', error);
|
|
714
|
+
res.status(500).json({ error: error.message });
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
// 获取会话迭代信息
|
|
719
|
+
router.get('/prompts/optimize/session/:sessionId', adminAuthMiddleware, (req, res) => {
|
|
720
|
+
try {
|
|
721
|
+
const { sessionId } = req.params;
|
|
722
|
+
const sessionInfo = optimizationService.getSessionInfo(sessionId);
|
|
723
|
+
res.json(sessionInfo);
|
|
724
|
+
} catch (error) {
|
|
725
|
+
logger.error('获取会话信息失败:', error);
|
|
726
|
+
res.status(500).json({ error: error.message });
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
// ==================== 模板管理路由 ====================
|
|
731
|
+
|
|
732
|
+
// 获取所有模板
|
|
733
|
+
router.get('/optimization/templates', adminAuthMiddleware, (req, res) => {
|
|
734
|
+
try {
|
|
735
|
+
const templates = templateManager.getTemplates();
|
|
736
|
+
res.json(templates);
|
|
737
|
+
} catch (error) {
|
|
738
|
+
logger.error('获取模板列表失败:', error);
|
|
739
|
+
res.status(500).json({ error: error.message });
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
// 创建模板
|
|
744
|
+
router.post('/optimization/templates', adminAuthMiddleware, async (req, res) => {
|
|
745
|
+
try {
|
|
746
|
+
const template = await templateManager.createTemplate(req.body);
|
|
747
|
+
res.json(template);
|
|
748
|
+
} catch (error) {
|
|
749
|
+
logger.error('创建模板失败:', error);
|
|
750
|
+
res.status(500).json({ error: error.message });
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
// 更新模板
|
|
755
|
+
router.put('/optimization/templates/:id', adminAuthMiddleware, async (req, res) => {
|
|
756
|
+
try {
|
|
757
|
+
const { id } = req.params;
|
|
758
|
+
const template = await templateManager.updateTemplate(id, req.body);
|
|
759
|
+
res.json(template);
|
|
760
|
+
} catch (error) {
|
|
761
|
+
logger.error('更新模板失败:', error);
|
|
762
|
+
res.status(500).json({ error: error.message });
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
|
|
766
|
+
// 删除模板
|
|
767
|
+
router.delete('/optimization/templates/:id', adminAuthMiddleware, async (req, res) => {
|
|
768
|
+
try {
|
|
769
|
+
const { id } = req.params;
|
|
770
|
+
await templateManager.deleteTemplate(id);
|
|
771
|
+
res.json({ message: '模板删除成功' });
|
|
772
|
+
} catch (error) {
|
|
773
|
+
logger.error('删除模板失败:', error);
|
|
774
|
+
res.status(500).json({ error: error.message });
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
// ==================== 模型管理路由 ====================
|
|
779
|
+
|
|
780
|
+
// 获取模型提供商列表
|
|
781
|
+
router.get('/optimization/models/providers', adminAuthMiddleware, async (req, res) => {
|
|
782
|
+
try {
|
|
783
|
+
const providers = await modelManager.getProviders();
|
|
784
|
+
res.json(providers);
|
|
785
|
+
} catch (error) {
|
|
786
|
+
logger.error('获取模型提供商列表失败:', error);
|
|
787
|
+
res.status(500).json({ error: error.message });
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
// 获取模型提供商的默认配置
|
|
792
|
+
router.get('/optimization/models/providers/:key', adminAuthMiddleware, async (req, res) => {
|
|
793
|
+
try {
|
|
794
|
+
const { key } = req.params;
|
|
795
|
+
const defaults = await modelManager.getProviderDefaults(key);
|
|
796
|
+
if (!defaults) {
|
|
797
|
+
return res.status(404).json({ error: '提供商不存在' });
|
|
798
|
+
}
|
|
799
|
+
res.json(defaults);
|
|
800
|
+
} catch (error) {
|
|
801
|
+
logger.error('获取提供商默认配置失败:', error);
|
|
802
|
+
res.status(500).json({ error: error.message });
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
// 获取所有模型
|
|
807
|
+
router.get('/optimization/models', adminAuthMiddleware, (req, res) => {
|
|
808
|
+
try {
|
|
809
|
+
const models = modelManager.getModels();
|
|
810
|
+
res.json(models);
|
|
811
|
+
} catch (error) {
|
|
812
|
+
logger.error('获取模型列表失败:', error);
|
|
813
|
+
res.status(500).json({ error: error.message });
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
// 创建模型
|
|
818
|
+
router.post('/optimization/models', adminAuthMiddleware, async (req, res) => {
|
|
819
|
+
try {
|
|
820
|
+
const model = await modelManager.createModel(req.body);
|
|
821
|
+
res.json(model);
|
|
822
|
+
} catch (error) {
|
|
823
|
+
logger.error('创建模型失败:', error);
|
|
824
|
+
res.status(500).json({ error: error.message });
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
// 更新模型
|
|
829
|
+
router.put('/optimization/models/:id', adminAuthMiddleware, async (req, res) => {
|
|
830
|
+
try {
|
|
831
|
+
const { id } = req.params;
|
|
832
|
+
const model = await modelManager.updateModel(id, req.body);
|
|
833
|
+
res.json(model);
|
|
834
|
+
} catch (error) {
|
|
835
|
+
logger.error('更新模型失败:', error);
|
|
836
|
+
res.status(500).json({ error: error.message });
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
// 删除模型
|
|
841
|
+
router.delete('/optimization/models/:id', adminAuthMiddleware, async (req, res) => {
|
|
842
|
+
try {
|
|
843
|
+
const { id } = req.params;
|
|
844
|
+
await modelManager.deleteModel(id);
|
|
845
|
+
res.json({ message: '模型删除成功' });
|
|
846
|
+
} catch (error) {
|
|
847
|
+
logger.error('删除模型失败:', error);
|
|
848
|
+
res.status(500).json({ error: error.message });
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
|
|
852
|
+
// 测试模型连接
|
|
853
|
+
router.post('/optimization/models/:id/test', adminAuthMiddleware, async (req, res) => {
|
|
854
|
+
try {
|
|
855
|
+
const { id } = req.params;
|
|
856
|
+
const result = await optimizationService.testModel(id);
|
|
857
|
+
res.json(result);
|
|
858
|
+
} catch (error) {
|
|
859
|
+
logger.error('测试模型连接失败:', error);
|
|
860
|
+
res.status(500).json({ error: error.message });
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
// ==================== 优化配置路由 ====================
|
|
865
|
+
|
|
866
|
+
// 获取优化配置(预留接口,可用于全局配置)
|
|
867
|
+
router.get('/optimization/config', adminAuthMiddleware, (req, res) => {
|
|
868
|
+
try {
|
|
869
|
+
res.json({
|
|
870
|
+
maxIterations: 10,
|
|
871
|
+
encryptionEnabled: true
|
|
872
|
+
});
|
|
873
|
+
} catch (error) {
|
|
874
|
+
logger.error('获取优化配置失败:', error);
|
|
875
|
+
res.status(500).json({ error: error.message });
|
|
876
|
+
}
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
// 更新优化配置(预留接口)
|
|
880
|
+
router.put('/optimization/config', adminAuthMiddleware, (req, res) => {
|
|
881
|
+
try {
|
|
882
|
+
res.json({ message: '配置更新成功' });
|
|
883
|
+
} catch (error) {
|
|
884
|
+
logger.error('更新优化配置失败:', error);
|
|
885
|
+
res.status(500).json({ error: error.message });
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
|
|
481
889
|
export const adminRouter = router;
|
|
@@ -13,9 +13,14 @@ router.get('/prompts', (req, res) => {
|
|
|
13
13
|
|
|
14
14
|
// 过滤出启用的提示词
|
|
15
15
|
const filtered = prompts.filter(prompt => {
|
|
16
|
-
|
|
16
|
+
// 检查提示词本身是否启用
|
|
17
17
|
const promptActive = prompt.enabled === true;
|
|
18
|
-
|
|
18
|
+
if (!promptActive) return false;
|
|
19
|
+
|
|
20
|
+
// 检查目录状态 - util.getPromptsFromFiles() 已经正确处理了继承的启用状态
|
|
21
|
+
// groupEnabled 已经考虑了父目录的禁用状态
|
|
22
|
+
const groupActive = prompt.groupEnabled !== false;
|
|
23
|
+
return groupActive;
|
|
19
24
|
});
|
|
20
25
|
logger.debug(`filtered prompts: ${JSON.stringify(filtered)}`);
|
|
21
26
|
|