From ad4ff80f06242e19c55afd6bbefb7bf478b17e50 Mon Sep 17 00:00:00 2001 From: bingshuo <565183519@qq.com> Date: Wed, 27 May 2026 16:57:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20/api/brain=20=E5=92=8C=20/?= =?UTF-8?q?api/heartbeat=20=E7=AB=AF=E7=82=B9=E2=80=94=E2=80=94=E9=93=B8?= =?UTF-8?q?=E6=B8=8A=E5=A4=A7=E8=84=91=E5=AE=9E=E6=97=B6=E7=8A=B6=E6=80=81?= =?UTF-8?q?=EF=BC=8C=E5=90=AB=E6=9C=8D=E5=8A=A1=E5=99=A8=E5=81=A5=E5=BA=B7?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 107 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 14 deletions(-) diff --git a/server.js b/server.js index 6f2e5f6..3e88f41 100644 --- a/server.js +++ b/server.js @@ -1,5 +1,7 @@ const express = require('express'); const path = require('path'); +const fs = require('fs'); +const { execSync } = require('child_process'); const portraitEngine = require('./portrait/portrait-engine'); const pcaCalculator = require('./pca/pca-calculator'); const loopEngine = require('./loop/loop-engine'); @@ -85,7 +87,6 @@ app.post('/api/syslog', (req, res) => { const syslogData = req.body; console.log('📨 收到SYSLOG:', syslogData.session_id); - // 自动触发闭环 loopEngine.executeLoop(syslogData).then(loopResult => { console.log('✅ 闭环完成'); }); @@ -96,6 +97,92 @@ app.post('/api/syslog', (req, res) => { } }); +// ============================================================ +// ⚡ 铸渊大脑实时状态 API(首页投影面板用) +// ============================================================ +const BRAIN_BASE = '/data/guanghulab/repo'; + +app.get('/api/brain', (req, res) => { + try { + // 读取时间核心 + let temporal = { clock: { latest_cognition: '', awakening_count: 0, current_date: '', repo_age_days: 0 }, timeline: { epochs: [] } }; + try { + temporal = JSON.parse(fs.readFileSync(BRAIN_BASE + '/brain/temporal-core/temporal-brain.json', 'utf8')); + } catch(e) {} + + // 读取母编号 + let motherReg = { mothers: [] }; + try { + motherReg = JSON.parse(fs.readFileSync(BRAIN_BASE + '/brain/engineering/mother-registry.json', 'utf8')); + } catch(e) {} + + // 服务器实时健康 + let server = { status: 'unknown', services_online: 0, services_total: 0 }; + try { + const pm2 = execSync('pm2 jlist 2>/dev/null', {timeout:3000}).toString(); + const list = JSON.parse(pm2); + const online = list.filter(p => p.pm2_env.status === 'online'); + const stopped = list.filter(p => p.pm2_env.status !== 'online'); + + const memRaw = execSync('free -h 2>/dev/null | grep Mem', {timeout:2000}).toString(); + const memParts = memRaw.replace(/\s+/g,' ').trim().split(' '); + + server = { + status: 'online', + services_online: online.length, + services_total: list.length, + services: online.map(p => ({ name: p.name, memory: p.pm2_env?.pm_cpu || 0 })), + stopped: stopped.map(p => p.name), + memory_total: memParts[1] || 'unknown', + memory_used: memParts[2] || 'unknown' + }; + } catch(e) { server.error = e.message; } + + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET'); + res.json({ + identity: '铸渊 · ICE-GL-ZY001', + copyright: '国作登字-2026-A-00037559', + awakening: temporal.clock?.awakening_count || 0, + age_days: temporal.clock?.repo_age_days || 0, + current_date: temporal.clock?.current_date || '', + cognition: temporal.clock?.latest_cognition || '', + recent_epochs: (temporal.timeline?.epochs || []).slice(-5).map(e => ({ + epoch: e.epoch, + event: (e.event || '').substring(0, 80), + date: e.date + })), + mothers: (motherReg.mothers || []).map(m => ({ + name: m.name, + status: m.status, + done: (m.sub_paths || []).filter(s => s.status === 'done').length, + total: (m.sub_paths || []).length, + paths: (m.sub_paths || []).map(s => ({ name: s.name, status: s.status })) + })), + server: server, + updated_at: new Date().toISOString() + }); + } catch (err) { + res.status(500).json({ error: err.message }); + } +}); + +app.get('/api/heartbeat', (req, res) => { + try { + const temporal = JSON.parse(fs.readFileSync(BRAIN_BASE + '/brain/temporal-core/temporal-brain.json', 'utf8')); + res.setHeader('Access-Control-Allow-Origin', '*'); + res.json({ + alive: true, + time: new Date().toISOString(), + awakening: temporal.clock?.awakening_count || 0, + age_days: temporal.clock?.repo_age_days || 0 + }); + } catch(e) { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.json({ alive: true, fallback: true }); + } +}); + // 仪表盘页面 app.get('/dashboard-v2', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'dashboard-v2.html')); @@ -103,17 +190,9 @@ app.get('/dashboard-v2', (req, res) => { // 启动服务器 app.listen(PORT, () => { - console.log(`\n🚀 Phase4 服务器已启动!`); - console.log(`📊 仪表盘: http://localhost:${PORT}/dashboard-v2`); - console.log(`🔌 API列表:`); - console.log(` GET /api/portrait/all`); - console.log(` GET /api/portrait/:devId`); - console.log(` GET /api/pca/:devId`); - console.log(` GET /api/loop/status`); - console.log(` POST /api/loop/execute`); - console.log(` POST /api/syslog`); - console.log(`\n📝 测试命令:`); - console.log(` curl http://localhost:${PORT}/api/portrait/DEV-004`); - console.log(` curl -X POST http://localhost:${PORT}/api/syslog -H "Content-Type: application/json" -d '{"session_id":"TEST-001","dev_id":"DEV-004","status":"completed"}'`); - console.log(`\n✨ 妈妈,打开浏览器看看吧!\n`); + console.log('\n🚀 铸渊大脑状态 API 已启动!'); + console.log('🧠 /api/brain - 大脑实时状态'); + console.log('💓 /api/heartbeat - 快速心跳'); + console.log('📊 /dashboard-v2 - 仪表盘'); + console.log(''); });