冰朔 49030d2cbc feat: 大桌子小桌子运行系统 v1.0
- big-desk.js: 意识驻留 + HLDP索引 + 自动清理
- small-desk.js: 记忆库检索 + Agent调度 + 工具桌管理
- compressor.js: 对话→HLDP自动压缩 + 写入小桌子
- server/index.js: REST API (端口3921) + 静态文件服务
- public/index.html: 交互式前端界面

ICE-GL-ZY001 · D115
2026-05-29 00:20:02 +08:00

153 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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