@iflow-mcp/promptx
Version:
AI角色创建平台和智能工具开发平台,基于MCP协议提供专业AI能力注入
1,619 lines (1,607 loc) • 737 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// ../../node_modules/tsup/assets/cjs_shims.js
var init_cjs_shims = __esm({
"../../node_modules/tsup/assets/cjs_shims.js"() {
"use strict";
}
});
// src/cognition/Cue.js
var require_Cue = __commonJS({
"src/cognition/Cue.js"(exports2, module2) {
"use strict";
init_cjs_shims();
var Cue = class _Cue {
/**
* 创建一个新的Cue节点
*
* @param {string} word - 概念词,作为节点的唯一标识
*
* @example
* const cue = new Cue("认知");
* cue.connections.set("模型", 1234567890);
*/
constructor(word) {
this.word = word;
this.connections = /* @__PURE__ */ new Map();
}
/**
* 获取节点的出度(连接到多少个其他节点)
*
* 出度的意义:
* - 高出度 = 枢纽节点(hub),概念发散性强
* - 低出度 = 专门节点,概念专一性强
*
* @returns {number} 出边数量
*/
getOutDegree() {
return this.connections.size;
}
/**
* 获取最强连接(权重最高的出边)
*
* 用途:
* - Prime时选择默认激活路径
* - Recall时决定主要扩散方向
*
* @returns {{word: string, weight: number}|null} 最强连接信息
*/
getStrongestConnection() {
if (this.connections.size === 0) return null;
let maxWeight = -Infinity;
let strongestWord = null;
for (const [word, weight] of this.connections) {
if (weight > maxWeight) {
maxWeight = weight;
strongestWord = word;
}
}
return { word: strongestWord, weight: maxWeight };
}
/**
* 获取按权重排序的连接列表
*
* @param {number} limit - 返回前N个连接
* @returns {Array<{word: string, weight: number}>} 排序后的连接列表
*/
getSortedConnections(limit = Infinity) {
return Array.from(this.connections.entries()).map(([word, weight]) => ({ word, weight })).sort((a, b) => b.weight - a.weight).slice(0, limit);
}
/**
* 序列化为JSON对象(用于持久化)
*
* @returns {Object} 可序列化的对象
*/
toJSON() {
return {
word: this.word,
connections: Array.from(this.connections.entries()).map(([target, weight]) => ({
target,
weight
}))
};
}
/**
* 从JSON对象恢复(用于加载)
*
* @param {Object} json - 序列化的对象
* @returns {Cue} 恢复的Cue实例
*/
static fromJSON(json) {
const cue = new _Cue(json.word);
if (json.connections) {
for (const conn of json.connections) {
cue.connections.set(conn.target, conn.weight);
}
}
return cue;
}
};
module2.exports = Cue;
}
});
// src/cognition/FrequencyCue.js
var require_FrequencyCue = __commonJS({
"src/cognition/FrequencyCue.js"(exports2, module2) {
"use strict";
init_cjs_shims();
var Cue = require_Cue();
var logger2 = require("@promptx/logger");
var FrequencyCue = class _FrequencyCue extends Cue {
/**
* 创建一个带频率统计的Cue
*
* @param {string} word - 概念词
*/
constructor(word) {
super(word);
this.recallFrequency = 0;
}
/**
* 增加recall频率
*
* 设计:
* - 简单递增,不设上限
* - 未来可以考虑添加衰减机制
* - 可以扩展为更复杂的统计(如时间窗口内的频率)
*/
incrementFrequency() {
this.recallFrequency++;
logger2.debug("[FrequencyCue] Frequency incremented", {
word: this.word,
newFrequency: this.recallFrequency
});
}
/**
* 获取频率值
*
* @returns {number} 当前频率
*/
getFrequency() {
return this.recallFrequency;
}
/**
* 重置频率(用于测试或清理)
*/
resetFrequency() {
this.recallFrequency = 0;
logger2.debug("[FrequencyCue] Frequency reset", { word: this.word });
}
/**
* 序列化为JSON(包含频率信息和记忆引用)
*
* @returns {Object} 包含频率和记忆引用的序列化对象
*/
toJSON() {
const json = {
...super.toJSON(),
recallFrequency: this.recallFrequency
};
if (this.memories && this.memories.size > 0) {
json.memories = Array.from(this.memories);
}
return json;
}
/**
* 从JSON恢复(包含频率信息和记忆引用)
*
* @param {Object} json - 序列化的对象
* @returns {FrequencyCue} 恢复的FrequencyCue实例
*/
static fromJSON(json) {
const freqCue = new _FrequencyCue(json.word);
if (json.connections) {
for (const conn of json.connections) {
freqCue.connections.set(conn.target, conn.weight);
}
}
freqCue.recallFrequency = json.recallFrequency || 0;
if (json.memories && json.memories.length > 0) {
freqCue.memories = new Set(json.memories);
}
return freqCue;
}
/**
* 获取调试信息
*
* @returns {Object} 调试信息
*/
getDebugInfo() {
return {
word: this.word,
outDegree: this.getOutDegree(),
recallFrequency: this.recallFrequency,
strongestConnection: this.getStrongestConnection()
};
}
};
module2.exports = FrequencyCue;
}
});
// src/cognition/Network.js
var require_Network = __commonJS({
"src/cognition/Network.js"(exports2, module2) {
"use strict";
init_cjs_shims();
var logger2 = require("@promptx/logger");
var fs2 = require("fs");
var path2 = require("path");
var Network = class {
constructor() {
this.cues = /* @__PURE__ */ new Map();
logger2.debug("[Network] Initialized empty network");
}
/**
* 添加或获取Cue
*
* 如果Cue不存在则创建,存在则返回现有的。
* 这是一个幂等操作,多次调用结果相同。
*
* @param {string} word - 概念词
* @returns {FrequencyCue} FrequencyCue实例
*/
getOrCreateCue(word) {
if (!this.cues.has(word)) {
const FrequencyCue = require_FrequencyCue();
const cue = new FrequencyCue(word);
this.cues.set(word, cue);
logger2.debug("[Network] Created new FrequencyCue", { word });
}
return this.cues.get(word);
}
/**
* 获取Cue(不创建)
*
* @param {string} word - 概念词
* @returns {Cue|undefined} Cue实例或undefined
*/
getCue(word) {
return this.cues.get(word);
}
/**
* 检查Cue是否存在
*
* @param {string} word - 概念词
* @returns {boolean} 是否存在
*/
hasCue(word) {
return this.cues.has(word);
}
/**
* 获取网络规模
*
* @returns {number} Cue总数
*/
size() {
return this.cues.size;
}
/**
* 计算网络的入度信息
*
* 入度 = 有多少其他Cue指向这个Cue
* 这需要遍历整个网络,因为我们只存储出边。
*
* @returns {Map<string, number>} word => 入度
*/
calculateInDegrees() {
const inDegrees = /* @__PURE__ */ new Map();
for (const word of this.cues.keys()) {
inDegrees.set(word, 0);
}
for (const [sourceWord, sourceCue] of this.cues) {
for (const targetWord of sourceCue.connections.keys()) {
const currentDegree = inDegrees.get(targetWord) || 0;
inDegrees.set(targetWord, currentDegree + 1);
}
}
return inDegrees;
}
/**
* 计算网络的入度权重(每个节点被指向的总权重)
*
* 用于Prime选择最重要的节点。
*
* @returns {Map<string, number>} word => 总入度权重
*/
calculateInWeights() {
const inWeights = /* @__PURE__ */ new Map();
for (const [sourceWord, sourceCue] of this.cues) {
for (const [targetWord, weight] of sourceCue.connections) {
const currentWeight = inWeights.get(targetWord) || 0;
inWeights.set(targetWord, currentWeight + weight);
}
}
return inWeights;
}
/**
* 获取网络统计信息
*
* @returns {Object} 统计信息
*/
getStatistics() {
let totalConnections = 0;
let maxOutDegree = 0;
let hubNode = null;
let isolatedNodes = 0;
for (const [word, cue] of this.cues) {
const outDegree = cue.connections.size;
totalConnections += outDegree;
if (outDegree === 0) {
isolatedNodes++;
}
if (outDegree > maxOutDegree) {
maxOutDegree = outDegree;
hubNode = word;
}
}
const inDegrees = this.calculateInDegrees();
let maxInDegree = 0;
let sinkNode = null;
for (const [word, inDegree] of inDegrees) {
if (inDegree > maxInDegree) {
maxInDegree = inDegree;
sinkNode = word;
}
}
return {
totalCues: this.cues.size,
totalConnections,
averageOutDegree: this.cues.size > 0 ? totalConnections / this.cues.size : 0,
maxOutDegree,
hubNode,
// 出度最高的节点(发散中心)
maxInDegree,
sinkNode,
// 入度最高的节点(汇聚中心)
isolatedNodes
// 孤立节点数量
};
}
/**
* 序列化Network到JSON文件
*
* 设计考虑:
* - 使用同步版本避免异步复杂性
* - 包含版本号便于未来升级
* - 包含时间戳便于调试
*
* @param {string} filePath - 保存路径
* @returns {Promise<void>}
*/
async persist(filePath) {
try {
const fs3 = require("fs").promises;
const path3 = require("path");
const data2 = {
version: "1.0",
timestamp: Date.now(),
cues: {}
};
for (const [word, cue] of this.cues) {
data2.cues[word] = cue.toJSON();
}
const dir = path3.dirname(filePath);
await fs3.mkdir(dir, { recursive: true });
await fs3.writeFile(filePath, JSON.stringify(data2, null, 2), "utf8");
logger2.info("[Network] Persisted to file", {
path: filePath,
cues: this.cues.size,
size: JSON.stringify(data2).length
});
} catch (error) {
logger2.error("[Network] Failed to persist", {
path: filePath,
error: error.message
});
throw error;
}
}
/**
* 从JSON文件加载Network
*
* @param {string} filePath - 文件路径
* @returns {Promise<void>}
*/
async load(filePath) {
try {
const fs3 = require("fs").promises;
const FrequencyCue = require_FrequencyCue();
const content = await fs3.readFile(filePath, "utf8");
const data2 = JSON.parse(content);
if (data2.version !== "1.0") {
logger2.warn("[Network] Version mismatch", {
expected: "1.0",
actual: data2.version
});
}
this.cues.clear();
for (const [word, cueData] of Object.entries(data2.cues)) {
const cue = FrequencyCue.fromJSON(cueData);
this.cues.set(word, cue);
}
logger2.info("[Network] Loaded from file", {
path: filePath,
cues: this.cues.size,
timestamp: new Date(data2.timestamp).toISOString()
});
} catch (error) {
logger2.error("[Network] Failed to load", {
path: filePath,
error: error.message
});
throw error;
}
}
/**
* 同步版本的persist
*
* Remember需要同步保存,避免异步复杂性。
*
* @param {string} filePath - 保存路径
*/
persistSync(filePath) {
try {
const data2 = {
version: "1.0",
timestamp: Date.now(),
cues: {}
};
for (const [word, cue] of this.cues) {
data2.cues[word] = cue.toJSON();
}
const dir = path2.dirname(filePath);
fs2.mkdirSync(dir, { recursive: true });
fs2.writeFileSync(filePath, JSON.stringify(data2, null, 2), "utf8");
logger2.debug("[Network] Persisted (sync) to file", {
path: filePath,
cues: this.cues.size
});
} catch (error) {
logger2.error("[Network] Failed to persist (sync)", {
path: filePath,
error: error.message
});
throw error;
}
}
/**
* 同步版本的load
*
* Prime需要同步加载,避免异步复杂性。
*
* @param {string} filePath - 文件路径
*/
loadSync(filePath) {
try {
const FrequencyCue = require_FrequencyCue();
const content = fs2.readFileSync(filePath, "utf8");
const data2 = JSON.parse(content);
if (data2.version !== "1.0") {
logger2.warn("[Network] Version mismatch", {
expected: "1.0",
actual: data2.version
});
}
this.cues.clear();
for (const [word, cueData] of Object.entries(data2.cues)) {
const cue = FrequencyCue.fromJSON(cueData);
this.cues.set(word, cue);
}
logger2.debug("[Network] Loaded (sync) from file", {
path: filePath,
cues: this.cues.size
});
} catch (error) {
logger2.error("[Network] Failed to load (sync)", {
path: filePath,
error: error.message
});
throw error;
}
}
/**
* 更新Recall频率
*
* 当Recall操作完成后,更新所有被激活节点的频率。
* 这是Network作为容器管理统计信息的体现。
*
* @param {Set<string>} activatedCues - 被激活的节点集合
*/
updateRecallFrequency(activatedCues) {
if (!activatedCues || activatedCues.size === 0) {
return;
}
let updatedCount = 0;
for (const word of activatedCues) {
const cue = this.cues.get(word);
if (cue && typeof cue.incrementFrequency === "function") {
cue.incrementFrequency();
updatedCount++;
}
}
logger2.debug("[Network] Updated recall frequencies", {
requested: activatedCues.size,
updated: updatedCount
});
}
/**
* 获取频率统计信息
*
* @returns {Object} 频率统计
*/
getFrequencyStatistics() {
let totalFrequency = 0;
let maxFrequency = 0;
let mostFrequentNode = null;
const frequencyDistribution = /* @__PURE__ */ new Map();
for (const [word, cue] of this.cues) {
const frequency = cue.recallFrequency || 0;
totalFrequency += frequency;
if (frequency > maxFrequency) {
maxFrequency = frequency;
mostFrequentNode = word;
}
const bucket = Math.floor(frequency / 10) * 10;
frequencyDistribution.set(bucket, (frequencyDistribution.get(bucket) || 0) + 1);
}
return {
totalRecalls: totalFrequency,
averageFrequency: this.cues.size > 0 ? totalFrequency / this.cues.size : 0,
maxFrequency,
mostFrequentNode,
distribution: Array.from(frequencyDistribution.entries()).sort((a, b) => a[0] - b[0]).map(([bucket, count]) => ({ range: `${bucket}-${bucket + 9}`, count }))
};
}
/**
* 清空网络
*
* 用于测试或重置。
*/
clear() {
const previousSize = this.cues.size;
this.cues.clear();
logger2.info("[Network] Cleared", { previousSize });
}
};
module2.exports = Network;
}
});
// src/cognition/Mind.js
var require_Mind = __commonJS({
"src/cognition/Mind.js"(exports2, module2) {
"use strict";
init_cjs_shims();
var Mind = class {
/**
* 创建一个新的Mind
*
* @param {Cue} center - 中心Cue(激活的起点)
*/
constructor(center) {
this.center = center;
this.activatedCues = /* @__PURE__ */ new Set();
this.connections = [];
this.centers = [];
this.depths = /* @__PURE__ */ new Map();
if (center) {
this.activatedCues.add(center.word);
this.depths.set(center.word, 0);
}
}
/**
* 添加一个激活的Cue
*
* @param {string} word - 概念词
* @param {number} depth - 距离中心的深度
*/
addActivatedCue(word, depth = 0) {
this.activatedCues.add(word);
if (!this.depths.has(word) || this.depths.get(word) > depth) {
this.depths.set(word, depth);
}
}
/**
* 添加一个连接
*
* @param {string} from - 源节点
* @param {string} to - 目标节点
* @param {number} weight - 连接权重
*/
addConnection(from, to, weight) {
const exists = this.connections.some(
(conn) => conn.from === from && conn.to === to
);
if (!exists) {
this.connections.push({ from, to, weight });
}
this.activatedCues.add(from);
this.activatedCues.add(to);
}
/**
* 获取激活的节点数量
*
* @returns {number} 节点数
*/
size() {
return this.activatedCues.size;
}
/**
* 获取连接数量
*
* @returns {number} 边数
*/
connectionCount() {
return this.connections.length;
}
/**
* 检查是否为空Mind
*
* @returns {boolean} 是否为空
*/
isEmpty() {
return this.activatedCues.size === 0;
}
/**
* 获取按权重排序的连接
*
* @returns {Array} 排序后的连接
*/
getSortedConnections() {
return [...this.connections].sort((a, b) => b.weight - a.weight);
}
/**
* 获取特定节点的所有出边
*
* @param {string} word - 节点词
* @returns {Array} 出边列表
*/
getOutgoingConnections(word) {
return this.connections.filter((conn) => conn.from === word);
}
/**
* 获取特定节点的所有入边
*
* @param {string} word - 节点词
* @returns {Array} 入边列表
*/
getIncomingConnections(word) {
return this.connections.filter((conn) => conn.to === word);
}
/**
* 转换为可序列化的JSON对象
*
* 用于:
* - 发送给大模型
* - 保存思维快照
* - 可视化展示
*
* @returns {Object} JSON对象
*/
toJSON() {
return {
center: this.center ? this.center.word : null,
centers: this.centers.map((c) => c.word),
activatedCues: Array.from(this.activatedCues),
connections: this.connections,
depths: Array.from(this.depths.entries()).map(([word, depth]) => ({ word, depth })),
statistics: {
nodeCount: this.activatedCues.size,
edgeCount: this.connections.length,
maxDepth: Math.max(...this.depths.values(), 0)
}
};
}
/**
* 生成Mermaid mindmap代码
*
* 可以直接用于可视化展示
*
* @returns {string} Mermaid mindmap代码
*/
toMermaid(maxNodes = 100, maxDepth = 5) {
if (!this.center || this.activatedCues.size === 0) {
return "mindmap\n root((\u7A7A))";
}
const tree = this.buildTree();
let mermaid = "mindmap\n";
mermaid += ` root((${this.center.word}))
`;
const visited = /* @__PURE__ */ new Set();
let nodeCount = 1;
const addChildren = (parent, indent, depth) => {
if (depth > maxDepth) {
return;
}
if (nodeCount >= maxNodes) {
return;
}
if (visited.has(parent)) {
return;
}
visited.add(parent);
const children = tree.get(parent) || [];
for (const child of children) {
if (nodeCount >= maxNodes) {
break;
}
if (visited.has(child)) {
continue;
}
mermaid += " ".repeat(indent) + child + "\n";
nodeCount++;
addChildren(child, indent + 2, depth + 1);
}
};
try {
addChildren(this.center.word, 4, 0);
} catch (error) {
return `mindmap
root((${this.center.word}))
[Network too large: ${this.activatedCues.size} nodes]`;
}
if (nodeCount >= maxNodes) {
mermaid += ` [...${this.activatedCues.size - nodeCount} more nodes]
`;
}
return mermaid;
}
/**
* 构建树形结构
* 用于生成mindmap
*
* @returns {Map<string, Array<string>>} 父节点 -> 子节点列表
*/
buildTree() {
const tree = /* @__PURE__ */ new Map();
const visited = /* @__PURE__ */ new Set();
for (const conn of this.connections) {
if (!tree.has(conn.from)) {
tree.set(conn.from, []);
}
if (!visited.has(`${conn.from}->${conn.to}`)) {
tree.get(conn.from).push(conn.to);
visited.add(`${conn.from}->${conn.to}`);
}
}
for (const [parent, children] of tree) {
const childrenWithWeight = children.map((child) => {
const conn = this.connections.find((c) => c.from === parent && c.to === child);
return { child, weight: conn ? conn.weight : 0 };
});
childrenWithWeight.sort((a, b) => b.weight - a.weight);
tree.set(parent, childrenWithWeight.map((item) => item.child));
}
return tree;
}
/**
* 合并另一个Mind
*
* 用于多线索思考的场景
*
* @param {Mind} otherMind - 要合并的Mind
*/
merge(otherMind) {
for (const cue of otherMind.activatedCues) {
this.activatedCues.add(cue);
}
const existingConns = new Set(
this.connections.map((c) => `${c.from}->${c.to}`)
);
for (const conn of otherMind.connections) {
const key = `${conn.from}->${conn.to}`;
if (!existingConns.has(key)) {
this.connections.push(conn);
}
}
for (const [word, depth] of otherMind.depths) {
if (!this.depths.has(word) || this.depths.get(word) > depth) {
this.depths.set(word, depth);
}
}
if (otherMind.center) {
this.centers.push(otherMind.center);
}
}
};
module2.exports = Mind;
}
});
// src/cognition/Engram.js
var require_Engram = __commonJS({
"src/cognition/Engram.js"(exports2, module2) {
"use strict";
init_cjs_shims();
var logger2 = require("@promptx/logger");
var Engram = class _Engram {
/**
* 创建记忆痕迹
*
* @param {Object} params - 参数对象
* @param {string} params.content - 原始经验内容
* @param {string|Array} params.schema - 概念序列(字符串或数组)
* @param {number} params.strength - 记忆强度 (0-1),表示角色的主观重要性评分
* @param {string} params.type - Engram类型:ATOMIC(原子概念)、LINK(关系连接)、PATTERN(模式结构)
* @param {number} [params.timestamp] - 时间戳(可选,默认为当前时间)
*/
constructor({ content, schema, strength, type, timestamp: timestamp2 }) {
if (!content) {
throw new Error("Engram requires content");
}
if (!schema) {
throw new Error("Engram requires schema");
}
if (strength === void 0 || strength === null) {
throw new Error("Engram requires strength");
}
if (!type) {
throw new Error("Engram requires type (ATOMIC, LINK, or PATTERN)");
}
if (!["ATOMIC", "LINK", "PATTERN"].includes(type)) {
throw new Error("Engram type must be ATOMIC, LINK, or PATTERN");
}
this.content = content;
this.schema = this._normalizeSchema(schema);
this.strength = this._validateStrength(strength);
this.type = type;
this.timestamp = timestamp2 || Date.now();
this.id = `${this.timestamp}_${Math.random().toString(36).substr(2, 9)}`;
logger2.debug("[Engram] Created new engram", {
type: this.type,
schemaLength: this.schema.length,
strength: this.strength,
timestamp: new Date(this.timestamp).toISOString()
});
}
/**
* 标准化schema格式
* 支持多种分隔符:空格、破折号、换行符
*
* @private
* @param {string|Array} schema - 原始schema
* @returns {Array<string>} 标准化的概念数组
*/
_normalizeSchema(schema) {
if (Array.isArray(schema)) {
return schema.filter((item) => item && typeof item === "string");
}
if (typeof schema === "string") {
let items;
if (schema.includes("\n")) {
items = schema.split("\n");
} else if (schema.includes(" - ")) {
items = schema.split(" - ");
} else {
items = schema.split(" ");
}
return items.map((s) => s.trim()).filter(Boolean);
}
throw new Error("Schema must be a string or array");
}
/**
* 验证strength值的有效性
*
* @private
* @param {number} strength - 强度值
* @returns {number} 验证后的强度值
*/
_validateStrength(strength) {
const num = Number(strength);
if (isNaN(num)) {
throw new Error("Strength must be a number");
}
if (num < 0 || num > 1) {
throw new Error("Strength must be between 0 and 1");
}
return num;
}
/**
* 获取schema长度
* 用于快速判断是否可以创建连接
*
* @returns {number} schema数组的长度
*/
get length() {
return this.schema.length;
}
/**
* 判断是否有效
* schema至少需要2个元素才能创建连接
*
* @returns {boolean} 是否为有效的engram
*/
isValid() {
return this.schema.length >= 2;
}
/**
* 获取预览字符串
* 用于日志和调试
*
* @param {number} [maxLength=5] - 最大显示元素数
* @returns {string} 预览字符串
*/
getPreview(maxLength = 5) {
const preview = this.schema.slice(0, maxLength).join(" -> ");
return this.schema.length > maxLength ? `${preview}...` : preview;
}
/**
* 转换为JSON对象
* 用于序列化和传输
*
* @returns {Object} JSON对象
*/
toJSON() {
return {
id: this.id,
content: this.content,
schema: this.schema,
strength: this.strength,
type: this.type,
timestamp: this.timestamp
};
}
/**
* 从JSON对象创建Engram
* 用于反序列化
*
* @static
* @param {Object} json - JSON对象
* @returns {Engram} 新的Engram实例
*/
static fromJSON(json) {
if (!json.type) {
json.type = "ATOMIC";
}
return new _Engram(json);
}
};
module2.exports = Engram;
}
});
// src/cognition/WeightContext.js
var require_WeightContext = __commonJS({
"src/cognition/WeightContext.js"(exports2, module2) {
"use strict";
init_cjs_shims();
var WeightContext = class {
/**
* 创建权重计算上下文
*
* @param {Object} data - 上下文数据
* @param {Cue} data.sourceCue - 源节点
* @param {string} data.targetWord - 目标词
* @param {number} data.position - 在Schema中的位置
* @param {number} [data.timestamp] - 时间戳(可选,默认当前时间)
* @param {Engram} [data.engram] - 完整的记忆痕迹对象(可选)
*/
constructor(data2) {
this.sourceCue = data2.sourceCue;
this.targetWord = data2.targetWord;
this.position = data2.position;
this.timestamp = data2.timestamp || Date.now();
this.sourceOutDegree = this.sourceCue ? this.sourceCue.connections.size : 0;
this.engram = data2.engram || null;
this.strength = this.engram ? this.engram.strength : 0.8;
}
/**
* 获取源词
*
* 便捷方法,避免总是写this.sourceCue.word
*
* @returns {string|null} 源词
*/
getSourceWord() {
return this.sourceCue ? this.sourceCue.word : null;
}
/**
* 转换为调试字符串
*
* 用于日志输出,包含关键信息。
*
* @returns {string} 调试信息
*/
toString() {
const sourceWord = this.getSourceWord();
return `WeightContext{${sourceWord}->${this.targetWord}, pos:${this.position}, degree:${this.sourceOutDegree}}`;
}
/**
* 转换为JSON对象
*
* 用于序列化和日志记录。
*
* @returns {Object} JSON对象
*/
toJSON() {
return {
sourceWord: this.getSourceWord(),
targetWord: this.targetWord,
position: this.position,
timestamp: this.timestamp,
sourceOutDegree: this.sourceOutDegree,
strength: this.strength
};
}
};
module2.exports = WeightContext;
}
});
// src/cognition/Remember.js
var require_Remember = __commonJS({
"src/cognition/Remember.js"(exports2, module2) {
"use strict";
init_cjs_shims();
var logger2 = require("@promptx/logger");
var Remember = class {
/**
* 创建Remember实例
*
* @param {Network} network - 全局认知网络
* @param {WeightStrategy} strategy - 权重计算策略
*/
constructor(network, options = {}) {
this.network = network;
this.strategy = options.strategy || null;
if (this.strategy) {
logger2.debug("[Remember] Initialized with strategy", {
strategy: this.strategy.constructor.name
});
} else {
logger2.warn("[Remember] No strategy provided");
}
}
/**
* 执行记忆写入
*
* 将Engram中的Schema序列写入Network,建立Cue之间的连接,
* 同时建立Cue到Engram.id的反向索引。
*
* @param {Engram} engram - 记忆痕迹对象
* @param {string} [engramId] - 可选的Engram ID,默认使用engram.id
* @returns {Object} 执行结果
* @returns {number} returns.processed - 处理的节点数
* @returns {Array} returns.connections - 创建的连接列表
* @returns {string} returns.engramId - 使用的Engram ID
*/
execute(engram, engramId = null) {
const Engram = require_Engram();
if (!engram || !(engram instanceof Engram)) {
logger2.warn("[Remember] Invalid engram provided", { engram });
return {
processed: 0,
connections: []
};
}
if (!engram.isValid()) {
logger2.debug("[Remember] Engram schema too short, no connections to create", {
length: engram.length
});
return {
processed: engram.length,
connections: []
};
}
const { schema, strength, timestamp: timestamp2 } = engram;
logger2.debug("[Remember] Processing engram", {
length: schema.length,
strength,
preview: engram.getPreview()
});
logger2.debug("[Remember] Phase 1: Ensuring all Cues exist");
const createdCues = [];
for (const word of schema) {
if (!this.network.cues.has(word)) {
createdCues.push(word);
}
this.network.getOrCreateCue(word);
}
if (createdCues.length > 0) {
logger2.debug("[Remember] Created new Cues", {
count: createdCues.length,
cues: createdCues.slice(0, 10)
// 只显示前10个
});
}
logger2.debug("[Remember] Phase 2: Building connection structure");
const WeightContext = require_WeightContext();
const connections = [];
for (let i = 0; i < schema.length - 1; i++) {
const sourceWord = schema[i];
const targetWord = schema[i + 1];
const sourceCue = this.network.cues.get(sourceWord);
const existingWeight = sourceCue.connections.get(targetWord);
if (!existingWeight) {
sourceCue.connections.set(targetWord, 0);
}
}
logger2.debug("[Remember] Phase 2.2: Calculating and updating weights");
for (let i = 0; i < schema.length - 1; i++) {
const sourceWord = schema[i];
const targetWord = schema[i + 1];
const sourceCue = this.network.cues.get(sourceWord);
const context = new WeightContext({
sourceCue,
targetWord,
position: i,
timestamp: timestamp2,
engram
// 传递完整的engram对象
});
const weight = this.strategy.calculate(context);
logger2.debug("[Remember] Weight calculation", {
from: sourceWord,
to: targetWord,
position: i,
outDegree: context.sourceOutDegree,
weight
});
sourceCue.connections.set(targetWord, weight);
connections.push({
source: sourceWord,
target: targetWord,
weight,
position: i
});
}
logger2.info("[Remember] Schema processed successfully", {
nodes: schema.length,
connections: connections.length,
timestamp: new Date(timestamp2).toISOString()
});
const actualEngramId = engramId || engram.id;
if (actualEngramId) {
for (const word of schema) {
const cue = this.network.cues.get(word);
if (cue) {
if (!cue.memories) {
cue.memories = /* @__PURE__ */ new Set();
}
cue.memories.add(actualEngramId);
logger2.debug("[Remember] Added engram reference", {
cue: word,
engramId: actualEngramId,
totalReferences: cue.memories.size
});
}
}
}
return {
processed: schema.length,
connections,
timestamp: timestamp2,
engramId: actualEngramId
};
}
};
module2.exports = Remember;
}
});
// src/cognition/ActivationStrategy.js
var require_ActivationStrategy = __commonJS({
"src/cognition/ActivationStrategy.js"(exports2, module2) {
"use strict";
init_cjs_shims();
var logger2 = require("@promptx/logger");
var ActivationStrategy = class {
constructor(options = {}) {
this.name = "base";
this.options = options;
}
/**
* 决定如何激活节点
*
* 子类必须实现此方法
*
* @param {ActivationContext} context - 激活上下文
* @returns {Object} 激活决策
* @returns {boolean} returns.shouldActivate - 是否应该激活
* @returns {Array} returns.edges - 要激活的边列表
*/
activate(context) {
throw new Error("ActivationStrategy.activate() must be implemented");
}
/**
* 判断是否继续激活
*
* @param {ActivationContext} context - 激活上下文
* @returns {boolean} true继续,false停止
*/
shouldContinue(context) {
return true;
}
/**
* 应用衰减或其他周期性操作
*
* @param {ActivationContext} context - 激活上下文
*/
applyDecay(context) {
}
};
var HippocampalActivationStrategy = class extends ActivationStrategy {
constructor(options = {}) {
super(options);
this.name = "hippocampal";
this.firingThreshold = options.firingThreshold || 0.1;
this.synapticDecay = options.synapticDecay || 0.9;
this.inhibitionFactor = options.inhibitionFactor || 0.1;
this.maxCycles = options.maxCycles || 10;
this.cycleDecay = options.cycleDecay || 0.9;
this.frequencyBoost = options.frequencyBoost || 0.1;
this.weightStrategy = options.weightStrategy || null;
logger2.debug("[HippocampalActivationStrategy] Initialized", {
firingThreshold: this.firingThreshold,
synapticDecay: this.synapticDecay,
maxCycles: this.maxCycles
});
}
/**
* 决定如何激活节点
*
* @param {ActivationContext} context - 激活上下文
* @returns {Object} 激活决策
*/
activate(context) {
var _a;
if (context.currentEnergy < this.firingThreshold) {
logger2.debug("[HippocampalActivationStrategy] Energy below threshold", {
word: (_a = context.sourceCue) == null ? void 0 : _a.word,
energy: context.currentEnergy,
threshold: this.firingThreshold
});
return { shouldActivate: false, edges: [] };
}
if (!context.sourceCue || !context.sourceCue.connections) {
return { shouldActivate: false, edges: [] };
}
let edges = Array.from(context.sourceCue.connections.entries()).map(([targetWord, weight]) => ({
targetWord,
weight,
frequency: context.getTargetFrequency(targetWord)
}));
const degree = edges.length;
const SAMPLE_SIZE = Math.min(
8,
// 最多采样8个(提高到8以增加扩散范围)
Math.max(3, Math.ceil(Math.log2(degree + 1)))
// 至少3个,对数增长
);
const sampledEdges = edges.sort((a, b) => b.weight - a.weight).slice(0, SAMPLE_SIZE);
const hubCompensation = 1 + Math.log(1 + degree) * 0.3;
const availableEnergy = context.currentEnergy * hubCompensation;
const energyPerEdge = availableEnergy * this.synapticDecay / Math.max(1, sampledEdges.length);
const processedEdges = sampledEdges.map((edge) => {
const freqBonus = 1 + Math.log(1 + edge.frequency) * this.frequencyBoost;
const transmittedEnergy = energyPerEdge * freqBonus;
const inhibition = 1 - this.inhibitionFactor * context.activatedNodes.size / 200;
const finalEnergy = transmittedEnergy * Math.max(0.5, inhibition);
return {
targetWord: edge.targetWord,
weight: edge.weight,
energy: finalEnergy,
frequency: edge.frequency,
shouldFire: finalEnergy >= this.firingThreshold
};
});
const activeEdges = processedEdges.filter(
(e) => e.shouldFire && !context.isActivated(e.targetWord)
);
logger2.debug("[HippocampalActivationStrategy] GraphSAGE activation", {
source: context.sourceCue.word,
sourceEnergy: context.currentEnergy,
degree,
sampleSize: SAMPLE_SIZE,
hubCompensation: hubCompensation.toFixed(2),
energyPerEdge: energyPerEdge.toFixed(3),
totalEdges: edges.length,
sampledEdges: sampledEdges.length,
activeEdges: activeEdges.length,
cycle: context.cycle
});
return { shouldActivate: true, edges: activeEdges };
}
/**
* 判断是否继续激活
*
* @param {ActivationContext} context - 激活上下文
* @returns {boolean} true继续,false停止
*/
shouldContinue(context) {
if (context.cycle >= this.maxCycles) {
logger2.debug("[HippocampalActivationStrategy] Max cycles reached", {
cycle: context.cycle,
maxCycles: this.maxCycles
});
return false;
}
let hasHighEnergyNode = false;
for (const [word, energy] of context.energyPool) {
if (energy >= this.firingThreshold) {
hasHighEnergyNode = true;
break;
}
}
if (!hasHighEnergyNode) {
logger2.debug("[HippocampalActivationStrategy] No high energy nodes", {
cycle: context.cycle,
poolSize: context.energyPool.size
});
}
return hasHighEnergyNode;
}
/**
* 应用能量衰减
*
* @param {ActivationContext} context - 激活上下文
*/
applyDecay(context) {
for (const [word, energy] of context.energyPool) {
const decayedEnergy = energy * this.cycleDecay;
if (decayedEnergy < 0.01) {
context.energyPool.delete(word);
} else {
context.energyPool.set(word, decayedEnergy);
}
}
logger2.debug("[HippocampalActivationStrategy] Applied decay", {
cycle: context.cycle,
remainingNodes: context.energyPool.size,
totalEnergy: Array.from(context.energyPool.values()).reduce((sum, e) => sum + e, 0).toFixed(2)
});
}
};
module2.exports = {
ActivationStrategy,
HippocampalActivationStrategy
};
}
});
// src/cognition/ActivationContext.js
var require_ActivationContext = __commonJS({
"src/cognition/ActivationContext.js"(exports2, module2) {
"use strict";
init_cjs_shims();
var ActivationContext = class {
/**
* 创建激活上下文
*
* @param {Object} params - 初始参数
* @param {Network} params.network - 认知网络
* @param {Cue} params.sourceCue - 当前源节点
* @param {number} params.depth - 当前深度(兼容旧代码)
* @param {number} params.currentEnergy - 当前节点能量
* @param {Set} params.activatedNodes - 已激活节点集
* @param {Map} params.energyPool - 节点能量池
* @param {number} params.cycle - 循环次数
* @param {Array} params.connections - 连接记录
*/
constructor(params = {}) {
this.network = params.network;
this.sourceCue = params.sourceCue || null;
this.depth = params.depth || 0;
this.currentEnergy = params.currentEnergy || 1;
this.activatedNodes = params.activatedNodes || /* @__PURE__ */ new Set();
this.energyPool = params.energyPool || /* @__PURE__ */ new Map();
this.cycle = params.cycle || 0;
this.connections = params.connections || [];
this.timestamp = params.timestamp || Date.now();
}
/**
* 获取目标节点的频率
*
* @param {string} targetWord - 目标词
* @returns {number} 频率值
*/
getTargetFrequency(targetWord) {
const targetCue = this.network.getCue(targetWord);
return (targetCue == null ? void 0 : targetCue.recallFrequency) || 0;
}
/**
* 检查节点是否已激活
*
* @param {string} word - 节点词
* @returns {boolean} 是否已激活
*/
isActivated(word) {
return this.activatedNodes.has(word);
}
/**
* 获取节点的当前能量
*
* @param {string} word - 节点词
* @returns {number} 能量值
*/
getNodeEnergy(word) {
return this.energyPool.get(word) || 0;
}
/**
* 设置节点能量
*
* @param {string} word - 节点词
* @param {number} energy - 能量值
*/
setNodeEnergy(word, energy) {
if (energy > 0) {
this.energyPool.set(word, energy);
} else {
this.energyPool.delete(word);
}
}
/**
* 累加节点能量
*
* @param {string} word - 节点词
* @param {number} energyToAdd - 要添加的能量
* @returns {number} 新的能量值
*/
addNodeEnergy(word, energyToAdd) {
const current = this.getNodeEnergy(word);
const newEnergy = current + energyToAdd;
this.setNodeEnergy(word, newEnergy);
return newEnergy;
}
/**
* 标记节点为已激活
*
* @param {string} word - 节点词
*/
markActivated(word) {
this.activatedNodes.add(word);
}
/**
* 记录连接
*
* @param {string} from - 源节点
* @param {string} to - 目标节点
* @param {number} weight - 连接权重
*/
recordConnection(from, to, weight) {
this.connections.push({ from, to, weight });
}
/**
* 增加循环计数
*/
incrementCycle() {
this.cycle++;
}
/**
* 获取统计信息
*
* @returns {Object} 统计信息
*/
getStatistics() {
return {
activatedNodes: this.activatedNodes.size,
totalEnergy: Array.from(this.energyPool.values()).reduce((sum, e) => sum + e, 0),
highEnergyNodes: Array.from(this.energyPool.entries()).filter(([_, energy]) => energy > 0.5).length,
connections: this.connections.length,
cycle: this.cycle
};
}
/**
* 转换为调试字符串
*
* @returns {string} 调试信息
*/
toString() {
const stats = this.getStatistics();
return `ActivationContext{cycle:${this.cycle}, activated:${stats.activatedNodes}, energy:${stats.totalEnergy.toFixed(2)}}`;
}
};
module2.exports = ActivationContext;
}
});
// src/cognition/Recall.js
var require_Recall = __commonJS({
"src/cognition/Recall.js"(exports2, module2) {
"use strict";
init_cjs_shims();
var logger2 = require("@promptx/logger");
var Recall = class {
/**
* @param {Network} network - 全局认知网络
* @param {Object} options - 可选配置
* @param {ActivationStrategy} options.activationStrategy - 激活策略
* @param {WeightStrategy} options.weightStrategy - 权重策略(用于归一化)
*/
constructor(network, options = {}) {
this.network = network;
this.weightStrategy = options.weightStrategy || null;
if (options.activationStrategy) {
this.activationStrategy = options.activationStrategy;
if (this.weightStrategy && typeof this.activationStrategy.setWeightStrategy === "function") {
this.activationStrategy.setWeightStrategy(this.weightStrategy);
}
} else {
const { HippocampalActivationStrategy } = require_ActivationStrategy();
this.activationStrategy = new HippocampalActivationStrategy({
weightStrategy: this.weightStrategy
});
}
logger2.debug("[Recall] Initialized", {
strategy: this.activationStrategy.name,
hasWeightStrategy: !!this.weightStrategy
});
}
/**
* 执行记忆检索
*
* @param {string|string[]} words - 起始词(单词或多词数组)
* @returns {Mind|null} 激活的认知网络
*/
execute(words) {
const wordList = Array.isArray(words) ? words : [words];
logger2.debug("[Recall] Starting recall", { words: wordList });
const validCues = [];
for (const word of wordList) {
const cue = this.network.cues.get(word);
if (cue) {
validCues.push({ word, cue });
} else {
logger2.warn("[Recall] Cue not found", { word });
}
}
if (validCues.length === 0) {
logger2.warn("[Recall] No valid cues found", { words: wordList });
return null;
}
const Cue = require_Cue();
const virtualMind = new Cue("mind");
const initialEnergy = validCues.length > 5 ? 1 : 1 / validCues.length;
const energyPool = /* @__PURE__ */ new Map();
const activatedNodes = /* @__PURE__ */ new Set();
for (const { word, cue } of validCues) {
virtualMind.connections.set(word, initialEnergy);
energyPool.set(word, initialEnergy);
activatedNodes.add(word);
logger2.debug("[Recall] Added center cue", {
word,
energy: initialEnergy,
outDegree: cue.connections.size,
frequency: cue.recallFrequency || 0
});
}
logger2.info("[Recall] Multi-center recall initialized", {
centerCount: validCues.length,
energyPerCenter: initialEnergy,
totalEnergy: initialEnergy * validCues.length
});
const Mind = require_Mind();
const mind = new Mind(virtualMind);
for (const word of activatedNodes) {
mind.addActivatedCue(word, 1);
mind.addConnection("mind", word, initialEnergy, Date.now());
}
const ActivationContext = require_ActivationContext();
const context = new ActivationContext({
network: this.network,
sourceCue: validCues[0].cue,
// 兼容性:保留第一个作为初始sourceCue
energyPool,
activatedNodes,
connections: []
});
const startTime = Date.now();
while (this.activationStrategy.shouldContinue(context)) {
const newActivations = /* @__PURE__ */ new Map();
for (const [word, energy] of context.energyPool) {
const sourceCue = this.network.getCue(word);
if (!sourceCue) continue;
context.sourceCue = sourceCue;
context.currentEnergy = energy;
const { shouldActivate, edges } = this.activationStrategy.activate(context);
if (shouldActivate && edges.length > 0) {
logger2.debug("[Recall] Activating from node", {
source: word,
energy: energy.toFixed(3),
edgeCount: edges.length,
cycle: context.cycle
});
for (const edge of edges) {
const currentEnergy = newActivations.get(edge.targetWord) || 0;
const totalEnergy = currentEnergy + edge.energy;
newActivations.set(edge.targetWord, totalEnergy);