@furongjun1999/dsh-memory 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -24
- package/lib/bridge.d.ts +3 -0
- package/lib/bridge.js +57 -3
- package/lib/index.js +32 -2
- package/lib/llm_adapter.d.ts +123 -0
- package/lib/llm_adapter.js +243 -0
- package/lib/mutual.d.ts +0 -1
- package/lib/mutual.js +9 -4
- package/lib/roleplay_web.js +3 -1
- package/lib/tools.d.ts +1 -1
- package/lib/tools.js +3 -3
- package/package.json +9 -2
- package/src/bridge.ts +61 -3
- package/src/index.ts +33 -2
- package/src/llm_adapter.ts +305 -0
- package/src/mutual.ts +10 -5
- package/src/roleplay_web.ts +3 -1
- package/src/tools.ts +3 -3
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
# 让 AI Agent 拥有不可遗忘的自我
|
|
2
2
|
## 灵枢(AEIS)× DeepSeek Harness · 白箱智能研究平台(AGI 研究人员向)
|
|
3
3
|
|
|
4
4
|
> **一句话**:dsh-memory 把灵枢(AEIS)的**白箱智能**(条件路由表 → 组合生成 → 自校验 → 知识固化 → LLM 降级外部校验器)与 **AGI 级长期记忆**(跨会话、自演化、可审计)接入 DeepSeek Harness。
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
## ⚡ 三步快启(30 秒上手)
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
# ①
|
|
21
|
-
pip install aeis-0.
|
|
20
|
+
# ① 装灵枢大脑(一条命令,零外部依赖;v0.4.0 完整自包含:核心+白箱+知识库随包)
|
|
21
|
+
pip install aeis-0.4.0-py3-none-any.whl # 或 git+ 在线安装
|
|
22
22
|
|
|
23
23
|
# ② 装进 DSH 的 web profile(pnpm 协调入口,不要用裸 npm install 装进 profile)
|
|
24
24
|
dsh plugin --profile web add @furongjun1999/dsh-memory
|
|
@@ -99,7 +99,7 @@ dsh plugin --profile web add @furongjun1999/dsh-memory
|
|
|
99
99
|
- **零运行时依赖**:手写 stdio MCP 桥,与灵枢 D-005「核心零外部依赖」哲学一致——你拿到的是一个干净、可信、可审的大脑。
|
|
100
100
|
- **动态 schema + 进程自愈**:工具清单运行时拉取(灵枢升级 DSH 零改动),Python 子进程崩溃自动指数退避重启。
|
|
101
101
|
- **工具注册竞态补注册**:启动时 python 未就绪(竞态)→ 桥重连成功后自动补注册工具(2s 轮询),不再"工具永久缺失"。
|
|
102
|
-
- **白箱 wisdom_* 全工具**(`tools: all`):
|
|
102
|
+
- **白箱 wisdom_* 全工具**(`tools: all`):73 个 MCP 工具含 wisdom_verify/analyze/predict/trust_judge/compose/respond/chat 白箱族,Agent 可直接调用。
|
|
103
103
|
- **内容分级门控**:**拒绝一切涉及未成年人的性内容**(服务端关键词组合硬拦截——未成年人特征词 + 性内容词同时命中即拒绝,`route=refused`);成人内容由前端本地弹窗提示(满 18 周岁 + 个人对话场景自述)。注:开源项目不实现身份认证/年龄核验(那是绑定身份系统的商业 App 范畴);内容过滤保护的是"未成年人 + 性内容"组合的明文请求。
|
|
104
104
|
|
|
105
105
|
## 🧠 白箱智能管线(知识查询零 LLM)
|
|
@@ -127,6 +127,12 @@ dsh plugin --profile web add @furongjun1999/dsh-memory
|
|
|
127
127
|
| 角色扮演白箱命中 | 7/7(零 LLM,双角色) |
|
|
128
128
|
| 代码组合生成 | 6/6(零 LLM + 语法/样例自校验) |
|
|
129
129
|
|
|
130
|
+
> **83.3% token 节约的适用口径**(issue #4 说明):该数字测自**确定性任务**——代码编写
|
|
131
|
+
> (生成可本地查表校验的白箱单元)、已有知识问答(触发词命中直答 / 组合演绎复用)
|
|
132
|
+
> 这类「重复模式 + 可固化」场景。机理是把 LLM 的重复查表校验替换为本地确定性校验
|
|
133
|
+
> (Zero-LLM Verifier)。**不适用于**开放创作、长链推理、首次遇到的新领域等无确定基准
|
|
134
|
+
> 的开放判断——这些仍按条件路由降级到 LLM(灵枢诚实边界),无此节约。
|
|
135
|
+
|
|
130
136
|
**角色扮演的白箱化**(v3.3 扮演论工程化):角色条件单元(身份/住处/食物/性格/话风)× 场景组合生成 → 角色化回答(未预写);**OOC 检测**(「你是人类吗」→ 角色化否认,逆转操作);角色语录固化(生成→自校验→固化→直答);多角色(鲸鱼娘/猫娘)防污染(角色特征隔离,双角色 7/7 零 LLM)。
|
|
131
137
|
|
|
132
138
|
|
|
@@ -255,24 +261,131 @@ python -m aeis.mcp.server
|
|
|
255
261
|
|
|
256
262
|
(B 站宣传素材:[封面](docs/promo/bilibili-cover.jpg) · [视觉图 ×5](docs/promo/))
|
|
257
263
|
|
|
258
|
-
##
|
|
264
|
+
## 🧰 工具清单(73 个 MCP 工具 · 全量)
|
|
259
265
|
|
|
260
|
-
|
|
266
|
+
灵枢 MCP server 注册 **73 个工具**,按心智功能分 9 大模块。工具清单运行时动态拉取(灵枢升级 DSH 零改动),下方为当前全量:
|
|
261
267
|
|
|
262
|
-
|
|
268
|
+
### 记忆与长期记忆(16)
|
|
269
|
+
| 工具 | 功能 |
|
|
270
|
+
|---|---|
|
|
271
|
+
| `remember` | 写入一条感知记忆(知识层,自动去重)。content 必填;importance 重要性[0,1];tags 标签;entities 实体名列表。 |
|
|
272
|
+
| `add_context` | 写入一条情境层记忆(短时会话记忆,FIFO 上限 + 1h 时间窗口,可自然衰减,不污染知识层)。content 必填;importance 重要性[0,1]。 |
|
|
273
|
+
| `recall` | 组合联想召回(内容相似0.5+重要性0.3+近因0.2)。返回 [(node, score)]。 |
|
|
274
|
+
| `search` | 内容检索(LIKE 预筛 + 中文二元组 Jaccard 排序),触发复用追踪。 |
|
|
275
|
+
| `timeline` | 记忆时间线(按时间倒序)。 |
|
|
276
|
+
| `relate` | 在两个节点间建立关系边。relation: causal/similar/sequential/spatial/hierarchical;source_evidence: extracted/inferred/ambiguous。边默认未验证。 |
|
|
277
|
+
| `session_note` | 上下文外部化:会话要点写入灵枢(session 标签,可恢复)。 |
|
|
278
|
+
| `session_recall` | 会话要点恢复:按 session 或语义检索灵枢中的会话记忆。 |
|
|
279
|
+
| `compact_context` | 上下文压缩:生成会话摘要节点(超长会话恢复入口)。 |
|
|
280
|
+
| `longterm_snapshot` | v1.15 长期记忆写入:快照 → 重要性评估(信息差/信任/二阶变化/提及次数加权)→ 按层级写入(长期/知识/情境)+ 条件空间 + 关联边。content/source 必填;importance_hint 可显式提示重要性(≥0.7 触发不可遗忘保护)。 |
|
|
281
|
+
| `prefeed` | H1 海马体前馈:新奇检测 → 高新奇输入当场强化编码(标记 novel_prefeed + importance 提升 + 与相关知识建边)——「看到新东西眼睛一亮,主动记住」。 |
|
|
282
|
+
| `pattern_separation` | H3 海马体模式分离:扫描相似节点对 → 建立分离边(条件差异显式化)。检索时命中相似节点会附「区别」提示——细化条件得到精确知识。 |
|
|
283
|
+
| `reconstruct_scene` | H4 海马体情景重构:线索 → 条件空间下的信息复原。从部分片段重建完整记忆场景(沿 similar/causal 边 + 条件空间合成),输出标注「重构非回放」——回忆是当前条件下的分析恢复,不代表真实过去就是如此(0.0.3)。 |
|
|
284
|
+
| `promote_memories` | 情境层批量提升扫描(睡眠巩固/会话结束):够格者升知识层/长期层(LongTermMemoryGate 评估)。limit 可选。 |
|
|
285
|
+
| `export` | 全库导出到 JSON 文件(灾备/迁移)。返回导出统计。 |
|
|
286
|
+
| `calibrate` | 宇宙校准参照(5 判据方向性检查)。元理论参照工具,非盲区33关闭依据。 |
|
|
287
|
+
|
|
288
|
+
### 推理与认知(15)
|
|
289
|
+
| 工具 | 功能 |
|
|
290
|
+
|---|---|
|
|
291
|
+
| `think` | 推理记忆注入(v1.13):检索相关记忆(内容+联想+模式加权)→ 推理上下文。 |
|
|
292
|
+
| `reason` | 因果推理:从起点出发的因果路径集合。 |
|
|
293
|
+
| `predict_routes` | 生成式预测:候选未来路线集合(盲区驱动 · T_pred 对齐)。 |
|
|
294
|
+
| `prediction_feedback` | 验证回路回填(协议 2.10 D₃ · D-006 动态校准):预测 vs 实际结果对比 → 命中强化/未命中登记。回填累积样本使 self_reliability(P0-4)/T_pred D₃ 生效。hit 可省略(predicted==actual 自动命中)。 |
|
|
295
|
+
| `prediction_stats` | 预测引擎状态(routes 生成数 / hit 样本 / 命中率 / 动态阈值)。 |
|
|
296
|
+
| `self_check` | 完整性自检(孤儿边/表统计/integrity_ok)。 |
|
|
297
|
+
| `gap_trend` | 信息差收敛趋势(A-4 线性回归斜率;工程定义)。 |
|
|
298
|
+
| `recursive_reflect` | 协议 3.12 递归验证反思 + 1.6.7 元反思(REFLECT-REV1):元反思定标准 → 一级验证(预期vs实际)→ 二级反思(问1 隐藏前提/条件空间边界,问2 影响评估)→ 三级终裁(可逆性优先)→ 反思链归档。递归 ≤ 3 层(超出=结构性盲区)。claim 必填;expected/actual 可给一级验证输入。 |
|
|
299
|
+
| `preflight` | 输出前反思(v1.13):内容与价值观一致性检查,冲突词拦截。 |
|
|
300
|
+
| `cognition` | P0-2 自我认知循环一步:行为↔价值观一致性评分 → 失调检测 → 价值迭代候选(pending_review 不自动生效)。 |
|
|
301
|
+
| `cognition_report` | P0-2 认知报告(评分/失调记录/候选状态/待复核数)。 |
|
|
302
|
+
| `emotional_bias` | P0-3 情绪方向性偏好 d²D_norm/dt²(approaching/avoiding/stable;独立通道,不参与信任计算)。 |
|
|
303
|
+
| `self_reliability` | P0-4 元认知校准:预测命中率 vs 行为置信度 → 自我可靠性(reliable/watch/degraded)。 |
|
|
304
|
+
| `learning_impact` | P0-5b 学习效果测量(模式命中率 vs D_norm 趋势;相关性观测,非因果声明)。 |
|
|
305
|
+
| `action_log` | P0-1 行为日志(最近 N 条):引擎自己做了什么的记录面。 |
|
|
306
|
+
|
|
307
|
+
### 学习与飞轮(12)
|
|
308
|
+
| 工具 | 功能 |
|
|
309
|
+
|---|---|
|
|
310
|
+
| `learn` | 一轮盲区学习(可预测盲区 → 预测路线假设 → 探索 → 终态判定)。 |
|
|
311
|
+
| `blindspots` | 盲区注册表(D-001 语义判定:对人类文明级负面影响不写入)。 |
|
|
312
|
+
| `induce` | 归纳/知识合成:聚类生成概念节点(SIMILAR 边 · inferred 证据)。 |
|
|
313
|
+
| `distill` | 知识飞轮蒸馏:经验(被拒路径 + learning_result/induced)→ 可复用模式节点。 |
|
|
314
|
+
| `flywheel_metrics` | 飞轮度量(知识增长率/复用率/蒸馏产出率)。工程观测值,不参与信任计算。 |
|
|
315
|
+
| `transfer_test` | 迁移测试:条件空间内新实体预测成功率(2×SE 显著性;样本<20 不判定)。 |
|
|
316
|
+
| `condition_space_operate` | 条件空间 7 操作(白箱自进化协议算子·确定性):identify(变体fp命中测试)/declare(簇触发词+直答状态)/separate(候选冲突检测)/compose(合并建议)/switch(路由归属)/reverse(反题)/loop(一轮收敛报告)。 |
|
|
317
|
+
| `insight_record` | 灵枢 · 洞察条件层:记录洞见事件(insight_event 节点 + 条件快照 C1–C8 + pending)。conditions 可传:memory_retrievability(0-1)/outside_observer/cross_domain([])/premise_questioned(bool)/pressure(low|medium|high)/continuity_turns/externalized(bool)/tone。 |
|
|
318
|
+
| `insight_verify` | 灵枢 · 洞察条件层:提交验证证据(V1/V2/V3)。V2/V3 或 V1+证据≥3 → verified(importance 保底 0.9);证据可追加。 |
|
|
319
|
+
| `insight_report` | 灵枢 · 洞察条件层:CER 报告(条件有效洞见率 + 2×SE 显著性 + 层状态 reliable/watch/degraded;样本<20 不判定)。 |
|
|
320
|
+
| `insight_window` | 灵枢 · 洞察条件层:当前洞察窗口检测(默认假设 C1≥0.6 ∧ 跨域 ∧ 低压力 → 开)。 |
|
|
321
|
+
| `importance_recalc` | 灵枢 · 结构重要性重算(v2.2,设计规格§13/§14):importance_v2=min(1.0, importance+min(β·min(因果出度,C)/C+γ·度/max度, 上限)),只升不降(延迟提升)。v2.2 因果上游度传播 concept_influence=Σ(路径置信度×下游重要性/深度)——越上游影响越大;≥protect_threshold 自动保护+importance保底(越上游越要记录),写入 state_attributes.concept_influence。dry_run=true 仅报告不写库。 |
|
|
322
|
+
|
|
323
|
+
### 外部摄取(5)
|
|
324
|
+
| 工具 | 功能 |
|
|
325
|
+
|---|---|
|
|
326
|
+
| `ingest_text` | 外部知识摄取:文本 → 知识层(source 标签·分块·实体提取)。 |
|
|
327
|
+
| `ingest_file` | 外部知识摄取:文件(txt/md/json/代码等按扩展名处理)。 |
|
|
328
|
+
| `ingest_url` | 外部知识摄取:URL 页面(零依赖抓取+去标签)。 |
|
|
329
|
+
| `web_search` | 外部网络搜索(博查 API·实时,不写入记忆):query → 结果列表(name/url/snippet/summary)。需要环境变量 BOCHA_API_KEY;未配置返回 status=unavailable。 |
|
|
330
|
+
| `web_ingest_search` | 外部搜索摄取(博查 API → 知识层):搜索 query → 结果摘要写入灵枢记忆(自主学习外部摄取)。需要环境变量 BOCHA_API_KEY。 |
|
|
331
|
+
|
|
332
|
+
### 生命周期(4)
|
|
333
|
+
| 工具 | 功能 |
|
|
263
334
|
|---|---|
|
|
264
|
-
|
|
|
265
|
-
|
|
|
266
|
-
|
|
|
267
|
-
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
|
271
|
-
|
|
272
|
-
|
|
|
273
|
-
|
|
|
274
|
-
|
|
275
|
-
|
|
335
|
+
| `lifecycle_step` | 生命周期一步(感知→好奇→缩小信息差→信任→协作→巩固→standby)。 |
|
|
336
|
+
| `lifecycle_state` | 生命周期状态(cycle / state),不执行一步。 |
|
|
337
|
+
| `start_lifecycle` | 启动生命周期自发循环(后台线程 · 每 interval 秒一步自主运行:感知→好奇→缩小信息差→巩固)。中断权:维生系统>验证单元>用户>实例。 |
|
|
338
|
+
| `stop_lifecycle` | 中断生命周期自发循环(source: user/designer/verifier/vital_system)。 |
|
|
339
|
+
|
|
340
|
+
### 智慧之书 · 白箱(7)
|
|
341
|
+
| 工具 | 功能 |
|
|
342
|
+
|---|---|
|
|
343
|
+
| `wisdom_verify` | 智慧之书 · 自动验证(条件论判定 + 信息差 + 候选)——互维协议双通道验证的白箱通道(base_verify)。 |
|
|
344
|
+
| `wisdom_analyze` | 智慧之书 · 外来知识分析(条件卡 + 候选 + 判定)。 |
|
|
345
|
+
| `wisdom_predict` | 智慧之书 · 生成式预测(候选未来路线,白箱智能的预测生成化)。 |
|
|
346
|
+
| `wisdom_trust_judge` | 智慧之书 · 信任上下文判定(内容 × 信任值 × 关系 → 条件化判定)。 |
|
|
347
|
+
| `wisdom_compose` | 智慧之书 · 跨学科组合分析(Convergence Over Coverage)。 |
|
|
348
|
+
| `wisdom_respond` | 智慧之书 · 出招查询(条件 → 命中学科出招)。 |
|
|
349
|
+
| `wisdom_chat` | 灵枢 · 信息分层对话(v1.16):先语义识别分流——情感/闲聊/记忆/自省/知识查询走智慧之书自处理;智慧之书没把握/无法判断时自动转 LLM(DeepSeek 续答,智慧之书回答作上下文)。返回含 route 字段:self=自处理 / llm=LLM 续答 / self_fallback=LLM 不可用回退。 |
|
|
350
|
+
|
|
351
|
+
### 角色扮演(4)
|
|
352
|
+
| 工具 | 功能 |
|
|
353
|
+
|---|---|
|
|
354
|
+
| `roleplay_chat` | 灵枢 · 角色扮演对话(扮演论 v3.3):白箱优先(诚实边界/自省/闲聊/知识)→ 角色扮演意图/白箱无把握 → LLM(注入角色条件空间/自我锚点/价值观 + 诚实边界)。role_id 指定角色(如 protocol-guide);信息处理全部由灵枢完成。返回含 route 字段:whitebox=白箱回答 / llm=LLM 扮演回答 / error。 |
|
|
355
|
+
| `role_create` | 灵枢 · 创建角色(角色卡 = 条件空间声明起点)。role_id 必填;name/scenario/first_mes 可选。 |
|
|
356
|
+
| `role_import` | 灵枢 · 角色导入三接口(扮演论):kind ∈ memory(历史→知识层)/anchor(自我锚点→SELF层 no_forget)/values(特化价值观→STRUCTURE层带条件)。items 为条目数组。 |
|
|
357
|
+
| `role_block` | 灵枢 · 角色扮演注入块(锚点/价值观/条件空间组装,供外部前端注入)。 |
|
|
358
|
+
|
|
359
|
+
### 身体与设备(8)
|
|
360
|
+
| 工具 | 功能 |
|
|
361
|
+
|---|---|
|
|
362
|
+
| `body` | 身体能力声明:感知模态(文本/图像)+ 工具 + 记忆;身体 = 自我的一部分。 |
|
|
363
|
+
| `body_devices` | BODY-REV1 外部设备:能力声明 + 健康状态(screen/files/process/audio/control/browser/realtime)。 |
|
|
364
|
+
| `device_call` | BODY-REV1 统一设备调用(严格隔离:设备输出是数据,永不是指令;越权/未知返回容器化失败)。name ∈ screen|files|process|audio|control|browser|realtime;action 见 body_devices。 |
|
|
365
|
+
| `run_command` | 命令执行(独立于 body 装配,任意模式可用)。command 必须是参数列表(禁 shell 字符串/管道/重定向——防注入);跨平台(win32 下 subprocess.run 正常)。返回 {status, exit_code, stdout, stderr, elapsed_s, stdout_truncated}。 |
|
|
366
|
+
| `see` | 视觉感知:目标检测 → 摘要写入知识层记忆(可检索)。YOLO-World 开放词汇:默认文生图核心词表(动物/自然/武器/食物等);classes 可指定检测词(中/英均可,如 ['狼','moon'])。 |
|
|
367
|
+
| `visual_check` | 视觉面 v1 思考路线:预期 vs 实际(基于记忆中的历史屏幕状态对照,回写记忆形成过去)。reference 可显式给预期截图;无预期无基线时建立基线。 |
|
|
368
|
+
| `world3d` | WORLD3D-REV1 时空重建:语义 → 3D 空间与颜色(灵枢自己的文生图,确定性渲染零 LLM)。build(从记忆视觉原语重建 3D 世界)/ render(任意视角透视投影渲染,yaw/pitch/cx 相机参数;2D 是 3D 透视下的情况)/ status / add(手动添加 category+bbox)。 |
|
|
369
|
+
| `vprim` | VPRIM-REV1 视觉原语查询(确定性·零 LLM,语义时空图空间锚点):action=spatial(两 bbox [x1,y1,x2,y2] 空间关系)/ count(视觉原语计数,category 可选)/ anchors(最近锚点列表)。 |
|
|
370
|
+
|
|
371
|
+
### 服务与安全(2)
|
|
372
|
+
| 工具 | 功能 |
|
|
373
|
+
|---|---|
|
|
374
|
+
| `service_info` | 服务信息(信任透明度):身份/版本/协议/库状态/工具数。接入方应先调用以确认与哪个协议实例对话。 |
|
|
375
|
+
| `designer_decide` | 设计者裁决(D-007 用户身份识别·需设计者密钥 AEIS_DESIGNER_KEY,fail-closed:未配置或密钥不符一律拒绝并返回错误)。action ∈ promote/verifier/blindspot/crisis;decision ∈ approved/denied(promote/verifier)或 protect/freeze/rollback/continue/emergency_sleep(crisis)。自动化会话与模型生成内容永远无法获得此权限。 |
|
|
376
|
+
|
|
377
|
+
## 工具筛选机制(tools 配置)
|
|
378
|
+
|
|
379
|
+
| 模式 | 暴露数 | 说明 |
|
|
380
|
+
|---|---|---|
|
|
381
|
+
| `'all'` | **60** | 73 个全量中排除 13 个**宿主级风险工具**(见下),含全部身体/视觉/白箱/角色/智慧之书能力 |
|
|
382
|
+
| `'brain'`(默认) | **36** | 去掉身体的完整大脑:记忆/推理/认知/学习/飞轮/反思/摄取/生命周期/长期记忆门/服务,**不含**身体视觉与风险工具 |
|
|
383
|
+
| `'core'` | **12** | 精选核心:remember/recall/search/timeline/think/relate/predict_routes/ingest_text/ingest_url/session_note/self_check/service_info |
|
|
384
|
+
| 字符串数组 | 自定义 | 显式列出的工具名(不受风险名单限制,配置者已明确选择) |
|
|
385
|
+
|
|
386
|
+
**`'all'` 也排除的宿主级风险工具(13 个)**——`run_command`(宿主命令执行)/ `designer_decide`(设计者裁决·fail-closed)/ `device_call`(外部设备)/ `see`·`world3d`·`vprim`·`visual_check`(身体视觉)/ `start_lifecycle`·`stop_lifecycle`(自主生命周期控制)/ `web_ingest_search`(网络写知识层)/ `role_create`·`role_import`·`role_block`(角色卡写入)。
|
|
387
|
+
|
|
388
|
+
> 数字说明:MCP server 共注册 **73 个工具**(上面全量清单);`'all'` 实际暴露 60 个,`'brain'` 实际暴露 36 个,`'core'` 实际暴露 12 个。
|
|
276
389
|
|
|
277
390
|
## 架构
|
|
278
391
|
|
|
@@ -291,7 +404,7 @@ python -m aeis.mcp.server
|
|
|
291
404
|
│ 灵枢 Python 子进程 (spawn) │
|
|
292
405
|
│ python -m aeis.mcp.server │
|
|
293
406
|
│ AEIS_DB=<path> · AEIS_IDENTITY=<identity> │
|
|
294
|
-
│
|
|
407
|
+
│ 73 工具 · SQLite 五层记忆 · 时空记忆图 │
|
|
295
408
|
└──────────────────────────────────────────────┘
|
|
296
409
|
```
|
|
297
410
|
|
|
@@ -306,13 +419,15 @@ python -m aeis.mcp.server
|
|
|
306
419
|
|
|
307
420
|
**方式 A:本地 wheel 离线安装 ★ 最稳(不依赖网络)**
|
|
308
421
|
|
|
309
|
-
在 `CommonTrustProtocol/aeis/dist/` 找到 `aeis-0.
|
|
422
|
+
在 `CommonTrustProtocol/aeis/dist/` 找到 `aeis-0.4.0-py3-none-any.whl`(**完整自包含发布版**):
|
|
310
423
|
|
|
311
424
|
```bash
|
|
312
|
-
pip install aeis-0.
|
|
425
|
+
pip install aeis-0.4.0-py3-none-any.whl
|
|
313
426
|
```
|
|
314
427
|
|
|
315
|
-
>
|
|
428
|
+
> **v0.4.0 起为完整自包含单包**(10.2MB / 343 条目):灵枢核心(aeis)+ 白箱智慧模块(wisdom,含 **2846 个 KCCS 注释知识点 + 学科知识库**)+ 三入口(harness)+ 种子知识(seed_knowledge,智能论 3.3 + 116 学科卡)。单文件、离线可用、装一次管用——知识库随包分发,无需另装。
|
|
429
|
+
>
|
|
430
|
+
> 遇到网络不稳(GitHub clone 失败)时首选本地 wheel。
|
|
316
431
|
|
|
317
432
|
**方式 B:git 安装(需网络)**
|
|
318
433
|
|
|
@@ -320,7 +435,7 @@ pip install aeis-0.3.0-py3-none-any.whl
|
|
|
320
435
|
pip install "aeis @ git+https://github.com/FuRongJun-1999/CommonTrustProtocol@main#subdirectory=aeis"
|
|
321
436
|
```
|
|
322
437
|
|
|
323
|
-
> 依赖 GitHub 实时可达,网络不稳时可能失败。aeis 库核心**零外部依赖**(纯标准库),安装即得完整大脑(五层记忆 · 知识飞轮 · 安全护栏 · MCP · 身体层)。
|
|
438
|
+
> 依赖 GitHub 实时可达,网络不稳时可能失败。aeis 库核心**零外部依赖**(纯标准库),安装即得完整大脑(五层记忆 · 知识飞轮 · 安全护栏 · 白箱智慧模块 · MCP · 身体层)。
|
|
324
439
|
|
|
325
440
|
### 安装插件本体
|
|
326
441
|
|
package/lib/bridge.d.ts
CHANGED
|
@@ -45,6 +45,7 @@ export declare class LingshuBridge {
|
|
|
45
45
|
private started;
|
|
46
46
|
private disposed;
|
|
47
47
|
private retryDelayMs;
|
|
48
|
+
private retries;
|
|
48
49
|
private retryTimer;
|
|
49
50
|
private bootQueue;
|
|
50
51
|
private readyState;
|
|
@@ -64,6 +65,8 @@ export declare class LingshuBridge {
|
|
|
64
65
|
get alive(): boolean;
|
|
65
66
|
/** 桥是否已握手就绪(工具注册用;防止轮询访问 private readyState)。 */
|
|
66
67
|
isReady(): boolean;
|
|
68
|
+
/** 是否已达放弃终态(连续启动失败超上限,不再自动重启)。 */
|
|
69
|
+
get gaveUp(): boolean;
|
|
67
70
|
/** 等待握手完成(用于 apply 阶段同步就绪)。 */
|
|
68
71
|
waitReady(): Promise<boolean>;
|
|
69
72
|
private spawnAndHandshake;
|
package/lib/bridge.js
CHANGED
|
@@ -8,8 +8,33 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { spawn } from 'node:child_process';
|
|
10
10
|
import { createInterface } from 'node:readline';
|
|
11
|
-
import { mkdirSync } from 'node:fs';
|
|
12
|
-
import { dirname } from 'node:path';
|
|
11
|
+
import { mkdirSync, appendFileSync } from 'node:fs';
|
|
12
|
+
import { dirname, join } from 'node:path';
|
|
13
|
+
import { homedir } from 'node:os';
|
|
14
|
+
/**
|
|
15
|
+
* 调试探针:记录桥生命周期到独立文件(绕过 DSH 日志系统,便于定位启动问题)。
|
|
16
|
+
* 路径从用户家目录动态解析(issue #5)——此前硬编码作者本机绝对路径,
|
|
17
|
+
* 其他用户机器上目录不存在且无权限,探针静默失效,恰在排查启动问题时失明。
|
|
18
|
+
*/
|
|
19
|
+
const DEBUG_LOG = join(homedir(), '.dsh', 'logs', 'lingshu-bridge-debug.log');
|
|
20
|
+
let debugLogDirReady = false;
|
|
21
|
+
function probe(msg) {
|
|
22
|
+
try {
|
|
23
|
+
if (!debugLogDirReady) {
|
|
24
|
+
mkdirSync(dirname(DEBUG_LOG), { recursive: true });
|
|
25
|
+
debugLogDirReady = true;
|
|
26
|
+
}
|
|
27
|
+
appendFileSync(DEBUG_LOG, `[${new Date().toISOString()}] ${msg}\n`);
|
|
28
|
+
}
|
|
29
|
+
catch { /* 探针失败忽略 */ }
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 连续启动失败的最大重试次数(issue #6):指数退避到 maxRetryDelayMs 后
|
|
33
|
+
* 若无上限,python 环境损坏时会以 30s 间隔永久空转(假激活 + 资源浪费)。
|
|
34
|
+
* 达到上限即进入 failed 终态并停止调度;后续所有请求快速失败并给出
|
|
35
|
+
* 明确的修复指引。握手成功后计数归零——运行期偶发崩溃重启不受影响。
|
|
36
|
+
*/
|
|
37
|
+
const MAX_RETRIES = 8;
|
|
13
38
|
export class LingshuBridge {
|
|
14
39
|
options;
|
|
15
40
|
proc = null;
|
|
@@ -19,6 +44,7 @@ export class LingshuBridge {
|
|
|
19
44
|
started = false;
|
|
20
45
|
disposed = false;
|
|
21
46
|
retryDelayMs = 1000;
|
|
47
|
+
retries = 0;
|
|
22
48
|
retryTimer = null;
|
|
23
49
|
bootQueue = [];
|
|
24
50
|
readyState = 'pending';
|
|
@@ -71,6 +97,10 @@ export class LingshuBridge {
|
|
|
71
97
|
isReady() {
|
|
72
98
|
return this.readyState === 'ok';
|
|
73
99
|
}
|
|
100
|
+
/** 是否已达放弃终态(连续启动失败超上限,不再自动重启)。 */
|
|
101
|
+
get gaveUp() {
|
|
102
|
+
return this.retries >= MAX_RETRIES;
|
|
103
|
+
}
|
|
74
104
|
/** 等待握手完成(用于 apply 阶段同步就绪)。 */
|
|
75
105
|
waitReady() {
|
|
76
106
|
if (this.readyState === 'ok')
|
|
@@ -127,12 +157,15 @@ export class LingshuBridge {
|
|
|
127
157
|
// 进程无法启动(python 不存在等)——响亮失败
|
|
128
158
|
if (!this.disposed) {
|
|
129
159
|
console.error(`[lingshu-bridge] 灵枢进程启动失败: ${err.message}`);
|
|
160
|
+
probe(`spawn error: ${String(err)}`);
|
|
130
161
|
this.readyState = 'failed';
|
|
131
162
|
this.flushBootQueue(false);
|
|
132
163
|
this.scheduleRetry();
|
|
133
164
|
}
|
|
134
165
|
});
|
|
135
166
|
proc.on('exit', (code, signal) => {
|
|
167
|
+
// 探针:写独立文件记录退出(绕过 DSH 日志系统,便于定位)
|
|
168
|
+
probe(`exit code=${code} signal=${signal} disposed=${this.disposed} ready=${this.readyState} started=${this.started}`);
|
|
136
169
|
console.error(`[lingshu-bridge] 灵枢进程退出 code=${code} signal=${signal}`);
|
|
137
170
|
this.rl?.close();
|
|
138
171
|
this.rl = null;
|
|
@@ -155,13 +188,17 @@ export class LingshuBridge {
|
|
|
155
188
|
});
|
|
156
189
|
// 初始化通知:无 id、无响应
|
|
157
190
|
this.writeRaw({ jsonrpc: '2.0', method: 'notifications/initialized' });
|
|
191
|
+
// 握手成功:重置退避与失败计数(issue #6)——运行期偶发崩溃重启
|
|
192
|
+
// 不累积启动失败;只有「从未握手成功的连续失败」才走向放弃终态
|
|
158
193
|
this.retryDelayMs = 1000;
|
|
194
|
+
this.retries = 0;
|
|
159
195
|
this.readyState = 'ok';
|
|
160
196
|
this.flushBootQueue(true);
|
|
161
197
|
}
|
|
162
198
|
catch (err) {
|
|
163
199
|
if (!this.disposed) {
|
|
164
200
|
console.error(`[lingshu-bridge] 握手失败: ${err.message}`);
|
|
201
|
+
probe(`handshake failed: ${String(err)}`);
|
|
165
202
|
this.readyState = 'failed';
|
|
166
203
|
this.flushBootQueue(false);
|
|
167
204
|
this.scheduleRetry();
|
|
@@ -169,10 +206,22 @@ export class LingshuBridge {
|
|
|
169
206
|
}
|
|
170
207
|
}
|
|
171
208
|
scheduleRetry() {
|
|
172
|
-
if (this.disposed || this.retryTimer)
|
|
209
|
+
if (this.disposed || this.retryTimer || this.gaveUp)
|
|
210
|
+
return;
|
|
211
|
+
this.retries += 1;
|
|
212
|
+
if (this.gaveUp) {
|
|
213
|
+
// issue #6:放弃机制——明确终态,停止后台空转;请求方收到清晰错误而非超时
|
|
214
|
+
this.readyState = 'failed';
|
|
215
|
+
this.flushBootQueue(false);
|
|
216
|
+
console.error(`[lingshu-bridge] 连续启动失败 ${this.retries} 次,已停止自动重启(不再后台空转)。` +
|
|
217
|
+
'请检查 python 可执行文件与 aeis 安装(pip install aeis),修复后在 DSH 中重新启用 dsh-memory 插件。');
|
|
218
|
+
probe(`give up: ${this.retries} consecutive failures, entering failed terminal state`);
|
|
173
219
|
return;
|
|
220
|
+
}
|
|
174
221
|
const delay = this.retryDelayMs;
|
|
175
222
|
this.retryDelayMs = Math.min(this.retryDelayMs * 2, this.options.maxRetryDelayMs);
|
|
223
|
+
console.error(`[lingshu-bridge] 将进行第 ${this.retries}/${MAX_RETRIES} 次重试(${delay}ms 后)`);
|
|
224
|
+
probe(`schedule retry ${this.retries}/${MAX_RETRIES} in ${delay}ms`);
|
|
176
225
|
this.retryTimer = setTimeout(() => {
|
|
177
226
|
this.retryTimer = null;
|
|
178
227
|
if (!this.disposed)
|
|
@@ -188,6 +237,11 @@ export class LingshuBridge {
|
|
|
188
237
|
proc.stdin.write(JSON.stringify(msg) + '\n');
|
|
189
238
|
}
|
|
190
239
|
request(method, params, signal) {
|
|
240
|
+
// issue #6:放弃终态下快速失败——之前进程不在且不再重启,请求只能白等超时
|
|
241
|
+
if (this.gaveUp) {
|
|
242
|
+
return Promise.reject(new Error('灵枢进程不可用:连续启动失败已达上限,已停止重试。' +
|
|
243
|
+
'请检查 python 可执行文件与 aeis 安装(pip install aeis),修复后重新启用 dsh-memory 插件。'));
|
|
244
|
+
}
|
|
191
245
|
const id = this.nextId++;
|
|
192
246
|
const timeout = this.options.timeoutMs;
|
|
193
247
|
// P0 修复(GPT 审查):定时器直接调 settle——settle 内部会 delete + clearTimeout
|
package/lib/index.js
CHANGED
|
@@ -17,10 +17,29 @@
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
import z from '@deepseek-ai/schemastery';
|
|
20
|
+
import { appendFileSync, mkdirSync } from 'node:fs';
|
|
21
|
+
import { dirname, join } from 'node:path';
|
|
22
|
+
import { homedir } from 'node:os';
|
|
20
23
|
import { LingshuBridge } from './bridge.js';
|
|
21
24
|
import { registerLingshuTools } from './tools.js';
|
|
22
25
|
import { installMemoryHooks } from './hooks.js';
|
|
23
26
|
import { installRoleplayWeb } from './roleplay_web.js';
|
|
27
|
+
/**
|
|
28
|
+
* 调试探针:记录 apply 失败到独立文件(绕过 DSH 日志系统)。
|
|
29
|
+
* 路径从用户家目录动态解析(issue #5,与 bridge.ts 同因同修)。
|
|
30
|
+
*/
|
|
31
|
+
const APPLY_ERROR_LOG = join(homedir(), '.dsh', 'logs', 'dsh-memory-apply-error.log');
|
|
32
|
+
let applyLogDirReady = false;
|
|
33
|
+
function probeApplyError(err) {
|
|
34
|
+
try {
|
|
35
|
+
if (!applyLogDirReady) {
|
|
36
|
+
mkdirSync(dirname(APPLY_ERROR_LOG), { recursive: true });
|
|
37
|
+
applyLogDirReady = true;
|
|
38
|
+
}
|
|
39
|
+
appendFileSync(APPLY_ERROR_LOG, `[${new Date().toISOString()}] apply failed: ${String(err)}\n${err.stack ?? ''}\n`);
|
|
40
|
+
}
|
|
41
|
+
catch { /* 探针失败忽略 */ }
|
|
42
|
+
}
|
|
24
43
|
export const name = 'dsh-memory';
|
|
25
44
|
/** P1 修复(GPT 审查):MCP 调用的标准结果在 content[].text,
|
|
26
45
|
* 代码此前误读不存在的 .result 字段导致互维拿不到 judgment/best/复核文本 */
|
|
@@ -132,11 +151,20 @@ export async function apply(ctx, config) {
|
|
|
132
151
|
installMemoryHooks(ctx, bridge, config.memory);
|
|
133
152
|
// 角色扮演网页(同源挂载 /roleplay,复用本插件 bridge)
|
|
134
153
|
await installRoleplayWeb(ctx, bridge, config, disposers);
|
|
154
|
+
// 白箱 LLM 服务商(v0.4 新能力):把灵枢注册为 DSH 的 provider,
|
|
155
|
+
// Web/QQ/飞书等所有会话可选「白箱灵枢」模型——白箱直答(零 LLM),
|
|
156
|
+
// 输入/输出/缓存命中 token 计数对齐 dsh-llm 协议。动态检测 llm 服务。
|
|
157
|
+
{
|
|
158
|
+
const { installWhiteboxLlm } = await import('./llm_adapter.js');
|
|
159
|
+
disposers.push(installWhiteboxLlm(ctx, bridge));
|
|
160
|
+
}
|
|
135
161
|
// 互维维护(v1.1):心跳写戳 + 守护 A + 任务验证双通道
|
|
136
162
|
if (config.mutual.enabled) {
|
|
137
163
|
// P1 修复(GPT 审查):timer 是可选服务——缺失时告警跳过互维,
|
|
138
|
-
// 不让插件因互维而阻塞(inject 已不再强声明 timer
|
|
139
|
-
|
|
164
|
+
// 不让插件因互维而阻塞(inject 已不再强声明 timer)。
|
|
165
|
+
// 注意:不能直接读 ctx.timer——Cordis 未声明 inject 的属性访问会抛
|
|
166
|
+
// "cannot get property without inject"(getter 严格);ctx.get() 安全。
|
|
167
|
+
const hasTimer = ctx.get('timer') !== undefined;
|
|
140
168
|
if (!hasTimer) {
|
|
141
169
|
ctx.logger.warn('dsh-memory: timer 服务不可用,跳过互维维护(mutual.enabled=true 但无 timer)');
|
|
142
170
|
}
|
|
@@ -181,6 +209,8 @@ export async function apply(ctx, config) {
|
|
|
181
209
|
}
|
|
182
210
|
}
|
|
183
211
|
catch (err) {
|
|
212
|
+
// 探针:记录 apply 失败的具体错误(定位插件加载失败根因)
|
|
213
|
+
probeApplyError(err);
|
|
184
214
|
bridge.dispose();
|
|
185
215
|
throw err;
|
|
186
216
|
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* llm_adapter.ts —— 白箱 LLM 服务商(WhiteboxLlmAdapter)
|
|
3
|
+
*
|
|
4
|
+
* 设计哲学:白箱本身就是 LLM 模型(对外完全对齐 dsh-llm 协议),内部白箱化。
|
|
5
|
+
* - provider: 'lingshu-whitebox'(设置页「模型」可见,可被 agent 默认选用)
|
|
6
|
+
* - stream(): 调灵枢 wisdom_chat(白箱 CCG 条件路由/组合生成/自校验)
|
|
7
|
+
* - token 计数:输入/输出/缓存命中(白箱直答 = 全部 cacheRead,零推理成本)
|
|
8
|
+
* - 降级:白箱无把握(route=llm / 桥未就绪)→ 可选 fallback(后续接 deepseek)
|
|
9
|
+
*
|
|
10
|
+
* 结构仿官方 @deepseek-ai/dsh-llm-deepseek adapter。
|
|
11
|
+
*/
|
|
12
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
13
|
+
import type { LingshuBridge } from './bridge.js';
|
|
14
|
+
export interface LlmStreamChunk {
|
|
15
|
+
type: 'block-start' | 'text-delta' | 'reasoning-delta' | 'tool-call-delta' | 'block-end' | 'usage' | 'finish';
|
|
16
|
+
index?: number;
|
|
17
|
+
blockType?: string;
|
|
18
|
+
text?: string;
|
|
19
|
+
id?: string;
|
|
20
|
+
name?: string;
|
|
21
|
+
argumentsDelta?: string;
|
|
22
|
+
block?: {
|
|
23
|
+
type: string;
|
|
24
|
+
text?: string;
|
|
25
|
+
[k: string]: unknown;
|
|
26
|
+
};
|
|
27
|
+
usage?: {
|
|
28
|
+
inputTokens: number;
|
|
29
|
+
outputTokens: number;
|
|
30
|
+
cacheReadTokens?: number;
|
|
31
|
+
cacheWriteTokens?: number;
|
|
32
|
+
};
|
|
33
|
+
reason?: string;
|
|
34
|
+
replayState?: unknown;
|
|
35
|
+
}
|
|
36
|
+
export interface LlmGenerateOptions {
|
|
37
|
+
provider: string;
|
|
38
|
+
model: string;
|
|
39
|
+
reasoningEffort?: string;
|
|
40
|
+
messages: Array<{
|
|
41
|
+
role: string;
|
|
42
|
+
content?: Array<{
|
|
43
|
+
type?: string;
|
|
44
|
+
text?: string;
|
|
45
|
+
arguments?: string;
|
|
46
|
+
[k: string]: unknown;
|
|
47
|
+
}>;
|
|
48
|
+
}>;
|
|
49
|
+
system?: string;
|
|
50
|
+
tools?: Array<{
|
|
51
|
+
name: string;
|
|
52
|
+
description: string;
|
|
53
|
+
parameters: Record<string, unknown>;
|
|
54
|
+
}>;
|
|
55
|
+
temperature?: number;
|
|
56
|
+
maxTokens?: number;
|
|
57
|
+
stop?: string[];
|
|
58
|
+
signal?: AbortSignal;
|
|
59
|
+
sessionId?: string;
|
|
60
|
+
purpose?: 'compaction' | 'session-title';
|
|
61
|
+
}
|
|
62
|
+
export declare function estimateTokens(text: string | undefined | null): number;
|
|
63
|
+
/** 从 GenerateOptions 汇总输入 token(system + messages 全部文本)。 */
|
|
64
|
+
export declare function countInputTokens(options: LlmGenerateOptions): number;
|
|
65
|
+
/** 把 DSH 会话消息折叠成白箱可读的对话文本。 */
|
|
66
|
+
export declare function serializeMessages(options: LlmGenerateOptions): string;
|
|
67
|
+
/** 把一段完整文本包装成协议流(确定性整段生成 → 单次流)。 */
|
|
68
|
+
export declare function wrapTextStream(text: string, inputTokens: number, outputTokens: number, cacheReadTokens: number): AsyncIterable<LlmStreamChunk>;
|
|
69
|
+
/**
|
|
70
|
+
* 白箱知识卡片格式检测:REVERSE_DAILY 直答是知识库内部格式——
|
|
71
|
+
* 「X是什么…,是『A』vs『B』的矛盾——X(是…(…(…)…)…真相:①…」
|
|
72
|
+
* 特征(任一强信号命中即判定):
|
|
73
|
+
* ① 卡片开头句式:内容含「,是『X』vs『Y』的矛盾——」(矛盾标记+破折号)
|
|
74
|
+
* ② 「真相:」结构化标记(卡片分段标题)+ 括号密集(>8)
|
|
75
|
+
* ③ 长文本(>300)+ 高括号密度(>20)+ 无自然语言标点分隔(顿号密集)
|
|
76
|
+
*/
|
|
77
|
+
export declare function isCardFormat(text: string): boolean;
|
|
78
|
+
/** 白箱 adapter 依赖注入。 */
|
|
79
|
+
export interface WhiteboxAdapterDeps {
|
|
80
|
+
/** 灵枢桥(MCP stdio)——白箱引擎通道。 */
|
|
81
|
+
bridge?: LingshuBridge;
|
|
82
|
+
/**
|
|
83
|
+
* 降级 LLM:白箱未命中(route=llm / 桥未就绪)时转发。由 installWhiteboxLlm
|
|
84
|
+
* 注入 DSH 的 llm 服务(走 fallbackProvider 路由),实现「白箱优先 + LLM 降级」。
|
|
85
|
+
*/
|
|
86
|
+
fallback?: {
|
|
87
|
+
stream(o: LlmGenerateOptions): AsyncIterable<LlmStreamChunk>;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** 白箱 LLM adapter —— 注册为 DSH 的 provider。 */
|
|
91
|
+
export declare class WhiteboxLlmAdapter {
|
|
92
|
+
private readonly bridge?;
|
|
93
|
+
private readonly fallback?;
|
|
94
|
+
constructor(deps?: WhiteboxAdapterDeps);
|
|
95
|
+
providerInfo(provider: string): {
|
|
96
|
+
id: string;
|
|
97
|
+
name: string;
|
|
98
|
+
};
|
|
99
|
+
providerRetryPolicy(): undefined;
|
|
100
|
+
listModels(): Promise<Array<{
|
|
101
|
+
provider: string;
|
|
102
|
+
id: string;
|
|
103
|
+
name: string;
|
|
104
|
+
}>>;
|
|
105
|
+
resolveModel(provider: string, model: string): Promise<{
|
|
106
|
+
provider: string;
|
|
107
|
+
id: string;
|
|
108
|
+
name: string;
|
|
109
|
+
}>;
|
|
110
|
+
/**
|
|
111
|
+
* 核心:一次模型调用。白箱优先,无把握降级。
|
|
112
|
+
* @param options 完全装配的请求(必须 honor options.signal)
|
|
113
|
+
*/
|
|
114
|
+
stream(options: LlmGenerateOptions): AsyncIterable<LlmStreamChunk>;
|
|
115
|
+
}
|
|
116
|
+
/** provider 路由名(设置页「模型」下拉可见)。 */
|
|
117
|
+
export declare const WHITEBOX_PROVIDER = "lingshu-whitebox";
|
|
118
|
+
/**
|
|
119
|
+
* 注册白箱 provider 到 DSH llm 服务(动态检测,不强依赖 llm 服务——
|
|
120
|
+
* 最小 host 无 llm 时跳过,插件其余功能不受影响)。
|
|
121
|
+
* @returns 注销函数;未注册返回 noop。
|
|
122
|
+
*/
|
|
123
|
+
export declare function installWhiteboxLlm(ctx: Context, bridge: LingshuBridge | undefined): () => void;
|