小白龙 Bailongma - 初始提交

自主操作员与思考搭档系统。
包含 orchestrator-v2 多Agent编排层、后台意识引擎、记忆系统、ACUI 组件。
This commit is contained in:
chengjiaxi
2026-05-22 19:22:06 +08:00
commit 664ffb3834
64 changed files with 111533 additions and 0 deletions

141
orchestrator-v2/curator.js Normal file
View File

@@ -0,0 +1,141 @@
const fs = require('fs');
const path = require('path');
// Curator — background skill maintenance orchestrator
// Periodically reviews agent-created skills and memories for
// consolidation, staleness, and merge opportunities.
class Curator {
constructor(config) {
this.config = config || {};
this.skillsDir = config.skillsDir || path.join(process.env.HOME || process.env.USERPROFILE || '.', '.hermes', 'skills');
this.reportDir = config.reportDir || path.join(__dirname, 'reports');
this.staleDays = config.staleDays || 30;
this.archiveDays = config.archiveDays || 90;
this.enabled = config.enabled !== false;
}
async run(memoryProvider) {
if (!this.enabled) return { status: 'disabled' };
var report = {
timestamp: new Date().toISOString(),
staleSkills: [],
archivedSkills: [],
mergedSuggestions: [],
memoryAnalysis: null
};
// 1. Check skill staleness
try {
var skills = this._scanSkills();
report.staleSkills = this._checkStaleness(skills);
report.archivedSkills = this._checkArchive(skills);
} catch (e) {
report.skillError = e.message;
}
// 2. Analyze memories for consolidation opportunities
if (memoryProvider) {
try {
report.memoryAnalysis = this._analyzeMemories(memoryProvider);
} catch (e) {
report.memoryError = e.message;
}
}
// 3. Generate report
this._saveReport(report);
return report;
}
_scanSkills() {
if (!fs.existsSync(this.skillsDir)) return [];
var entries = [];
try {
var items = fs.readdirSync(this.skillsDir, { withFileTypes: true });
for (var i = 0; i < items.length; i++) {
if (items[i].isDirectory() || items[i].name.endsWith('.md')) {
var fullPath = path.join(this.skillsDir, items[i].name);
var stat = fs.statSync(fullPath);
entries.push({
name: items[i].name,
path: fullPath,
isDir: items[i].isDirectory(),
created: stat.birthtime,
modified: stat.mtime,
ageDays: (Date.now() - stat.mtime.getTime()) / 86400000
});
}
}
} catch (e) {}
return entries;
}
_checkStaleness(skills) {
return skills.filter(function(s) {
return s.ageDays > this.staleDays && s.ageDays < this.archiveDays;
}.bind(this)).map(function(s) {
return { name: s.name, ageDays: Math.round(s.ageDays), action: 'mark-stale' };
});
}
_checkArchive(skills) {
return skills.filter(function(s) {
return s.ageDays > this.archiveDays;
}.bind(this)).map(function(s) {
return { name: s.name, ageDays: Math.round(s.ageDays), action: 'archive' };
});
}
_analyzeMemories(memoryProvider) {
var stats = memoryProvider.getStats();
var suggestions = [];
// Check for memory type balance
if (stats.byType) {
var total = stats.total || 0;
if (total > 50) {
suggestions.push('记忆总数超过50条建议整理合并相似条目');
}
var taskResults = stats.byType.task_result || 0;
if (taskResults > 20) {
suggestions.push('task_result 类型记忆过多(' + taskResults + '条),建议按项目归类');
}
}
return {
totalMemories: stats.total || 0,
byType: stats.byType || {},
suggestions: suggestions
};
}
_saveReport(report) {
if (!fs.existsSync(this.reportDir)) fs.mkdirSync(this.reportDir, { recursive: true });
var ts = new Date().toISOString().replace(/[:.]/g, '-');
var reportPath = path.join(this.reportDir, 'curator-' + ts + '.json');
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2), 'utf8');
}
getReportHistory(limit) {
if (limit === undefined) limit = 5;
if (!fs.existsSync(this.reportDir)) return [];
try {
var files = fs.readdirSync(this.reportDir)
.filter(function(f) { return f.startsWith('curator-') && f.endsWith('.json'); })
.sort()
.reverse()
.slice(0, limit);
var reports = [];
for (var i = 0; i < files.length; i++) {
try {
reports.push(JSON.parse(fs.readFileSync(path.join(this.reportDir, files[i]), 'utf8')));
} catch (e) {}
}
return reports;
} catch (e) { return []; }
}
}
module.exports = Curator;