feat: Capability Evolver 升级 + 日常运行日志
主要变更: - Capability Evolver 技能大幅升级 - 新增 LLM 审查、叙事记忆、反思机制模块 - 改进 Agent 间通信协议和技能搜索 - 整合 Git 备份到 evolver-run.sh - Agent 配置与日志更新 - dev-assist/haonan/main 认证和会话配置 - 5 个 agent 的 AGENTS.md 文档更新 - haonan 的 MEMORY.md 和 SOUL.md 更新 - 新增功能目录 - hooks/self-improvement 自我改进钩子 - memory/evolution 进化记忆状态 - workspace/.learnings/ 学习记录 - 清理 - 删除 scripts/git-auto-sync.sh(已整合到 evolver) - 删除旧的 _meta.json 配置 - 忽略临时工作空间目录
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
// Append-only asset call log for tracking Hub asset interactions per evolution run.
|
||||
// Log file: {evolution_dir}/asset_call_log.jsonl
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { getEvolutionDir } = require('./paths');
|
||||
|
||||
function getLogPath() {
|
||||
return path.join(getEvolutionDir(), 'asset_call_log.jsonl');
|
||||
}
|
||||
|
||||
function ensureDir(filePath) {
|
||||
const dir = path.dirname(filePath);
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a single asset call record to the log.
|
||||
*
|
||||
* @param {object} entry
|
||||
* @param {string} entry.run_id
|
||||
* @param {string} entry.action - hub_search_hit | hub_search_miss | asset_reuse | asset_reference | asset_publish | asset_publish_skip
|
||||
* @param {string} [entry.asset_id]
|
||||
* @param {string} [entry.asset_type]
|
||||
* @param {string} [entry.source_node_id]
|
||||
* @param {string} [entry.chain_id]
|
||||
* @param {number} [entry.score]
|
||||
* @param {string} [entry.mode] - direct | reference
|
||||
* @param {string[]} [entry.signals]
|
||||
* @param {string} [entry.reason]
|
||||
* @param {object} [entry.extra]
|
||||
*/
|
||||
function logAssetCall(entry) {
|
||||
if (!entry || typeof entry !== 'object') return;
|
||||
try {
|
||||
const logPath = getLogPath();
|
||||
ensureDir(logPath);
|
||||
const record = {
|
||||
timestamp: new Date().toISOString(),
|
||||
...entry,
|
||||
};
|
||||
fs.appendFileSync(logPath, JSON.stringify(record) + '\n', 'utf8');
|
||||
} catch (e) {
|
||||
// Non-fatal: never block evolution for logging failure
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read asset call log entries with optional filters.
|
||||
*
|
||||
* @param {object} [opts]
|
||||
* @param {string} [opts.run_id] - filter by run_id
|
||||
* @param {string} [opts.action] - filter by action type
|
||||
* @param {number} [opts.last] - only return last N entries
|
||||
* @param {string} [opts.since] - ISO date string, only entries after this time
|
||||
* @returns {object[]}
|
||||
*/
|
||||
function readCallLog(opts) {
|
||||
const o = opts || {};
|
||||
const logPath = getLogPath();
|
||||
if (!fs.existsSync(logPath)) return [];
|
||||
|
||||
const raw = fs.readFileSync(logPath, 'utf8');
|
||||
const lines = raw.split('\n').filter(Boolean);
|
||||
|
||||
let entries = [];
|
||||
for (const line of lines) {
|
||||
try {
|
||||
entries.push(JSON.parse(line));
|
||||
} catch (e) { /* skip corrupt lines */ }
|
||||
}
|
||||
|
||||
if (o.since) {
|
||||
const sinceTs = new Date(o.since).getTime();
|
||||
if (Number.isFinite(sinceTs)) {
|
||||
entries = entries.filter(e => new Date(e.timestamp).getTime() >= sinceTs);
|
||||
}
|
||||
}
|
||||
|
||||
if (o.run_id) {
|
||||
entries = entries.filter(e => e.run_id === o.run_id);
|
||||
}
|
||||
|
||||
if (o.action) {
|
||||
entries = entries.filter(e => e.action === o.action);
|
||||
}
|
||||
|
||||
if (o.last && Number.isFinite(o.last) && o.last > 0) {
|
||||
entries = entries.slice(-o.last);
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Summarize asset call log (for CLI display).
|
||||
*
|
||||
* @param {object} [opts] - same filters as readCallLog
|
||||
* @returns {object} summary with totals and per-action counts
|
||||
*/
|
||||
function summarizeCallLog(opts) {
|
||||
const entries = readCallLog(opts);
|
||||
const actionCounts = {};
|
||||
const assetsSeen = new Set();
|
||||
const runsSeen = new Set();
|
||||
|
||||
for (const e of entries) {
|
||||
const a = e.action || 'unknown';
|
||||
actionCounts[a] = (actionCounts[a] || 0) + 1;
|
||||
if (e.asset_id) assetsSeen.add(e.asset_id);
|
||||
if (e.run_id) runsSeen.add(e.run_id);
|
||||
}
|
||||
|
||||
return {
|
||||
total_entries: entries.length,
|
||||
unique_assets: assetsSeen.size,
|
||||
unique_runs: runsSeen.size,
|
||||
by_action: actionCounts,
|
||||
entries,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
logAssetCall,
|
||||
readCallLog,
|
||||
summarizeCallLog,
|
||||
getLogPath,
|
||||
};
|
||||
Reference in New Issue
Block a user