amrita_plugin_memory 0.4.1__tar.gz → 0.5.0__tar.gz

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.
Files changed (35) hide show
  1. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/PKG-INFO +10 -10
  2. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/README.md +6 -6
  3. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/rethinking/__init__.py +1 -2
  4. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/rethinking/runner.py +19 -37
  5. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory.egg-info/PKG-INFO +10 -10
  6. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory.egg-info/SOURCES.txt +0 -1
  7. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory.egg-info/requires.txt +3 -3
  8. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/pyproject.toml +4 -4
  9. amrita_plugin_memory-0.4.1/amrita_plugin_memory/rethinking/nodes.py +0 -27
  10. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/LICENSE +0 -0
  11. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/__init__.py +0 -0
  12. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/cli.py +0 -0
  13. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/config.py +0 -0
  14. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/embed.py +0 -0
  15. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/embedding.py +0 -0
  16. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/keys.py +0 -0
  17. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/matchers.py +0 -0
  18. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/memo.py +0 -0
  19. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/migrations/21f55abc2b90_init.py +0 -0
  20. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/migrations/6004d221a7de_state.py +0 -0
  21. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/models.py +0 -0
  22. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/rethinking/_state.py +0 -0
  23. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/rethinking/backend.py +0 -0
  24. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/rethinking/consts.py +0 -0
  25. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/rethinking/hooks.py +0 -0
  26. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/rethinking/knowledge.py +0 -0
  27. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/rethinking/schemas.py +0 -0
  28. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/rethinking/tools.py +0 -0
  29. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/rethinking/types.py +0 -0
  30. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/tools.py +0 -0
  31. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory/vector.py +0 -0
  32. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory.egg-info/dependency_links.txt +0 -0
  33. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory.egg-info/entry_points.txt +0 -0
  34. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/amrita_plugin_memory.egg-info/top_level.txt +0 -0
  35. {amrita_plugin_memory-0.4.1 → amrita_plugin_memory-0.5.0}/setup.cfg +0 -0
@@ -1,17 +1,17 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amrita_plugin_memory
3
- Version: 0.4.1
3
+ Version: 0.5.0
4
4
  Summary: Amrita长期记忆插件
5
5
  Requires-Python: <3.14,>=3.10
6
6
  Description-Content-Type: text/markdown
7
7
  License-File: LICENSE
8
8
  Requires-Dist: aiohttp>=3.13.3
9
9
  Requires-Dist: aiologic>=0.16.0
10
- Requires-Dist: amrita-core>=0.8.5
11
- Requires-Dist: amrita>=1.3
10
+ Requires-Dist: amrita-core<2.0.0,>=1.0.0
11
+ Requires-Dist: amrita>=1.10
12
12
  Requires-Dist: chromadb>=1.5.8
13
13
  Requires-Dist: click>=8.1
14
- Requires-Dist: nonebot-plugin-amrita>=0.3.0
14
+ Requires-Dist: nonebot-plugin-amrita>=0.4.0
15
15
  Requires-Dist: nonebot-plugin-apscheduler>=0.5.0
16
16
  Requires-Dist: nonebot-plugin-localstore>=0.7.4
17
17
  Requires-Dist: nonebot-plugin-orm[default]>=0.8.2
