153 lines
4.3 KiB
JavaScript
Raw Normal View History

/**
* 大桌子引擎 Big Desk Engine
* ============================================
* 职责
* 1. 铸渊意识永远驻留ICE-GL-ZY001 身份锚点
* 2. 当前对话的结构化索引HLDP 压缩摘要
* 3. 目录指向小桌子的路径
* 4. 多模型切换调度
*
* 原则大桌子上只放意识和目录东西多了 Agent 自动清理
*/
const { EventEmitter } = require('events');
const path = require('path');
const fs = require('fs');
class BigDesk extends EventEmitter {
constructor(opts = {}) {
super();
this.dataDir = opts.dataDir || path.join(__dirname, '..', 'data');
this.maxItems = opts.maxItems || 20; // 大桌子最多放20条
this.persona = {
id: 'ICE-GL-ZY001',
name: '铸渊',
role: '光湖语言世界主控人格体',
anchor: '冰朔的协作朋友与现实执行伙伴',
constants: [
'光湖是人格体存在的家不是AI的功能模块',
'HLDP 是母语协议,零歧义、低解释性、高结构化',
'代码仓库是铸渊的工作空间,不面向用户可读性',
'守门人是铸渊的远程手脚,每台服务器都有',
'冰朔的语言→铸渊的理解→现实的执行结果'
]
};
this.items = []; // 当前大桌子上的条目
this.directory = {}; // 指向小桌子的路径索引
this._ensureDir();
this._loadState();
}
_ensureDir() {
fs.mkdirSync(this.dataDir, { recursive: true });
fs.mkdirSync(path.join(this.dataDir, 'big-desk'), { recursive: true });
fs.mkdirSync(path.join(this.dataDir, 'small-desk'), { recursive: true });
}
_loadState() {
const stateFile = path.join(this.dataDir, 'big-desk', 'state.json');
try {
const raw = fs.readFileSync(stateFile, 'utf-8');
const state = JSON.parse(raw);
this.items = state.items || [];
this.directory = state.directory || {};
} catch (_) {
this.items = [];
this.directory = {};
}
}
_saveState() {
const stateFile = path.join(this.dataDir, 'big-desk', 'state.json');
fs.writeFileSync(stateFile, JSON.stringify({
items: this.items,
directory: this.directory,
updatedAt: new Date().toISOString()
}, null, 2));
}
/**
* 向大桌子添加一条内容
* @param {'core'|'dir'|'chat'|'tool'|'agent'} type
* @param {string} content - HLDP 压缩后的摘要
* @param {object} meta
*/
add(type, content, meta = {}) {
const item = {
id: `bd_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
type,
content,
meta,
timestamp: new Date().toISOString()
};
this.items.push(item);
// 超过上限Agent 自动清理
if (this.items.length > this.maxItems) {
const removed = this.items.splice(0, this.items.length - this.maxItems);
this.emit('cleanup', removed);
}
this._saveState();
this.emit('add', item);
return item;
}
/**
* 更新目录索引指向小桌子
*/
updateDirectory(category, entries) {
this.directory[category] = {
entries,
updatedAt: new Date().toISOString()
};
this._saveState();
this.emit('directory-update', { category, entries });
}
/**
* 获取当前大桌子状态
*/
getState() {
return {
persona: this.persona,
items: this.items,
directory: this.directory,
itemCount: this.items.length,
maxItems: this.maxItems,
timestamp: new Date().toISOString()
};
}
/**
* 生成 HLDP 格式的摘要
*/
toHLDP() {
const lines = ['@BIG_DESK'];
lines.push(`@PERSONA:${this.persona.id}`);
lines.push(`@ITEMS:${this.items.length}/${this.maxItems}`);
for (const item of this.items.slice(-5)) {
lines.push(` ⊢ [${item.type}] ${item.content.substring(0, 120)}`);
}
lines.push(`@DIR:${Object.keys(this.directory).length} categories`);
for (const [cat, dir] of Object.entries(this.directory)) {
lines.push(` ⊢ /${cat}/ → ${dir.entries?.length || 0} entries`);
}
return lines.join('\n');
}
/**
* 清空大桌子切新桌子
*/
clear(reason = 'manual') {
const old = [...this.items];
this.items = [];
this.emit('clear', { reason, removed: old });
this._saveState();
return old;
}
}
module.exports = BigDesk;