@becrafter/prompt-manager 0.1.2 → 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.
Files changed (110) hide show
  1. package/README.md +304 -121
  2. package/app/cli/commands/start.js +28 -4
  3. package/app/cli/support/argv.js +6 -0
  4. package/env.example +32 -0
  5. package/package.json +36 -6
  6. package/packages/server/api/admin.routes.js +409 -1
  7. package/packages/server/api/open.routes.js +7 -2
  8. package/packages/server/api/tool.routes.js +479 -0
  9. package/packages/server/app.js +97 -25
  10. package/packages/server/configs/models/built-in/bigmodel.yaml +6 -0
  11. package/packages/server/configs/models/providers.yaml +50 -0
  12. package/packages/server/configs/templates/built-in/general-iteration.yaml +60 -0
  13. package/packages/server/configs/templates/built-in/general-optimize.yaml +63 -0
  14. package/packages/server/configs/templates/built-in/output-format-optimize.yaml +95 -0
  15. package/packages/server/mcp/heartbeat-patch.js +73 -0
  16. package/packages/server/mcp/mcp.server.js +63 -314
  17. package/packages/server/mcp/prompt.handler.js +26 -0
  18. package/packages/server/mcp/thinking-toolkit.handler.js +380 -0
  19. package/packages/server/package.json +35 -3
  20. package/packages/server/server.js +114 -12
  21. package/packages/server/services/TerminalService.js +498 -0
  22. package/packages/server/services/WebSocketService.js +484 -0
  23. package/packages/server/services/manager.js +38 -7
  24. package/packages/server/services/model.service.js +473 -0
  25. package/packages/server/services/optimization.service.js +457 -0
  26. package/packages/server/services/template.service.js +333 -0
  27. package/packages/server/toolm/tool-description-generator-optimized.service.js +5 -2
  28. package/packages/server/toolm/tool-sync.service.js +47 -3
  29. package/packages/server/utils/config.js +8 -1
  30. package/packages/server/utils/port-checker.js +63 -0
  31. package/packages/server/utils/util.js +27 -0
  32. package/IFLOW.md +0 -175
  33. package/app/desktop/assets/app.1.png +0 -0
  34. package/app/desktop/assets/app.png +0 -0
  35. package/app/desktop/assets/icons/icon.icns +0 -0
  36. package/app/desktop/assets/icons/icon.ico +0 -0
  37. package/app/desktop/assets/icons/icon.png +0 -0
  38. package/app/desktop/assets/icons/tray.png +0 -0
  39. package/app/desktop/assets/templates/about.html +0 -147
  40. package/app/desktop/assets/tray.1.png +0 -0
  41. package/app/desktop/assets/tray.png +0 -0
  42. package/app/desktop/main.js +0 -241
  43. package/app/desktop/package-lock.json +0 -5026
  44. package/app/desktop/package.json +0 -100
  45. package/app/desktop/preload.js +0 -7
  46. package/app/desktop/src/core/error-handler.js +0 -108
  47. package/app/desktop/src/core/event-emitter.js +0 -84
  48. package/app/desktop/src/core/logger.js +0 -108
  49. package/app/desktop/src/core/state-manager.js +0 -125
  50. package/app/desktop/src/services/module-loader.js +0 -214
  51. package/app/desktop/src/services/runtime-manager.js +0 -301
  52. package/app/desktop/src/services/service-manager.js +0 -169
  53. package/app/desktop/src/services/update-manager.js +0 -267
  54. package/app/desktop/src/ui/about-dialog-manager.js +0 -208
  55. package/app/desktop/src/ui/admin-window-manager.js +0 -757
  56. package/app/desktop/src/ui/splash-manager.js +0 -253
  57. package/app/desktop/src/ui/tray-manager.js +0 -186
  58. package/app/desktop/src/utils/icon-manager.js +0 -133
  59. package/app/desktop/src/utils/path-utils.js +0 -58
  60. package/app/desktop/src/utils/resource-paths.js +0 -49
  61. package/app/desktop/src/utils/resource-sync.js +0 -260
  62. package/app/desktop/src/utils/runtime-sync.js +0 -241
  63. package/app/desktop/src/utils/template-renderer.js +0 -284
  64. package/app/desktop/src/utils/version-utils.js +0 -59
  65. package/examples/prompts/developer/code-review.yaml +0 -32
  66. package/examples/prompts/developer/code_refactoring.yaml +0 -31
  67. package/examples/prompts/developer/doc-generator.yaml +0 -36
  68. package/examples/prompts/developer/error-code-fixer.yaml +0 -35
  69. package/examples/prompts/engineer/engineer-professional.yaml +0 -92
  70. package/examples/prompts/engineer/laowang-engineer.yaml +0 -132
  71. package/examples/prompts/engineer/nekomata-engineer.yaml +0 -123
  72. package/examples/prompts/engineer/ojousama-engineer.yaml +0 -124
  73. package/examples/prompts/generator/gen_3d_edu_webpage_html.yaml +0 -117
  74. package/examples/prompts/generator/gen_3d_webpage_html.yaml +0 -75
  75. package/examples/prompts/generator/gen_bento_grid_html.yaml +0 -112
  76. package/examples/prompts/generator/gen_html_web_page.yaml +0 -88
  77. package/examples/prompts/generator/gen_knowledge_card_html.yaml +0 -83
  78. package/examples/prompts/generator/gen_magazine_card_html.yaml +0 -82
  79. package/examples/prompts/generator/gen_mimeng_headline_title.yaml +0 -71
  80. package/examples/prompts/generator/gen_podcast_script.yaml +0 -69
  81. package/examples/prompts/generator/gen_prd_prototype_html.yaml +0 -175
  82. package/examples/prompts/generator/gen_summarize.yaml +0 -157
  83. package/examples/prompts/generator/gen_title.yaml +0 -119
  84. package/examples/prompts/generator/others/api_documentation.yaml +0 -32
  85. package/examples/prompts/generator/others/build_mcp_server.yaml +0 -26
  86. package/examples/prompts/generator/others/project_architecture.yaml +0 -31
  87. package/examples/prompts/generator/others/test_case_generator.yaml +0 -30
  88. package/examples/prompts/generator/others/writing_assistant.yaml +0 -72
  89. package/examples/prompts/recommend/human_3-0_growth_diagnostic_coach_prompt.yaml +0 -105
  90. package/examples/prompts/workflow/sixstep-workflow.yaml +0 -192
  91. package/packages/admin-ui/.babelrc +0 -3
  92. package/packages/admin-ui/admin.html +0 -412
  93. package/packages/admin-ui/css/codemirror-theme_xq-light.css +0 -43
  94. package/packages/admin-ui/css/codemirror.css +0 -344
  95. package/packages/admin-ui/css/main.css +0 -2592
  96. package/packages/admin-ui/css/recommended-prompts.css +0 -610
  97. package/packages/admin-ui/package-lock.json +0 -6973
  98. package/packages/admin-ui/package.json +0 -36
  99. package/packages/admin-ui/src/codemirror.js +0 -53
  100. package/packages/admin-ui/src/index.js +0 -3188
  101. package/packages/admin-ui/webpack.config.js +0 -76
  102. package/packages/server/toolm/test-tools.js +0 -264
  103. package/scripts/build-icons.js +0 -135
  104. package/scripts/build.sh +0 -57
  105. package/scripts/postinstall.js +0 -34
  106. package/scripts/surge/CNAME +0 -1
  107. package/scripts/surge/README.md +0 -47
  108. package/scripts/surge/package-lock.json +0 -34
  109. package/scripts/surge/package.json +0 -20
  110. 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.2",
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 packages/server/server.js",
23
- "help": "node packages/server/server.js --help",
24
- "admin": "ADMIN_ENABLE=true ADMIN_REQUIRE_AUTH=true ADMIN_USERNAME=admin ADMIN_PASSWORD=admin123 node packages/server/server.js -p ./examples/prompts",
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": ">=18.0.0"
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 => prompt.enabled);
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
- const groupActive = prompt.groupEnabled !== false;
16
+ // 检查提示词本身是否启用
17
17
  const promptActive = prompt.enabled === true;
18
- return groupActive && promptActive;
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