forked from lioensky/VCPToolBox
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsarPromptManager.js
More file actions
153 lines (132 loc) · 5.1 KB
/
Copy pathsarPromptManager.js
File metadata and controls
153 lines (132 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// modules/sarPromptManager.js
const fs = require('fs').promises;
const fsSync = require('fs');
const path = require('path');
const chokidar = require('chokidar');
const SARPROMPT_FILE = path.join(__dirname, '..', 'sarprompt.json');
class SarPromptManager {
constructor() {
this.prompts = []; // Array<{ promptKey: string, models: string[], content: string, matchMode?: string }>
this.debugMode = false;
}
async initialize(debugMode = false) {
this.debugMode = debugMode;
console.log('[SarPromptManager] Initializing...');
if (!fsSync.existsSync(SARPROMPT_FILE)) {
await this.migrateFromEnv();
} else {
await this.loadPrompts();
}
this.watchFile();
}
async migrateFromEnv() {
console.log('[SarPromptManager] sarprompt.json not found. Migrating from .env...');
const migratedPrompts = [];
// Scan for SarPrompt1, SarPrompt2, ...
// We look up to 100 as a reasonable limit for legacy migration
for (let i = 1; i <= 100; i++) {
const promptKey = `SarPrompt${i}`;
const modelKey = `SarModel${i}`;
const promptValue = process.env[promptKey];
const modelsValue = process.env[modelKey];
if (promptValue && modelsValue) {
const models = modelsValue.split(',').map(m => m.trim()).filter(m => m !== '');
migratedPrompts.push({
promptKey,
models,
content: promptValue
});
}
}
if (migratedPrompts.length > 0) {
this.prompts = migratedPrompts;
await this.savePrompts();
console.log(`[SarPromptManager] Migrated ${migratedPrompts.length} groups from .env to sarprompt.json.`);
} else {
console.log('[SarPromptManager] No SarPrompt variables found in .env.');
// Save an empty array to identify that migration has been attempt
this.prompts = [];
await this.savePrompts();
}
}
async loadPrompts() {
try {
const content = await fs.readFile(SARPROMPT_FILE, 'utf8');
this.prompts = JSON.parse(content);
if (this.debugMode) {
console.log(`[SarPromptManager] Loaded ${this.prompts.length} prompt groups.`);
}
} catch (error) {
console.error('[SarPromptManager] Error loading sarprompt.json:', error);
this.prompts = [];
}
}
async savePrompts() {
try {
await fs.writeFile(SARPROMPT_FILE, JSON.stringify(this.prompts, null, 2), 'utf8');
if (this.debugMode) {
console.log('[SarPromptManager] sarprompt.json saved successfully.');
}
} catch (error) {
console.error('[SarPromptManager] Error saving sarprompt.json:', error);
throw error;
}
}
watchFile() {
try {
const watcher = chokidar.watch(SARPROMPT_FILE, {
persistent: true,
ignoreInitial: true,
});
watcher.on('change', () => {
console.log('[SarPromptManager] sarprompt.json changed. Reloading...');
this.loadPrompts();
});
watcher.on('error', (error) => {
console.error('[SarPromptManager] Watcher error:', error);
});
} catch (error) {
console.error('[SarPromptManager] Failed to set up file watcher:', error);
}
}
/**
* 模型匹配辅助函数
* @param {string[]} modelList - 已toLowerCase的模型名数组
* @param {string} normalizedModel - 已toLowerCase的当前模型名
* @param {string} matchMode - 'exact'(默认) | 'includes'(子串包含)
* @returns {boolean}
*/
isModelMatch(modelList, normalizedModel, matchMode = 'exact') {
const filtered = modelList.filter(m => m.length > 0); // 过滤空字符串
if (matchMode === 'includes') {
return filtered.some(m => normalizedModel.includes(m));
}
// 默认精确匹配(含未知matchMode值的fallback)
return filtered.includes(normalizedModel);
}
getSarPrompt(modelName) {
if (!modelName) return null;
const normalizedModel = modelName.toLowerCase();
for (const group of this.prompts) {
if (!group.models || group.models.length === 0) continue;
const modelList = group.models.map(m => m.trim().toLowerCase());
const matchMode = group.matchMode || 'exact';
if (this.isModelMatch(modelList, normalizedModel, matchMode)) {
return group;
}
}
return null;
}
getAllPrompts() {
return this.prompts;
}
async updateAllPrompts(newPrompts) {
if (!Array.isArray(newPrompts)) {
throw new Error('Prompts must be an array');
}
this.prompts = newPrompts;
await this.savePrompts();
}
}
const sarPromptManager = new SarPromptManager();
module.exports = sarPromptManager;