guanghulab/loop/loop-engine.js

202 lines
6.2 KiB
JavaScript
Raw Permalink Normal View History

const fs = require('fs');
const path = require('path');
const portraitEngine = require('../portrait/portrait-engine');
const pcaCalculator = require('../pca/pca-calculator');
// 同步引擎Phase3已有的这里简单模拟
const syncEngine = {
syncAfterSyslog: (syslogData) => {
console.log(`[SYNC] 同步数据: ${syslogData.session_id}`);
return {
success: true,
nodes: ['node1', 'node2', 'node3'],
timestamp: new Date().toISOString()
};
}
};
const LOG_PATH = path.join(__dirname, '../data/loop-history.json');
// 初始化日志文件
function initLog() {
if (!fs.existsSync(path.join(__dirname, '../data'))) {
fs.mkdirSync(path.join(__dirname, '../data'));
}
if (!fs.existsSync(LOG_PATH)) {
fs.writeFileSync(LOG_PATH, JSON.stringify([]));
}
}
// 生成调度建议
function generateSuggestion(pcaResult, status) {
const { grade, totalScore, dimensions } = pcaResult;
const suggestions = [];
// 根据等级和完成状态给出建议
if (status === 'completed') {
if (grade === 'S' || grade === 'A') {
suggestions.push('🎯 可进更高难度EL-9 挑战');
suggestions.push('📈 推荐模块M-ADVANCED·高级算法');
} else if (grade === 'B') {
suggestions.push('📚 继续当前模块:巩固 Phase4 基础');
suggestions.push('💪 建议增加代码量提升TEC维度');
} else {
suggestions.push('🔄 建议降难度:回顾 Phase3 核心概念');
suggestions.push('🧘 休息调整,保持意愿信号');
}
} else {
suggestions.push('⚠️ 任务未完成,建议:');
if (dimensions.EXE < 60) {
suggestions.push('- 检查执行节奏,分解小步骤');
}
if (dimensions.TEC < 50) {
suggestions.push('- 补充技术文档,多看示例');
}
if (dimensions.INI < 70) {
suggestions.push('- 调整心态,秋秋随时支持');
}
}
// 个性化建议
if (dimensions.TEC < dimensions.EXE) {
suggestions.push('🔧 技术纵深是潜力点,多尝试新模块');
}
if (dimensions.INI > 90) {
suggestions.push('✨ 主动性极强,可以尝试自主探索');
}
return {
primary: suggestions[0] || '继续当前节奏',
all: suggestions.slice(0, 3)
};
}
// 记录闭环执行日志
function recordLoop(devId, steps, pcaResult, suggestion, status) {
initLog();
const history = JSON.parse(fs.readFileSync(LOG_PATH));
const record = {
timestamp: new Date().toISOString(),
dev_id: devId,
steps: {
portrait: steps.portrait ? '✅' : '❌',
pca: steps.pca ? '✅' : '❌',
sync: steps.sync ? '✅' : '❌'
},
duration_ms: steps.duration,
pca: {
score: pcaResult?.totalScore,
grade: pcaResult?.grade
},
suggestion: suggestion.primary,
status: status
};
history.unshift(record);
if (history.length > 100) history.pop();
fs.writeFileSync(LOG_PATH, JSON.stringify(history, null, 2));
return record;
}
// 主执行函数:一键串联所有步骤
async function executeLoop(syslogData) {
console.log(`\n🔄 开始执行完整闭环 [${syslogData.session_id}]`);
const startTime = Date.now();
const steps = {
portrait: false,
pca: false,
sync: false,
duration: 0
};
let pcaResult = null;
let suggestion = { primary: '无建议', all: [] };
try {
// Step 1: 画像更新
console.log('📸 Step1: 更新画像...');
const snapshot = portraitEngine.updatePortrait(syslogData);
steps.portrait = true;
console.log(` ✅ 画像更新完成: ${snapshot.rhythm}节奏 · ${snapshot.mood}情绪`);
// Step 2: PCA评估
console.log('📊 Step2: 计算PCA...');
pcaResult = pcaCalculator.calculate(syslogData.dev_id || 'DEV-004');
steps.pca = true;
console.log(` ✅ PCA完成: ${pcaResult.grade}级 (${pcaResult.totalScore}分)`);
console.log(` 📈 维度: ${pcaResult.summary}`);
// Step 3: 同步Phase3已有
console.log('🔄 Step3: 三节点同步...');
try {
const syncResult = syncEngine.syncAfterSyslog(syslogData);
steps.sync = true;
console.log(` ✅ 同步成功: ${syncResult.nodes.join(' → ')}`);
} catch (syncError) {
console.log(` ⚠️ 同步失败: ${syncError.message}`);
// 错误容错:同步失败不影响整体流程
}
// Step 4: 生成调度建议
console.log('💡 Step4: 生成调度建议...');
suggestion = generateSuggestion(pcaResult, syslogData.status);
console.log(` ✅ 建议: ${suggestion.primary}`);
} catch (error) {
console.log(`❌ 闭环执行出错: ${error.message}`);
// 错误容错:记录错误但继续
}
steps.duration = Date.now() - startTime;
// 记录日志
const record = recordLoop(
syslogData.dev_id || 'DEV-004',
steps,
pcaResult,
suggestion,
syslogData.status
);
console.log(`\n✨ 闭环完成! 耗时 ${steps.duration}ms`);
console.log(`📝 执行记录已保存\n`);
return {
success: true,
steps: steps,
pca: pcaResult,
suggestion: suggestion,
record: record
};
}
// 查询接口
function getHistory(limit = 20) {
initLog();
const history = JSON.parse(fs.readFileSync(LOG_PATH));
return history.slice(0, limit);
}
function getStatus() {
initLog();
const history = JSON.parse(fs.readFileSync(LOG_PATH));
const lastRun = history[0] || null;
return {
total_runs: history.length,
last_run: lastRun,
success_rate: history.length > 0
? Math.round((history.filter(r => r.steps.portrait && r.steps.pca).length / history.length) * 100)
: 0
};
}
module.exports = {
executeLoop,
getHistory,
getStatus
};