/** * 大桌子引擎 — 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;