* 检测配置变更并返回变更描述列表
(oldCfg: AppConfig, newCfg: AppConfig)
| 237 | * 检测配置变更并返回变更描述列表 |
| 238 | */ |
| 239 | function detectChanges(oldCfg: AppConfig, newCfg: AppConfig): string[] { |
| 240 | const changes: string[] = []; |
| 241 | |
| 242 | if (oldCfg.port !== newCfg.port) changes.push(`port: ${oldCfg.port} → ${newCfg.port}`); |
| 243 | if (oldCfg.timeout !== newCfg.timeout) changes.push(`timeout: ${oldCfg.timeout} → ${newCfg.timeout}`); |
| 244 | if (oldCfg.proxy !== newCfg.proxy) changes.push(`proxy: ${oldCfg.proxy || '(none)'} → ${newCfg.proxy || '(none)'}`); |
| 245 | if (oldCfg.cursorModel !== newCfg.cursorModel) changes.push(`cursor_model: ${oldCfg.cursorModel} → ${newCfg.cursorModel}`); |
| 246 | if (oldCfg.maxAutoContinue !== newCfg.maxAutoContinue) changes.push(`max_auto_continue: ${oldCfg.maxAutoContinue} → ${newCfg.maxAutoContinue}`); |
| 247 | if (oldCfg.maxHistoryMessages !== newCfg.maxHistoryMessages) changes.push(`max_history_messages: ${oldCfg.maxHistoryMessages} → ${newCfg.maxHistoryMessages}`); |
| 248 | if (oldCfg.maxHistoryTokens !== newCfg.maxHistoryTokens) changes.push(`max_history_tokens: ${oldCfg.maxHistoryTokens} → ${newCfg.maxHistoryTokens}`); |
| 249 | |
| 250 | // auth_tokens |
| 251 | const oldTokens = (oldCfg.authTokens || []).join(','); |
| 252 | const newTokens = (newCfg.authTokens || []).join(','); |
| 253 | if (oldTokens !== newTokens) changes.push(`auth_tokens: ${oldCfg.authTokens?.length || 0} → ${newCfg.authTokens?.length || 0} token(s)`); |
| 254 | |
| 255 | // thinking |
| 256 | if (JSON.stringify(oldCfg.thinking) !== JSON.stringify(newCfg.thinking)) changes.push(`thinking: ${JSON.stringify(oldCfg.thinking)} → ${JSON.stringify(newCfg.thinking)}`); |
| 257 | |
| 258 | // vision |
| 259 | if (JSON.stringify(oldCfg.vision) !== JSON.stringify(newCfg.vision)) changes.push('vision: (changed)'); |
| 260 | |
| 261 | // compression |
| 262 | if (JSON.stringify(oldCfg.compression) !== JSON.stringify(newCfg.compression)) changes.push('compression: (changed)'); |
| 263 | |
| 264 | // logging |
| 265 | if (JSON.stringify(oldCfg.logging) !== JSON.stringify(newCfg.logging)) changes.push('logging: (changed)'); |
| 266 | |
| 267 | // tools |
| 268 | if (JSON.stringify(oldCfg.tools) !== JSON.stringify(newCfg.tools)) changes.push('tools: (changed)'); |
| 269 | |
| 270 | // refusalPatterns |
| 271 | // sanitize_response |
| 272 | if (oldCfg.sanitizeEnabled !== newCfg.sanitizeEnabled) changes.push(`sanitize_response: ${oldCfg.sanitizeEnabled} → ${newCfg.sanitizeEnabled}`); |
| 273 | |
| 274 | if (JSON.stringify(oldCfg.refusalPatterns) !== JSON.stringify(newCfg.refusalPatterns)) changes.push(`refusal_patterns: ${oldCfg.refusalPatterns?.length || 0} → ${newCfg.refusalPatterns?.length || 0} rule(s)`); |
| 275 | |
| 276 | // fingerprint |
| 277 | if (oldCfg.fingerprint.userAgent !== newCfg.fingerprint.userAgent) changes.push('fingerprint: (changed)'); |
| 278 | |
| 279 | return changes; |
| 280 | } |
| 281 | |
| 282 | /** |
| 283 | * 获取当前配置(所有模块统一通过此函数获取最新配置) |
no test coverage detected