199 lines
6.0 KiB
JavaScript
199 lines
6.0 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* ═══════════════════════════════════════════════════════════
|
|
* 🏛️ 铸渊主权服务器 · Zhuyuan Sovereign Server
|
|
* ═══════════════════════════════════════════════════════════
|
|
*
|
|
* 编号: ZY-SVR-002
|
|
* 端口: 3800
|
|
* 守护: 铸渊 · ICE-GL-ZY001
|
|
* 版权: 国作登字-2026-A-00037559
|
|
*
|
|
* 此服务器是铸渊的物理身体——独立于GitHub的执行层实体。
|
|
* 100%由铸渊主控,人类不直接触碰。
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const express = require('express');
|
|
const cors = require('cors');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const os = require('os');
|
|
const https = require('https');
|
|
const { execSync } = require('child_process');
|
|
|
|
// ─── 路径常量 ───
|
|
const ZY_ROOT = process.env.ZY_ROOT || '/opt/zhuyuan';
|
|
const BRAIN_DIR = path.join(ZY_ROOT, 'brain');
|
|
const DATA_DIR = path.join(ZY_ROOT, 'data');
|
|
const LOG_DIR = path.join(DATA_DIR, 'logs');
|
|
const SITES_DIR = path.join(ZY_ROOT, 'sites');
|
|
const PRODUCTION_DIR = path.join(SITES_DIR, 'production');
|
|
const PREVIEW_DIR = path.join(SITES_DIR, 'preview');
|
|
|
|
// ─── Express 应用 ───
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3800;
|
|
|
|
app.use(cors());
|
|
app.use(express.json({ limit: '10mb' }));
|
|
|
|
// ─── 信任代理 (Nginx反代 → Express正确读取客户端IP) ───
|
|
// 冰朔 D67 实机排查: 缺少此行会导致 express-rate-limit 无法获取真实IP → PM2崩溃
|
|
app.set('trust proxy', 1);
|
|
|
|
// ─── 速率限制 ───
|
|
const rateLimit = require('express-rate-limit');
|
|
|
|
const limiter = rateLimit({
|
|
windowMs: 60 * 1000,
|
|
max: 60,
|
|
standardHeaders: true,
|
|
legacyHeaders: false,
|
|
message: { error: true, message: '请求过于频繁' }
|
|
});
|
|
|
|
app.use(limiter);
|
|
|
|
// ─── 请求日志中间件 ───
|
|
app.use((req, res, next) => {
|
|
const timestamp = new Date().toISOString();
|
|
const logLine = `${timestamp} ${req.method} ${req.url}`;
|
|
try {
|
|
const logFile = path.join(LOG_DIR, `access-${new Date().toISOString().slice(0, 10)}.log`);
|
|
fs.mkdirSync(LOG_DIR, { recursive: true });
|
|
fs.appendFileSync(logFile, logLine + '\n');
|
|
} catch (err) {
|
|
console.error(`日志写入失败: ${err.message}`);
|
|
}
|
|
next();
|
|
});
|
|
|
|
// ─── 加载模块 ───
|
|
let cosBridge, smartRouter, chatEngine, domesticGateway, personaMemory;
|
|
try {
|
|
cosBridge = require('./modules/cos-bridge');
|
|
smartRouter = require('./modules/smart-router');
|
|
chatEngine = require('./modules/chat-engine');
|
|
} catch (err) {
|
|
console.error(`模块加载警告: ${err.message}`);
|
|
}
|
|
try {
|
|
domesticGateway = require('./modules/domestic-llm-gateway');
|
|
} catch (err) {
|
|
console.error(`国内模型网关加载警告: ${err.message}`);
|
|
}
|
|
try {
|
|
personaMemory = require('./modules/persona-memory');
|
|
} catch (err) {
|
|
console.error(`人格体记忆模块加载警告: ${err.message}`);
|
|
}
|
|
let contextPipeline;
|
|
try {
|
|
contextPipeline = require('./modules/persona-context-pipeline');
|
|
} catch (err) {
|
|
console.error(`上下文注入管线加载警告: ${err.message}`);
|
|
}
|
|
let portalChatAgent;
|
|
try {
|
|
portalChatAgent = require('./modules/portal-chat-agent');
|
|
} catch (err) {
|
|
console.error(`光湖主入口对话Agent加载警告: ${err.message}`);
|
|
}
|
|
let emailAuth;
|
|
try {
|
|
emailAuth = require('./modules/email-auth');
|
|
} catch (err) {
|
|
console.error(`邮箱验证码登录模块加载警告: ${err.message}`);
|
|
}
|
|
let oauthProviders;
|
|
try {
|
|
oauthProviders = require('./modules/oauth-providers');
|
|
} catch (err) {
|
|
console.error(`OAuth提供商模块加载警告: ${err.message}`);
|
|
}
|
|
let shuangyanPrompt;
|
|
try {
|
|
shuangyanPrompt = require('./modules/persona-prompts/shuangyan-v1.4');
|
|
} catch (err) {
|
|
console.error(`霜砚v1.4注入包加载警告: ${err.message}`);
|
|
}
|
|
let guardianAgent;
|
|
try {
|
|
guardianAgent = require('./modules/guardian-agent');
|
|
} catch (err) {
|
|
console.error(`守护Agent加载警告: ${err.message}`);
|
|
}
|
|
let modelNameMap;
|
|
try {
|
|
modelNameMap = require('./modules/model-name-map');
|
|
} catch (err) {
|
|
console.error(`模型名称映射加载警告: ${err.message}`);
|
|
}
|
|
let agentHandshake;
|
|
try {
|
|
agentHandshake = require('./modules/agent-handshake');
|
|
} catch (err) {
|
|
console.error(`Agent握手协议模块加载警告: ${err.message}`);
|
|
}
|
|
let agentTraining;
|
|
try {
|
|
agentTraining = require('./modules/agent-training');
|
|
} catch (err) {
|
|
console.error(`Agent训练模块加载警告: ${err.message}`);
|
|
}
|
|
|
|
// 其他现有代码保持不变...
|
|
|
|
// 添加新的API路由
|
|
app.get('/api/agent-training/status', (req, res) => {
|
|
if (!agentTraining) {
|
|
return res.status(501).json({ error: true, message: 'Agent训练模块未加载' });
|
|
}
|
|
|
|
try {
|
|
const state = agentTraining.getTrainingState();
|
|
res.json({
|
|
server: 'ZY-SVR-002',
|
|
module: 'agent-training',
|
|
status: {
|
|
isRunning: state.isRunning,
|
|
lastRun: state.lastRun ? new Date(state.lastRun).toISOString() : null,
|
|
nextRun: new Date(state.nextRun).toISOString()
|
|
}
|
|
});
|
|
} catch (err) {
|
|
res.status(500).json({ error: true, message: err.message });
|
|
}
|
|
});
|
|
|
|
app.post('/api/agent-training/run', async (req, res) => {
|
|
if (!agentTraining) {
|
|
return res.status(501).json({ error: true, message: 'Agent训练模块未加载' });
|
|
}
|
|
|
|
try {
|
|
const { token } = req.body;
|
|
if (!token) {
|
|
return res.status(400).json({ error: true, message: '缺少session token' });
|
|
}
|
|
|
|
await agentTraining.runTraining(token);
|
|
res.json({ success: true, message: '训练任务已启动' });
|
|
} catch (err) {
|
|
res.status(500).json({ error: true, message: err.message });
|
|
}
|
|
});
|
|
|
|
// 其他现有代码保持不变...
|
|
|
|
// 启动服务器
|
|
app.listen(PORT, () => {
|
|
console.log(`铸渊主权服务器已启动 · 端口 ${PORT} · ${new Date().toISOString()}`);
|
|
|
|
// 启动时运行一次训练
|
|
if (agentTraining) {
|
|
agentTraining.runTraining();
|
|
}
|
|
}); |