guanghulab/exe-engine/src/context/context-manager.js
2026-05-10 13:12:44 +08:00

169 lines
3.7 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.

// exe-engine/src/context/context-manager.js
// EXE-Engine · 上下文管理器
// 支持持久化的升级上下文系统Grid-DB 接口预留)
// PRJ-EXE-001 · Phase 1 · ZY-EXE-P1-001
// 版权:国作登字-2026-A-00037559
'use strict';
const { randomUUID } = require('crypto');
/**
* 上下文管理器
*
* 本体论锚定:上下文 = 笔的记忆链。
* 每次对话都有连续的记忆,管理器负责维护这条记忆链。
* Phase 1 使用内存 + ContextCachePhase 2 对接 Grid-DB 持久化。
*/
class ContextManager {
/**
* @param {object} deps
* @param {ContextCache} deps.cache 上下文缓存实例
*/
constructor(deps = {}) {
this._cache = deps.cache || null;
this._contexts = new Map();
// Grid-DB 持久化接口预留
this._gridDB = null;
}
/**
* 创建新上下文
* @param {string} agentId Agent ID
* @param {string} sessionId 会话 ID
* @param {object} [initialData] 初始数据
* @returns {string} contextId
*/
createContext(agentId, sessionId, initialData = {}) {
const contextId = `ctx-${randomUUID().slice(0, 12)}`;
const now = new Date().toISOString();
const context = {
contextId,
agentId,
sessionId,
data: { ...initialData },
messages: [],
createdAt: now,
updatedAt: now,
status: 'active'
};
this._contexts.set(contextId, context);
// 同步到缓存
if (this._cache) {
this._cache.set(contextId, context);
}
return contextId;
}
/**
* 获取上下文
* @param {string} contextId
* @returns {object|null}
*/
getContext(contextId) {
// 先查内存
const ctx = this._contexts.get(contextId);
if (ctx) return ctx;
// 再查缓存
if (this._cache) {
const cached = this._cache.get(contextId);
if (cached) {
this._contexts.set(contextId, cached);
return cached;
}
}
return null;
}
/**
* 更新上下文数据
* @param {string} contextId
* @param {object} updates 要合并的更新
* @returns {boolean} 是否成功
*/
updateContext(contextId, updates) {
const ctx = this._contexts.get(contextId);
if (!ctx) return false;
Object.assign(ctx.data, updates);
ctx.updatedAt = new Date().toISOString();
if (this._cache) {
this._cache.set(contextId, ctx);
}
return true;
}
/**
* 标记上下文为过期
* @param {string} contextId
* @returns {boolean}
*/
expireContext(contextId) {
const ctx = this._contexts.get(contextId);
if (!ctx) return false;
ctx.status = 'expired';
ctx.updatedAt = new Date().toISOString();
return true;
}
/**
* 列出指定 Agent 的所有上下文
* @param {string} agentId
* @returns {object[]}
*/
listContexts(agentId) {
const results = [];
for (const [, ctx] of this._contexts) {
if (ctx.agentId === agentId) {
results.push(ctx);
}
}
return results;
}
/**
* 向上下文追加消息
* @param {string} contextId
* @param {string} role 角色 (user | assistant | system)
* @param {string} content 消息内容
* @returns {boolean}
*/
addMessage(contextId, role, content) {
const ctx = this._contexts.get(contextId);
if (!ctx) return false;
ctx.messages.push({
role,
content,
timestamp: new Date().toISOString()
});
ctx.updatedAt = new Date().toISOString();
if (this._cache) {
this._cache.set(contextId, ctx);
}
return true;
}
/**
* 设置 Grid-DB 持久化实例P2 对接预留)
* @param {object} gridDBInstance
*/
setGridDBPersistence(gridDBInstance) {
this._gridDB = gridDBInstance;
}
}
module.exports = ContextManager;