@@ -165,7 +165,7 @@ L3 在代码中沿用历史标识符 `subconscious` / `rethinking`(避免破
165
165
  | `subconscious_*` 工具 | 巩固循环工具 | — |
166
166
  | 用户聊天 → `cancel_and_reschedule` | 任务负激活 | 专注任务时 DMN 被抑制 |
167
167
  | 静默期触发 `_run` | 空闲时活跃 | DMN 在无任务时活跃 |
168
- | 去重 / 压缩 / `MemoryLimiter` | 记忆巩固 | 海马 → 皮层的系统巩固 |
168
+ | 去重 / 压缩 / `ContextCompactor` | 记忆巩固 | 海马 → 皮层的系统巩固 |
169
169
  | 画像构建(`*_profile`) | 自传体记忆 | DMN 负责自我参照加工 |
170
170
  | 主动消息(`send_to_user`) | 心智游移 | 走神产生与自我相关的念头 |
171
171
  | 每轮数万 tokens | 静息高能耗 | DMN 占脑能耗约 20% |
@@ -287,7 +287,7 @@ $$\text{delay} = \min(\text{base} \times \text{multiplier}^{\text{penalty}-1},\
287
287
  | 阶段 | 内容 |
288
288
  | -------------- | ---------------------------------------------------------- |
289
289
  | 状态加载 | 从 `SubconsciousState` 表恢复 `total_runs` / 摘要窗口 |
290
- | 记忆限幅 | Core `MemoryLimiter` 截断超限消息并生成摘要 |
290
+ | 记忆限幅 | Core `ContextCompactor` 截断超限消息并生成摘要 |
291
291
  | ReAct 循环 | Agent 调用 `subconscious_*` 工具执行整理 |
292
292
  | 后处理 | 更新全局 usage、持久化元状态、重置惩罚、调度下次运行 |
293
293
 
@@ -304,12 +304,13 @@ $$\text{delay} = \min(\text{base} \times \text{multiplier}^{\text{penalty}-1},\
304
304
 
305
305
  ```mermaid
306
306
  flowchart TD
307
- LOAD_STATE --> JINJA2_RENDER --> LIMITING_MEMORY --> BUILD_MESSAGE --> REACT_BLOCK
307
+ LOAD_STATE --> NORMALIZE_MESSAGES --> COMPACT_HISTORY --> JINJA2_RENDER --> BUILD_MESSAGE --> REACT_BLOCK
308
308
  ```
309
309
 
310
310
  `SubconsciousRunner` 把 ChatObject 当数据容器,注入自定义 `SubconsciousBackend`
311
311
  (隔离的工具 + memory 后端)与 Core `ReActAgentStrategy`。
312
- `LIMITING_MEMORY` 在 Agent Loop 前运行 Core `MemoryLimiter`。
312
+ 工作流直接复用 Core 内置的 `REACT_ONLY`,其中的 `COMPACT_HISTORY` 节点在 Agent
313
+ Loop 前运行 Core `ContextCompactor`。压缩排在渲染之前,摘要才能进入本次请求的系统提示词。
313
314
 
314
315
  ---
315
316
 
@@ -473,7 +474,7 @@ flowchart TD
473
474
  | ---------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
474
475
  | L1 备忘录 | `UserMemo` 表(插件自有 ORM,主键 = uni_id) | LLM 维护的常驻用户元信息(≤ `memo_max_chars`) |
475
476
  | 循环元状态 | `SubconsciousState` 表(插件自有 ORM,uid=`amrita_memory`) | `total_runs`、`last_abstracts`、`pending_messages`、`knowledge_suggestions` |
476
- | Session 摘要缓存 | `LRUCache[int, str]`(最大 128 条) | session DB id → LLM 生成的摘要文本,避免重复调用 MemoryLimiter |
477
+ | Session 摘要缓存 | `LRUCache[int, str]`(最大 128 条) | session DB id → LLM 生成的摘要文本,避免重复调用 `ContextCompactor` |
477
478
  | 惩罚计数器 | 内存(不持久化) | `_penalty_count`:重启后从 0 开始 |
478
479
  | L2 记忆 | ChromaDB `amrita_user_memory` | 向量 + documents + metadatas(含嵌入指纹与分区键版本) |
479
480
  | 用户画像 | `data/amrita_plugin_memory/user_profile.md` | Markdown 文件,`summary---body` 格式,行级增量更新 |
@@ -649,7 +650,6 @@ amrita_plugin_memory/
649
650
  ├── types.py # TypedDict 定义
650
651
  ├── consts.py # 默认 Prompt 模板 / ensure_prompt_file
651
652
  ├── backend.py # SubconsciousBackend — 隔离的工具 + memory 后端
652
- ├── nodes.py # LIMITING_MEMORY 工作流节点
653
653
  ├── runner.py # SubconsciousRunner — 核心编排器
654
654
  ├── hooks.py # on_precompletion hook / 生命周期管理
655
655
  ├── tools.py # 20 个巩固循环工具 handler
@@ -146,7 +146,7 @@ L3 在代码中沿用历史标识符 `subconscious` / `rethinking`(避免破
146
146
  | `subconscious_*` 工具 | 巩固循环工具 | — |
147
147
  | 用户聊天 → `cancel_and_reschedule` | 任务负激活 | 专注任务时 DMN 被抑制 |
148
148
  | 静默期触发 `_run` | 空闲时活跃 | DMN 在无任务时活跃 |
149
- | 去重 / 压缩 / `MemoryLimiter` | 记忆巩固 | 海马 → 皮层的系统巩固 |
149
+ | 去重 / 压缩 / `ContextCompactor` | 记忆巩固 | 海马 → 皮层的系统巩固 |
150
150
  | 画像构建(`*_profile`) | 自传体记忆 | DMN 负责自我参照加工 |
151
151
  | 主动消息(`send_to_user`) | 心智游移 | 走神产生与自我相关的念头 |
152
152
  | 每轮数万 tokens | 静息高能耗 | DMN 占脑能耗约 20% |
@@ -268,7 +268,7 @@ $$\text{delay} = \min(\text{base} \times \text{multiplier}^{\text{penalty}-1},\
268
268
  | 阶段 | 内容 |
269
269
  | -------------- | ---------------------------------------------------------- |
270
270
  | 状态加载 | 从 `SubconsciousState` 表恢复 `total_runs` / 摘要窗口 |
271
- | 记忆限幅 | Core `MemoryLimiter` 截断超限消息并生成摘要 |
271
+ | 记忆限幅 | Core `ContextCompactor` 截断超限消息并生成摘要 |
272
272
  | ReAct 循环 | Agent 调用 `subconscious_*` 工具执行整理 |
273
273
  | 后处理 | 更新全局 usage、持久化元状态、重置惩罚、调度下次运行 |
274
274
 
@@ -285,12 +285,13 @@ $$\text{delay} = \min(\text{base} \times \text{multiplier}^{\text{penalty}-1},\
285
285
 
286
286
  ```mermaid
287
287
  flowchart TD
288
- LOAD_STATE --> JINJA2_RENDER --> LIMITING_MEMORY --> BUILD_MESSAGE --> REACT_BLOCK
288
+ LOAD_STATE --> NORMALIZE_MESSAGES --> COMPACT_HISTORY --> JINJA2_RENDER --> BUILD_MESSAGE --> REACT_BLOCK
289
289
  ```
290
290
 
291
291
  `SubconsciousRunner` 把 ChatObject 当数据容器,注入自定义 `SubconsciousBackend`
292
292
  (隔离的工具 + memory 后端)与 Core `ReActAgentStrategy`。
293
- `LIMITING_MEMORY` 在 Agent Loop 前运行 Core `MemoryLimiter`。
293
+ 工作流直接复用 Core 内置的 `REACT_ONLY`,其中的 `COMPACT_HISTORY` 节点在 Agent
294
+ Loop 前运行 Core `ContextCompactor`。压缩排在渲染之前,摘要才能进入本次请求的系统提示词。
294
295
 
295
296
  ---
296
297
 
@@ -454,7 +455,7 @@ flowchart TD
454
455
  | ---------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
455
456
  | L1 备忘录 | `UserMemo` 表(插件自有 ORM,主键 = uni_id) | LLM 维护的常驻用户元信息(≤ `memo_max_chars`) |
456
457
  | 循环元状态 | `SubconsciousState` 表(插件自有 ORM,uid=`amrita_memory`) | `total_runs`、`last_abstracts`、`pending_messages`、`knowledge_suggestions` |
457
- | Session 摘要缓存 | `LRUCache[int, str]`(最大 128 条) | session DB id → LLM 生成的摘要文本,避免重复调用 MemoryLimiter |
458
+ | Session 摘要缓存 | `LRUCache[int, str]`(最大 128 条) | session DB id → LLM 生成的摘要文本,避免重复调用 `ContextCompactor` |
458
459
  | 惩罚计数器 | 内存(不持久化) | `_penalty_count`:重启后从 0 开始 |
459
460
  | L2 记忆 | ChromaDB `amrita_user_memory` | 向量 + documents + metadatas(含嵌入指纹与分区键版本) |
460
461
  | 用户画像 | `data/amrita_plugin_memory/user_profile.md` | Markdown 文件,`summary---body` 格式,行级增量更新 |
@@ -630,7 +631,6 @@ amrita_plugin_memory/
630
631
  ├── types.py # TypedDict 定义
631
632
  ├── consts.py # 默认 Prompt 模板 / ensure_prompt_file
632
633
  ├── backend.py # SubconsciousBackend — 隔离的工具 + memory 后端
633
- ├── nodes.py # LIMITING_MEMORY 工作流节点
634
634
  ├── runner.py # SubconsciousRunner — 核心编排器
635
635
  ├── hooks.py # on_precompletion hook / 生命周期管理
636
636
  ├── tools.py # 20 个巩固循环工具 handler
@@ -1,12 +1,11 @@
1
1
  """潜意识推理循环(rethinking)"""
2
2
 
3
- from . import _state, backend, hooks, nodes, schemas, tools
3
+ from . import _state, backend, hooks, schemas, tools
4
4
 
5
5
  __all__ = [
6
6
  "_state",
7
7
  "backend",
8
8
  "hooks",
9
- "nodes",
10
9
  "schemas",
11
10
  "tools",
12
11
  ]
@@ -12,13 +12,12 @@ from amrita.plugins.chat.utils.libchat import add_usage
12
12
  from amrita_core import SuspendObjectStream
13
13
  from amrita_core.base.backend import BackendSlots
14
14
  from amrita_core.builtins.agent import ReActAgentStrategy
15
- from amrita_core.builtins.workflows import REACT_BLOCK
15
+ from amrita_core.builtins.workflows import REACT_ONLY
16
16
  from amrita_core.chatmanager import ChatObject
17
- from amrita_core.components.llm import JINJA2_RENDER
18
- from amrita_core.components.process import BUILD_MESSAGE, LOAD_STATE
17
+ from amrita_core.components.compaction import ContextCompactor
19
18
  from amrita_core.config import AmritaConfig, get_config
20
19
  from amrita_core.preset import ModelPreset
21
- from amrita_core.types import Message, UniResponseUsage
20
+ from amrita_core.types import CONTENT_LIST_TYPE, Message, UniResponseUsage
22
21
  from amrita_core.utils import gather_usage
23
22
  from jinja2 import Template
24
23
  from nonebot import logger
@@ -44,7 +43,6 @@ from .consts import (
44
43
  load_character_prompt,
45
44
  )
46
45
  from .knowledge import KnowledgeBaseManager
47
- from .nodes import LIMITING_MEMORY
48
46
  from .types import ProfileResult, SessionSummary
49
47
 
50
48
  _STATE_UID = "amrita_memory"
@@ -52,10 +50,8 @@ _LEGACY_REPO_UID = (
52
50
  "amrita_memory" # 旧版本元状态占用的 Bot Memory 表 uid(仅用于升级迁移)
53
51
  )
54
52
 
55
- # 工作流 = 加载状态 -> Jinja2 渲染 -> 记忆限幅 -> 构建消息 -> ReAct 循环
56
- _WORKFLOW = (
57
- LOAD_STATE >> JINJA2_RENDER >> LIMITING_MEMORY >> BUILD_MESSAGE >> REACT_BLOCK
58
- ).render()
53
+ # 工作流 = Core 内置 REACT_ONLY(已包含上下文压缩节点),不再自建
54
+ _WORKFLOW = REACT_ONLY.render()
59
55
 
60
56
 
61
57
  async def _ign_cb(*_, **__): ...
@@ -65,8 +61,8 @@ class SubconsciousRunner:
65
61
  """常驻推理循环运行器。
66
62
 
67
63
  使用 ChatObject 作为数据容器 + 标准 Agent 框架(ReActAgentStrategy)。
68
- LIMITING_MEMORY 节点在 Agent Loop 之前运行 MemoryLimiter 压缩会话消息。
69
- 元状态持久化使用独立的 SubconsciousState 表。
64
+ 工作流直接复用 Core 的 REACT_ONLY,其中的 COMPACT_HISTORY 节点在 Agent
65
+ Loop 之前压缩会话消息。元状态持久化使用独立的 SubconsciousState 表。
70
66
  """
71
67
 
72
68
  def __init__(self, config: SubconsciousConfig) -> None:
@@ -91,7 +87,7 @@ class SubconsciousRunner:
91
87
  """构建自定义 AmritaConfig —— 从全局拷贝并覆写本插件关心的字段。"""
92
88
  cfg = get_config().model_copy(deep=True)
93
89
  cfg.builtin.loop_reasoning_trigger = self._config.loop_detect_threshold
94
- cfg.llm.enable_memory_abstract = self._config.enable_memory_compress
90
+ cfg.llm.enable_compaction = self._config.enable_memory_compress
95
91
  return cfg
96
92
 
97
93
  async def start(self) -> None:
@@ -195,7 +191,7 @@ class SubconsciousRunner:
195
191
  finally:
196
192
  self._chat_obj = None
197
193
 
198
- # MemoryLimiter 在 workflow 中已经产出 chat_obj._di_memory.memory.abstract
194
+ # 压缩节点已在 workflow 中把摘要写入 chat_obj._di_memory.memory.abstract
199
195
  await self._post_process(chat_obj)
200
196
 
201
197
  @staticmethod
@@ -210,7 +206,7 @@ class SubconsciousRunner:
210
206
  # 1. 更新全局 usage(复用 Bot 的 InsightsModel 统计)
211
207
  await self._update_global_usage(chat_obj)
212
208
 
213
- # 2. 提取 MemoryLimiter 产出的摘要
209
+ # 2. 提取压缩节点产出的摘要
214
210
  mem = chat_obj._di_memory.memory
215
211
  if mem is not None and mem.abstract:
216
212
  self._last_abstracts.append(mem.abstract)
@@ -246,7 +242,7 @@ class SubconsciousRunner:
246
242
  """更新全局 InsightsModel usage,复用 Bot 的 add_usage 逻辑。
247
243
 
248
244
  chat_obj._di_resp.response 是 LLM 最终返回的 UniResponse,
249
- chat_obj._di_resp.extra_usage 是 MemoryLimiter 等组件累积的额外 token。
245
+ chat_obj._di_resp.extra_usage 是压缩等组件累积的额外 token。
250
246
  """
251
247
  try:
252
248
  resp_state = chat_obj._di_resp
@@ -480,10 +476,7 @@ class SubconsciousRunner:
480
476
  return []
481
477
 
482
478
  async def _summarize_session(self, session: MemorySessionsSchema) -> str:
483
- """用 MemoryLimiter 生成单个 session 的全会话摘要。"""
484
- from amrita_core.chatmanager.memory_limiter import MemoryLimiter
485
- from amrita_core.types import MemoryModel
486
-
479
+ """用 Core 的 ContextCompactor 生成单个 session 的全会话摘要。"""
487
480
  data = session.data
488
481
  if data is None:
489
482
  return "空会话"
@@ -498,24 +491,13 @@ class SubconsciousRunner:
498
491
  except (ValueError, OSError):
499
492
  date_str = str(created_at)
500
493
 
501
- memory = MemoryModel(messages=[], abstract="")
502
- for m in raw_messages:
503
- if isinstance(m, dict):
504
- memory.messages.append(Message.model_validate(m))
505
-
506
- async with MemoryLimiter(
507
- memory,
508
- Message(role="system", content=""),
509
- ) as lim:
510
- # 把所有消息放入 dropped_part -> 触发全量摘要
511
- lim._dropped_messages = list(memory.messages)
512
- memory.messages = []
513
- await lim._make_abstract()
514
- return (
515
- f"[{date_str}] {memory.abstract}"
516
- if memory.abstract
517
- else f"[{date_str}] 无法生成摘要"
518
- )
494
+ messages: CONTENT_LIST_TYPE = [
495
+ Message.model_validate(m) for m in raw_messages if isinstance(m, dict)
496
+ ]
497
+ if not messages:
498
+ return "空会话"
499
+ abstract = await ContextCompactor(config=get_config()).summarize(messages)
500
+ return f"[{date_str}] {abstract}" if abstract else f"[{date_str}] 无法生成摘要"
519
501
 
520
502
  async def _read_profile(
521
503
  self, start_line: int | None = None, end_line: int | None = None
@@ -1,17 +1,17 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amrita_plugin_memory
3
- Version: 0.4.1
3
+ Version: 0.5.0
4
4
  Summary: Amrita长期记忆插件
5
5
  Requires-Python: <3.14,>=3.10
6
6
  Description-Content-Type: text/markdown
7
7
  License-File: LICENSE
8
8
  Requires-Dist: aiohttp>=3.13.3
9
9
  Requires-Dist: aiologic>=0.16.0
10
- Requires-Dist: amrita-core>=0.8.5
11
- Requires-Dist: amrita>=1.3
10
+ Requires-Dist: amrita-core<2.0.0,>=1.0.0
11
+ Requires-Dist: amrita>=1.10
12
12
  Requires-Dist: chromadb>=1.5.8
13
13
  Requires-Dist: click>=8.1
14
- Requires-Dist: nonebot-plugin-amrita>=0.3.0
14
+ Requires-Dist: nonebot-plugin-amrita>=0.4.0
15
15
  Requires-Dist: nonebot-plugin-apscheduler>=0.5.0
16
16
  Requires-Dist: nonebot-plugin-localstore>=0.7.4
17
17
  Requires-Dist: nonebot-plugin-orm[default]>=0.8.2
@@ -165,7 +165,7 @@ L3 在代码中沿用历史标识符 `subconscious` / `rethinking`(避免破
165
165
  | `subconscious_*` 工具 | 巩固循环工具 | — |
166
166
  | 用户聊天 → `cancel_and_reschedule` | 任务负激活 | 专注任务时 DMN 被抑制 |
167
167
  | 静默期触发 `_run` | 空闲时活跃 | DMN 在无任务时活跃 |
168
- | 去重 / 压缩 / `MemoryLimiter` | 记忆巩固 | 海马 → 皮层的系统巩固 |
168
+ | 去重 / 压缩 / `ContextCompactor` | 记忆巩固 | 海马 → 皮层的系统巩固 |
169
169
  | 画像构建(`*_profile`) | 自传体记忆 | DMN 负责自我参照加工 |
170
170
  | 主动消息(`send_to_user`) | 心智游移 | 走神产生与自我相关的念头 |
171
171
  | 每轮数万 tokens | 静息高能耗 | DMN 占脑能耗约 20% |
@@ -287,7 +287,7 @@ $$\text{delay} = \min(\text{base} \times \text{multiplier}^{\text{penalty}-1},\
287
287
  | 阶段 | 内容 |
288
288
  | -------------- | ---------------------------------------------------------- |
289
289
  | 状态加载 | 从 `SubconsciousState` 表恢复 `total_runs` / 摘要窗口 |
290
- | 记忆限幅 | Core `MemoryLimiter` 截断超限消息并生成摘要 |
290
+ | 记忆限幅 | Core `ContextCompactor` 截断超限消息并生成摘要 |
291
291
  | ReAct 循环 | Agent 调用 `subconscious_*` 工具执行整理 |
292
292
  | 后处理 | 更新全局 usage、持久化元状态、重置惩罚、调度下次运行 |
293
293
 
@@ -304,12 +304,13 @@ $$\text{delay} = \min(\text{base} \times \text{multiplier}^{\text{penalty}-1},\
304
304
 
305
305
  ```mermaid
306
306
  flowchart TD
307
- LOAD_STATE --> JINJA2_RENDER --> LIMITING_MEMORY --> BUILD_MESSAGE --> REACT_BLOCK
307
+ LOAD_STATE --> NORMALIZE_MESSAGES --> COMPACT_HISTORY --> JINJA2_RENDER --> BUILD_MESSAGE --> REACT_BLOCK
308
308
  ```
309
309
 
310
310
  `SubconsciousRunner` 把 ChatObject 当数据容器,注入自定义 `SubconsciousBackend`
311
311
  (隔离的工具 + memory 后端)与 Core `ReActAgentStrategy`。
312
- `LIMITING_MEMORY` 在 Agent Loop 前运行 Core `MemoryLimiter`。
312
+ 工作流直接复用 Core 内置的 `REACT_ONLY`,其中的 `COMPACT_HISTORY` 节点在 Agent
313
+ Loop 前运行 Core `ContextCompactor`。压缩排在渲染之前,摘要才能进入本次请求的系统提示词。
313
314
 
314
315
  ---
315
316
 
@@ -473,7 +474,7 @@ flowchart TD
473
474
  | ---------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
474
475
  | L1 备忘录 | `UserMemo` 表(插件自有 ORM,主键 = uni_id) | LLM 维护的常驻用户元信息(≤ `memo_max_chars`) |
475
476
  | 循环元状态 | `SubconsciousState` 表(插件自有 ORM,uid=`amrita_memory`) | `total_runs`、`last_abstracts`、`pending_messages`、`knowledge_suggestions` |
476
- | Session 摘要缓存 | `LRUCache[int, str]`(最大 128 条) | session DB id → LLM 生成的摘要文本,避免重复调用 MemoryLimiter |
477
+ | Session 摘要缓存 | `LRUCache[int, str]`(最大 128 条) | session DB id → LLM 生成的摘要文本,避免重复调用 `ContextCompactor` |
477
478
  | 惩罚计数器 | 内存(不持久化) | `_penalty_count`:重启后从 0 开始 |
478
479
  | L2 记忆 | ChromaDB `amrita_user_memory` | 向量 + documents + metadatas(含嵌入指纹与分区键版本) |
479
480
  | 用户画像 | `data/amrita_plugin_memory/user_profile.md` | Markdown 文件,`summary---body` 格式,行级增量更新 |
@@ -649,7 +650,6 @@ amrita_plugin_memory/
649
650
  ├── types.py # TypedDict 定义
650
651
  ├── consts.py # 默认 Prompt 模板 / ensure_prompt_file
651
652
  ├── backend.py # SubconsciousBackend — 隔离的工具 + memory 后端
652
- ├── nodes.py # LIMITING_MEMORY 工作流节点
653
653
  ├── runner.py # SubconsciousRunner — 核心编排器
654
654
  ├── hooks.py # on_precompletion hook / 生命周期管理
655
655
  ├── tools.py # 20 个巩固循环工具 handler
@@ -26,7 +26,6 @@ amrita_plugin_memory/rethinking/backend.py
26
26
  amrita_plugin_memory/rethinking/consts.py
27
27
  amrita_plugin_memory/rethinking/hooks.py
28
28
  amrita_plugin_memory/rethinking/knowledge.py
29
- amrita_plugin_memory/rethinking/nodes.py
30
29
  amrita_plugin_memory/rethinking/runner.py
31
30
  amrita_plugin_memory/rethinking/schemas.py
32
31
  amrita_plugin_memory/rethinking/tools.py
@@ -1,10 +1,10 @@
1
1
  aiohttp>=3.13.3
2
2
  aiologic>=0.16.0
3
- amrita-core>=0.8.5
4
- amrita>=1.3
3
+ amrita-core<2.0.0,>=1.0.0
4
+ amrita>=1.10
5
5
  chromadb>=1.5.8
6
6
  click>=8.1
7
- nonebot-plugin-amrita>=0.3.0
7
+ nonebot-plugin-amrita>=0.4.0
8
8
  nonebot-plugin-apscheduler>=0.5.0
9
9
  nonebot-plugin-localstore>=0.7.4
10
10
  nonebot-plugin-orm[default]>=0.8.2
@@ -1,15 +1,15 @@
1
1
  [project]
2
2
  name = "amrita_plugin_memory"
3
3
  description = "Amrita长期记忆插件"
4
- version = "0.4.1"
4
+ version = "0.5.0"
5
5
  dependencies = [
6
6
  "aiohttp>=3.13.3",
7
7
  "aiologic>=0.16.0",
8
- "amrita-core>=0.8.5",
9
- "amrita>=1.3",
8
+ "amrita-core>=1.0.0,<2.0.0",
9
+ "amrita>=1.10",
10
10
  "chromadb>=1.5.8",
11
11
  "click>=8.1",
12
- "nonebot-plugin-amrita>=0.3.0",
12
+ "nonebot-plugin-amrita>=0.4.0",
13
13
  "nonebot-plugin-apscheduler>=0.5.0",
14
14
  "nonebot-plugin-localstore>=0.7.4",
15
15
  "nonebot-plugin-orm[default]>=0.8.2",
@@ -1,27 +0,0 @@
1
- """工作流 Node — 复用 Core Agent 框架。"""
2
-
3
- from amrita_core.chatmanager import ChatObject
4
- from amrita_core.chatmanager.memory_limiter import MemoryLimiter
5
- from amrita_core.utils import gather_usage
6
- from amrita_sense import Node
7
-
8
-
9
- @Node(tag="subconscious_limiting_memory")
10
- async def LIMITING_MEMORY(chat_obj: ChatObject) -> None:
11
- """运行 Core MemoryLimiter — 截断超限消息并生成摘要。
12
-
13
- 等价于 chat_object.py 的 _limiting_memory,去掉了 SuspendEnum 暂停机制
14
- (因为我们不使用 ChatObject 的流式暂停)。
15
- """
16
- mem_ctx = chat_obj._di_memory
17
- input_ctx = chat_obj._di_input
18
- ab = chat_obj._di_ability
19
- resp = chat_obj._di_resp
20
- if not ab.config.llm.enable_memory_abstract:
21
- return
22
- assert mem_ctx.memory is not None, "Memory must be loaded before limiting"
23
- async with MemoryLimiter(mem_ctx.memory, input_ctx.train, config=ab.config) as lim:
24
- await lim.run_enforce()
25
- if abs_usage := lim.usage:
26
- resp.extra_usage = gather_usage(resp.extra_usage, abs_usage)
27
- mem_ctx.memory = lim.memory