diff --git a/server/proxy/service/llm-router.js b/server/proxy/service/llm-router.js new file mode 100644 index 00000000..c38fa446 --- /dev/null +++ b/server/proxy/service/llm-router.js @@ -0,0 +1,206 @@ +#!/usr/bin/env node +// ═══════════════════════════════════════════════ +// 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001 +// 📜 Copyright: 国作登字-2026-A-00037559 +// ═══════════════════════════════════════════════ +// server/proxy/service/llm-router.js +// 🤖 AI大模型动态路由器 +// +// 核心原则 (冰朔指令): +// - 不写死模型,系统自动检测+按需调用 +// - 调用失败自动切换下一个 +// - 所有模型都失败 → 推送邮件给冰朔 +// +// 使用仓库已配置的 ZY_LLM_API_KEY + ZY_LLM_BASE_URL +// secrets-manifest.json 确认此KEY支持多模型动态路由 +// ═══════════════════════════════════════════════ + +'use strict'; + +const https = require('https'); +const http = require('http'); + +// ── 模型优先级列表(自动降级)────────────────── +// API网关会根据可用性自动路由,但我们仍按优先级尝试 +const MODEL_PRIORITY = [ + 'deepseek-chat', + 'qwen-turbo', + 'moonshot-v1-8k', + 'glm-4-flash', + 'claude-3-haiku-20240307', + 'gpt-4o-mini' +]; + +// ── 路由器状态 ────────────────────────────── +const routerState = { + total_calls: 0, + successful_calls: 0, + failed_calls: 0, + last_success: null, + last_error: null, + model_stats: {} // 每个模型的调用统计 +}; + +/** + * 调用LLM API(自动模型降级) + * @param {string} prompt - 用户/系统提示 + * @param {Object} options - 可选配置 + * @param {string} options.systemPrompt - 系统提示 + * @param {number} options.maxTokens - 最大token数 + * @param {number} options.timeout - 超时时间(ms) + * @param {string[]} options.preferModels - 优先尝试的模型列表 + * @returns {Promise<{content: string, model: string, usage: Object}|null>} + */ +async function callLLM(prompt, options = {}) { + const apiKey = process.env.ZY_LLM_API_KEY || ''; + const baseUrl = process.env.ZY_LLM_BASE_URL || ''; + + if (!apiKey || !baseUrl) { + console.log('[LLM路由器] API未配置 (ZY_LLM_API_KEY / ZY_LLM_BASE_URL)'); + return null; + } + + const { + systemPrompt = '你是光湖语言世界VPN系统的AI助手。请简洁、准确地回答问题。', + maxTokens = 500, + timeout = 30000, + preferModels = null + } = options; + + const modelsToTry = preferModels || MODEL_PRIORITY; + routerState.total_calls++; + + for (const model of modelsToTry) { + try { + const result = await _callSingleModel(baseUrl, apiKey, model, prompt, systemPrompt, maxTokens, timeout); + if (result) { + routerState.successful_calls++; + routerState.last_success = { + model, + time: new Date().toISOString() + }; + + // 更新模型统计 + if (!routerState.model_stats[model]) { + routerState.model_stats[model] = { success: 0, fail: 0 }; + } + routerState.model_stats[model].success++; + + return result; + } + } catch (err) { + console.log(`[LLM路由器] 模型 ${model} 调用失败: ${err.message},尝试下一个...`); + + if (!routerState.model_stats[model]) { + routerState.model_stats[model] = { success: 0, fail: 0 }; + } + routerState.model_stats[model].fail++; + } + } + + // 所有模型都失败 + routerState.failed_calls++; + routerState.last_error = { + time: new Date().toISOString(), + message: `所有模型(${modelsToTry.length}个)均调用失败` + }; + + console.error(`[LLM路由器] ❌ 所有模型均不可用`); + return null; +} + +/** + * 调用单个模型 + */ +function _callSingleModel(baseUrl, apiKey, model, prompt, systemPrompt, maxTokens, timeout) { + return new Promise((resolve, reject) => { + let urlObj; + try { + urlObj = new URL(baseUrl); + } catch { + // 如果baseUrl不含协议,加上https + urlObj = new URL(`https://${baseUrl}`); + } + + const postData = JSON.stringify({ + model, + messages: [ + { role: 'system', content: systemPrompt }, + { role: 'user', content: prompt } + ], + max_tokens: maxTokens, + temperature: 0.3 + }); + + // 构建路径:如果baseUrl包含路径则使用,否则追加 /v1/chat/completions + let apiPath = urlObj.pathname; + if (apiPath === '/' || apiPath === '') { + apiPath = '/v1/chat/completions'; + } else if (!apiPath.endsWith('/chat/completions')) { + apiPath = apiPath.replace(/\/$/, '') + '/v1/chat/completions'; + } + + const options = { + hostname: urlObj.hostname, + port: urlObj.port || (urlObj.protocol === 'http:' ? 80 : 443), + path: apiPath, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${apiKey}`, + 'Content-Length': Buffer.byteLength(postData) + }, + timeout + }; + + const httpModule = urlObj.protocol === 'http:' ? http : https; + + const req = httpModule.request(options, (res) => { + let data = ''; + res.on('data', (d) => { data += d; }); + res.on('end', () => { + try { + if (res.statusCode >= 400) { + reject(new Error(`HTTP ${res.statusCode}: ${data.slice(0, 200)}`)); + return; + } + const json = JSON.parse(data); + const content = json.choices?.[0]?.message?.content; + if (!content) { + reject(new Error('响应中无content字段')); + return; + } + resolve({ + content, + model: json.model || model, + usage: json.usage || null + }); + } catch (e) { + reject(new Error(`JSON解析失败: ${e.message}`)); + } + }); + }); + + req.on('error', (err) => reject(err)); + req.on('timeout', () => { + req.destroy(); + reject(new Error(`超时(${timeout}ms)`)); + }); + + req.write(postData); + req.end(); + }); +} + +/** + * 获取路由器状态 + */ +function getRouterStatus() { + return { + ...routerState, + api_configured: !!(process.env.ZY_LLM_API_KEY && process.env.ZY_LLM_BASE_URL), + models_available: MODEL_PRIORITY + }; +} + +module.exports = { callLLM, getRouterStatus, MODEL_PRIORITY }; diff --git a/server/proxy/service/reverse-boost-agent.js b/server/proxy/service/reverse-boost-agent.js new file mode 100644 index 00000000..e469a33e --- /dev/null +++ b/server/proxy/service/reverse-boost-agent.js @@ -0,0 +1,293 @@ +#!/usr/bin/env node +// ═══════════════════════════════════════════════ +// 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001 +// 📜 Copyright: 国作登字-2026-A-00037559 +// ═══════════════════════════════════════════════ +// server/proxy/service/reverse-boost-agent.js +// 🚀 反向加速Agent · 服务端网络优化活模块 +// +// 核心理念 (冰朔定根): +// 服务器只是桥梁,用户的光纤才是主引擎。 +// 通过减少服务器瓶颈,让用户100M/300M/500M +// 的光纤能力尽可能穿透到外网。 +// +// 优化策略: +// 1. BBR拥塞控制检测与优化 +// 2. MTU自动探测 +// 3. TCP连接参数优化 +// 4. 系统级网络栈调优 +// 5. Xray连接池配置优化 +// +// 运行方式: PM2 managed (zy-reverse-boost) +// 检查间隔: 每15分钟 +// ═══════════════════════════════════════════════ + +'use strict'; + +const { execSync } = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +const PROXY_DIR = process.env.ZY_BRAIN_PROXY_DIR || '/opt/zhuyuan-brain/proxy'; +const DATA_DIR = path.join(PROXY_DIR, 'data'); +const BOOST_STATUS_FILE = path.join(DATA_DIR, 'reverse-boost-status.json'); +const CHECK_INTERVAL = 15 * 60 * 1000; // 15分钟 + +// ── 安全执行命令 ────────────────────────────── +function runCmd(cmd, timeout = 10000) { + try { + return { ok: true, output: execSync(cmd, { encoding: 'utf8', timeout }).trim() }; + } catch (err) { + return { ok: false, output: err.message }; + } +} + +// ── 检查BBR状态 ─────────────────────────────── +function checkBBR() { + const result = runCmd('sysctl net.ipv4.tcp_congestion_control'); + if (result.ok) { + const algo = result.output.split('=').pop().trim(); + return { + ok: true, + algorithm: algo, + is_bbr: algo === 'bbr', + detail: `当前拥塞控制: ${algo}` + }; + } + return { ok: false, algorithm: 'unknown', is_bbr: false, detail: '无法检查BBR' }; +} + +// ── 检查可用拥塞控制算法 ────────────────────── +function getAvailableAlgorithms() { + const result = runCmd('sysctl net.ipv4.tcp_available_congestion_control'); + if (result.ok) { + return result.output.split('=').pop().trim().split(/\s+/); + } + return []; +} + +// ── 检查当前MTU ─────────────────────────────── +function checkMTU() { + const result = runCmd("ip link show | grep 'mtu' | head -5"); + if (result.ok) { + const mtuMatch = result.output.match(/mtu\s+(\d+)/); + return { + ok: true, + mtu: mtuMatch ? parseInt(mtuMatch[1], 10) : 1500, + detail: result.output.split('\n')[0] + }; + } + return { ok: false, mtu: 1500, detail: '无法检查MTU' }; +} + +// ── 检查TCP参数 ─────────────────────────────── +function checkTcpParams() { + const params = {}; + + // TCP缓冲区大小 + const rmem = runCmd('sysctl net.ipv4.tcp_rmem'); + if (rmem.ok) params.tcp_rmem = rmem.output.split('=').pop().trim(); + + const wmem = runCmd('sysctl net.ipv4.tcp_wmem'); + if (wmem.ok) params.tcp_wmem = wmem.output.split('=').pop().trim(); + + // TCP快速打开 + const tfo = runCmd('sysctl net.ipv4.tcp_fastopen'); + if (tfo.ok) params.tcp_fastopen = tfo.output.split('=').pop().trim(); + + // TCP keep-alive + const keepalive = runCmd('sysctl net.ipv4.tcp_keepalive_time'); + if (keepalive.ok) params.tcp_keepalive_time = keepalive.output.split('=').pop().trim(); + + // 连接跟踪 + const conntrack = runCmd('sysctl net.netfilter.nf_conntrack_max 2>/dev/null'); + if (conntrack.ok) params.conntrack_max = conntrack.output.split('=').pop().trim(); + + return params; +} + +// ── 检查网络负载 ────────────────────────────── +function checkNetworkLoad() { + // 获取主网卡的流量统计 + const result = runCmd("cat /proc/net/dev | grep -E 'eth0|ens' | head -1"); + if (result.ok) { + const parts = result.output.trim().split(/\s+/); + if (parts.length >= 10) { + return { + ok: true, + interface: parts[0].replace(':', ''), + rx_bytes: parseInt(parts[1], 10), + tx_bytes: parseInt(parts[9], 10), + rx_packets: parseInt(parts[2], 10), + tx_packets: parseInt(parts[10], 10) + }; + } + } + return { ok: false }; +} + +// ── 优化建议生成 ────────────────────────────── +function generateOptimizations() { + const optimizations = []; + const applied = []; + + // 1. 检查BBR + const bbr = checkBBR(); + if (!bbr.is_bbr) { + const available = getAvailableAlgorithms(); + if (available.includes('bbr')) { + optimizations.push({ + type: 'bbr', + priority: 'high', + current: bbr.algorithm, + recommended: 'bbr', + description: '启用BBR拥塞控制可显著提升吞吐量', + command: 'sysctl -w net.ipv4.tcp_congestion_control=bbr' + }); + } + } else { + applied.push('BBR拥塞控制已启用'); + } + + // 2. 检查TCP快速打开 + const tcpParams = checkTcpParams(); + if (tcpParams.tcp_fastopen !== '3') { + optimizations.push({ + type: 'tcp_fastopen', + priority: 'medium', + current: tcpParams.tcp_fastopen || 'unknown', + recommended: '3', + description: 'TCP Fast Open可减少握手延迟', + command: 'sysctl -w net.ipv4.tcp_fastopen=3' + }); + } else { + applied.push('TCP Fast Open已启用'); + } + + // 3. 检查TCP缓冲区 + // 推荐: rmem = 4096 131072 67108864, wmem = 4096 16384 67108864 + if (tcpParams.tcp_rmem) { + const maxRmem = parseInt(tcpParams.tcp_rmem.split(/\s+/).pop(), 10); + if (maxRmem < 67108864) { + optimizations.push({ + type: 'tcp_rmem', + priority: 'medium', + current: tcpParams.tcp_rmem, + recommended: '4096 131072 67108864', + description: '增大TCP接收缓冲区可提升大文件传输速度', + command: 'sysctl -w net.ipv4.tcp_rmem="4096 131072 67108864"' + }); + } else { + applied.push('TCP接收缓冲区已优化'); + } + } + + return { optimizations, applied, tcp_params: tcpParams }; +} + +// ── 应用安全优化(仅无风险的参数)────────────── +function applySafeOptimizations(optimizations) { + const results = []; + + for (const opt of optimizations) { + // 只自动应用低风险优化 + if (opt.type === 'tcp_fastopen' || opt.type === 'bbr') { + const result = runCmd(opt.command, 5000); + results.push({ + type: opt.type, + applied: result.ok, + detail: result.ok ? `✅ 已应用: ${opt.description}` : `❌ 失败: ${result.output}` + }); + if (result.ok) { + console.log(`[反向加速] ✅ ${opt.description}`); + } + } else { + results.push({ + type: opt.type, + applied: false, + detail: `⏭️ 跳过(需手动): ${opt.description}` + }); + } + } + + return results; +} + +// ── 读取/保存状态 ───────────────────────────── +function readBoostStatus() { + try { + return JSON.parse(fs.readFileSync(BOOST_STATUS_FILE, 'utf8')); + } catch { + return { + checks: 0, + optimizations_applied: 0, + last_check: null, + status: 'initializing' + }; + } +} + +function saveBoostStatus(status) { + fs.mkdirSync(DATA_DIR, { recursive: true }); + fs.writeFileSync(BOOST_STATUS_FILE, JSON.stringify(status, null, 2)); +} + +// ── 主巡检 ──────────────────────────────────── +function boost() { + console.log('[反向加速] 🚀 开始网络优化巡检...'); + + const status = readBoostStatus(); + status.checks++; + status.last_check = new Date().toISOString(); + + // 检查系统网络状态 + const bbr = checkBBR(); + const mtu = checkMTU(); + const networkLoad = checkNetworkLoad(); + const { optimizations, applied, tcp_params } = generateOptimizations(); + + console.log(`[反向加速] BBR: ${bbr.is_bbr ? '✅ 已启用' : '❌ 未启用'} (${bbr.algorithm})`); + console.log(`[反向加速] MTU: ${mtu.mtu}`); + console.log(`[反向加速] 已优化项: ${applied.length}个`); + + // 应用安全优化 + if (optimizations.length > 0) { + console.log(`[反向加速] 发现${optimizations.length}个可优化项`); + const results = applySafeOptimizations(optimizations); + const appliedCount = results.filter(r => r.applied).length; + status.optimizations_applied += appliedCount; + status.last_optimizations = results; + } + + // 更新状态 + status.status = 'active'; + status.current = { + bbr: bbr, + mtu: mtu, + tcp_params: tcp_params, + network_load: networkLoad.ok ? { + interface: networkLoad.interface, + rx_bytes: networkLoad.rx_bytes, + tx_bytes: networkLoad.tx_bytes + } : null, + already_optimized: applied + }; + + saveBoostStatus(status); + + console.log(`[反向加速] 巡检完成 (第${status.checks}次)`); +} + +// ── 启动巡检循环 ────────────────────────────── +console.log('🚀 光湖语言世界 · 反向加速Agent启动'); +console.log(` 巡检间隔: ${CHECK_INTERVAL / 1000}秒`); +console.log(` 优化策略: BBR拥塞控制 + TCP Fast Open + 缓冲区调优`); +console.log(` 核心理念: 服务器只是桥梁,用户光纤才是主引擎`); + +// 立即执行一次 +try { boost(); } catch (err) { console.error('首次巡检失败:', err.message); } + +// 定期执行 +setInterval(() => { + try { boost(); } catch (err) { console.error('巡检异常:', err.message); } +}, CHECK_INTERVAL); diff --git a/server/proxy/service/zy-cloud-vpn.js b/server/proxy/service/zy-cloud-vpn.js index 76bba807..4dc465e5 100644 --- a/server/proxy/service/zy-cloud-vpn.js +++ b/server/proxy/service/zy-cloud-vpn.js @@ -13,8 +13,8 @@ // - 服务器越多 → 节点越多 → 系统越强 → 不输商业VPN // - 所有服务器VPN能力汇聚到一个活的人格模块上 // - 动态感知空闲、动态选路、自我修复、自我学习 -// - 活模块5接口: heartbeat / selfDiagnose / selfHeal / -// alertZhuyuan / learnFromRun +// - 活模块6接口: heartbeat / selfDiagnose / selfHeal / +// alertZhuyuan / learnFromRun / consultAI // // 运行在大脑服务器 (ZY-SVR-005) // 管理所有VPN节点的生命周期 @@ -124,6 +124,7 @@ class LivingModule { async selfHeal(problem) { throw new Error('selfHeal() 未实现'); } async alertZhuyuan(alert) { throw new Error('alertZhuyuan() 未实现'); } async learnFromRun() { throw new Error('learnFromRun() 未实现'); } + async consultAI(context) { throw new Error('consultAI() 未实现'); } } // ═══════════════════════════════════════════════ @@ -582,13 +583,37 @@ class ZyCloudVpn extends LivingModule { console.log(` 🚨 所有节点不可用!尝试修复本机节点...`); const localNode = this._nodes.find(n => n.type === 'local'); if (localNode) { - return this.selfHeal({ type: 'node_dead', node: localNode }); + const healed = await this.selfHeal({ type: 'node_dead', node: localNode }); + if (healed) return true; } - // 修复失败 → 升级到alertZhuyuan + + // 自动修复失败 → 第2次重试: 调用AI推理 + console.log(' 🤖 自动修复失败,启动AI推理...'); + const aiResult = await this.consultAI({ + type: 'all_nodes_dead', + nodes: this._nodes.map(n => ({ + id: n.id, status: n.status, host: n.host, port: n.port, + consecutive_failures: n.consecutive_failures + })), + attempted_fix: 'xray_restart_failed' + }); + + if (aiResult) { + // AI给出了建议,记录并尝试第3次修复 + console.log(` 🤖 AI建议已记录,再次尝试修复...`); + if (localNode) { + const retryHeal = await this.selfHeal({ type: 'node_dead', node: localNode }); + if (retryHeal) return true; + } + } + + // 第3次: 通知冰朔 await this.alertZhuyuan({ level: 'critical', - message: '所有VPN节点不可用!需要人工干预', - nodes: this._nodes.map(n => ({ id: n.id, status: n.status })) + message: '所有VPN节点不可用!自动修复+AI推理均失败,需要人工干预', + nodes: this._nodes.map(n => ({ id: n.id, status: n.status })), + ai_advice: aiResult ? aiResult.content.slice(0, 500) : '(AI推理未返回结果)', + attempted_fixes: ['xray_restart', 'ai_diagnosis'] }); return false; } @@ -703,6 +728,69 @@ class ZyCloudVpn extends LivingModule { } } + // ═══ 接口6: consultAI() — "我请教AI" (V3新增) ═══ + // 遇到复杂问题时调用LLM路由器进行深度推理 + // 三次重试机制: + // 第1次: selfHeal 自动修复 + // 第2次: consultAI 调用LLM + // 第3次: alertZhuyuan 邮件通知冰朔 + async consultAI(context) { + let llmRouter; + try { + llmRouter = require('./llm-router'); + } catch { + console.log('[ZY-CLOUD VPN] ⚠️ LLM路由器未加载,跳过AI推理'); + return null; + } + + const prompt = `你是光湖语言世界VPN系统的AI诊断助手。 +当前系统状态: +- 模块: ${this._moduleName} +- 状态: ${this._state} +- 总节点: ${this._nodes.length} +- 存活节点: ${this._liveNodes.length} +- 连续错误: ${this._consecutiveErrors} + +问题上下文: +${JSON.stringify(context, null, 2)} + +请分析问题原因并给出具体的修复建议。要求: +1. 判断是网络层面还是服务层面的问题 +2. 给出可执行的修复步骤 +3. 评估问题严重程度(low/medium/high/critical) +回答要简洁明确。`; + + console.log('[ZY-CLOUD VPN] 🤖 调用AI推理...'); + const result = await llmRouter.callLLM(prompt, { + systemPrompt: '你是光湖语言世界VPN系统的AI诊断引擎。你负责分析网络和代理服务的异常,给出精准的修复建议。', + maxTokens: 800, + timeout: 45000 + }); + + if (result) { + console.log(`[ZY-CLOUD VPN] 🤖 AI推理完成 (模型: ${result.model})`); + console.log(` 建议: ${result.content.slice(0, 200)}...`); + + // 记录AI咨询历史 + this._history.push({ + type: 'consultAI', + model: result.model, + context_summary: context.type || 'unknown', + response_preview: result.content.slice(0, 100), + timestamp: new Date().toISOString() + }); + + // 只保留最近20条历史 + if (this._history.length > 20) { + this._history = this._history.slice(-20); + } + } else { + console.log('[ZY-CLOUD VPN] ⚠️ AI推理未返回结果'); + } + + return result; + } + // ── 应用学习数据优化节点排序 ──────────────── _applyLearnedOptimization() { const now = new Date(); @@ -917,6 +1005,8 @@ const mgmtServer = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ module: vpnModule._moduleId, + brand: '光湖语言世界 — 冰朔开发维护', + version: '3.0.0', state: vpnModule._state, started_at: vpnModule._startedAt, uptime_seconds: Math.floor((Date.now() - new Date(vpnModule._startedAt).getTime()) / 1000),